You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by sa...@apache.org on 2017/07/20 07:12:48 UTC

[cloudstack] branch master updated (445dbe7 -> e243a31)

This is an automated email from the ASF dual-hosted git repository.

sateesh pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack.git.


    from 445dbe7  Merge remote-tracking branch 'origin/4.10'
     new 884606f  CLOUDSTACK-8672 : NCC Integration with CloudStack.
     new b2f7f9a  CLOUDSTACK-8672 : NCC Integration with CloudStack.
     new b2b422c  CLOUDSTACK-8672 : NCC Integration with CloudStack.
     new 6535949  CLOUDSTACK-8672 : NCC Integration with CloudStack. Marvin Integration Tests for Shared and Dedicated Workflow.
     new e243a31  CLOUDSTACK-8672 : NCC Integration with CloudStack. Improvements.

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 api/src/com/cloud/agent/api/to/LoadBalancerTO.java |  71 +-
 api/src/com/cloud/event/EventTypes.java            |  16 +
 api/src/com/cloud/host/Host.java                   |   2 +-
 api/src/com/cloud/network/NetworkService.java      |   7 +
 .../com/cloud/network/VirtualRouterProvider.java   |   2 +-
 .../com/cloud/network/router/VirtualRouter.java    |   2 +-
 api/src/com/cloud/offering/NetworkOffering.java    |   4 +-
 api/src/com/cloud/vm/VirtualMachine.java           |   1 +
 .../org/apache/cloudstack/api/ApiConstants.java    |   2 +
 .../admin/address/AcquirePodIpCmdByAdmin.java      |  92 ++
 .../admin/address/ReleasePodIpCmdByAdmin.java      |  79 ++
 .../admin/network/CreateNetworkOfferingCmd.java    |  15 +-
 .../loadbalancer/UpdateLoadBalancerRuleCmd.java    |   7 +
 .../user/loadbalancer/UploadSslCertCmd.java        |   8 +
 .../api/response/AcquireIPAddressResponse.java     | 286 +++++++
 .../api/response/AcquirePodIpCmdResponse.java      | 113 +++
 .../cloudstack/api/response/SslCertResponse.java   |   8 +
 .../cloudstack/api/response/SystemVmResponse.java  |  25 +-
 .../org/apache/cloudstack/network/tls/SslCert.java |   2 +-
 .../api/ExternalNetworkResourceUsageCommand.java   |   9 +
 .../api/NetScalerImplementNetworkCommand.java      |  65 ++
 .../api/StartupExternalLoadBalancerCommand.java    |   3 +
 .../api/routing/HealthCheckLBConfigCommand.java    |   8 +-
 .../service/NetworkOrchestrationService.java       |  18 +-
 .../service/VolumeOrchestrationService.java        |   6 +-
 .../src/com/cloud/network/IpAddressManager.java    |  81 +-
 .../com/cloud/vm/VirtualMachineManagerImpl.java    |   3 +-
 .../com/cloud/dc/dao/DataCenterIpAddressDao.java   |   2 +
 .../cloud/dc/dao/DataCenterIpAddressDaoImpl.java   |  13 +
 engine/schema/src/com/cloud/dc/dao/HostPodDao.java |   2 +
 .../src/com/cloud/dc/dao/HostPodDaoImpl.java       |   8 +
 .../schema/src/com/cloud/host/dao/HostDaoImpl.java |   2 +-
 .../src/com/cloud/network/dao/NetworkDao.java      |   2 +
 .../src/com/cloud/network/dao/NetworkDaoImpl.java  |  16 +-
 .../src/com/cloud/network/dao/SslCertVO.java       |  11 +-
 .../src/com/cloud/offerings/NetworkOfferingVO.java |  12 +
 .../cloud/offerings/dao/NetworkOfferingDao.java    |   3 +
 .../offerings/dao/NetworkOfferingDaoImpl.java      |  32 +
 .../src/com/cloud/hypervisor/guru/VMwareGuru.java  |   4 +
 .../hypervisor/vmware/resource/VmwareResource.java |  10 +
 .../xenserver/resource/CitrixResourceBase.java     |  16 +-
 .../wrapper/xenbase/CitrixStartCommandWrapper.java |   1 -
 plugins/network-elements/netscaler/pom.xml         |   5 +
 .../netscaler/spring-netscaler-context.xml         |   5 +-
 .../commands/DeleteNetscalerControlCenterCmd.java  |  95 +++
 .../commands/DeleteNetscalerLoadBalancerCmd.java   |   2 +-
 .../commands/DeleteServicePackageOfferingCmd.java  |  92 ++
 ...BalancerCmd.java => DeployNetscalerVpxCmd.java} |  87 +-
 .../commands/ListNetscalerControlCenterCmd.java    |  93 +++
 .../commands/ListRegisteredServicePackageCmd.java  |  81 ++
 ...java => RegisterNetscalerControlCenterCmd.java} |  76 +-
 ...ncerCmd.java => RegisterServicePackageCmd.java} |  76 +-
 .../com/cloud/api/commands/StopNetScalerVMCmd.java | 132 +++
 .../response/NetScalerServicePackageResponse.java  |  73 ++
 .../response/NetscalerControlCenterResponse.java   |  98 +++
 .../cloud/network/NetScalerControlCenterVO.java    | 127 +++
 .../cloud/network/NetScalerServicePackageVO.java   | 105 +++
 .../network/dao/NetScalerControlCenterDao.java     |  15 +-
 .../network/dao/NetScalerControlCenterDaoImpl.java |  26 +-
 .../network/dao/NetScalerServicePackageDao.java    |  19 +-
 .../dao/NetScalerServicePackageDaoImpl.java        |  67 ++
 .../cloud/network/element/NetscalerElement.java    | 694 +++++++++++++---
 .../NetscalerLoadBalancerElementService.java       |  75 +-
 .../resource/NetScalerControlCenterResource.java   | 924 +++++++++++++++++++++
 .../com/cloud/network/vm/NetScalerVMManager.java   |  42 +
 .../cloud/network/vm/NetScalerVMManagerImpl.java   | 448 ++++++++++
 server/src/com/cloud/alert/AlertManagerImpl.java   | 208 ++---
 server/src/com/cloud/api/ApiResponseHelper.java    |   6 +-
 server/src/com/cloud/configuration/Config.java     |   9 +-
 .../configuration/ConfigurationManagerImpl.java    |  39 +-
 .../com/cloud/hypervisor/HypervisorGuruBase.java   |   4 +
 .../network/ExternalDeviceUsageManagerImpl.java    |  40 +-
 .../ExternalLoadBalancerDeviceManagerImpl.java     | 104 ++-
 .../com/cloud/network/IpAddressManagerImpl.java    | 578 +++++++------
 .../src/com/cloud/network/NetworkServiceImpl.java  |  25 +
 .../network/lb/LoadBalancingRulesManagerImpl.java  |  14 +-
 .../src/com/cloud/server/ManagementServerImpl.java |   5 +
 server/src/com/cloud/server/StatsCollector.java    |   1 +
 .../cloudstack/network/ssl/CertServiceImpl.java    |   4 +-
 .../ExternalLoadBalancerDeviceManagerImplTest.java |  19 +-
 .../test/com/cloud/vpc/MockNetworkManagerImpl.java |  12 +
 .../test/com/cloud/vpc/dao/MockNetworkDaoImpl.java | 153 +---
 setup/db/db/schema-4930to41000.sql                 |  25 +-
 .../component/test_ncc_integration_dedicated.py    | 269 ++++++
 .../component/test_ncc_integration_shared.py       | 323 +++++++
 tools/apidoc/gen_toc.py                            |  10 +
 tools/marvin/marvin/config/test_data.py            |  48 ++
 tools/marvin/marvin/lib/base.py                    |  21 +
 tools/marvin/marvin/lib/ncc.py                     | 317 +++++++
 ui/index.html                                      |   1 +
 ui/l10n/en.js                                      |  24 +
 ui/scripts/accounts.js                             | 193 +++++
 ui/scripts/configuration.js                        |  93 ++-
 ui/scripts/docs.js                                 |   4 +
 ui/scripts/lbCertificatePolicy.js                  | 183 ++++
 ui/scripts/network.js                              | 349 ++++----
 ui/scripts/regions.js                              | 222 +++++
 ui/scripts/system.js                               |  63 +-
 98 files changed, 6859 insertions(+), 1033 deletions(-)
 create mode 100644 api/src/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java
 create mode 100644 api/src/org/apache/cloudstack/api/command/admin/address/ReleasePodIpCmdByAdmin.java
 create mode 100644 api/src/org/apache/cloudstack/api/response/AcquireIPAddressResponse.java
 create mode 100644 api/src/org/apache/cloudstack/api/response/AcquirePodIpCmdResponse.java
 create mode 100644 core/src/com/cloud/agent/api/NetScalerImplementNetworkCommand.java
 create mode 100644 plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerControlCenterCmd.java
 create mode 100644 plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteServicePackageOfferingCmd.java
 copy plugins/network-elements/netscaler/src/com/cloud/api/commands/{DeleteNetscalerLoadBalancerCmd.java => DeployNetscalerVpxCmd.java} (52%)
 create mode 100644 plugins/network-elements/netscaler/src/com/cloud/api/commands/ListNetscalerControlCenterCmd.java
 create mode 100644 plugins/network-elements/netscaler/src/com/cloud/api/commands/ListRegisteredServicePackageCmd.java
 copy plugins/network-elements/netscaler/src/com/cloud/api/commands/{DeleteNetscalerLoadBalancerCmd.java => RegisterNetscalerControlCenterCmd.java} (58%)
 copy plugins/network-elements/netscaler/src/com/cloud/api/commands/{DeleteNetscalerLoadBalancerCmd.java => RegisterServicePackageCmd.java} (51%)
 create mode 100644 plugins/network-elements/netscaler/src/com/cloud/api/commands/StopNetScalerVMCmd.java
 create mode 100644 plugins/network-elements/netscaler/src/com/cloud/api/response/NetScalerServicePackageResponse.java
 create mode 100644 plugins/network-elements/netscaler/src/com/cloud/api/response/NetscalerControlCenterResponse.java
 create mode 100644 plugins/network-elements/netscaler/src/com/cloud/network/NetScalerControlCenterVO.java
 create mode 100644 plugins/network-elements/netscaler/src/com/cloud/network/NetScalerServicePackageVO.java
 copy core/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java => plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerControlCenterDao.java (68%)
 copy engine/schema/src/com/cloud/dc/dao/HostPodDao.java => plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerControlCenterDaoImpl.java (58%)
 copy api/src/com/cloud/network/VirtualRouterProvider.java => plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDao.java (66%)
 create mode 100644 plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDaoImpl.java
 create mode 100644 plugins/network-elements/netscaler/src/com/cloud/network/resource/NetScalerControlCenterResource.java
 create mode 100644 plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManager.java
 create mode 100644 plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManagerImpl.java
 create mode 100755 test/integration/component/test_ncc_integration_dedicated.py
 create mode 100755 test/integration/component/test_ncc_integration_shared.py
 create mode 100755 tools/marvin/marvin/lib/ncc.py
 create mode 100644 ui/scripts/lbCertificatePolicy.js
 mode change 100755 => 100644 ui/scripts/network.js
 mode change 100644 => 100755 ui/scripts/system.js

-- 
To stop receiving notification emails like this one, please contact
['"commits@cloudstack.apache.org" <co...@cloudstack.apache.org>'].

[cloudstack] 01/05: CLOUDSTACK-8672 : NCC Integration with CloudStack.

Posted by sa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sateesh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit 884606f77be7621944d2f315fd8eabe8884c45d9
Author: Rajesh Battala <ra...@citrix.com>
AuthorDate: Thu Jul 23 14:14:07 2015 +0530

    CLOUDSTACK-8672 : NCC Integration with CloudStack.
---
 api/src/com/cloud/event/EventTypes.java            |    9 +
 api/src/com/cloud/host/Host.java                   |    2 +-
 .../org/apache/cloudstack/api/ApiConstants.java    |    2 +
 .../api/NetScalerImplementNetworkCommand.java      |   65 +
 .../api/StartupExternalLoadBalancerCommand.java    |    3 +
 .../engine/orchestration/NetworkOrchestrator.java  |   18 +-
 .../schema/src/com/cloud/host/dao/HostDaoImpl.java |    2 +-
 plugins/network-elements/netscaler/pom.xml         |    5 +
 .../netscaler/spring-netscaler-context.xml         |    3 +-
 .../RegisterNetscalerControlCenterCmd.java         |  144 +
 .../api/commands/RegisterServicePackageCmd.java    |  107 +
 .../response/NetScalerServicePackageResponse.java  |   71 +
 .../cloud/network/NetScalerControlCenterVO.java    |  129 +
 .../cloud/network/NetScalerServicePackageVO.java   |  107 +
 .../network/dao/NetScalerControlCenterDao.java     |   15 +-
 .../network/dao/NetScalerControlCenterDaoImpl.java |   31 +-
 .../network/dao/NetScalerServicePackageDao.java    |   16 +-
 .../dao/NetScalerServicePackageDaoImpl.java        |   65 +
 .../cloud/network/element/NetscalerElement.java    |  329 +-
 .../NetscalerLoadBalancerElementService.java       |   20 +
 .../resource/NetScalerControlCenterResource.java   | 4026 ++++++++++++++++++++
 server/src/com/cloud/configuration/Config.java     |    9 +-
 .../ExternalLoadBalancerDeviceManagerImpl.java     |    7 +-
 server/src/com/cloud/server/StatsCollector.java    |    1 +
 setup/db/db/schema-4930to41000.sql                 |   25 +-
 25 files changed, 5170 insertions(+), 41 deletions(-)

diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java
index 3cc4eac..b46b352 100644
--- a/api/src/com/cloud/event/EventTypes.java
+++ b/api/src/com/cloud/event/EventTypes.java
@@ -545,6 +545,11 @@ public class EventTypes {
     //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";
+
+
     static {
 
         // TODO: need a way to force author adding event types to declare the entity details as well, with out braking
@@ -918,6 +923,10 @@ public class EventTypes {
 
         //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");
+
     }
 
     public static String getEntityForEvent(String eventName) {
diff --git a/api/src/com/cloud/host/Host.java b/api/src/com/cloud/host/Host.java
index 689ed12..3ed4f5e 100644
--- a/api/src/com/cloud/host/Host.java
+++ b/api/src/com/cloud/host/Host.java
@@ -31,7 +31,7 @@ import com.cloud.utils.fsm.StateObject;
 public interface Host extends StateObject<Status>, Identity, InternalIdentity {
     public enum Type {
         Storage(false), Routing(false), SecondaryStorage(false), SecondaryStorageCmdExecutor(false), ConsoleProxy(true), ExternalFirewall(false), ExternalLoadBalancer(
-                false), ExternalVirtualSwitchSupervisor(false), PxeServer(false), BaremetalPxe(false), BaremetalDhcp(false), TrafficMonitor(false),
+                false), ExternalVirtualSwitchSupervisor(false), PxeServer(false), BaremetalPxe(false), BaremetalDhcp(false), TrafficMonitor(false), NetScalerControlCenter(false),
 
         ExternalDhcp(false), SecondaryStorageVM(true), LocalSecondaryStorage(false), L2Networking(false);
         boolean _virtual;
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
index a16a327..febbb0f 100644
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -652,6 +652,8 @@ public class ApiConstants {
     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 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";
diff --git a/core/src/com/cloud/agent/api/NetScalerImplementNetworkCommand.java b/core/src/com/cloud/agent/api/NetScalerImplementNetworkCommand.java
new file mode 100644
index 0000000..ea6afa1
--- /dev/null
+++ b/core/src/com/cloud/agent/api/NetScalerImplementNetworkCommand.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 com.cloud.agent.api;
+
+public class NetScalerImplementNetworkCommand extends Command {
+    private String _networkDetails;
+
+    public NetScalerImplementNetworkCommand() {
+        super();
+    }
+
+    private Long dcId;
+    private Long hostId;
+
+    public NetScalerImplementNetworkCommand(Long dcId) {
+        super();
+        this.dcId = dcId;
+    }
+
+    public NetScalerImplementNetworkCommand(Long dcId, Long hostId, String networkDetails) {
+        this(dcId);
+        this.hostId = hostId;
+        this._networkDetails = networkDetails;
+    }
+
+    public void setDetails(String details) {
+        _networkDetails = details;
+    }
+
+    public String getDetails() {
+        return _networkDetails;
+    }
+
+    public Long getDataCenterId() {
+        return dcId;
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        //TODO checkout whether we need to mark it true ??
+        //Marking it true is causing another guest network execution in queue
+        return false;
+    }
+
+    public Long getHostId() {
+        return hostId;
+    }
+}
diff --git a/core/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java b/core/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java
index 50187b2..698988e 100644
--- a/core/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java
+++ b/core/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java
@@ -26,4 +26,7 @@ public class StartupExternalLoadBalancerCommand extends StartupCommand {
         super(Host.Type.ExternalLoadBalancer);
     }
 
+    public StartupExternalLoadBalancerCommand(Host.Type type) {
+        super(type);
+    }
 }
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
index 37f5330..7f43b52 100644
--- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
+++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
@@ -442,7 +442,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
                 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, null, false, null, true, null);
                     offering.setState(NetworkOffering.State.Enabled);
                     _networkOfferingDao.update(offering.getId(), offering);
                 }
@@ -451,7 +451,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
                 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);
+                            null, true, false, null, false, null, true, null);
                     offering.setState(NetworkOffering.State.Enabled);
                     _networkOfferingDao.update(offering.getId(), offering);
                 }
@@ -460,7 +460,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
                 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);
+                            null, true, null);
                     offering.setState(NetworkOffering.State.Enabled);
                     _networkOfferingDao.update(offering.getId(), offering);
                 }
@@ -470,7 +470,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
                     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);
+                            true, null);
 
                     offering.setState(NetworkOffering.State.Enabled);
                     _networkOfferingDao.update(offering.getId(), offering);
@@ -480,7 +480,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
                 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);
+                            defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, null);
                     offering.setState(NetworkOffering.State.Enabled);
                     _networkOfferingDao.update(offering.getId(), offering);
                 }
@@ -491,7 +491,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
                     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);
+                            null, defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, null);
                     offering.setState(NetworkOffering.State.Enabled);
                     _networkOfferingDao.update(offering.getId(), offering);
                 }
@@ -500,7 +500,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
                 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);
+                            true, null, true, false, null, false, null, true, null);
                     offering.setState(NetworkOffering.State.Enabled);
                     _networkOfferingDao.update(offering.getId(), offering);
                 }
@@ -524,7 +524,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
                 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, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, null);
                     offering.setState(NetworkOffering.State.Enabled);
                     offering.setInternalLb(true);
                     offering.setPublicLb(false);
@@ -556,7 +556,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
                 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);
+                            netscalerServiceProviders, true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true, false, null, false, null, true, null);
                     offering.setState(NetworkOffering.State.Enabled);
                     offering.setDedicatedLB(false);
                     _networkOfferingDao.update(offering.getId(), offering);
diff --git a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java
index a74b908..f12a628 100644
--- a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java
+++ b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java
@@ -642,7 +642,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
         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.L2Networking, Type.NetScalerControlCenter);
         List<HostVO> hosts = lockRows(sc, null, true);
 
         for (HostVO host : hosts) {
diff --git a/plugins/network-elements/netscaler/pom.xml b/plugins/network-elements/netscaler/pom.xml
index 9076687..a8a7eb1 100644
--- a/plugins/network-elements/netscaler/pom.xml
+++ b/plugins/network-elements/netscaler/pom.xml
@@ -37,5 +37,10 @@
       <artifactId>sdx_nitro</artifactId>
       <version>${cs.nitro.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.json</groupId>
+      <artifactId>json</artifactId>
+      <version>20090211</version>
+    </dependency>
   </dependencies>
 </project>
diff --git a/plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/spring-netscaler-context.xml b/plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/spring-netscaler-context.xml
index a75db6b..5727304 100644
--- a/plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/spring-netscaler-context.xml
+++ b/plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/spring-netscaler-context.xml
@@ -26,7 +26,8 @@
                       http://www.springframework.org/schema/context
                       http://www.springframework.org/schema/context/spring-context.xsd"
                       >
-
+    <bean id="netScalerServicePackageDaoImpl" class="com.cloud.network.dao.NetScalerServicePackageDaoImpl" />
+    <bean id="netScalerControlCenterDaoImpl" class="com.cloud.network.dao.NetScalerControlCenterDaoImpl" />
     <bean id="netScalerPodDaoImpl" class="com.cloud.network.dao.NetScalerPodDaoImpl" />
     <bean id="netscalerElement" class="com.cloud.network.element.NetscalerElement" >
         <property name="name" value="Netscaler"/>
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterNetscalerControlCenterCmd.java b/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterNetscalerControlCenterCmd.java
new file mode 100644
index 0000000..8887736
--- /dev/null
+++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterNetscalerControlCenterCmd.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.commands;
+
+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.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.api.response.NetscalerLoadBalancerResponse;
+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.NetScalerControlCenterVO;
+import com.cloud.network.element.NetscalerLoadBalancerElementService;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@APICommand(name = "registerNetscalerControlCenter", responseObject = NetscalerLoadBalancerResponse.class, description = "Adds a netscaler control center device",
+        requestHasSensitiveInfo = true, responseHasSensitiveInfo = false)
+public class RegisterNetscalerControlCenterCmd extends BaseAsyncCmd {
+
+    public static final Logger s_logger = Logger.getLogger(RegisterNetscalerControlCenterCmd.class.getName());
+    private static final String s_name = "registernetscalercontrolcenterrresponse";
+    @Inject
+    NetscalerLoadBalancerElementService _netsclarLbService;
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.IP_ADDRESS , type = CommandType.STRING, required = true, description = "URL of the netscaler controlcenter appliance.")
+    private String ipaddress;
+
+    @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = true, description = "Credentials to reach netscaler controlcenter device")
+    private String username;
+
+    @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, required = true, description = "Credentials to reach netscaler controlcenter  device")
+    private String password;
+
+    @Parameter(name = ApiConstants.NUM_RETRIES , type = CommandType.INTEGER, required = true, description = "Credentials to reach netscaler controlcenter device")
+    private int numretries;
+
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+
+    public String getUsername() {
+        return username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+
+    public static Logger getsLogger() {
+        return s_logger;
+    }
+
+    public static String getsName() {
+        return s_name;
+    }
+
+    public NetscalerLoadBalancerElementService get_netsclarLbService() {
+        return _netsclarLbService;
+    }
+
+    public String getIpaddress() {
+        return ipaddress;
+    }
+
+    public int getNumretries() {
+        return numretries;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
+        ResourceAllocationException {
+        try {
+            NetScalerControlCenterVO nccVO = _netsclarLbService.registerNetscalerControlCenter(this);
+            if (nccVO != null) {
+                /*NetscalerLoadBalancerResponse response = _netsclarLbService.createNetscalerLoadBalancerResponse(lbDeviceVO);
+                response.setObjectName("netscalerloadbalancer");
+                response.setResponseName(getCommandName());
+                this.setResponseObject(response);*/
+            } else {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add netscaler load balancer 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());
+        }
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Adding a netscaler load balancer device";
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_EXTERNAL_LB_DEVICE_ADD;
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return CallContext.current().getCallingAccount().getId();
+    }
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..52e8e5a
--- /dev/null
+++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterServicePackageCmd.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.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 String getEventType() {
+        return EventTypes.EVENT_NETSCALER_SERVICEPACKAGE_ADD;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Adding Netscaler Service Package";
+    }
+*/
+    @Override
+    public void execute() throws ServerApiException, ConcurrentOperationException, EntityExistsException {
+        try {
+            NetScalerServicePackageResponse response =  _netsclarLbService.registerNetscalerServicePackage(this);
+
+            if (response != null) {
+                //NetScalerServicePackageResponse response = _netsclarLbService.createNetscalerServicePackageResponse(servicePackageVO);
+                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/api/response/NetScalerServicePackageResponse.java b/plugins/network-elements/netscaler/src/com/cloud/api/response/NetScalerServicePackageResponse.java
new file mode 100644
index 0000000..4950875
--- /dev/null
+++ b/plugins/network-elements/netscaler/src/com/cloud/api/response/NetScalerServicePackageResponse.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.api.response;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+
+import com.cloud.network.NetScalerServicePackageVO;
+import com.cloud.serializer.Param;
+
+public class NetScalerServicePackageResponse extends BaseResponse {
+    @SerializedName(ApiConstants.ID)
+    @Param(description = "Service Package UUID")
+    private String id;
+
+    @SerializedName(ApiConstants.NAME)
+    @Param(description = "Service Package Name")
+    private String name;
+
+    @SerializedName(ApiConstants.DESCRIPTION)
+    @Param(description = "Description of Service Package")
+    private String description;
+
+    public NetScalerServicePackageResponse() {}
+
+    public NetScalerServicePackageResponse(NetScalerServicePackageVO servicePackage) {
+        this.id = servicePackage.getUuid();
+        this.name = servicePackage.getName();
+        this.description = servicePackage.getDescription();
+    }
+
+    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 getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+}
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerControlCenterVO.java b/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerControlCenterVO.java
new file mode 100644
index 0000000..e1cd13d
--- /dev/null
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerControlCenterVO.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.network;
+
+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.api.InternalIdentity;
+
+
+/**
+ * NetScalerPodVO contains information about a EIP deployment where on datacenter L3 router a PBR (policy
+ * based routing) is setup between a POD's subnet IP range to a NetScaler device. This VO object
+ * represents a mapping between a POD and NetScaler device where PBR is setup.
+ *
+ */
+@Entity
+@Table(name = "external_netscaler_controlcenter")
+public class NetScalerControlCenterVO implements InternalIdentity {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id")
+    private long id;
+
+    @Column(name = "username")
+    private String username;
+
+    @Column(name = "password")
+    private String password;
+
+    @Column(name = "uuid")
+    private String uuid;
+
+    @Column(name = "ncc_ip")
+    private String nccip;
+
+    @Column(name = "num_retries")
+    private int numRetries;
+
+    public NetScalerControlCenterVO() {
+    }
+
+    public NetScalerControlCenterVO(long hostId, String username, String password, String nccip, int retries) {
+        this.username = username;
+        this.password = password;
+        this.uuid = UUID.randomUUID().toString();
+        this.nccip = nccip;
+        this.numRetries = retries;
+    }
+    public NetScalerControlCenterVO(String username, String password, String nccip, int retries) {
+        this.username = username;
+        this.password = password;
+        this.uuid = UUID.randomUUID().toString();
+        this.nccip = nccip;
+        this.numRetries = retries;
+    }
+
+    public String getUuid() {
+        return uuid;
+    }
+
+    public String getNccip() {
+        return nccip;
+    }
+
+    public void setNccip(String nccip) {
+        this.nccip = nccip;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    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;
+    }
+
+    public int getNumRetries() {
+        return numRetries;
+    }
+
+    public void setNumRetries(int numRetries) {
+        this.numRetries = numRetries;
+    }
+
+    @Override
+    public long getId() {
+        // TODO Auto-generated method stub
+        return id;
+    }
+
+}
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerServicePackageVO.java b/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerServicePackageVO.java
new file mode 100644
index 0000000..758d5a3
--- /dev/null
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerServicePackageVO.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.network;
+
+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.api.InternalIdentity;
+
+import com.cloud.api.commands.RegisterServicePackageCmd;
+
+/**
+ * NetScalerPodVO contains information about a EIP deployment where on datacenter L3 router a PBR (policy
+ * based routing) is setup between a POD's subnet IP range to a NetScaler device. This VO object
+ * represents a mapping between a POD and NetScaler device where PBR is setup.
+ *
+ */
+@Entity
+@Table(name = " netscaler_servicepackages")
+public class NetScalerServicePackageVO implements InternalIdentity {
+
+
+    @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;
+
+    public NetScalerServicePackageVO() {
+
+    }
+
+
+    public NetScalerServicePackageVO(RegisterServicePackageCmd cmd) {
+        this.name = cmd.getSpName();
+        this.description = cmd.getDescription();
+        this.uuid = UUID.randomUUID().toString();
+    }
+
+    @Override
+    public long getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+
+    public String getDescription() {
+        return description;
+    }
+
+
+    public String getUuid() {
+        return uuid;
+    }
+
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+}
diff --git a/core/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerControlCenterDao.java
similarity index 68%
copy from core/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java
copy to plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerControlCenterDao.java
index 50187b2..acf8dce 100644
--- a/core/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerControlCenterDao.java
@@ -1,4 +1,3 @@
-//
 // Licensed to the Apache Software Foundation (ASF) under one
 // or more contributor license agreements.  See the NOTICE file
 // distributed with this work for additional information
@@ -15,15 +14,15 @@
 // KIND, either express or implied.  See the License for the
 // specific language governing permissions and limitations
 // under the License.
-//
+package com.cloud.network.dao;
 
-package com.cloud.agent.api;
+import java.util.List;
 
-import com.cloud.host.Host;
+import com.cloud.network.NetScalerControlCenterVO;
+import com.cloud.utils.db.GenericDao;
 
-public class StartupExternalLoadBalancerCommand extends StartupCommand {
-    public StartupExternalLoadBalancerCommand() {
-        super(Host.Type.ExternalLoadBalancer);
-    }
+public interface NetScalerControlCenterDao extends GenericDao<NetScalerControlCenterVO, Long> {
 
+    NetScalerControlCenterVO findByPodId(long podId);
+    List<NetScalerControlCenterVO> listByNetScalerDeviceId(long netscalerDeviceId);
 }
diff --git a/core/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerControlCenterDaoImpl.java
similarity index 51%
copy from core/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java
copy to plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerControlCenterDaoImpl.java
index 50187b2..ec24842 100644
--- a/core/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerControlCenterDaoImpl.java
@@ -1,4 +1,3 @@
-//
 // Licensed to the Apache Software Foundation (ASF) under one
 // or more contributor license agreements.  See the NOTICE file
 // distributed with this work for additional information
@@ -15,15 +14,33 @@
 // 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.util.List;
+
+import javax.ejb.Local;
 
-package com.cloud.agent.api;
+import org.springframework.stereotype.Component;
 
-import com.cloud.host.Host;
+import com.cloud.network.NetScalerControlCenterVO;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GenericDaoBase;
+
+@Component
+@Local(value = NetScalerControlCenterDao.class)
+@DB
+public class NetScalerControlCenterDaoImpl extends GenericDaoBase<NetScalerControlCenterVO, Long> implements NetScalerControlCenterDao {
+
+    @Override
+    public NetScalerControlCenterVO findByPodId(long podId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
 
-public class StartupExternalLoadBalancerCommand extends StartupCommand {
-    public StartupExternalLoadBalancerCommand() {
-        super(Host.Type.ExternalLoadBalancer);
+    @Override
+    public List<NetScalerControlCenterVO> listByNetScalerDeviceId(long netscalerDeviceId) {
+        // TODO Auto-generated method stub
+        return null;
     }
 
 }
diff --git a/core/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDao.java
similarity index 67%
copy from core/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java
copy to plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDao.java
index 50187b2..fcda584 100644
--- a/core/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDao.java
@@ -1,4 +1,3 @@
-//
 // Licensed to the Apache Software Foundation (ASF) under one
 // or more contributor license agreements.  See the NOTICE file
 // distributed with this work for additional information
@@ -15,15 +14,16 @@
 // 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.util.List;
 
-package com.cloud.agent.api;
+import com.cloud.network.NetScalerServicePackageVO;
+import com.cloud.utils.db.GenericDao;
 
-import com.cloud.host.Host;
+public interface NetScalerServicePackageDao extends GenericDao<NetScalerServicePackageVO, Long> {
 
-public class StartupExternalLoadBalancerCommand extends StartupCommand {
-    public StartupExternalLoadBalancerCommand() {
-        super(Host.Type.ExternalLoadBalancer);
-    }
+    NetScalerServicePackageVO findByPodId(long podId);
 
+    List<NetScalerServicePackageVO> listByNetScalerDeviceId(long netscalerDeviceId);
 }
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDaoImpl.java b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDaoImpl.java
new file mode 100644
index 0000000..df99b49
--- /dev/null
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDaoImpl.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 com.cloud.network.dao;
+
+import java.util.List;
+
+import javax.ejb.Local;
+
+import org.springframework.stereotype.Component;
+
+import com.cloud.network.NetScalerServicePackageVO;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+
+@Component
+@Local(value = NetScalerServicePackageDao.class)
+@DB
+public class NetScalerServicePackageDaoImpl extends GenericDaoBase<NetScalerServicePackageVO, Long> implements NetScalerServicePackageDao {
+
+    final SearchBuilder<NetScalerServicePackageVO> podIdSearch;
+    final SearchBuilder<NetScalerServicePackageVO> deviceIdSearch;
+
+    protected NetScalerServicePackageDaoImpl() {
+        super();
+
+        podIdSearch = createSearchBuilder();
+        //podIdSearch.and("pod_id", podIdSearch.entity().getPodId(), Op.EQ);
+        podIdSearch.done();
+
+        deviceIdSearch = createSearchBuilder();
+        //deviceIdSearch.and("netscalerDeviceId", deviceIdSearch.entity().getNetscalerDeviceId(), Op.EQ);
+        deviceIdSearch.done();
+    }
+
+    @Override
+    public NetScalerServicePackageVO findByPodId(long podId) {
+        SearchCriteria<NetScalerServicePackageVO> sc = podIdSearch.create();
+        sc.setParameters("pod_id", podId);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public List<NetScalerServicePackageVO> listByNetScalerDeviceId(long netscalerDeviceId) {
+        SearchCriteria<NetScalerServicePackageVO> sc = deviceIdSearch.create();
+        sc.setParameters("netscalerDeviceId", netscalerDeviceId);
+        return search(sc, null);
+    }
+
+}
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
index dbf6d9a..60baa89 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java
@@ -23,20 +23,26 @@ 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.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;
@@ -51,12 +57,16 @@ import com.cloud.api.commands.ConfigureNetscalerLoadBalancerCmd;
 import com.cloud.api.commands.DeleteNetscalerLoadBalancerCmd;
 import com.cloud.api.commands.ListNetscalerLoadBalancerNetworksCmd;
 import com.cloud.api.commands.ListNetscalerLoadBalancersCmd;
+import com.cloud.api.commands.RegisterNetscalerControlCenterCmd;
+import com.cloud.api.commands.RegisterServicePackageCmd;
+import com.cloud.api.response.NetScalerServicePackageResponse;
 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;
@@ -67,13 +77,17 @@ 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;
@@ -88,7 +102,9 @@ 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;
@@ -98,6 +114,7 @@ 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.rules.FirewallRule;
 import com.cloud.network.rules.LbStickinessMethod;
@@ -105,9 +122,13 @@ import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType;
 import com.cloud.network.rules.LoadBalancerContainer;
 import com.cloud.network.rules.StaticNat;
 import com.cloud.offering.NetworkOffering;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ServerResource;
 import com.cloud.utils.NumbersUtil;
 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;
@@ -155,9 +176,25 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
     DataCenterIpAddressDao _privateIpAddressDao;
     @Inject
     ExternalLoadBalancerDeviceDao _externalLoadBalancerDeviceDao;
+    @Inject
+    NetScalerServicePackageDao _netscalerServicePackageDao;
+    @Inject
+    NetScalerControlCenterDao _netscalerControlCenterDao;
+    @Inject
+    ResourceManager _resourceMgr;
+    @Inject
+    HostDetailsDao _hostDetailDao;
+    @Inject
+    IpAddressManager _ipAddrMgr;
+    @Inject
+    NetworkOrchestrationService _networkService;
+    @Inject
+    NetworkOfferingDao _networkOfferingDao = null;
 
     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 =
@@ -193,13 +230,217 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         }
 
         try {
-            return manageGuestNetworkWithExternalLoadBalancer(true, guestConfig);
+            if(offering.getServicePackage() == null) {
+                return manageGuestNetworkWithExternalLoadBalancer(true, guestConfig);
+            } else {
+                // if the network offering has service package implement it with Netscaler Control Center
+                manageGuestNetworkWithNetscalerControlCenter(true, guestConfig, offering);
+                return true;
+            }
         } 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());
         }
     }
 
+
+    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", 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", zoneId);
+            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) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+
+        NetScalerImplementNetworkCommand cmd = new NetScalerImplementNetworkCommand(zoneId, 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 (add) {
+                     // Insert a new NIC for this guest network to reserve the self IP
+                     _networkService.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
+             return true;
+             //write code to remove the self nic or the clean up work
+         }
+        // Send a command to the external load balancer to implement or shutdown the guest network
+/*        long guestVlanTag = Long.parseLong(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.getIp4Address();
+        }
+*/
+        // 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, String.valueOf(guestVlanTag), selfIp, guestVlanNetmask, null, networkRate, inline);
+        IpAddressTO[] ips = new IpAddressTO[1];
+        ips[0] = ip;
+        IpAssocCommand cmd = new IpAssocCommand(ips);
+        Answer answer = _agentMgr.easySend(netscalerControlCenter.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 prepare(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
         throws ConcurrentOperationException, InsufficientNetworkCapacityException, ResourceUnavailableException {
@@ -218,11 +459,24 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         }
 
         try {
-            return manageGuestNetworkWithExternalLoadBalancer(false, guestConfig);
+
+            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);
+                //return true;
+            }
+            //return manageGuestNetworkWithExternalLoadBalancer(false, guestConfig);
         } catch (InsufficientCapacityException capacityException) {
             // TODO: handle out of capacity exception gracefully in case of multple providers available
             return false;
+        } catch (ConfigurationException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
         }
+        return false;
     }
 
     @Override
@@ -528,6 +782,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         cmdList.add(DeleteNetscalerLoadBalancerCmd.class);
         cmdList.add(ListNetscalerLoadBalancerNetworksCmd.class);
         cmdList.add(ListNetscalerLoadBalancersCmd.class);
+        cmdList.add(RegisterServicePackageCmd.class);
+        cmdList.add(RegisterNetscalerControlCenterCmd.class);
 
         return cmdList;
     }
@@ -645,7 +901,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
                 }
             }
         }
-        return false;
+        return true;
     }
 
     @Override
@@ -1046,4 +1302,71 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         }
         return true;
     }
+
+    @Override
+    public NetScalerServicePackageResponse registerNetscalerServicePackage(RegisterServicePackageCmd cmd) {
+        NetScalerServicePackageVO servicePackage = new NetScalerServicePackageVO(cmd);
+        NetScalerServicePackageResponse response = null;
+        _netscalerServicePackageDao.persist(servicePackage);
+        response = new NetScalerServicePackageResponse(servicePackage);
+        return response;
+    }
+
+    @Override
+    public NetScalerServicePackageResponse deleteNetscalerServicePackage(RegisterServicePackageCmd cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public NetScalerServicePackageResponse listNetscalerServicePackage(RegisterServicePackageCmd cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public NetScalerServicePackageResponse createNetscalerServicePackageResponse(NetScalerServicePackageVO servicePackageVO) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    @DB
+    public NetScalerControlCenterVO registerNetscalerControlCenter(RegisterNetscalerControlCenterCmd cmd) {
+
+        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(), cmdinfo.getPassword(),
+                            cmdinfo.getIpaddress(), cmdinfo.getNumretries());
+                    _netscalerControlCenterDao.persist(nccVO);
+                    /*DetailVO hostDetail = new DetailVO(host.getId(), ApiConstants.NETSCALER_CONTROLCENTER_ID , String.valueOf(nccVO.getId()));
+                    _hostDetailDao.persist(hostDetail);*/
+                    return nccVO;
+                }
+            });
+        } catch (ConfigurationException e) {
+            resource = null;
+            throw new CloudRuntimeException(e.getMessage());
+        }
+    }
 }
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerLoadBalancerElementService.java b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerLoadBalancerElementService.java
index ea4ab93..81c5b7c 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerLoadBalancerElementService.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerLoadBalancerElementService.java
@@ -23,7 +23,12 @@ import com.cloud.api.commands.ConfigureNetscalerLoadBalancerCmd;
 import com.cloud.api.commands.DeleteNetscalerLoadBalancerCmd;
 import com.cloud.api.commands.ListNetscalerLoadBalancerNetworksCmd;
 import com.cloud.api.commands.ListNetscalerLoadBalancersCmd;
+import com.cloud.api.commands.RegisterNetscalerControlCenterCmd;
+import com.cloud.api.commands.RegisterServicePackageCmd;
 import com.cloud.api.response.NetscalerLoadBalancerResponse;
+import com.cloud.api.response.NetScalerServicePackageResponse;
+import com.cloud.network.NetScalerControlCenterVO;
+import com.cloud.network.NetScalerServicePackageVO;
 import com.cloud.network.Network;
 import com.cloud.network.dao.ExternalLoadBalancerDeviceVO;
 import com.cloud.utils.component.PluggableService;
@@ -71,4 +76,19 @@ public interface NetscalerLoadBalancerElementService extends PluggableService {
      * @return NetscalerLoadBalancerResponse
      */
     public NetscalerLoadBalancerResponse createNetscalerLoadBalancerResponse(ExternalLoadBalancerDeviceVO lbDeviceVO);
+
+    /**
+     * creates API response object for netscaler load balancers
+     * @param lbDeviceVO external load balancer VO object
+     * @return NetscalerLoadBalancerResponse
+     */
+    public NetScalerServicePackageResponse registerNetscalerServicePackage(RegisterServicePackageCmd cmd);
+
+    public NetScalerServicePackageResponse deleteNetscalerServicePackage(RegisterServicePackageCmd cmd);
+
+    public NetScalerServicePackageResponse listNetscalerServicePackage(RegisterServicePackageCmd cmd);
+
+    public NetScalerServicePackageResponse createNetscalerServicePackageResponse(NetScalerServicePackageVO servicePackageVO);
+
+    public NetScalerControlCenterVO registerNetscalerControlCenter(RegisterNetscalerControlCenterCmd registerNetscalerControlCenterCmd);
 }
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
new file mode 100644
index 0000000..15342dc
--- /dev/null
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetScalerControlCenterResource.java
@@ -0,0 +1,4026 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.io.StringWriter;
+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.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Formatter;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.commons.io.output.ByteArrayOutputStream;
+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.bouncycastle.openssl.PEMWriter;
+import org.json.JSONObject;
+
+import com.citrix.netscaler.nitro.exception.nitro_exception;
+import com.citrix.netscaler.nitro.resource.base.base_response;
+import com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction;
+import com.citrix.netscaler.nitro.resource.config.autoscale.autoscalepolicy;
+import com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleprofile;
+import com.citrix.netscaler.nitro.resource.config.basic.server_service_binding;
+import com.citrix.netscaler.nitro.resource.config.basic.service_lbmonitor_binding;
+import com.citrix.netscaler.nitro.resource.config.basic.servicegroup;
+import com.citrix.netscaler.nitro.resource.config.basic.servicegroup_lbmonitor_binding;
+import com.citrix.netscaler.nitro.resource.config.gslb.gslbservice;
+import com.citrix.netscaler.nitro.resource.config.gslb.gslbservice_lbmonitor_binding;
+import com.citrix.netscaler.nitro.resource.config.gslb.gslbsite;
+import com.citrix.netscaler.nitro.resource.config.gslb.gslbsite_gslbservice_binding;
+import com.citrix.netscaler.nitro.resource.config.gslb.gslbvserver;
+import com.citrix.netscaler.nitro.resource.config.gslb.gslbvserver_domain_binding;
+import com.citrix.netscaler.nitro.resource.config.gslb.gslbvserver_gslbservice_binding;
+import com.citrix.netscaler.nitro.resource.config.lb.lbmetrictable;
+import com.citrix.netscaler.nitro.resource.config.lb.lbmetrictable_metric_binding;
+import com.citrix.netscaler.nitro.resource.config.lb.lbmonitor;
+import com.citrix.netscaler.nitro.resource.config.lb.lbmonitor_metric_binding;
+import com.citrix.netscaler.nitro.resource.config.lb.lbvserver;
+import com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding;
+import com.citrix.netscaler.nitro.resource.config.lb.lbvserver_servicegroup_binding;
+import com.citrix.netscaler.nitro.resource.config.network.inat;
+import com.citrix.netscaler.nitro.resource.config.network.rnat;
+import com.citrix.netscaler.nitro.resource.config.network.vlan;
+import com.citrix.netscaler.nitro.resource.config.network.vlan_interface_binding;
+import com.citrix.netscaler.nitro.resource.config.network.vlan_nsip_binding;
+import com.citrix.netscaler.nitro.resource.config.ns.nsconfig;
+import com.citrix.netscaler.nitro.resource.config.ns.nsip;
+import com.citrix.netscaler.nitro.resource.config.ns.nstimer;
+import com.citrix.netscaler.nitro.resource.config.ns.nstimer_autoscalepolicy_binding;
+import com.citrix.netscaler.nitro.resource.config.ssl.sslcertkey;
+import com.citrix.netscaler.nitro.resource.config.ssl.sslcertkey_sslvserver_binding;
+import com.citrix.netscaler.nitro.resource.config.ssl.sslcertlink;
+import com.citrix.netscaler.nitro.resource.config.ssl.sslvserver_sslcertkey_binding;
+import com.citrix.netscaler.nitro.resource.stat.lb.lbvserver_stats;
+import com.citrix.netscaler.nitro.service.nitro_service;
+import com.citrix.netscaler.nitro.util.filtervalue;
+import com.citrix.sdx.nitro.resource.config.ns.ns;
+import com.citrix.sdx.nitro.resource.config.xen.xen_nsvpx_image;
+import com.google.common.collect.Lists;
+import com.google.gson.Gson;
+
+import org.apache.cloudstack.api.ApiConstants;
+
+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.CreateLoadBalancerApplianceCommand;
+import com.cloud.agent.api.routing.DestroyLoadBalancerApplianceCommand;
+import com.cloud.agent.api.routing.GlobalLoadBalancerConfigAnswer;
+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.SetStaticNatRulesAnswer;
+import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
+import com.cloud.agent.api.routing.SiteLoadBalancerConfig;
+import com.cloud.agent.api.to.IpAddressTO;
+import com.cloud.agent.api.to.LoadBalancerTO;
+import com.cloud.agent.api.to.LoadBalancerTO.AutoScalePolicyTO;
+import com.cloud.agent.api.to.LoadBalancerTO.AutoScaleVmGroupTO;
+import com.cloud.agent.api.to.LoadBalancerTO.AutoScaleVmProfileTO;
+import com.cloud.agent.api.to.LoadBalancerTO.ConditionTO;
+import com.cloud.agent.api.to.LoadBalancerTO.CounterTO;
+import com.cloud.agent.api.to.LoadBalancerTO.DestinationTO;
+import com.cloud.agent.api.to.LoadBalancerTO.HealthCheckPolicyTO;
+import com.cloud.agent.api.to.LoadBalancerTO.StickinessPolicyTO;
+import com.cloud.agent.api.to.StaticNatRuleTO;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.network.lb.LoadBalancingRule.LbSslCert;
+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.Pair;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.exception.ExecutionException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.security.CertificateHelper;
+import com.cloud.utils.ssh.SshHelper;
+
+/*class NitroError {
+    static final int NS_RESOURCE_EXISTS = 273;
+    static final int NS_RESOURCE_NOT_EXISTS = 258;
+    static final int NS_NO_SERIVCE = 344;
+    static final int NS_OPERATION_NOT_PERMITTED = 257;
+    static final int NS_INTERFACE_ALREADY_BOUND_TO_VLAN = 2080;
+    static final int NS_GSLB_DOMAIN_ALREADY_BOUND = 1842;
+}*/
+
+public class NetScalerControlCenterResource implements ServerResource {
+
+    public final static int DEFAULT_SNMP_PORT = 161;
+    // deployment configuration
+    private String _name;
+    private String _zoneId;
+    private String _physicalNetworkId;
+    private String _ip;
+    private String _username;
+    private String _password;
+    private String _publicInterface;
+    private String _privateInterface;
+    private Integer _numRetries;
+    private String _guid;
+    private boolean _inline;
+    private boolean _isSdx;
+    private boolean _cloudManaged;
+    private String _deviceName;
+    private String _publicIP;
+    private String _publicIPNetmask;
+    private String _publicIPGateway;
+    private String _publicIPVlan;
+    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";
+
+    // interface to interact with VPX and MPX devices
+    com.citrix.netscaler.nitro.service.nitro_service _netscalerService;
+
+    // interface to interact with service VM of the SDX appliance
+    com.citrix.sdx.nitro.service.nitro_service _netscalerSdxService;
+
+    base_response apiCallResult;
+
+    public NetScalerControlCenterResource() {
+        _gson = GsonHelper.getGsonLogger();
+    }
+
+    @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");
+            }
+
+/*            _physicalNetworkId = (String)params.get("physicalNetworkId");
+            if (_physicalNetworkId == null) {
+                throw new ConfigurationException("Unable to find physical network 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");
+            }
+
+            // validate device configuration parameters
+            String response = login();
+            if(response == null) {
+                throw new ConfigurationException("No Response Received from the NetScalerControlCenter Device");
+            } else {
+                jsonResponse = new JSONObject(response);
+              org.json.JSONArray loginResponse = jsonResponse.getJSONArray("login");
+              //loginResponse.getJSONObject(0);
+              _sessionid = jsonResponse.getJSONArray("login").getJSONObject(0).getString("sessionid");
+            }
+            // Make GET request with the new session to verify
+            s_logger.debug("Making Request to get all Service packages");
+            getServicePackages();
+            return true;
+        } catch (Exception e) {
+            throw new ConfigurationException(e.getMessage());
+        }
+    }
+
+    public void getServicePackages() throws ExecutionException {
+            String result = null;
+            try {
+                // If a previous session was open, log it out.
+                //logout();
+                //http://10.102.31.78/nitro/v2/config/login
+                URI agentUri = null;
+                //String url = protocol + "://" + _ip +"/nitro/v2/config/login";
+                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();
+                //String loginBody= "{ \"login\": {\"username\":\"" + _username  +"\", \"password\":\"" + _password +"\" }}";
+/*                jsonCredentials.put("username", _username);
+                jsonCredentials.put("password", _password);
+                jsonBody.put("login", jsonCredentials);
+*/
+                result = getHttpRequest(jsonBody.toString(), agentUri, _sessionid);
+                s_logger.debug("List of Service Packages in NCC:: " + result);
+                //return 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());
+            }
+            //return result;
+    }
+
+    private void logout() throws ExecutionException {
+        try {
+            if (!_isSdx) {
+                if (_netscalerService != null) {
+                    _netscalerService.logout();
+                }
+            } else {
+                if (_netscalerSdxService != null) {
+                    _netscalerSdxService.logout();
+                }
+            }
+        } catch (Exception e) {
+            // Ignore logout exceptions
+        }
+    }
+
+    private String login() throws ExecutionException {
+        String result = null;
+        try {
+            // If a previous session was open, log it out.
+            //logout();
+            //http://10.102.31.78/nitro/v2/config/login
+            URI agentUri = null;
+            //String url = protocol + "://" + _ip +"/nitro/v2/config/login";
+            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();
+            //String loginBody= "{ \"login\": {\"username\":\"" + _username  +"\", \"password\":\"" + _password +"\" }}";
+            jsonCredentials.put("username", _username);
+            jsonCredentials.put("password", _password);
+            jsonBody.put("login", jsonCredentials);
+
+            result = postHttpRequest(jsonBody.toString(), agentUri, _sessionid);
+            s_logger.debug("NCC Device got Added:: " + result);
+            return 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());
+        }
+        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 CreateLoadBalancerApplianceCommand) {
+            return execute((CreateLoadBalancerApplianceCommand)cmd, numRetries);
+        } else if (cmd instanceof DestroyLoadBalancerApplianceCommand) {
+            return execute((DestroyLoadBalancerApplianceCommand)cmd, numRetries);
+        } else if (cmd instanceof SetStaticNatRulesCommand) {
+            return execute((SetStaticNatRulesCommand)cmd, numRetries);
+        } else if (cmd instanceof GlobalLoadBalancerConfigCommand) {
+            return execute((GlobalLoadBalancerConfigCommand)cmd, numRetries);
+        } 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 synchronized Answer execute(NetScalerImplementNetworkCommand cmd, int numRetries) {
+        String result = null;
+        try {
+            // If a previous session was open, log it out.
+            //logout();
+            //http://10.102.31.78/nitro/v2/config/login
+            URI agentUri = null;
+            //String url = protocol + "://" + _ip +"/nitro/v2/config/login";
+            //url: <ip>/cs/cca/networks
+            agentUri =
+                    new URI("https", null, _ip, DEFAULT_PORT,
+                            "/cs/cca/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);
+            //return result;
+            } catch (URISyntaxException e) {
+                String errMsg = "Could not generate URI for Hyper-V agent";
+                s_logger.error(errMsg, e);
+            } catch (Exception e) {
+            }
+
+        return Answer.createUnsupportedCommandAnswer(cmd);
+    }
+
+    private synchronized Answer execute(IpAssocCommand cmd,  int numRetries) {
+        if (_isSdx) {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+
+        String[] results = new String[cmd.getIpAddresses().length];
+        int i = 0;
+        try {
+            IpAddressTO[] ips = cmd.getIpAddresses();
+            for (IpAddressTO ip : ips) {
+                long guestVlanTag = Long.parseLong(ip.getBroadcastUri());
+                String vlanSelfIp = ip.getVlanGateway();
+                String vlanNetmask = ip.getVlanNetmask();
+
+                if (ip.isAdd()) {
+                    // Add a new guest VLAN and its subnet and bind it to private interface
+                    addGuestVlanAndSubnet(guestVlanTag, vlanSelfIp, vlanNetmask, true);
+                } else {
+                    // Check and delete guest VLAN with this tag, self IP, and netmask
+                    deleteGuestVlan(guestVlanTag, vlanSelfIp, vlanNetmask);
+                }
+
+                saveConfiguration();
+                results[i++] = ip.getPublicIp() + " - success";
+                String action = ip.isAdd() ? "associate" : "remove";
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Netscaler load balancer " + _ip + " successfully executed IPAssocCommand to " + action + " IP " + ip);
+                }
+            }
+        } catch (ExecutionException e) {
+            s_logger.error("Netscaler loadbalancer " + _ip + " failed to execute IPAssocCommand due to " + e.getMessage());
+            if (shouldRetry(numRetries)) {
+                return retry(cmd, numRetries);
+            } else {
+                results[i++] = IpAssocAnswer.errorResult;
+            }
+        }
+
+        return new IpAssocAnswer(cmd, results);
+    }
+
+    private Answer execute(HealthCheckLBConfigCommand cmd, int numRetries) {
+
+        List<LoadBalancerTO> hcLB = new ArrayList<LoadBalancerTO>();
+        try {
+
+            if (_isSdx) {
+                return Answer.createUnsupportedCommandAnswer(cmd);
+            }
+
+            LoadBalancerTO[] loadBalancers = cmd.getLoadBalancers();
+
+            if (loadBalancers == null) {
+                return new HealthCheckLBConfigAnswer(hcLB);
+            }
+
+            for (LoadBalancerTO loadBalancer : loadBalancers) {
+                HealthCheckPolicyTO[] healthCheckPolicies = loadBalancer.getHealthCheckPolicies();
+                if ((healthCheckPolicies != null) && (healthCheckPolicies.length > 0) && (healthCheckPolicies[0] != null)) {
+                    String nsVirtualServerName = generateNSVirtualServerName(loadBalancer.getSrcIp(), loadBalancer.getSrcPort());
+
+                    com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding[] serviceBindings =
+                            com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.get(_netscalerService, nsVirtualServerName);
+
+                    if (serviceBindings != null) {
+                        for (DestinationTO destination : loadBalancer.getDestinations()) {
+                            String nsServiceName = generateNSServiceName(destination.getDestIp(), destination.getDestPort());
+                            for (com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding binding : serviceBindings) {
+                                if (nsServiceName.equalsIgnoreCase(binding.get_servicename())) {
+                                    destination.setMonitorState(binding.get_curstate());
+                                    break;
+                                }
+                            }
+                        }
+                        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 synchronized Answer execute(LoadBalancerConfigCommand cmd, int numRetries) {
+        try {
+            if (_isSdx) {
+                return Answer.createUnsupportedCommandAnswer(cmd);
+            }
+
+            LoadBalancerTO[] loadBalancers = cmd.getLoadBalancers();
+            if (loadBalancers == null) {
+                return new Answer(cmd);
+            }
+
+            for (LoadBalancerTO loadBalancer : loadBalancers) {
+                String srcIp = loadBalancer.getSrcIp();
+                int srcPort = loadBalancer.getSrcPort();
+                String lbProtocol = getNetScalerProtocol(loadBalancer);
+                String lbAlgorithm = loadBalancer.getAlgorithm();
+                String nsVirtualServerName = generateNSVirtualServerName(srcIp, srcPort);
+                String nsMonitorName = generateNSMonitorName(srcIp, srcPort);
+                LbSslCert sslCert = loadBalancer.getSslCert();
+
+                if (loadBalancer.isAutoScaleVmGroupTO()) {
+                    applyAutoScaleConfig(loadBalancer);
+                    // Continue to process all the rules.
+                    continue;
+                }
+                boolean hasMonitor = false;
+                boolean deleteMonitor = false;
+                boolean destinationsToAdd = false;
+                boolean deleteCert = false;
+                for (DestinationTO destination : loadBalancer.getDestinations()) {
+                    if (!destination.isRevoked()) {
+                        destinationsToAdd = true;
+                        break;
+                    }
+                }
+
+                if (!loadBalancer.isRevoked() && destinationsToAdd) {
+
+                    // create a load balancing virtual server
+                    addLBVirtualServer(nsVirtualServerName, srcIp, srcPort, lbAlgorithm, lbProtocol, loadBalancer.getStickinessPolicies(), null);
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Created load balancing virtual server " + nsVirtualServerName + " on the Netscaler device");
+                    }
+
+                    // create a new monitor
+                    HealthCheckPolicyTO[] healthCheckPolicies = loadBalancer.getHealthCheckPolicies();
+                    if ((healthCheckPolicies != null) && (healthCheckPolicies.length > 0) && (healthCheckPolicies[0] != null)) {
+
+                        for (HealthCheckPolicyTO healthCheckPolicyTO : healthCheckPolicies) {
+                            if (!healthCheckPolicyTO.isRevoked()) {
+                                addLBMonitor(nsMonitorName, lbProtocol, healthCheckPolicyTO);
+                                hasMonitor = true;
+                            } else {
+                                deleteMonitor = true;
+                                hasMonitor = false;
+                            }
+                        }
+
+                    }
+
+                    for (DestinationTO destination : loadBalancer.getDestinations()) {
+
+                        String nsServerName = generateNSServerName(destination.getDestIp());
+                        String nsServiceName = generateNSServiceName(destination.getDestIp(), destination.getDestPort());
+                        if (!destination.isRevoked()) {
+                            // add a new destination to deployed load balancing rule
+
+                            // add a new server
+                            if (!nsServerExists(nsServerName)) {
+                                com.citrix.netscaler.nitro.resource.config.basic.server nsServer = new com.citrix.netscaler.nitro.resource.config.basic.server();
+                                nsServer.set_name(nsServerName);
+                                nsServer.set_ipaddress(destination.getDestIp());
+                                apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.add(_netscalerService, nsServer);
+                                if ((apiCallResult.errorcode != 0) && (apiCallResult.errorcode != NitroError.NS_RESOURCE_EXISTS)) {
+                                    throw new ExecutionException("Failed to add server " + destination.getDestIp() + " due to" + apiCallResult.message);
+                                }
+                            }
+
+                            // create a new service using the server added
+                            if (!nsServiceExists(nsServiceName)) {
+                                com.citrix.netscaler.nitro.resource.config.basic.service newService = new com.citrix.netscaler.nitro.resource.config.basic.service();
+                                newService.set_name(nsServiceName);
+                                newService.set_port(destination.getDestPort());
+                                newService.set_servername(nsServerName);
+                                newService.set_state("ENABLED");
+                                if(lbProtocol.equalsIgnoreCase(NetUtils.SSL_PROTO)) {
+                                    newService.set_servicetype(NetUtils.HTTP_PROTO);
+                                } else {
+                                    newService.set_servicetype(lbProtocol);
+                                }
+
+                                apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.service.add(_netscalerService, newService);
+                                if (apiCallResult.errorcode != 0) {
+                                    throw new ExecutionException("Failed to create service " + nsServiceName + " using server " + nsServerName + " due to" +
+                                            apiCallResult.message);
+                                }
+                            }
+
+                            //bind service to load balancing virtual server
+                            if (!nsServiceBindingExists(nsVirtualServerName, nsServiceName)) {
+                                com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding svcBinding =
+                                        new com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding();
+                                svcBinding.set_name(nsVirtualServerName);
+                                svcBinding.set_servicename(nsServiceName);
+                                apiCallResult = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.add(_netscalerService, svcBinding);
+
+                                if (apiCallResult.errorcode != 0) {
+                                    throw new ExecutionException("Failed to bind service: " + nsServiceName + " to the lb virtual server: " + nsVirtualServerName +
+                                            " on Netscaler device");
+                                }
+                            }
+
+                            // After binding the service to the LB Vserver
+                            // successfully, bind the created monitor to the
+                            // service.
+                            if (hasMonitor) {
+                                if (!isServiceBoundToMonitor(nsServiceName, nsMonitorName)) {
+                                    bindServiceToMonitor(nsServiceName, nsMonitorName);
+                                }
+                            } else {
+                                // check if any monitor created by CS is already
+                                // existing, if yes, unbind it from services and
+                                // delete it.
+                                if (nsMonitorExist(nsMonitorName)) {
+                                    // unbind the service from the monitor and
+                                    // delete the monitor
+                                    unBindServiceToMonitor(nsServiceName, nsMonitorName);
+                                    deleteMonitor = true;
+                                }
+
+                            }
+
+                            if (sslCert != null && lbProtocol.equalsIgnoreCase(NetUtils.SSL_PROTO)) {
+                                if (sslCert.isRevoked()) {
+                                    deleteCert = true;
+                                } else {
+
+                                    // If there is a chain, that should go first to the NS
+
+                                    String previousCertKeyName = null;
+
+                                    if (sslCert.getChain() != null) {
+                                        List<Certificate> chainList = CertificateHelper.parseChain(sslCert.getChain());
+                                        // go from ROOT to intermediate CAs
+                                        for (Certificate intermediateCert : Lists.reverse(chainList)) {
+
+                                            String fingerPrint = CertificateHelper.generateFingerPrint(intermediateCert);
+                                            String intermediateCertKeyName = generateSslCertKeyName(fingerPrint);
+                                            String intermediateCertFileName = intermediateCertKeyName + ".pem";
+
+                                            if (!SSL.isSslCertKeyPresent(_netscalerService, intermediateCertKeyName)) {
+                                                intermediateCert.getEncoded();
+                                                StringWriter textWriter = new StringWriter();
+                                                PEMWriter pemWriter = new PEMWriter(textWriter);
+                                                pemWriter.writeObject(intermediateCert);
+                                                pemWriter.flush();
+
+                                                SSL.uploadCert(_ip, _username, _password, intermediateCertFileName, textWriter.toString().getBytes());
+                                                SSL.createSslCertKey(_netscalerService, intermediateCertFileName, null, intermediateCertKeyName, null);
+                                            }
+
+                                            if (previousCertKeyName != null && !SSL.certLinkExists(_netscalerService, intermediateCertKeyName, previousCertKeyName)) {
+                                                SSL.linkCerts(_netscalerService, intermediateCertKeyName, previousCertKeyName);
+                                            }
+
+                                            previousCertKeyName = intermediateCertKeyName;
+                                        }
+                                    }
+
+                                    String certFilename = generateSslCertName(sslCert.getFingerprint()) + ".pem"; //netscaler uses ".pem" format for "bundle" files
+                                    String keyFilename = generateSslKeyName(sslCert.getFingerprint()) + ".pem"; //netscaler uses ".pem" format for "bundle" files
+                                    String certKeyName = generateSslCertKeyName(sslCert.getFingerprint());
+
+                                    ByteArrayOutputStream certDataStream = new ByteArrayOutputStream();
+                                    certDataStream.write(sslCert.getCert().getBytes());
+
+                                    if (!SSL.isSslCertKeyPresent(_netscalerService, certKeyName)) {
+
+                                        SSL.uploadCert(_ip, _username, _password, certFilename, certDataStream.toByteArray());
+                                        SSL.uploadKey(_ip, _username, _password, keyFilename, sslCert.getKey().getBytes());
+                                        SSL.createSslCertKey(_netscalerService, certFilename, keyFilename, certKeyName, sslCert.getPassword());
+                                    }
+
+                                    if (previousCertKeyName != null && !SSL.certLinkExists(_netscalerService, certKeyName, previousCertKeyName)) {
+                                        SSL.linkCerts(_netscalerService, certKeyName, previousCertKeyName);
+                                    }
+
+                                    SSL.bindCertKeyToVserver(_netscalerService, certKeyName, nsVirtualServerName);
+                                }
+
+                            }
+
+                            if (s_logger.isDebugEnabled()) {
+                                s_logger.debug("Successfully added LB destination: " + destination.getDestIp() + ":" + destination.getDestPort() + " to load balancer " +
+                                        srcIp + ":" + srcPort);
+                            }
+
+                        } else {
+                            // remove a destination from the deployed load balancing rule
+                            com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding[] serviceBindings =
+                                    com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.get(_netscalerService, nsVirtualServerName);
+                            if (serviceBindings != null) {
+                                for (com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding binding : serviceBindings) {
+                                    if (nsServiceName.equalsIgnoreCase(binding.get_servicename())) {
+                                        // delete the binding
+                                        apiCallResult = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.delete(_netscalerService, binding);
+                                        if (apiCallResult.errorcode != 0) {
+                                            throw new ExecutionException("Failed to delete the binding between the virtual server: " + nsVirtualServerName +
+                                                    " and service:" + nsServiceName + " due to" + apiCallResult.message);
+                                        }
+
+                                        // check if service is bound to any other virtual server
+                                        if (!isServiceBoundToVirtualServer(nsServiceName)) {
+                                            // no lb virtual servers are bound to this service so delete it
+                                            apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.service.delete(_netscalerService, nsServiceName);
+                                            if (apiCallResult.errorcode != 0) {
+                                                throw new ExecutionException("Failed to delete service: " + nsServiceName + " due to " + apiCallResult.message);
+                                            }
+                                        }
+
+                                        // delete the server if there is no associated services
+                                        server_service_binding[] services = server_service_binding.get(_netscalerService, nsServerName);
+                                        if ((services == null) || (services.length == 0)) {
+                                            apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.delete(_netscalerService, nsServerName);
+                                            if (apiCallResult.errorcode != 0) {
+                                                throw new ExecutionException("Failed to remove server:" + nsServerName + " due to " + apiCallResult.message);
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                } else {
+                    // delete the implemented load balancing rule and its destinations
+                    lbvserver lbserver = getVirtualServerIfExisits(nsVirtualServerName);
+                    if (lbserver != null) {
+                        //unbind the all services associated with this virtual server
+                        com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding[] serviceBindings =
+                                com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.get(_netscalerService, nsVirtualServerName);
+
+                        if (serviceBindings != null) {
+                            for (com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding binding : serviceBindings) {
+                                String serviceName = binding.get_servicename();
+                                apiCallResult = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.delete(_netscalerService, binding);
+                                if (apiCallResult.errorcode != 0) {
+                                    throw new ExecutionException("Failed to unbind service from the lb virtual server: " + nsVirtualServerName + " due to " +
+                                            apiCallResult.message);
+                                }
+
+                                com.citrix.netscaler.nitro.resource.config.basic.service svc =
+                                        com.citrix.netscaler.nitro.resource.config.basic.service.get(_netscalerService, serviceName);
+                                String nsServerName = svc.get_servername();
+
+                                // check if service is bound to any other virtual server
+                                if (!isServiceBoundToVirtualServer(serviceName)) {
+                                    // no lb virtual servers are bound to this service so delete it
+                                    apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.service.delete(_netscalerService, serviceName);
+                                    if (apiCallResult.errorcode != 0) {
+                                        throw new ExecutionException("Failed to delete service: " + serviceName + " due to " + apiCallResult.message);
+                                    }
+                                }
+
+                                //delete the server if no more services attached
+                                server_service_binding[] services = server_service_binding.get(_netscalerService, nsServerName);
+                                if ((services == null) || (services.length == 0)) {
+                                    apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.delete(_netscalerService, nsServerName);
+                                    if (apiCallResult.errorcode != 0) {
+                                        throw new ExecutionException("Failed to remove server:" + nsServerName + " due to " + apiCallResult.message);
+                                    }
+                                }
+                            }
+                        }
+                        removeLBVirtualServer(nsVirtualServerName);
+                        deleteMonitor = true;
+                        deleteCert = true;
+                    }
+                }
+                if (deleteMonitor) {
+                    removeLBMonitor(nsMonitorName);
+                }
+                if (sslCert != null && deleteCert) {
+
+                    String certFilename = generateSslCertName(sslCert.getFingerprint()) + ".pem"; //netscaler uses ".pem" format for "bundle" files
+                    String keyFilename = generateSslKeyName(sslCert.getFingerprint()) + ".pem"; //netscaler uses ".pem" format for "bundle" files
+                    String certKeyName = generateSslCertKeyName(sslCert.getFingerprint());
+
+                    // unbind before deleting
+                    if (nsVirtualServerExists(nsVirtualServerName) &&
+                            SSL.isSslCertKeyPresent(_netscalerService, certKeyName) &&
+                            SSL.isBoundToVserver(_netscalerService, certKeyName, nsVirtualServerName)) {
+                        SSL.unbindCertKeyFromVserver(_netscalerService, certKeyName, nsVirtualServerName);
+                    }
+
+                    if (SSL.isSslCertKeyPresent(_netscalerService, certKeyName)) {
+
+                        SSL.deleteSslCertKey(_netscalerService, certKeyName);
+                        SSL.deleteCertFile(_ip, _username, _password, certFilename);
+                        SSL.deleteKeyFile(_ip, _username, _password, keyFilename);
+                    }
+
+                    /*
+                     * Check and delete intermediate certs:
+                     * we can delete an intermediate cert if no other
+                     * cert references it as the athority
+                     */
+
+                    if (sslCert.getChain() != null) {
+                        List<Certificate> chainList = CertificateHelper.parseChain(sslCert.getChain());
+                        //go from intermediate CAs to ROOT
+                        for (Certificate intermediateCert : chainList) {
+
+                            String fingerPrint = CertificateHelper.generateFingerPrint(intermediateCert);
+                            String intermediateCertKeyName = generateSslCertKeyName(fingerPrint);
+                            String intermediateCertFileName = intermediateCertKeyName + ".pem";
+
+                            if (SSL.isSslCertKeyPresent(_netscalerService, intermediateCertKeyName) &&
+                                    !SSL.isCaforCerts(_netscalerService, intermediateCertKeyName)) {
+                                SSL.deleteSslCertKey(_netscalerService, intermediateCertKeyName);
+                                SSL.deleteCertFile(_ip, _username, _password, intermediateCertFileName);
+                            } else {
+                                break;// if this cert has another certificate as a child then stop at this point because we need the whole chain
+                            }
+
+                        }
+                    }
+                }
+
+            }
+
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("Successfully executed resource LoadBalancerConfigCommand: " + _gson.toJson(cmd));
+            }
+
+            saveConfiguration();
+            return new Answer(cmd);
+        } catch (ExecutionException e) {
+            s_logger.error("Failed to execute LoadBalancerConfigCommand due to ", e);
+            if (shouldRetry(numRetries)) {
+                return retry(cmd, numRetries);
+            } else {
+                return new Answer(cmd, e);
+            }
+        } 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, e);
+            }
+        }
+    }
+
+    private synchronized Answer execute(CreateLoadBalancerApplianceCommand cmd, int numRetries) {
+
+        if (!_isSdx) {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+
+        try {
+            String vpxName = "Cloud-VPX-" + cmd.getLoadBalancerIP();
+            String username = "admin";
+            String password = "admin";
+
+            ns ns_obj = new ns();
+            ns_obj.set_name(vpxName);
+            ns_obj.set_ip_address(cmd.getLoadBalancerIP());
+            ns_obj.set_netmask(cmd.getNetmask());
+            ns_obj.set_gateway(cmd.getGateway());
+            ns_obj.set_username(username);
+            ns_obj.set_password(password);
+
+            // configure VPX instances with defaults
+            ns_obj.set_license("Standard");
+            ns_obj.set_vm_memory_total(new Double(2048));
+            ns_obj.set_throughput(new Double(1000));
+            ns_obj.set_pps(new Double(1000000));
+            ns_obj.set_number_of_ssl_cores(0);
+            ns_obj.set_profile_name("ns_nsroot_profile");
+
+            // use the first VPX image of the available VPX images on the SDX to create an instance of VPX
+            // TODO: should enable the option to choose the template while adding the SDX device in to CloudStack
+            xen_nsvpx_image[] vpxImages = xen_nsvpx_image.get(_netscalerSdxService);
+            if (!(vpxImages != null && vpxImages.length >= 1)) {
+                new Answer(cmd, new ExecutionException("Failed to create VPX instance on the netscaler SDX device " + _ip +
+                        " as there are no VPX images on SDX to use for creating VPX."));
+            }
+            String imageName = vpxImages[0].get_file_name();
+            ns_obj.set_image_name(imageName);
+
+            String publicIf = _publicInterface;
+            String privateIf = _privateInterface;
+
+            // enable only the interfaces that will be used by VPX
+            enableVPXInterfaces(_publicInterface, _privateInterface, ns_obj);
+
+            // create new VPX instance
+            ns newVpx = ns.add(_netscalerSdxService, ns_obj);
+
+            if (newVpx == null) {
+                return new Answer(cmd, new ExecutionException("Failed to create VPX instance on the netscaler SDX device " + _ip));
+            }
+
+            // wait for VPX instance to start-up
+            long startTick = System.currentTimeMillis();
+            long startWaitMilliSeconds = 600000;
+            while (!newVpx.get_instance_state().equalsIgnoreCase("up") && System.currentTimeMillis() - startTick < startWaitMilliSeconds) {
+                try {
+                    Thread.sleep(10000);
+                } catch (InterruptedException e) {
+                }
+                ns refreshNsObj = new ns();
+                refreshNsObj.set_id(newVpx.get_id());
+                newVpx = ns.get(_netscalerSdxService, refreshNsObj);
+            }
+
+            // if vpx instance never came up then error out
+            if (!newVpx.get_instance_state().equalsIgnoreCase("up")) {
+                return new Answer(cmd, new ExecutionException("Failed to start VPX instance " + vpxName + " created on the netscaler SDX device " + _ip));
+            }
+
+            // wait till NS service in side VPX is actually ready
+            startTick = System.currentTimeMillis();
+            boolean nsServiceUp = false;
+            long nsServiceWaitMilliSeconds = 60000;
+            while (System.currentTimeMillis() - startTick < nsServiceWaitMilliSeconds) {
+                try {
+                    nitro_service _netscalerService = new nitro_service(cmd.getLoadBalancerIP(), "https");
+                    _netscalerService.set_certvalidation(false);
+                    _netscalerService.set_hostnameverification(false);
+                    _netscalerService.set_credential(username, password);
+                    apiCallResult = _netscalerService.login();
+                    if (apiCallResult.errorcode == 0) {
+                        nsServiceUp = true;
+                        break;
+                    }
+                } catch (Exception e) {
+                    Thread.sleep(10000);
+                    continue;
+                }
+            }
+
+            if (!nsServiceUp) {
+                return new Answer(cmd, new ExecutionException("Failed to create VPX instance " + vpxName + " on the netscaler SDX device " + _ip));
+            }
+
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("Successfully provisioned VPX instance " + vpxName + " on the Netscaler SDX device " + _ip);
+            }
+
+            // physical interfaces on the SDX range from 10/1 to 10/8 & 1/1 to 1/8 of which two different port or same port can be used for public and private interfaces
+            // However the VPX instances created will have interface range start from 10/1 but will only have as many interfaces enabled while creating the VPX instance
+            // So due to this, we need to map public & private interface on SDX to correct public & private interface of VPX
+
+            int publicIfnum = Integer.parseInt(_publicInterface.substring(_publicInterface.lastIndexOf("/") + 1));
+            int privateIfnum = Integer.parseInt(_privateInterface.substring(_privateInterface.lastIndexOf("/") + 1));
+
+            if (_publicInterface.startsWith("10/") && _privateInterface.startsWith("10/")) {
+                if (publicIfnum == privateIfnum) {
+                    publicIf = "10/1";
+                    privateIf = "10/1";
+                } else if (publicIfnum > privateIfnum) {
+                    privateIf = "10/1";
+                    publicIf = "10/2";
+                } else {
+                    publicIf = "10/1";
+                    privateIf = "10/2";
+                }
+            } else if (_publicInterface.startsWith("1/") && _privateInterface.startsWith("1/")) {
+                if (publicIfnum == privateIfnum) {
+                    publicIf = "1/1";
+                    privateIf = "1/1";
+                } else if (publicIfnum > privateIfnum) {
+                    privateIf = "1/1";
+                    publicIf = "1/2";
+                } else {
+                    publicIf = "1/1";
+                    privateIf = "1/2";
+                }
+            } else if (_publicInterface.startsWith("1/") && _privateInterface.startsWith("10/")) {
+                publicIf = "1/1";
+                privateIf = "10/1";
+            } else if (_publicInterface.startsWith("10/") && _privateInterface.startsWith("1/")) {
+                publicIf = "10/1";
+                privateIf = "1/1";
+            }
+
+            return new CreateLoadBalancerApplianceAnswer(cmd, true, "provisioned VPX instance", "NetscalerVPXLoadBalancer", "Netscaler", new NetScalerControlCenterResource(),
+                    publicIf, privateIf, _username, _password);
+        } catch (Exception e) {
+            if (shouldRetry(numRetries)) {
+                return retry(cmd, numRetries);
+            }
+            return new CreateLoadBalancerApplianceAnswer(cmd, false, "failed to provisioned VPX instance due to " + e.getMessage(), null, null, null, null, null, null,
+                    null);
+        }
+    }
+
+    private Answer execute(GlobalLoadBalancerConfigCommand gslbCmd, int numRetries) {
+
+        String lbMethod = gslbCmd.getLoadBalancerMethod();
+        String persistenceType = gslbCmd.getPersistenceType();
+        String serviceType = gslbCmd.getServiceType();
+        boolean forRevoke = gslbCmd.isForRevoke();
+        long gslbId = gslbCmd.getGslbId();
+        List<SiteLoadBalancerConfig> sites = gslbCmd.getSiteDetails();
+
+        String domainName = gslbCmd.getDomainName();
+        String vserverName = GSLB.generateVirtualServerName(domainName);
+
+        try {
+
+            if (!forRevoke) { //check if the global load balancer rule is being added
+
+                // Add a GSLB virtual server
+                GSLB.createVirtualServer(_netscalerService, vserverName, lbMethod, persistenceType, gslbId, serviceType);
+
+                if (sites != null) { // check if there are any sites that are participating in global load balancing
+                    for (SiteLoadBalancerConfig site : sites) {
+
+                        String sitePrivateIP = site.getGslbProviderPrivateIp();
+                        String sitePublicIP = site.getGslbProviderPublicIp();
+                        String servicePublicIp = site.getServicePublicIp();
+                        String servicePublicPort = site.getServicePort();
+                        String siteName = GSLB.generateUniqueSiteName(sitePrivateIP, sitePublicIP, site.getDataCenterId());
+
+                        // Add/Delete GSLB local and remote sites that are part of GSLB virtual server
+                        if (!site.forRevoke()) {
+                            String siteType = (site.isLocal()) ? "LOCAL" : "REMOTE";
+                            if (GSLB.getSiteObject(_netscalerService, siteName) != null) {
+                                GSLB.updateSite(_netscalerService, siteType, siteName, site.getGslbProviderPrivateIp(), site.getGslbProviderPublicIp());
+                            } else {
+                                GSLB.createSite(_netscalerService, siteName, siteType, site.getGslbProviderPrivateIp(), site.getGslbProviderPublicIp());
+                            }
+                        }
+
+                        // Add/Delete GSLB service corresponding the service running on each site
+                        String serviceName = GSLB.generateUniqueServiceName(siteName, servicePublicIp, servicePublicPort);
+                        String monitorName = GSLB.generateGslbServiceMonitorName(servicePublicIp);
+                        if (!site.forRevoke()) {
+                            // create a 'gslbservice' object
+                            GSLB.createService(_netscalerService, serviceName, site.getServiceType(), servicePublicIp, servicePublicPort, siteName);
+
+                            // Bind 'gslbservice' service object to GSLB virtual server
+                            GSLB.createVserverServiceBinding(_netscalerService, serviceName, vserverName, site.getWeight());
+
+                            // create a monitor for the service running on the site
+                            GSLB.createGslbServiceMonitor(_netscalerService, servicePublicIp, serviceName);
+
+                            // bind the monitor to the GSLB service
+                            GSLB.createGslbServiceGslbMonitorBinding(_netscalerService, monitorName, serviceName);
+
+                        } else {
+
+                            // delete GSLB service and GSLB monitor binding
+                            GSLB.deleteGslbServiceGslbMonitorBinding(_netscalerService, monitorName, serviceName);
+
+                            // Unbind GSLB service with GSLB virtual server
+                            GSLB.deleteVserverServiceBinding(_netscalerService, serviceName, vserverName);
+
+                            GSLB.getServiceObject(_netscalerService, serviceName);
+                            GSLB.deleteService(_netscalerService, serviceName);
+
+                            // delete the GSLB service monitor
+                            GSLB.deleteGslbServiceMonitor(_netscalerService, monitorName);
+                        }
+
+                        if (site.forRevoke()) { // delete the site if its for revoke
+                            GSLB.deleteSite(_netscalerService, siteName);
+                        }
+                    }
+                }
+
+                // Bind GSLB vserver to domain
+                GSLB.createVserverDomainBinding(_netscalerService, vserverName, domainName);
+
+            } else {  // global load balancer rule is being deleted, so clean up all objects created
+
+                // remove binding between virtual server and the domain name
+                GSLB.deleteVserverDomainBinding(_netscalerService, vserverName, domainName);
+
+                if (sites != null) {
+                    for (SiteLoadBalancerConfig site : sites) {
+
+                        String sitePrivateIP = site.getGslbProviderPrivateIp();
+                        String sitePublicIP = site.getGslbProviderPublicIp();
+                        String servicePublicIp = site.getServicePublicIp();
+                        String servicePublicPort = site.getServicePort();
+                        String siteName = GSLB.generateUniqueSiteName(sitePrivateIP, sitePublicIP, site.getDataCenterId());
+                        String serviceName = GSLB.generateUniqueServiceName(siteName, servicePublicIp, servicePublicPort);
+                        String monitorName = GSLB.generateGslbServiceMonitorName(servicePublicIp);
+
+                        // delete GSLB service and GSLB monitor binding
+                        GSLB.deleteGslbServiceGslbMonitorBinding(_netscalerService, monitorName, serviceName);
+
+                        // remove binding between virtual server and services
+                        GSLB.deleteVserverServiceBinding(_netscalerService, serviceName, vserverName);
+
+                        // delete service object
+                        GSLB.deleteService(_netscalerService, serviceName);
+
+                        // delete GSLB site object
+                        GSLB.deleteSite(_netscalerService, siteName);
+
+                        // delete the GSLB service monitor
+                        GSLB.deleteGslbServiceMonitor(_netscalerService, monitorName);
+                    }
+                }
+
+                // delete GSLB virtual server
+                GSLB.deleteVirtualServer(_netscalerService, vserverName);
+            }
+
+            saveConfiguration();
+
+        } catch (Exception e) {
+            String errMsg = "Failed to apply GSLB configuration due to " + e.getMessage();
+            if (shouldRetry(numRetries)) {
+                return retry(gslbCmd, numRetries);
+            }
+            return new GlobalLoadBalancerConfigAnswer(false, errMsg);
+        }
+
+        return new GlobalLoadBalancerConfigAnswer(true, "Successfully applied GSLB configuration.");
+    }
+
+    /*
+     * convenience class to create/update/delete/get the GSLB specific NetScaler objects
+     *     - gslbsite
+     *     - gslbvserver
+     *     - gslbservice
+     *     - vserver-service binding
+     *     - vserver-domain bindings
+     */
+    private static class GSLB {
+
+        // create a 'gslbsite' object representing a site
+        private static void createSite(nitro_service client, String siteName, String siteType, String siteIP, String sitePublicIP) throws ExecutionException {
+            try {
+                gslbsite site;
+                site = getSiteObject(client, siteName);
+
+                boolean isUpdateSite = false;
+                if (site == null) {
+                    site = new gslbsite();
+                } else {
+                    isUpdateSite = true;
+                }
+
+                assert ("LOCAL".equalsIgnoreCase(siteType) || "REMOTE".equalsIgnoreCase(siteType));
+                site.set_sitetype(siteType);
+                site.set_sitename(siteName);
+                site.set_siteipaddress(siteIP);
+                site.set_publicip(sitePublicIP);
+                site.set_metricexchange("ENABLED");
+                site.set_nwmetricexchange("ENABLED");
+                site.set_sessionexchange("ENABLED");
+                if (isUpdateSite) {
+                    gslbsite.update(client, site);
+                } else {
+                    gslbsite.add(client, site);
+                }
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Successfully created GSLB site: " + siteName);
+                }
+            } catch (Exception e) {
+                String errMsg = "Failed to create GSLB site: " + siteName + " due to " + e.getMessage();
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(errMsg);
+                }
+                throw new ExecutionException(errMsg);
+            }
+        }
+
+        // delete 'gslbsite' object representing a site
+        private static void deleteSite(nitro_service client, String siteName) throws ExecutionException {
+            try {
+                gslbsite site = getSiteObject(client, siteName);
+                if (site != null) {
+                    gslbsite_gslbservice_binding[] serviceBindings = gslbsite_gslbservice_binding.get(client, siteName);
+                    if (serviceBindings != null && serviceBindings.length > 0) {
+                        if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("There are services associated with GSLB site: " + siteName + " so ignoring site deletion");
+                        }
+                    }
+                    gslbsite.delete(client, siteName);
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Successfully deleted GSLB site: " + siteName);
+                    }
+                } else {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.warn("Ignoring delete request for non existing  GSLB site: " + siteName);
+                    }
+                }
+            } catch (Exception e) {
+                String errMsg = "Failed to delete GSLB site: " + siteName + " due to " + e.getMessage();
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(errMsg);
+                }
+                throw new ExecutionException(errMsg);
+            }
+        }
+
+        // update 'gslbsite' object representing a site
+        private static void updateSite(nitro_service client, String siteType, String siteName, String siteIP, String sitePublicIP) throws ExecutionException {
+            try {
+                gslbsite site;
+                site = getSiteObject(client, siteName);
+                if (site == null) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.warn("Ignoring update request for non existing  GSLB site: " + siteName);
+                    }
+                    return;
+                }
+                assert ("LOCAL".equalsIgnoreCase(siteType) || "REMOTE".equalsIgnoreCase(siteType));
+                site.set_sitetype(siteType);
+                site.set_sitename(siteName);
+                site.set_siteipaddress(siteIP);
+                site.set_publicip(sitePublicIP);
+                site.set_metricexchange("ENABLED");
+                site.set_nwmetricexchange("ENABLED");
+                site.set_sessionexchange("ENABLED");
+                gslbsite.update(client, site);
+
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Successfully updated GSLB site: " + siteName);
+                }
+
+            } catch (Exception e) {
+                String errMsg = "Failed to update GSLB site: " + siteName + " due to " + e.getMessage();
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(errMsg);
+                }
+                throw new ExecutionException(errMsg);
+            }
+        }
+
+        // create a 'gslbvserver' object representing a globally load balanced service
+        private static void
+        createVirtualServer(nitro_service client, String vserverName, String lbMethod, String persistenceType, long persistenceId, String serviceType)
+                throws ExecutionException {
+            try {
+                gslbvserver vserver;
+                vserver = getVserverObject(client, vserverName);
+
+                boolean isUpdateSite = false;
+                if (vserver == null) {
+                    vserver = new gslbvserver();
+                } else {
+                    isUpdateSite = true;
+                }
+
+                vserver.set_name(vserverName);
+                if ("RoundRobin".equalsIgnoreCase(lbMethod)) {
+                    vserver.set_lbmethod("ROUNDROBIN");
+                } else if ("LeastConn".equalsIgnoreCase(lbMethod)) {
+                    vserver.set_lbmethod("LEASTCONNECTION");
+                } else if ("Proximity".equalsIgnoreCase(lbMethod)) {
+                    vserver.set_lbmethod("RTT");
+                } else {
+                    throw new ExecutionException("Unsupported LB method");
+                }
+                vserver.set_persistencetype(persistenceType);
+                if ("SOURCEIP".equalsIgnoreCase(persistenceType)) {
+                    vserver.set_persistenceid(persistenceId);
+                }
+                vserver.set_servicetype(serviceType);
+                vserver.set_state("ENABLED");
+                vserver.set_cookietimeout(null);
+                vserver.set_domainname(null);
+                if (isUpdateSite) {
+                    // both netmask and LB method can not be specified while update so set to null
+                    vserver.set_netmask(null);
+                    vserver.set_v6netmasklen(null);
+                    gslbvserver.update(client, vserver);
+                } else {
+                    gslbvserver.add(client, vserver);
+                }
+
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Successfully added GSLB virtual server: " + vserverName);
+                }
+
+            } catch (Exception e) {
+                String errMsg = "Failed to add GSLB virtual server: " + vserverName + " due to " + e.getMessage();
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(errMsg);
+                }
+                throw new ExecutionException(errMsg);
+            }
+        }
+
+        // delete 'gslbvserver' object representing a globally load balanced service
+        private static void deleteVirtualServer(nitro_service client, String vserverName) throws ExecutionException {
+            try {
+                gslbvserver vserver = getVserverObject(client, vserverName);
+                if (vserver != null) {
+                    gslbvserver.delete(client, vserver);
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Successfully deleted GSLB virtual server: " + vserverName);
+                    }
+                } else {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.warn("Ignoring delete request for non existing  GSLB virtual server: " + vserverName);
+                    }
+                }
+            } catch (Exception e) {
+                String errMsg = "Failed to delete GSLB virtual server: " + vserverName + " due to " + e.getMessage();
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(errMsg);
+                }
+                throw new ExecutionException(errMsg);
+            }
+        }
+
+        // enable 'gslbvserver' object representing a globally load balanced service
+        private static void enableVirtualServer(nitro_service client, String vserverName) throws ExecutionException {
+            try {
+                gslbvserver vserver = getVserverObject(client, vserverName);
+                if (vserver != null) {
+                    gslbvserver.enable(client, vserver);
+                }
+            } catch (Exception e) {
+                String errMsg = "Failed to enable GSLB virtual server: " + vserverName + " due to " + e.getMessage();
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(errMsg);
+                }
+                throw new ExecutionException(errMsg);
+            }
+        }
+
+        // disable 'gslbvserver' object representing a globally load balanced service
+        private static void disableVirtualServer(nitro_service client, String vserverName) throws ExecutionException {
+            try {
+                gslbvserver vserver = getVserverObject(client, vserverName);
+                if (vserver != null) {
+                    gslbvserver.disable(client, vserver);
+                }
+            } catch (Exception e) {
+                String errMsg = "Failed to disable GSLB virtual server: " + vserverName + " due to " + e.getMessage();
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(errMsg);
+                }
+                throw new ExecutionException(errMsg);
+            }
+        }
+
+        // update 'gslbvserver' object representing a globally load balanced service
+        private static void updateVirtualServer(nitro_service client, String vserverName, String lbMethod, String persistenceType, String serviceType)
+                throws ExecutionException {
+            try {
+                gslbvserver vServer = getVserverObject(client, vserverName);
+                if (vServer != null) {
+                    vServer.set_lbmethod(lbMethod);
+                    vServer.set_persistencetype(persistenceType);
+                    vServer.set_servicetype(serviceType);
+                    gslbvserver.update(client, vServer);
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Successfully updated GSLB virtual server: " + vserverName);
+                    }
+                }
+            } catch (Exception e) {
+                String errMsg = "Failed to update GSLB virtual server: " + vserverName + " due to " + e.getMessage();
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(errMsg);
+                }
+                throw new ExecutionException(errMsg);
+            }
+        }
+
+        // create, delete, update, get the GSLB services
+        private static void createService(nitro_service client, String serviceName, String serviceType, String serviceIp, String servicePort, String siteName)
+                throws ExecutionException {
+            try {
+                gslbservice service;
+                service = getServiceObject(client, serviceName);
+                String gslbServerName = generateGslbServerName(serviceIp);
+
+                if (!gslbServerExists(client, gslbServerName)) {
+                    base_response apiCallResult;
+                    com.citrix.netscaler.nitro.resource.config.basic.server nsServer = new com.citrix.netscaler.nitro.resource.config.basic.server();
+                    nsServer.set_name(gslbServerName);
+                    nsServer.set_ipaddress(serviceIp);
+                    apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.add(client, nsServer);
+                    if ((apiCallResult.errorcode != 0) && (apiCallResult.errorcode != NitroError.NS_RESOURCE_EXISTS)) {
+                        throw new ExecutionException("Failed to add server " + gslbServerName + " due to" + apiCallResult.message);
+                    }
+                }
+
+                boolean isUpdateSite = false;
+                if (service == null) {
+                    service = new gslbservice();
+                } else {
+                    isUpdateSite = true;
+                }
+
+                service.set_sitename(siteName);
+                service.set_servername(gslbServerName);
+                int port = Integer.parseInt(servicePort);
+                service.set_port(port);
+                service.set_servicename(serviceName);
+                service.set_servicetype(serviceType);
+                if (isUpdateSite) {
+                    service.set_viewip(null);
+                    service.set_viewname(null);
+                    gslbservice.update(client, service);
+                } else {
+                    gslbservice.add(client, service);
+                }
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Successfully created service: " + serviceName + " at site: " + siteName);
+                }
+            } catch (Exception e) {
+                String errMsg = "Failed to created service: " + serviceName + " at site: " + siteName + " due to " + e.getMessage();
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(errMsg);
+                }
+                throw new ExecutionException(errMsg);
+            }
+        }
+
+        private static void deleteService(nitro_service client, String serviceName) throws ExecutionException {
+            try {
+                gslbservice service = getServiceObject(client, serviceName);
+                if (service != null) {
+                    gslbservice.delete(client, serviceName);
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Successfully deleted service: " + serviceName);
+                    }
+                } else {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.warn("Ignoring delete request for non existing  service: " + serviceName);
+                    }
+                }
+            } catch (Exception e) {
+                String errMsg = "Failed to delete service: " + serviceName + " due to " + e.getMessage();
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(errMsg);
+                }
+                throw new ExecutionException(errMsg);
+            }
+        }
+
+        private static void updateService(nitro_service client, String serviceName, String serviceType, String publicIp, String publicPort, String siteName)
+                throws ExecutionException {
+            try {
+                gslbservice service;
+                service = getServiceObject(client, serviceName);
+
+                if (service != null) {
+                    service.set_sitename(siteName);
+                    service.set_publicip(publicIp);
+                    service.set_publicport(Integer.getInteger(publicPort));
+                    service.set_servicename(serviceName);
+                    service.set_servicetype(serviceType);
+                    gslbservice.update(client, service);
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Successfully updated service: " + serviceName + " at site: " + siteName);
+                    }
+                }
+            } catch (Exception e) {
+                String errMsg = "Failed to update service: " + serviceName + " at site: " + siteName + "due to " + e.getMessage();
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(errMsg);
+                }
+                throw new ExecutionException(errMsg);
+            }
+        }
+
+        private static void createVserverServiceBinding(nitro_service client, String serviceName, String vserverName, long weight) throws ExecutionException {
+            String errMsg;
+            try {
+                assert (weight >= 1 && weight <= 100);
+                gslbvserver_gslbservice_binding binding = new gslbvserver_gslbservice_binding();
+                binding.set_name(vserverName);
+                binding.set_servicename(serviceName);
+                binding.set_weight(weight);
+                gslbvserver_gslbservice_binding.add(client, binding);
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Successfully created service: " + serviceName + " and virtual server: " + vserverName + " binding");
+                }
+            } catch (nitro_exception ne) {
+                if (ne.getErrorCode() == 273) {
+                    return;
+                }
+                errMsg = "Failed to create service: " + serviceName + " and virtual server: " + vserverName + " binding due to " + ne.getMessage();
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(errMsg);
+                }
+                throw new ExecutionException(errMsg);
+            } catch (Exception e) {
+                errMsg = "Failed to create service: " + serviceName + " and virtual server: " + vserverName + " binding due to " + e.getMessage();
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(errMsg);
+                }
+                throw new ExecutionException(errMsg);
+            }
+        }
+
+        private static void deleteVserverServiceBinding(nitro_service client, String serviceName, String vserverName) throws ExecutionException {
+            try {
+                gslbvserver_gslbservice_binding[] bindings = gslbvserver_gslbservice_binding.get(client, vserverName);
+                if (bindings != null) {
+                    for (gslbvserver_gslbservice_binding binding : bindings) {
+                        if (binding.get_servicename().equalsIgnoreCase(serviceName) && binding.get_name().equals(vserverName)) {
+                            gslbvserver_gslbservice_binding.delete(client, binding);
+                            if (s_logger.isDebugEnabled()) {
+                                s_logger.debug("Successfully deleted service: " + serviceName + " and virtual server: " + vserverName + " binding");
+                            }
+                            break;
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                String errMsg = "Failed to create service: " + serviceName + " and virtual server: " + vserverName + " binding due to " + e.getMessage();
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(errMsg);
+                }
+                throw new ExecutionException(errMsg);
+            }
+        }
+
+        // create, delete GSLB virtual server and domain bindings
+        private static void createVserverDomainBinding(nitro_service client, String vserverName, String domainName) throws ExecutionException {
+            String errMsg;
+            try {
+                gslbvserver_domain_binding binding = new gslbvserver_domain_binding();
+                binding.set_domainname(domainName);
+                binding.set_name(vserverName);
+                gslbvserver_domain_binding.add(client, binding);
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Successfully added virtual server: " + vserverName + " domain name: " + domainName + " binding");
+                }
+                return;
+            } catch (nitro_exception e) {
+                if (e.getErrorCode() == NitroError.NS_GSLB_DOMAIN_ALREADY_BOUND) {
+                    return;
+                }
+                errMsg = e.getMessage();
+            } catch (Exception e) {
+                errMsg = e.getMessage();
+            }
+            errMsg = "Failed to create virtual server: " + vserverName + " domain name: " + domainName + " binding" + errMsg;
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug(errMsg);
+            }
+            throw new ExecutionException(errMsg);
+        }
+
+        private static void deleteVserverDomainBinding(nitro_service client, String vserverName, String domainName) throws ExecutionException {
+            try {
+                gslbvserver_domain_binding[] bindings = gslbvserver_domain_binding.get(client, vserverName);
+                if (bindings != null) {
+                    for (gslbvserver_domain_binding binding : bindings) {
+                        if (binding.get_domainname().equalsIgnoreCase(domainName)) {
+                            gslbvserver_domain_binding.delete(client, binding);
+                            if (s_logger.isDebugEnabled()) {
+                                s_logger.debug("Successfully deleted virtual server: " + vserverName + " and " + " domain: " + domainName + " binding");
+                            }
+                            break;
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                String errMsg = "Failed to delete virtual server: " + vserverName + " and domain " + domainName + " binding due to " + e.getMessage();
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(errMsg);
+                }
+                throw new ExecutionException(errMsg);
+            }
+        }
+
+        private static void createGslbServiceMonitor(nitro_service nsService, String servicePublicIp, String serviceName) throws ExecutionException {
+            try {
+                lbmonitor newmonitor = new lbmonitor();
+                String monitorName = generateGslbServiceMonitorName(servicePublicIp);
+                newmonitor.set_type("TCP");
+                newmonitor.set_servicename(serviceName);
+                newmonitor.set_monitorname(monitorName);
+                newmonitor.set_state("ENABLED");
+                lbmonitor.add(nsService, newmonitor);
+            } catch (nitro_exception ne) {
+                if (ne.getErrorCode() == NitroError.NS_RESOURCE_EXISTS) {
+                    return;
+                }
+            } catch (Exception e) {
+                String errMsg = "Failed to create GSLB monitor for service public ip" + servicePublicIp;
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(errMsg);
+                }
+                throw new ExecutionException(errMsg);
+            }
+        }
+
+        private static void deleteGslbServiceMonitor(nitro_service nsService, String monitorName) throws ExecutionException {
+            try {
+                lbmonitor serviceMonitor = lbmonitor.get(nsService, monitorName);
+                if (serviceMonitor != null) {
+                    lbmonitor.delete(nsService, serviceMonitor);
+                }
+            } catch (nitro_exception ne) {
+                if (ne.getErrorCode() != NitroError.NS_RESOURCE_NOT_EXISTS) {
+                    String errMsg = "Failed to delete monitor " + monitorName + " for GSLB service due to " + ne.getMessage();
+                    s_logger.debug(errMsg);
+                    throw new com.cloud.utils.exception.ExecutionException(errMsg);
+                }
+            } catch (Exception e) {
+                String errMsg = "Failed to delete monitor " + monitorName + " for GSLB service due to " + e.getMessage();
+                s_logger.debug(errMsg);
+                throw new com.cloud.utils.exception.ExecutionException(errMsg);
+            }
+        }
+
+        private static void createGslbServiceGslbMonitorBinding(nitro_service nsService, String monitorName, String serviceName) {
+            try {
+                gslbservice_lbmonitor_binding monitorBinding = new gslbservice_lbmonitor_binding();
+                monitorBinding.set_monitor_name(monitorName);
+                monitorBinding.set_servicename(serviceName);
+                gslbservice_lbmonitor_binding.add(nsService, monitorBinding);
+            } catch (Exception e) {
+                // TODO: Nitro API version 10.* is not compatible for NetScalers 9.*, so may fail
+                // against NetScaler version lesser than 10 hence ignore the exception
+                s_logger.warn("Failed to bind monitor to GSLB service due to " + e.getMessage());
+            }
+        }
+
+        private static void deleteGslbServiceGslbMonitorBinding(nitro_service nsService, String monitorName, String serviceName) {
+            try {
+                gslbservice_lbmonitor_binding[] monitorBindings = gslbservice_lbmonitor_binding.get(nsService, serviceName);
+                if (monitorBindings != null && monitorBindings.length > 0) {
+                    for (gslbservice_lbmonitor_binding binding : monitorBindings) {
+                        if (binding.get_monitor_name().equalsIgnoreCase(monitorName)) {
+                            s_logger.info("Found a binding between monitor " + binding.get_monitor_name() + " and " + binding.get_servicename());
+                            gslbservice_lbmonitor_binding.delete(nsService, binding);
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                s_logger.debug("Failed to delete GSLB monitor " + monitorName + " and GSLB service " + serviceName + " binding due to " + e.getMessage() +
+                        " but moving on ..., will be cleaned up as part of GSLB " + " service delete any way..");
+            }
+        }
+
+        // get 'gslbsite' object corresponding to a site name
+        private static gslbsite getSiteObject(nitro_service client, String siteName) {
+            try {
+                gslbsite site = gslbsite.get(client, siteName);
+                if (site != null) {
+                    return site;
+                }
+            } catch (Exception e) {
+
+            }
+            return null;
+        }
+
+        private static gslbvserver getVserverObject(nitro_service client, String vserverName) {
+            try {
+                gslbvserver vserver = gslbvserver.get(client, vserverName);
+                return vserver;
+            } catch (Exception e) {
+                return null;
+            }
+        }
+
+        private static gslbservice getServiceObject(nitro_service client, String serviceName) {
+            try {
+                gslbservice service = gslbservice.get(client, serviceName);
+                return service;
+            } catch (Exception e) {
+                return null;
+            }
+        }
+
+        private static String generateUniqueSiteName(String sitePrivateIp, String sitePublicIP, long dataCenterId) {
+            return "cloudsite" + String.valueOf(dataCenterId);
+        }
+
+        private static String generateVirtualServerName(String domainName) {
+            return "cloud-gslb-vserver-" + domainName;
+        }
+
+        private static String generateUniqueServiceName(String siteName, String publicIp, String publicPort) {
+            return "cloud-gslb-service-" + siteName + "-" + publicIp + "-" + publicPort;
+        }
+
+        private static String generateGslbServiceMonitorName(String publicIp) {
+            return "cloud-monitor-" + publicIp;
+        }
+
+        private static boolean gslbServerExists(nitro_service client, String serverName) throws ExecutionException {
+            try {
+                if (com.citrix.netscaler.nitro.resource.config.basic.server.get(client, serverName) != null) {
+                    return true;
+                } else {
+                    return false;
+                }
+            } catch (nitro_exception e) {
+                if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
+                    return false;
+                } else {
+                    throw new ExecutionException("Failed to verify Server " + serverName + " exists on the NetScaler device due to " + e.getMessage());
+                }
+            } catch (Exception e) {
+                throw new ExecutionException("Failed to verify Server " + serverName + " exists on the NetScaler device due to " + e.getMessage());
+            }
+        }
+
+        private static String generateGslbServerName(String serverIP) {
+            return genGslbObjectName("Cloud-Server-", serverIP);
+        }
+
+        private static String genGslbObjectName(Object... args) {
+            StringBuffer buff = new StringBuffer();
+            for (int i = 0; i < args.length; i++) {
+                buff.append(args[i]);
+                if (i != args.length - 1) {
+                    buff.append("-");
+                }
+            }
+            return buff.toString();
+        }
+    }
+
+    /* SSL Termination */
+    private static class SSL {
+
+        private static final String SSL_CERT_PATH = "/nsconfig/ssl/";
+        private static final int SSH_PORT = 22;
+
+        private static boolean isSslCertKeyPresent(nitro_service ns, String certKeyName) throws ExecutionException {
+
+            String filter = "certkey:" + certKeyName;
+
+            try {
+                if (sslcertkey.count_filtered(ns, filter) > 0)
+                    return true;
+            } catch (nitro_exception e) {
+                throw new ExecutionException("Failed to get certkey " + e.getMessage());
+            } catch (Exception e) {
+                throw new ExecutionException("Failed to get certkey " + e.getMessage());
+            }
+
+            return false;
+        }
+
+        private static void deleteSslCertKey(nitro_service ns, String certKeyName) throws ExecutionException {
+            try {
+
+                sslcertkey certkey = new sslcertkey();
+                certkey.set_certkey(certKeyName);
+                sslcertkey.delete(ns, certkey);
+
+            } catch (nitro_exception e) {
+                throw new ExecutionException("Failed to delete certkey " + e.getMessage());
+            } catch (Exception e) {
+                throw new ExecutionException("Failed to delete certkey " + e.getMessage());
+            }
+
+        }
+
+        private static void deleteCertFile(String nsIp, String username, String password, String certFilename) throws Exception {
+            SshHelper.sshExecute(nsIp, SSH_PORT, username, null, password, "shell rm " + SSL_CERT_PATH + certFilename);
+        }
+
+        private static void deleteKeyFile(String nsIp, String username, String password, String keyFilename) throws Exception {
+            SshHelper.sshExecute(nsIp, SSH_PORT, username, null, password, "shell rm " + SSL_CERT_PATH + keyFilename);
+        }
+
+        private static void createSslCertKey(nitro_service ns, String certFilename, String keyFilename, String certKeyName, String password) throws ExecutionException {
+            s_logger.debug("Adding cert to netscaler");
+            try {
+                sslcertkey certkey = new sslcertkey();
+                certkey.set_certkey(certKeyName);
+                certkey.set_cert(SSL_CERT_PATH + certFilename);
+
+                if (keyFilename != null)
+                    certkey.set_key(SSL_CERT_PATH + keyFilename);
+
+                if (password != null) {
+                    certkey.set_passplain(password);
+                }
+
+                certkey.perform_operation(ns);
+
+            } catch (nitro_exception e) {
+                throw new ExecutionException("Failed to add certkey binding " + e.getMessage());
+            } catch (Exception e) {
+                throw new ExecutionException("Failed to add certkey binding " + e.getMessage());
+            }
+
+        }
+
+        public static void updateCertKey(nitro_service ns, String certKeyName, String cert, String key, String password) throws ExecutionException {
+            try {
+                sslcertkey certkey = sslcertkey.get(ns, certKeyName);
+                if (cert != null)
+                    certkey.set_cert(cert);
+                if (key != null)
+                    certkey.set_key(cert);
+                if (password != null)
+                    certkey.set_passplain(cert);
+
+                sslcertkey.change(ns, certkey);
+
+            } catch (nitro_exception e) {
+                throw new ExecutionException("Failed to update ssl on load balancer due to " + e.getMessage());
+            } catch (Exception e) {
+                throw new ExecutionException("Failed to update ssl on load balancer due to " + e.getMessage());
+            }
+        }
+
+        private static void bindCertKeyToVserver(nitro_service ns, String certKeyName, String vserver) throws ExecutionException {
+            s_logger.debug("Adding cert to netscaler");
+
+            try {
+                sslvserver_sslcertkey_binding cert_binding = new sslvserver_sslcertkey_binding();
+                cert_binding.set_certkeyname(certKeyName);
+                cert_binding.set_vservername(vserver);
+                cert_binding.perform_operation(ns);
+            } catch (nitro_exception e) {
+                throw new ExecutionException("Failed to bind certkey to vserver due to " + e.getMessage());
+            } catch (Exception e) {
+                throw new ExecutionException("Failed to bind certkey to vserver due to " + e.getMessage());
+            }
+        }
+
+        private static void unbindCertKeyFromVserver(nitro_service ns, String certKeyName, String vserver) throws ExecutionException {
+            try {
+
+                sslvserver_sslcertkey_binding cert_binding = new sslvserver_sslcertkey_binding();
+                cert_binding.set_certkeyname(certKeyName);
+                cert_binding.set_vservername(vserver);
+                sslvserver_sslcertkey_binding.delete(ns, cert_binding);
+
+            } catch (nitro_exception e) {
+                throw new ExecutionException("Failed to unbind certkey to vserver due to " + e.getMessage());
+            } catch (Exception e) {
+                throw new ExecutionException("Failed to unbind certkey to vserver due to " + e.getMessage());
+            }
+
+        }
+
+        private static void uploadCert(String nsIp, String user, String password, String certFilename, byte[] certData) throws ExecutionException {
+            try {
+                SshHelper.scpTo(nsIp, SSH_PORT, user, null, password, SSL_CERT_PATH, certData, certFilename, null);
+            } catch (Exception e) {
+                throw new ExecutionException("Failed to copy private key to device " + e.getMessage());
+            }
+        }
+
+        private static void uploadKey(String nsIp, String user, String password, String keyFilename, byte[] keyData) throws ExecutionException {
+            try {
+                SshHelper.scpTo(nsIp, SSH_PORT, user, null, password, SSL_CERT_PATH, keyData, keyFilename, null);
+            } catch (Exception e) {
+                throw new ExecutionException("Failed to copy private key to device " + e.getMessage());
+            }
+        }
+
+        private static void enableSslFeature(nitro_service ns, boolean isSdx) throws ExecutionException {
+            if (isSdx) {
+                return;
+            }
+            try {
+                base_response result = ns.enable_features(new String[] {"SSL"});
+                if (result.errorcode != 0)
+                    throw new ExecutionException("Unable to enable SSL on LB");
+            } catch (nitro_exception e) {
+                throw new ExecutionException("Failed to enable ssl feature on load balancer due to " + e.getMessage());
+            } catch (Exception e) {
+                throw new ExecutionException("Failed to enable ssl feature on load balancer due to " + e.getMessage());
+            }
+        }
+
+        public static boolean checkSslFeature(nitro_service ns) throws ExecutionException {
+            try {
+                String[] features = ns.get_enabled_features();
+                if (features != null) {
+                    for (String feature : features) {
+                        if (feature.equalsIgnoreCase("SSL")) {
+                            return true;
+                        }
+                    }
+                }
+                return false;
+            } catch (nitro_exception e) {
+                throw new ExecutionException("Failed to check ssl feature on load balancer due to " + e.getMessage());
+            } catch (Exception e) {
+                throw new ExecutionException("Failed to check ssl feature on load balancer due to " + e.getMessage());
+            }
+        }
+
+        public static boolean certLinkExists(nitro_service ns, String userCertName, String caCertName) throws ExecutionException {
+            try {
+                // check if there is a link from userCertName to caCertName
+
+                sslcertkey userCert = sslcertkey.get(ns, userCertName);
+                String nsCaCert = userCert.get_linkcertkeyname();
+
+                if (nsCaCert != null && nsCaCert.equals(caCertName))
+                    return true;
+
+            } catch (nitro_exception e) {
+                throw new ExecutionException("Failed to check cert link on load balancer to " + e.getMessage());
+            } catch (Exception e) {
+                throw new ExecutionException("Failed to check cert link on load balancer due to " + e.getMessage());
+            }
+            return false;
+        }
+
+        public static void linkCerts(nitro_service ns, String userCertName, String caCertName) throws ExecutionException {
+            try {
+
+                // the assumption is that that both userCertName and caCertName are present on NS
+
+                sslcertkey caCert = sslcertkey.get(ns, caCertName);
+                sslcertkey userCert = sslcertkey.get(ns, userCertName);
+
+                sslcertkey linkResource = new sslcertkey();
+
+                // link user cert to CA cert
+                linkResource.set_certkey(userCert.get_certkey());
+                linkResource.set_linkcertkeyname(caCert.get_certkey());
+                sslcertkey.link(ns, linkResource);
+
+            } catch (nitro_exception e) {
+                throw new ExecutionException("Failed to check cert link on load balancer to " + e.getMessage());
+            } catch (Exception e) {
+                throw new ExecutionException("Failed to check cert link on load balancer due to " + e.getMessage());
+            }
+
+        }
+
+        public static boolean isCaforCerts(nitro_service ns, String caCertName) throws ExecutionException {
+            // check if this certificate  serves as a CA for other certificates
+            try {
+                sslcertlink[] childLinks = sslcertlink.get_filtered(ns, "linkcertkeyname:" + caCertName);
+                if (childLinks != null && childLinks.length > 0) {
+                    return true;
+                }
+
+            } catch (nitro_exception e) {
+                throw new ExecutionException("Failed to check cert link on load balancer to " + e.getMessage());
+            } catch (Exception e) {
+                throw new ExecutionException("Failed to check cert link on load balancer due to " + e.getMessage());
+            }
+            return false;
+
+        }
+
+        public static boolean isBoundToVserver(nitro_service ns, String certKeyName, String nsVirtualServerName) throws ExecutionException {
+            try {
+
+                sslcertkey_sslvserver_binding[] cert_vs_binding = sslcertkey_sslvserver_binding.get_filtered(ns, certKeyName, "vservername:" + nsVirtualServerName);
+                if (cert_vs_binding != null && cert_vs_binding.length > 0) {
+                    return true;
+                }
+
+            } catch (nitro_exception e) {
+                throw new ExecutionException("Failed to check cert link on load balancer to " + e.getMessage());
+            } catch (Exception e) {
+                throw new ExecutionException("Failed to check cert link on load balancer due to " + e.getMessage());
+            }
+            return false;
+
+        }
+    }
+
+    private void enableVPXInterfaces(String publicIf, String privateIf, ns nsObj) {
+        // enable VPX to use 10 gigabit Ethernet interfaces if public/private interface
+        // on SDX is a 10Gig interface
+        if (publicIf.equals("10/1") || privateIf.equals("10/1")) {
+            nsObj.set_if_10_1(new Boolean(true));
+        }
+
+        if (publicIf.equals("10/2") || privateIf.equals("10/2")) {
+            nsObj.set_if_10_2(new Boolean(true));
+        }
+
+        if (publicIf.equals("10/3") || privateIf.equals("10/3")) {
+            nsObj.set_if_10_3(new Boolean(true));
+        }
+
+        if (publicIf.equals("10/4") || privateIf.equals("10/4")) {
+            nsObj.set_if_10_4(new Boolean(true));
+        }
+
+        if (publicIf.equals("10/5") || privateIf.equals("10/5")) {
+            nsObj.set_if_10_5(new Boolean(true));
+        }
+
+        if (publicIf.equals("10/6") || privateIf.equals("10/6")) {
+            nsObj.set_if_10_6(new Boolean(true));
+        }
+
+        if (publicIf.equals("10/7") || privateIf.equals("10/7")) {
+            nsObj.set_if_10_7(new Boolean(true));
+        }
+
+        if (publicIf.equals("10/8") || privateIf.equals("10/8")) {
+            nsObj.set_if_10_8(new Boolean(true));
+        }
+
+        // enable VPX to use 1 gigabit Ethernet interfaces if public/private interface
+        // on SDX is a 1Gig interface
+        if (publicIf.equals("1/1") || privateIf.equals("1/1")) {
+            nsObj.set_if_1_1(new Boolean(true));
+        }
+
+        if (publicIf.equals("1/2") || privateIf.equals("1/2")) {
+            nsObj.set_if_1_2(new Boolean(true));
+        }
+
+        if (publicIf.equals("1/3") || privateIf.equals("1/3")) {
+            nsObj.set_if_1_3(new Boolean(true));
+        }
+
+        if (publicIf.equals("1/4") || privateIf.equals("1/4")) {
+            nsObj.set_if_1_4(new Boolean(true));
+        }
+
+        if (publicIf.equals("1/5") || privateIf.equals("1/5")) {
+            nsObj.set_if_1_5(new Boolean(true));
+        }
+
+        if (publicIf.equals("1/6") || privateIf.equals("1/6")) {
+            nsObj.set_if_1_6(new Boolean(true));
+        }
+
+        if (publicIf.equals("1/7") || privateIf.equals("1/7")) {
+            nsObj.set_if_1_7(new Boolean(true));
+        }
+
+        if (publicIf.equals("1/8") || privateIf.equals("1/8")) {
+            nsObj.set_if_1_8(new Boolean(true));
+        }
+    }
+
+    private synchronized Answer execute(DestroyLoadBalancerApplianceCommand cmd, int numRetries) {
+        String vpxName = "Cloud-VPX-" + cmd.getLoadBalancerIP();
+        if (!_isSdx) {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+
+        try {
+            ns vpxToDelete = null;
+            ns[] vpxInstances = ns.get(_netscalerSdxService);
+            for (ns vpx : vpxInstances) {
+                if (vpx.get_name().equals(vpxName)) {
+                    vpxToDelete = vpx;
+                    break;
+                }
+            }
+
+            if (vpxToDelete == null) {
+                String msg = "There is no VPX instance " + vpxName + " on the Netscaler SDX device " + _ip + " to delete";
+                s_logger.warn(msg);
+                return new DestroyLoadBalancerApplianceAnswer(cmd, true, msg);
+            }
+
+            // destroy the VPX instance
+            ns nsDelObj = new ns();
+            nsDelObj.set_id(vpxToDelete.get_id());
+            vpxToDelete = ns.delete(_netscalerSdxService, nsDelObj);
+            String msg = "Deleted VPX instance " + vpxName + " on Netscaler SDX " + _ip + " successfully.";
+            s_logger.info(msg);
+            return new DestroyLoadBalancerApplianceAnswer(cmd, true, msg);
+        } catch (Exception e) {
+            if (shouldRetry(numRetries)) {
+                return retry(cmd, numRetries);
+            }
+            return new DestroyLoadBalancerApplianceAnswer(cmd, false, "Failed to delete VPX instance " + vpxName + " on Netscaler SDX " + _ip);
+        }
+    }
+
+    private synchronized Answer execute(SetStaticNatRulesCommand cmd, int numRetries) {
+
+        if (_isSdx) {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+
+        String[] results = new String[cmd.getRules().length];
+        int i = 0;
+        boolean endResult = true;
+
+        try {
+            for (StaticNatRuleTO rule : cmd.getRules()) {
+                String srcIp = rule.getSrcIp();
+                String dstIP = rule.getDstIp();
+                String iNatRuleName = generateInatRuleName(srcIp, dstIP);
+                String rNatRuleName = generateRnatRuleName(srcIp, dstIP);
+                inat iNatRule = null;
+                rnat rnatRule = null;
+
+                if (!rule.revoked()) {
+                    try {
+                        iNatRule = inat.get(_netscalerService, iNatRuleName);
+                    } catch (nitro_exception e) {
+                        if (e.getErrorCode() != NitroError.NS_RESOURCE_NOT_EXISTS) {
+                            throw e;
+                        }
+                    }
+
+                    if (iNatRule == null) {
+                        iNatRule = new inat();
+                        iNatRule.set_name(iNatRuleName);
+                        iNatRule.set_publicip(srcIp);
+                        iNatRule.set_privateip(dstIP);
+                        iNatRule.set_usnip("OFF");
+                        iNatRule.set_usip("ON");
+                        try {
+                            apiCallResult = inat.add(_netscalerService, iNatRule);
+                        } catch (nitro_exception e) {
+                            if (e.getErrorCode() != NitroError.NS_RESOURCE_EXISTS) {
+                                throw e;
+                            }
+                        }
+                        s_logger.debug("Created Inat rule on the Netscaler device " + _ip + " to enable static NAT from " + srcIp + " to " + dstIP);
+                    }
+                    try {
+                        rnat[] rnatRules = rnat.get(_netscalerService);
+                        if (rnatRules != null) {
+                            for (rnat rantrule : rnatRules) {
+                                if (rantrule.get_network().equalsIgnoreCase(rNatRuleName)) {
+                                    rnatRule = rantrule;
+                                    break;
+                                }
+                            }
+                        }
+                    } catch (nitro_exception e) {
+                        throw e;
+                    }
+
+                    if (rnatRule == null) {
+                        rnatRule = new rnat();
+                        rnatRule.set_natip(srcIp);
+                        rnatRule.set_network(dstIP);
+                        rnatRule.set_netmask("255.255.255.255");
+                        try {
+                            apiCallResult = rnat.update(_netscalerService, rnatRule);
+                        } catch (nitro_exception e) {
+                            if (e.getErrorCode() != NitroError.NS_RESOURCE_EXISTS) {
+                                throw e;
+                            }
+                        }
+                        s_logger.debug("Created Rnat rule on the Netscaler device " + _ip + " to enable revese static NAT from " + dstIP + " to " + srcIp);
+                    }
+                } else {
+                    try {
+                        inat.delete(_netscalerService, iNatRuleName);
+                        rnat[] rnatRules = rnat.get(_netscalerService);
+                        if (rnatRules != null) {
+                            for (rnat rantrule : rnatRules) {
+                                if (rantrule.get_network().equalsIgnoreCase(dstIP)) {
+                                    rnatRule = rantrule;
+                                    rnat.clear(_netscalerService, rnatRule);
+                                    break;
+                                }
+                            }
+                        }
+                    } catch (nitro_exception e) {
+                        if (e.getErrorCode() != NitroError.NS_RESOURCE_NOT_EXISTS) {
+                            throw e;
+                        }
+                    }
+                    s_logger.debug("Deleted Inat rule on the Netscaler device " + _ip + " to remove static NAT from " + srcIp + " to " + dstIP);
+                }
+
+                saveConfiguration();
+                results[i++] = "Static nat rule from " + srcIp + " to " + dstIP + " successfully " + (rule.revoked() ? " revoked." : " created.");
+            }
+        } catch (Exception e) {
+            if (shouldRetry(numRetries)) {
+                return retry(cmd, numRetries);
+            }
+            results[i++] = "Configuring static nat rule failed due to " + e.getMessage();
+            endResult = false;
+            return new SetStaticNatRulesAnswer(cmd, results, endResult);
+        }
+
+        return new SetStaticNatRulesAnswer(cmd, results, endResult);
+    }
+
+    private synchronized Answer execute(ExternalNetworkResourceUsageCommand cmd, int numRetries) {
+        try {
+            if (!_isSdx) {
+                return getPublicIpBytesSentAndReceived(cmd);
+            } else {
+                return Answer.createUnsupportedCommandAnswer(cmd);
+            }
+        } catch (ExecutionException e) {
+            if (shouldRetry(numRetries)) {
+                return retry(cmd, numRetries);
+            } else {
+                return new ExternalNetworkResourceUsageAnswer(cmd, e);
+            }
+        }
+    }
+
+    private void addSubnetIP(String snip, String netmask) throws ExecutionException {
+        try {
+            nsip selfIp = new nsip();
+            selfIp.set_ipaddress(snip);
+            selfIp.set_netmask(netmask);
+            selfIp.set_type("SNIP");
+            apiCallResult = nsip.add(_netscalerService, selfIp);
+            if (apiCallResult.errorcode != 0) {
+                throw new ExecutionException("Failed to add SNIP object on the Netscaler device due to " + apiCallResult.message);
+            }
+        } catch (nitro_exception e) {
+            throw new ExecutionException("Failed to add SNIP object on the Netscaler device due to " + e.getMessage());
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to add SNIP object on the Netscaler device due to " + e.getMessage());
+        }
+    }
+
+    private void addGuestVlanAndSubnet(long vlanTag, String vlanSelfIp, String vlanNetmask, boolean guestVlan) throws ExecutionException {
+        try {
+            // add vlan object for guest VLAN
+            if (!nsVlanExists(vlanTag)) {
+                try {
+                    vlan vlanObj = new vlan();
+                    vlanObj.set_id(vlanTag);
+                    apiCallResult = vlan.add(_netscalerService, vlanObj);
+                    if (apiCallResult.errorcode != 0) {
+                        throw new ExecutionException("Failed to add new vlan with tag:" + vlanTag + "on the NetScaler device due to " + apiCallResult.message);
+                    }
+                } catch (nitro_exception e) {
+                    throw new ExecutionException("Failed to add new vlan with tag:" + vlanTag + "on the NetScaler device due to " + e.getMessage());
+                }
+            }
+
+            // add subnet IP object for this guest network
+            if (!nsSnipExists(vlanSelfIp)) {
+                try {
+                    nsip selfIp = new nsip();
+                    selfIp.set_ipaddress(vlanSelfIp);
+                    selfIp.set_netmask(vlanNetmask);
+                    selfIp.set_type("SNIP");
+                    apiCallResult = nsip.add(_netscalerService, selfIp);
+                    if (apiCallResult.errorcode != 0) {
+                        throw new ExecutionException("Failed to add SNIP object for the guest network on the Netscaler device due to " + apiCallResult.message);
+                    }
+                } catch (nitro_exception e) {
+                    throw new ExecutionException("Failed to add SNIP object for the guest network on the Netscaler device due to " + e.getMessage());
+                }
+            }
+
+            // bind the vlan object to subnet IP object
+            if (!nsVlanNsipBindingExists(vlanTag, vlanSelfIp)) {
+                try {
+                    vlan_nsip_binding ipVlanBinding = new vlan_nsip_binding();
+                    ipVlanBinding.set_id(vlanTag);
+                    ipVlanBinding.set_ipaddress(vlanSelfIp);
+                    ipVlanBinding.set_netmask(vlanNetmask);
+                    apiCallResult = vlan_nsip_binding.add(_netscalerService, ipVlanBinding);
+                    if (apiCallResult.errorcode != 0) {
+                        throw new ExecutionException("Failed to bind VLAN with tag:" + vlanTag + " to the subnet due to " + apiCallResult.message);
+                    }
+                } catch (nitro_exception e) {
+                    throw new ExecutionException("Failed to bind VLAN with tage:" + vlanTag + " to the subnet due to " + e.getMessage());
+                }
+            }
+
+            // bind vlan object to the private interface
+            try {
+                vlan_interface_binding vlanBinding = new vlan_interface_binding();
+                if (guestVlan) {
+                    vlanBinding.set_ifnum(_privateInterface);
+                } else {
+                    vlanBinding.set_ifnum(_publicInterface);
+                }
+                vlanBinding.set_tagged(true);
+                vlanBinding.set_id(vlanTag);
+                apiCallResult = vlan_interface_binding.add(_netscalerService, vlanBinding);
+                if (apiCallResult.errorcode != 0) {
+                    String vlanInterface = guestVlan ? _privateInterface : _publicInterface;
+                    throw new ExecutionException("Failed to bind vlan with tag:" + vlanTag + " with the interface " + vlanInterface + " due to " + apiCallResult.message);
+                }
+            } catch (nitro_exception e) {
+                if (!(e.getErrorCode() == NitroError.NS_INTERFACE_ALREADY_BOUND_TO_VLAN)) {
+                    throw new ExecutionException("Failed to bind VLAN " + vlanTag + " with interface on the Netscaler device due to " + e.getMessage());
+                }
+            }
+        } catch (nitro_exception e) {
+            throw new ExecutionException("Failed to implement guest network on the Netscaler device due to " + e.getMessage());
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to implement guest network on the Netscaler device due to " + e.getMessage());
+        }
+    }
+
+    private void deleteGuestVlan(long vlanTag, String vlanSelfIp, String vlanNetmask) throws ExecutionException {
+        try {
+
+            // Delete all servers and associated services from this guest VLAN
+            deleteServersInGuestVlan(vlanTag, vlanSelfIp, vlanNetmask);
+
+            // unbind vlan to the private interface
+            try {
+                vlan_interface_binding vlanIfBinding = new vlan_interface_binding();
+                vlanIfBinding.set_id(vlanTag);
+                vlanIfBinding.set_ifnum(_privateInterface);
+                vlanIfBinding.set_tagged(true);
+                apiCallResult = vlan_interface_binding.delete(_netscalerService, vlanIfBinding);
+                if (apiCallResult.errorcode != 0) {
+                    throw new ExecutionException("Failed to unbind vlan:" + vlanTag + " with the private interface due to " + apiCallResult.message);
+                }
+            } catch (nitro_exception e) {
+                // if Vlan to interface binding does not exist then ignore the exception and proceed
+                if (!(e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS)) {
+                    throw new ExecutionException("Failed to unbind vlan from the interface while shutdown of guest network on the Netscaler device due to " +
+                            e.getMessage());
+                }
+            }
+
+            // unbind the vlan to subnet
+            try {
+                vlan_nsip_binding vlanSnipBinding = new vlan_nsip_binding();
+                vlanSnipBinding.set_netmask(vlanNetmask);
+                vlanSnipBinding.set_ipaddress(vlanSelfIp);
+                vlanSnipBinding.set_id(vlanTag);
+                apiCallResult = vlan_nsip_binding.delete(_netscalerService, vlanSnipBinding);
+                if (apiCallResult.errorcode != 0) {
+                    throw new ExecutionException("Failed to unbind vlan:" + vlanTag + " with the subnet due to " + apiCallResult.message);
+                }
+            } catch (nitro_exception e) {
+                // if Vlan to subnet binding does not exist then ignore the exception and proceed
+                if (!(e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS)) {
+                    throw new ExecutionException("Failed to unbind vlan:" + vlanTag + " with the subnet due to " + e.getMessage());
+                }
+            }
+
+            // remove subnet IP
+            try {
+                nsip _vlanSelfIp = new nsip();
+                _vlanSelfIp.set_ipaddress(vlanSelfIp);
+
+                nsip subnetIp = nsip.get(_netscalerService, _vlanSelfIp);
+                apiCallResult = nsip.delete(_netscalerService, subnetIp);
+                if (apiCallResult.errorcode != 0) {
+                    throw new ExecutionException("Failed to remove subnet ip:" + vlanSelfIp + " from the NetScaler device due to" + apiCallResult.message);
+                }
+            } catch (nitro_exception e) {
+                // if subnet SNIP does not exist then ignore the exception and proceed
+                if (!(e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS)) {
+                    throw new ExecutionException("Failed to remove subnet ip:" + vlanSelfIp + " from the NetScaler device due to" + e.getMessage());
+                }
+            }
+
+            // remove the vlan from the NetScaler device
+            if (nsVlanExists(vlanTag)) {
+                // remove vlan
+                apiCallResult = com.citrix.netscaler.nitro.resource.config.network.vlan.delete(_netscalerService, vlanTag);
+                if (apiCallResult.errorcode != 0) {
+                    throw new ExecutionException("Failed to remove vlan with tag:" + vlanTag + "due to" + apiCallResult.message);
+                }
+            }
+        } catch (nitro_exception e) {
+            throw new ExecutionException("Failed to delete guest vlan network on the Netscaler device due to " + e.getMessage());
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to delete guest vlan network on the Netscaler device due to " + e.getMessage());
+        }
+    }
+
+    private boolean nsVlanExists(long vlanTag) throws ExecutionException {
+        try {
+            if (vlan.get(_netscalerService, new Long(vlanTag)) != null) {
+                return true;
+            } else {
+                return false;
+            }
+        } catch (nitro_exception e) {
+            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
+                return false;
+            } else {
+                throw new ExecutionException("Failed to verify  VLAN exists on the NetScaler device due to " + e.getMessage());
+            }
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to verify  VLAN exists on the NetScaler device due to " + e.getMessage());
+        }
+    }
+
+    private boolean nsSnipExists(String subnetIp) throws ExecutionException {
+        try {
+            nsip _subnetIp = new nsip();
+            _subnetIp.set_ipaddress(subnetIp);
+
+            nsip snip = nsip.get(_netscalerService, _subnetIp);
+            return (snip != null);
+        } catch (nitro_exception e) {
+            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
+                return false;
+            } else {
+                throw new ExecutionException("Failed to verify if SNIP exists on the NetScaler device due to " + e.getMessage());
+            }
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to verify if SNIP exists on the NetScaler device due to " + e.getMessage());
+        }
+    }
+
+    private boolean nsServerExists(String serverName) throws ExecutionException {
+        try {
+            if (com.citrix.netscaler.nitro.resource.config.basic.server.get(_netscalerService, serverName) != null) {
+                return true;
+            } else {
+                return false;
+            }
+        } catch (nitro_exception e) {
+            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
+                return false;
+            } else {
+                throw new ExecutionException("Failed to verify Server " + serverName + " exists on the NetScaler device due to " + e.getMessage());
+            }
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to verify Server " + serverName + " exists on the NetScaler device due to " + e.getMessage());
+        }
+    }
+
+    private boolean nsVirtualServerExists(String vserverName) throws ExecutionException {
+        try {
+            if (com.citrix.netscaler.nitro.resource.config.lb.lbvserver.get(_netscalerService, vserverName) != null) {
+                return true;
+            } else {
+                return false;
+            }
+        } catch (nitro_exception e) {
+            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
+                return false;
+            } else {
+                throw new ExecutionException("Failed to verify VServer " + vserverName + " exists on the NetScaler device due to " + e.getMessage());
+            }
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to verify VServer " + vserverName + " exists on the NetScaler device due to " + e.getMessage());
+        }
+    }
+
+    private boolean nsVlanNsipBindingExists(long vlanTag, String vlanSelfIp) throws ExecutionException {
+        try {
+            vlan_nsip_binding[] vlanNsipBindings = vlan_nsip_binding.get(_netscalerService, vlanTag);
+            if (vlanNsipBindings != null && vlanNsipBindings[0] != null && vlanNsipBindings[0].get_ipaddress().equalsIgnoreCase(vlanSelfIp)) {
+                return true;
+            } else {
+                return false;
+            }
+        } catch (nitro_exception e) {
+            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
+                return false;
+            } else {
+                throw new ExecutionException("Failed to verify Vlan " + vlanTag + " to SNIP " + vlanSelfIp + " binding exists due to " + e.getMessage());
+            }
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to verify Vlan " + vlanTag + " to SNIP " + vlanSelfIp + " binding exists due to " + e.getMessage());
+        }
+    }
+
+    private lbvserver getVirtualServerIfExisits(String lbVServerName) throws ExecutionException {
+        try {
+            return lbvserver.get(_netscalerService, lbVServerName);
+        } catch (nitro_exception e) {
+            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
+                return null;
+            } else {
+                throw new ExecutionException(e.getMessage());
+            }
+        } catch (Exception e) {
+            throw new ExecutionException(e.getMessage());
+        }
+    }
+
+    private lbmonitor getMonitorIfExisits(String lbMonitorName) throws ExecutionException {
+        try {
+            return lbmonitor.get(_netscalerService, lbMonitorName);
+        } catch (nitro_exception e) {
+            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
+                return null;
+            } else {
+                throw new ExecutionException(e.getMessage());
+            }
+        } catch (Exception e) {
+            throw new ExecutionException(e.getMessage());
+        }
+    }
+
+    private boolean isServiceBoundToVirtualServer(String serviceName) throws ExecutionException {
+        try {
+            lbvserver[] lbservers = lbvserver.get(_netscalerService);
+            for (lbvserver vserver : lbservers) {
+                filtervalue[] filter = new filtervalue[1];
+                filter[0] = new filtervalue("servicename", serviceName);
+                lbvserver_service_binding[] result = lbvserver_service_binding.get_filtered(_netscalerService, vserver.get_name(), filter);
+                if (result != null && result.length > 0) {
+                    return true;
+                }
+            }
+            return false;
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to verify service " + serviceName + " is bound to any virtual server due to " + e.getMessage());
+        }
+    }
+
+    private boolean isServiceBoundToMonitor(String nsServiceName, String nsMonitorName) throws ExecutionException {
+
+        filtervalue[] filter = new filtervalue[1];
+        filter[0] = new filtervalue("monitor_name", nsMonitorName);
+        service_lbmonitor_binding[] result;
+        try {
+            result = service_lbmonitor_binding.get_filtered(_netscalerService, nsServiceName, filter);
+            if (result != null && result.length > 0) {
+                return true;
+            }
+
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to verify service " + nsServiceName + " is bound to any monitor due to " + e.getMessage());
+        }
+        return false;
+    }
+
+    private boolean nsMonitorExist(String nsMonitorname) throws ExecutionException {
+        if (getMonitorIfExisits(nsMonitorname) != null)
+            return true;
+        else
+            return false;
+    }
+
+    private boolean nsServiceExists(String serviceName) throws ExecutionException {
+        try {
+            if (com.citrix.netscaler.nitro.resource.config.basic.service.get(_netscalerService, serviceName) != null) {
+                return true;
+            } else {
+                return false;
+            }
+        } catch (nitro_exception e) {
+            if (e.getErrorCode() == NitroError.NS_NO_SERIVCE) {
+                return false;
+            } else {
+                throw new ExecutionException("Failed to verify service " + serviceName + " exists due to " + e.getMessage());
+            }
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to verify service " + serviceName + " exists due to " + e.getMessage());
+        }
+    }
+
+    private boolean nsServiceBindingExists(String lbVirtualServer, String serviceName) throws ExecutionException {
+        try {
+            com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding[] serviceBindings =
+                    com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.get(_netscalerService, lbVirtualServer);
+            if (serviceBindings != null) {
+                for (com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding binding : serviceBindings) {
+                    if (serviceName.equalsIgnoreCase(binding.get_servicename())) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        } catch (nitro_exception e) {
+            throw new ExecutionException("Failed to verify lb vserver " + lbVirtualServer + "and service " + serviceName + " binding exists due to " + e.getMessage());
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to verify lb vserver " + lbVirtualServer + "and service " + serviceName + " binding exists due to " + e.getMessage());
+        }
+    }
+
+    private boolean isServiceGroupBoundToVirtualServer(String nsVirtualServerName, String serviceGroupName) throws ExecutionException {
+
+        new lbvserver_servicegroup_binding();
+
+        try {
+            lbvserver_servicegroup_binding[] result =
+                    lbvserver_servicegroup_binding.get_filtered(_netscalerService, nsVirtualServerName, "servicegroupname:" + serviceGroupName);
+            if (result != null && result.length > 0) {
+                return true;
+            }
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to verify lb vserver " + nsVirtualServerName + "and servicegrop " + serviceGroupName + " binding exists due to " +
+                    e.getMessage());
+        }
+        return false;
+
+    }
+
+    private boolean nsServiceGroupExists(String lbVServerName) throws ExecutionException {
+        try {
+            return servicegroup.get(_netscalerService, lbVServerName) != null;
+        } catch (nitro_exception e) {
+            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
+                return false; // service group does not exist
+            } else {
+                throw new ExecutionException(e.getMessage());
+            }
+        } catch (Exception e) {
+            throw new ExecutionException(e.getMessage());
+        }
+    }
+
+    private void deleteServersInGuestVlan(long vlanTag, String vlanSelfIp, String vlanNetmask) throws ExecutionException {
+        try {
+            com.citrix.netscaler.nitro.resource.config.basic.server[] serverList = com.citrix.netscaler.nitro.resource.config.basic.server.get(_netscalerService);
+
+            if (serverList == null) {
+                return;
+            }
+
+            // remove the server and services associated with guest vlan
+            for (com.citrix.netscaler.nitro.resource.config.basic.server server : serverList) {
+                // check if server belong to same subnet as one associated with vlan
+                if (NetUtils.sameSubnet(vlanSelfIp, server.get_ipaddress(), vlanNetmask)) {
+                    // first remove services associated with this server
+                    com.citrix.netscaler.nitro.resource.config.basic.service serveicesList[] =
+                            com.citrix.netscaler.nitro.resource.config.basic.service.get(_netscalerService);
+                    if (serveicesList != null) {
+                        for (com.citrix.netscaler.nitro.resource.config.basic.service svc : serveicesList) {
+                            if (svc.get_servername().equals(server.get_ipaddress())) {
+                                apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.service.delete(_netscalerService, svc.get_name());
+                                if (apiCallResult.errorcode != 0) {
+                                    throw new ExecutionException("Failed to remove service:" + svc.get_name());
+                                }
+                            }
+                        }
+                    }
+                    // remove the server
+                    // don't delete server which has no ip address (these servers are created by NS for autoscale
+                    if (server.get_ipaddress() != null) {
+                        apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.delete(_netscalerService, server.get_name());
+                        if (apiCallResult.errorcode != 0) {
+                            throw new ExecutionException("Failed to remove server:" + server.get_name());
+                        }
+                    }
+                }
+            }
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to delete server and services in the guest vlan:" + vlanTag + " on the Netscaler device due to: " + e.getMessage());
+        }
+    }
+
+    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 void addLBVirtualServer(String virtualServerName, String publicIp, int publicPort, String lbAlgorithm, String protocol, StickinessPolicyTO[] stickyPolicies,
+            AutoScaleVmGroupTO vmGroupTO) throws ExecutionException {
+        try {
+            String lbMethod;
+            if ("roundrobin".equalsIgnoreCase(lbAlgorithm)) {
+                lbMethod = "ROUNDROBIN";
+            } else if ("leastconn".equalsIgnoreCase(lbAlgorithm)) {
+                lbMethod = "LEASTCONNECTION";
+            } else if ("source".equalsIgnoreCase(lbAlgorithm)) {
+                lbMethod = "SOURCEIPHASH";
+            } else {
+                throw new ExecutionException("Got invalid load balancing algorithm: " + lbAlgorithm + " in the load balancing rule");
+            }
+
+            boolean vserverExisis = false;
+            lbvserver vserver = getVirtualServerIfExisits(virtualServerName);
+            if (vserver != null) {
+                if (!vserver.get_servicetype().equalsIgnoreCase(protocol)) {
+                    throw new ExecutionException("Can not update virtual server:" + virtualServerName + " as current protocol:" + vserver.get_servicetype() +
+                            " of virtual server is different from the " + " intended protocol:" + protocol);
+                }
+                vserverExisis = true;
+            }
+            // Use new vserver always for configuration
+            vserver = new lbvserver();
+            vserver.set_name(virtualServerName);
+            vserver.set_ipv46(publicIp);
+            vserver.set_port(publicPort);
+            vserver.set_servicetype(protocol);
+            vserver.set_lbmethod(lbMethod);
+
+            // netmask can only be set for source IP load balancer algorithm
+            if (!lbMethod.equalsIgnoreCase("SOURCEIPHASH")) {
+                vserver.set_netmask(null);
+                vserver.set_v6netmasklen(null);
+            }
+
+            if ((stickyPolicies != null) && (stickyPolicies.length > 0) && (stickyPolicies[0] != null)) {
+                long timeout = 2;// netscaler default 2 min
+                String cookieName = null;
+                StickinessPolicyTO stickinessPolicy = stickyPolicies[0];
+
+                // get the session persistence parameters
+                List<Pair<String, String>> paramsList = stickinessPolicy.getParams();
+                for (Pair<String, String> param : paramsList) {
+                    if ("holdtime".equalsIgnoreCase(param.first())) {
+                        timeout = Long.parseLong(param.second());
+                    } else if ("name".equalsIgnoreCase(param.first())) {
+                        cookieName = param.second();
+                    }
+                }
+
+                // configure virtual server based on the persistence method
+                if (StickinessMethodType.LBCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) {
+                    vserver.set_persistencetype("COOKIEINSERT");
+                } else if (StickinessMethodType.SourceBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) {
+                    vserver.set_persistencetype("SOURCEIP");
+                } else if (StickinessMethodType.AppCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) {
+                    vserver.set_persistencetype("RULE");
+                    vserver.set_rule("HTTP.REQ.HEADER(\"COOKIE\").VALUE(0).typecast_nvlist_t('=',';').value(\"" + cookieName + "\")");
+                    vserver.set_resrule("HTTP.RES.HEADER(\"SET-COOKIE\").VALUE(0).typecast_nvlist_t('=',';').value(\"" + cookieName + "\")");
+                } else {
+                    throw new ExecutionException("Got invalid session persistence method: " + stickinessPolicy.getMethodName() + " in the load balancing rule");
+                }
+
+                // set session persistence timeout
+                vserver.set_timeout(timeout);
+            } else {
+                // delete the LB stickyness policy
+                vserver.set_persistencetype("NONE");
+            }
+
+            if (vserverExisis) {
+                apiCallResult = lbvserver.update(_netscalerService, vserver);
+            } else {
+                apiCallResult = lbvserver.add(_netscalerService, vserver);
+            }
+            if (apiCallResult.errorcode != 0) {
+                throw new ExecutionException("Failed to create new load balancing virtual server:" + virtualServerName + " due to " + apiCallResult.message);
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Created load balancing virtual server " + virtualServerName + " on the Netscaler device");
+            }
+        } catch (nitro_exception e) {
+            throw new ExecutionException("Failed to create new virtual server:" + virtualServerName + " due to " + e.getMessage());
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to create new virtual server:" + virtualServerName + " due to " + e.getMessage());
+        }
+    }
+
+    private void removeLBVirtualServer(String virtualServerName) throws ExecutionException {
+        try {
+            lbvserver vserver = lbvserver.get(_netscalerService, virtualServerName);
+            if (vserver == null) {
+                return;
+            }
+            apiCallResult = lbvserver.delete(_netscalerService, vserver);
+            if (apiCallResult.errorcode != 0) {
+                throw new ExecutionException("Failed to delete virtual server:" + virtualServerName + " due to " + apiCallResult.message);
+            }
+        } catch (nitro_exception e) {
+            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
+                return;
+            } else {
+                throw new ExecutionException("Failed remove virtual server:" + virtualServerName + " due to " + e.getMessage());
+            }
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to remove virtual server:" + virtualServerName + " due to " + e.getMessage());
+        }
+    }
+
+    // Monitor related methods
+    private void addLBMonitor(String nsMonitorName, String lbProtocol, HealthCheckPolicyTO hcp) throws ExecutionException {
+        try {
+            // check if the monitor exists
+            boolean csMonitorExisis = false;
+            lbmonitor csMonitor = getMonitorIfExisits(nsMonitorName);
+            if (csMonitor != null) {
+                if (!csMonitor.get_type().equalsIgnoreCase(lbProtocol)) {
+                    throw new ExecutionException("Can not update monitor :" + nsMonitorName + " as current protocol:" + csMonitor.get_type() +
+                            " of monitor is different from the " + " intended protocol:" + lbProtocol);
+                }
+                csMonitorExisis = true;
+            }
+            if (!csMonitorExisis) {
+                lbmonitor csMon = new lbmonitor();
+                csMon.set_monitorname(nsMonitorName);
+                csMon.set_type(lbProtocol);
+                if (lbProtocol.equalsIgnoreCase("HTTP")) {
+                    csMon.set_httprequest(hcp.getpingPath());
+                    s_logger.trace("LB Protocol is HTTP,  Applying  ping path on HealthCheck Policy");
+                } else {
+                    s_logger.debug("LB Protocol is not HTTP, Skipping to apply  ping path on HealthCheck Policy");
+                }
+
+                csMon.set_interval(hcp.getHealthcheckInterval());
+                csMon.set_retries(Math.max(hcp.getHealthcheckThresshold(), hcp.getUnhealthThresshold()) + 1);
+                csMon.set_resptimeout(hcp.getResponseTime());
+                csMon.set_failureretries(hcp.getUnhealthThresshold());
+                csMon.set_successretries(hcp.getHealthcheckThresshold());
+                s_logger.debug("Monitor properites going to get created :interval :: " + csMon.get_interval() + "respTimeOUt:: " + csMon.get_resptimeout() +
+                        "failure retires(unhealththresshold) :: " + csMon.get_failureretries() + "successtries(healththresshold) ::" + csMon.get_successretries());
+                lbmonitor.add(_netscalerService, csMon);
+            } else {
+                s_logger.debug("Monitor :" + nsMonitorName + " is already existing. Skipping to delete and create it");
+            }
+        } catch (nitro_exception e) {
+            throw new ExecutionException("Failed to create new monitor :" + nsMonitorName + " due to " + e.getMessage());
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to create new monitor :" + nsMonitorName + " due to " + e.getMessage());
+        }
+    }
+
+    private void bindServiceToMonitor(String nsServiceName, String nsMonitorName) throws ExecutionException {
+
+        try {
+            com.citrix.netscaler.nitro.resource.config.basic.service serviceObject = new com.citrix.netscaler.nitro.resource.config.basic.service();
+            serviceObject = com.citrix.netscaler.nitro.resource.config.basic.service.get(_netscalerService, nsServiceName);
+            if (serviceObject != null) {
+                com.citrix.netscaler.nitro.resource.config.basic.service_lbmonitor_binding serviceMonitor =
+                        new com.citrix.netscaler.nitro.resource.config.basic.service_lbmonitor_binding();
+                serviceMonitor.set_monitor_name(nsMonitorName);
+                serviceMonitor.set_name(nsServiceName);
+                serviceMonitor.set_monstate("ENABLED");
+                s_logger.debug("Trying to bind  the monitor :" + nsMonitorName + " to the service :" + nsServiceName);
+                com.citrix.netscaler.nitro.resource.config.basic.service_lbmonitor_binding.add(_netscalerService, serviceMonitor);
+                s_logger.debug("Successfully binded the monitor :" + nsMonitorName + " to the service :" + nsServiceName);
+            }
+        } catch (nitro_exception e) {
+            throw new ExecutionException("Failed to create new monitor :" + nsMonitorName + " due to " + e.getMessage());
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to create new monitor :" + nsMonitorName + " due to " + e.getMessage());
+        }
+    }
+
+    private void unBindServiceToMonitor(String nsServiceName, String nsMonitorName) throws ExecutionException {
+
+        try {
+            com.citrix.netscaler.nitro.resource.config.basic.service serviceObject = new com.citrix.netscaler.nitro.resource.config.basic.service();
+            serviceObject = com.citrix.netscaler.nitro.resource.config.basic.service.get(_netscalerService, nsServiceName);
+
+            if (serviceObject != null) {
+                com.citrix.netscaler.nitro.resource.config.basic.service_lbmonitor_binding serviceMonitor =
+                        new com.citrix.netscaler.nitro.resource.config.basic.service_lbmonitor_binding();
+                serviceMonitor.set_monitor_name(nsMonitorName);
+                serviceMonitor.set_name(nsServiceName);
+                s_logger.debug("Trying to unbind  the monitor :" + nsMonitorName + " from the service :" + nsServiceName);
+                service_lbmonitor_binding.delete(_netscalerService, serviceMonitor);
+                s_logger.debug("Successfully unbinded the monitor :" + nsMonitorName + " from the service :" + nsServiceName);
+            }
+
+        } catch (nitro_exception e) {
+            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
+                return;
+            } else {
+                throw new ExecutionException("Failed to unbind monitor :" + nsMonitorName + "from the service :" + nsServiceName + "due to " + e.getMessage());
+            }
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to unbind monitor :" + nsMonitorName + "from the service :" + nsServiceName + "due to " + e.getMessage());
+        }
+
+    }
+
+    private void removeLBMonitor(String nsMonitorName) throws ExecutionException {
+
+        try {
+            if (nsMonitorExist(nsMonitorName)) {
+                lbmonitor monitorObj = lbmonitor.get(_netscalerService, nsMonitorName);
+                monitorObj.set_respcode(null);
+                lbmonitor.delete(_netscalerService, monitorObj);
+                s_logger.info("Successfully deleted monitor : " + nsMonitorName);
+            }
+        } catch (nitro_exception e) {
+            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
+                return;
+            } else {
+                throw new ExecutionException("Failed to delete monitor :" + nsMonitorName + " due to " + e.getMessage());
+            }
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to delete monitor :" + nsMonitorName + " due to " + e.getMessage());
+        }
+
+    }
+
+    public synchronized void applyAutoScaleConfig(LoadBalancerTO loadBalancer) throws Exception, ExecutionException {
+
+        AutoScaleVmGroupTO vmGroupTO = loadBalancer.getAutoScaleVmGroupTO();
+        if (!isAutoScaleSupportedInNetScaler()) {
+            throw new ExecutionException("AutoScale not supported in this version of NetScaler");
+        }
+        if (loadBalancer.isRevoked() || vmGroupTO.getState().equals("revoke")) {
+            removeAutoScaleConfig(loadBalancer);
+        } else {
+            createAutoScaleConfig(loadBalancer);
+        }
+        // AutoScale APIs are successful executed, now save the configuration.
+        saveConfiguration();
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Successfully executed resource AutoScaleConfig");
+        }
+    }
+
+    @SuppressWarnings("static-access")
+    private synchronized boolean createAutoScaleConfig(LoadBalancerTO loadBalancerTO) throws ExecutionException, Exception {
+
+        String srcIp = loadBalancerTO.getSrcIp();
+        int srcPort = loadBalancerTO.getSrcPort();
+        String lbProtocol = getNetScalerProtocol(loadBalancerTO);
+        String lbAlgorithm = loadBalancerTO.getAlgorithm();
+        generateAutoScaleVmGroupIdentifier(loadBalancerTO);
+        String nsVirtualServerName = generateNSVirtualServerName(srcIp, srcPort);
+        AutoScaleVmGroupTO vmGroupTO = loadBalancerTO.getAutoScaleVmGroupTO();
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Created load balancing virtual server " + nsVirtualServerName + " on the Netscaler device");
+        }
+        addLBVirtualServer(nsVirtualServerName, srcIp, srcPort, lbAlgorithm, lbProtocol, loadBalancerTO.getStickinessPolicies(), vmGroupTO);
+
+        String serviceGroupName = generateAutoScaleServiceGroupName(loadBalancerTO);
+        if (!nsServiceGroupExists(serviceGroupName)) {
+            // add servicegroup lb_autoscaleGroup -autoscale POLICY -memberPort 80
+            int memberPort = vmGroupTO.getMemberPort();
+            try {
+                servicegroup serviceGroup = new servicegroup();
+                serviceGroup.set_servicegroupname(serviceGroupName);
+                serviceGroup.set_servicetype(lbProtocol);
+                serviceGroup.set_autoscale("POLICY");
+                serviceGroup.set_memberport(memberPort);
+                servicegroup.add(_netscalerService, serviceGroup);
+            } catch (Exception e) {
+                throw e;
+            }
+        }
+
+        if (!isServiceGroupBoundToVirtualServer(nsVirtualServerName, serviceGroupName)) {
+            // Bind autoscale service group
+            // bind lb vserver lb lb_autoscaleGroup
+            lbvserver_servicegroup_binding vserver_servicegroup_binding = new lbvserver_servicegroup_binding();
+
+            try {
+                vserver_servicegroup_binding.set_name(nsVirtualServerName);
+                vserver_servicegroup_binding.set_servicegroupname(serviceGroupName);
+                lbvserver_servicegroup_binding.add(_netscalerService, vserver_servicegroup_binding);
+            } catch (Exception e) {
+                throw e;
+            }
+        }
+
+        // Create the autoscale config
+        if (!loadBalancerTO.getAutoScaleVmGroupTO().getState().equals("disabled")) {
+            // on restart of network, there might be vmgrps in disabled state, no need to create autoscale config for them
+            enableAutoScaleConfig(loadBalancerTO, false);
+        } else if (loadBalancerTO.getAutoScaleVmGroupTO().getState().equals("disabled")) {
+            disableAutoScaleConfig(loadBalancerTO, false);
+        }
+
+        return true;
+    }
+
+    @SuppressWarnings("static-access")
+    private synchronized boolean removeAutoScaleConfig(LoadBalancerTO loadBalancerTO) throws Exception, ExecutionException {
+        String srcIp = loadBalancerTO.getSrcIp();
+        int srcPort = loadBalancerTO.getSrcPort();
+        generateAutoScaleVmGroupIdentifier(loadBalancerTO);
+
+        String nsVirtualServerName = generateNSVirtualServerName(srcIp, srcPort);
+        String serviceGroupName = generateAutoScaleServiceGroupName(loadBalancerTO);
+
+        if (loadBalancerTO.getAutoScaleVmGroupTO().getCurrentState().equals("enabled")) {
+            disableAutoScaleConfig(loadBalancerTO, false);
+        }
+
+        if (isServiceGroupBoundToVirtualServer(nsVirtualServerName, serviceGroupName)) {
+            // UnBind autoscale service group
+            // unbind lb vserver lb lb_autoscaleGroup
+            lbvserver_servicegroup_binding vserver_servicegroup_binding = new lbvserver_servicegroup_binding();
+            try {
+                vserver_servicegroup_binding.set_name(nsVirtualServerName);
+                vserver_servicegroup_binding.set_servicegroupname(serviceGroupName);
+                lbvserver_servicegroup_binding.delete(_netscalerService, vserver_servicegroup_binding);
+            } catch (Exception e) {
+                throw e;
+            }
+        }
+
+        if (nsServiceGroupExists(serviceGroupName)) {
+            // Remove autoscale service group
+            com.citrix.netscaler.nitro.resource.config.basic.servicegroup serviceGroup = new com.citrix.netscaler.nitro.resource.config.basic.servicegroup();
+            try {
+                serviceGroup.set_servicegroupname(serviceGroupName);
+                servicegroup.delete(_netscalerService, serviceGroup);
+            } catch (Exception e) {
+                throw e;
+            }
+        }
+
+        removeLBVirtualServer(nsVirtualServerName);
+
+        return true;
+    }
+
+    @SuppressWarnings("static-access")
+    private synchronized boolean enableAutoScaleConfig(LoadBalancerTO loadBalancerTO, boolean isCleanUp) throws Exception {
+        String vmGroupIdentifier = generateAutoScaleVmGroupIdentifier(loadBalancerTO);
+        String srcIp = loadBalancerTO.getSrcIp();
+        int srcPort = loadBalancerTO.getSrcPort();
+
+        String nsVirtualServerName = generateNSVirtualServerName(srcIp, srcPort);
+        String serviceGroupName = generateAutoScaleServiceGroupName(loadBalancerTO);
+        String profileName = generateAutoScaleProfileName(vmGroupIdentifier);
+        String timerName = generateAutoScaleTimerName(vmGroupIdentifier);
+        String scaleDownActionName = generateAutoScaleScaleDownActionName(vmGroupIdentifier);
+        String scaleUpActionName = generateAutoScaleScaleUpActionName(vmGroupIdentifier);
+        String mtName = generateSnmpMetricTableName(vmGroupIdentifier);
+        String monitorName = generateSnmpMonitorName(vmGroupIdentifier);
+        AutoScaleVmGroupTO vmGroupTO = loadBalancerTO.getAutoScaleVmGroupTO();
+        AutoScaleVmProfileTO profileTO = vmGroupTO.getProfile();
+        List<AutoScalePolicyTO> policies = vmGroupTO.getPolicies();
+        int interval = vmGroupTO.getInterval();
+        profileTO.getCounterParamList();
+        String snmpCommunity = null;
+        int snmpPort = DEFAULT_SNMP_PORT;
+        long cur_prirotiy = 1;
+
+        // get the session persistence parameters
+        List<Pair<String, String>> paramsList = profileTO.getCounterParamList();
+        for (Pair<String, String> param : paramsList) {
+            if ("snmpcommunity".equalsIgnoreCase(param.first())) {
+                snmpCommunity = param.second();
+            } else if ("snmpport".equalsIgnoreCase(param.first())) {
+                snmpPort = Integer.parseInt(param.second());
+            }
+        }
+
+        try {
+            // Set min and max autoscale members;
+            // add lb vserver lb  http 10.102.31.100 80 -minAutoscaleMinMembers 3 -maxAutoscaleMembers 10
+            int minAutoScaleMembers = vmGroupTO.getMinMembers();
+            int maxAutoScaleMembers = vmGroupTO.getMaxMembers();
+            lbvserver vserver = new lbvserver();
+            try {
+                vserver.set_name(nsVirtualServerName);
+                vserver.set_minautoscalemembers(minAutoScaleMembers);
+                vserver.set_maxautoscalemembers(maxAutoScaleMembers);
+                lbvserver.update(_netscalerService, vserver);
+            } catch (Exception e) {
+                // Ignore Exception on cleanup
+                if (!isCleanUp)
+                    throw e;
+            }
+
+            /* AutoScale Config */
+            // Add AutoScale Profile
+            // add autoscale profile lb_asprofile CLOUDSTACK -url -http:// 10.102.31.34:8080/client/api- -apiKey abcdef
+            // -sharedSecret xyzabc
+            String apiKey = profileTO.getAutoScaleUserApiKey();
+            String secretKey = profileTO.getAutoScaleUserSecretKey();
+            String url = profileTO.getCloudStackApiUrl();
+
+            autoscaleprofile autoscaleProfile = new autoscaleprofile();
+            try {
+                autoscaleProfile.set_name(profileName);
+                autoscaleProfile.set_type("CLOUDSTACK");
+                autoscaleProfile.set_apikey(apiKey);
+                autoscaleProfile.set_sharedsecret(secretKey);
+                autoscaleProfile.set_url(url);
+                autoscaleprofile.add(_netscalerService, autoscaleProfile);
+            } catch (Exception e) {
+                // Ignore Exception on cleanup
+                if (!isCleanUp)
+                    throw e;
+            }
+
+            // Add Timer
+            nstimer timer = new nstimer();
+            try {
+                timer.set_name(timerName);
+                timer.set_interval(interval);
+                nstimer.add(_netscalerService, timer);
+            } catch (Exception e) {
+                // Ignore Exception on cleanup
+                if (!isCleanUp)
+                    throw e;
+            }
+
+            // AutoScale Actions
+            Integer scaleUpQuietTime = null;
+            Integer scaleDownQuietTime = null;
+            for (AutoScalePolicyTO autoScalePolicyTO : policies) {
+                if (scaleUpQuietTime == null) {
+                    if (isScaleUpPolicy(autoScalePolicyTO)) {
+                        scaleUpQuietTime = autoScalePolicyTO.getQuietTime();
+                        if (scaleDownQuietTime != null) {
+                            break;
+                        }
+                    }
+                }
+                if (scaleDownQuietTime == null) {
+                    if (isScaleDownPolicy(autoScalePolicyTO)) {
+                        scaleDownQuietTime = autoScalePolicyTO.getQuietTime();
+                        if (scaleUpQuietTime != null) {
+                            break;
+                        }
+                    }
+                }
+            }
+
+            // Add AutoScale ScaleUp action
+            // add autoscale action lb_scaleUpAction provision -vserver lb -profilename lb_asprofile -params
+            // -lbruleid=1234&command=deployvm&zoneid=10&templateid=5&serviceofferingid=3- -quiettime 300
+            com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction scaleUpAction =
+                    new com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction();
+            try {
+                scaleUpAction.set_name(scaleUpActionName);
+                scaleUpAction.set_type("SCALE_UP"); // TODO: will this be called provision?
+                scaleUpAction.set_vserver(nsVirtualServerName); // Actions Vserver, the one that is autoscaled, with CS
+                // now both are same. Not exposed in API.
+                scaleUpAction.set_profilename(profileName);
+                if(scaleUpQuietTime != null) {
+                    scaleUpAction.set_quiettime(scaleUpQuietTime);
+                }
+                String scaleUpParameters =
+                        "command=deployVirtualMachine" + "&" + ApiConstants.ZONE_ID + "=" + profileTO.getZoneId() + "&" + ApiConstants.SERVICE_OFFERING_ID + "=" +
+                                profileTO.getServiceOfferingId() + "&" + ApiConstants.TEMPLATE_ID + "=" + profileTO.getTemplateId() + "&" + ApiConstants.DISPLAY_NAME + "=" +
+                                profileTO.getVmName() + "&" + ((profileTO.getNetworkId() == null) ? "" : (ApiConstants.NETWORK_IDS + "=" + profileTO.getNetworkId() + "&")) +
+                                ((profileTO.getOtherDeployParams() == null) ? "" : (profileTO.getOtherDeployParams() + "&")) + "lbruleid=" + loadBalancerTO.getUuid();
+                scaleUpAction.set_parameters(scaleUpParameters);
+                autoscaleaction.add(_netscalerService, scaleUpAction);
+            } catch (Exception e) {
+                // Ignore Exception on cleanup
+                if (!isCleanUp)
+                    throw e;
+            }
+
+            com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction scaleDownAction =
+                    new com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction();
+            Integer destroyVmGracePeriod = profileTO.getDestroyVmGraceperiod();
+            try {
+                scaleDownAction.set_name(scaleDownActionName);
+                scaleDownAction.set_type("SCALE_DOWN"); // TODO: will this be called de-provision?
+                scaleDownAction.set_vserver(nsVirtualServerName); // TODO: no global option as of now through Nitro.
+                // Testing cannot be done.
+                scaleDownAction.set_profilename(profileName);
+                scaleDownAction.set_quiettime(scaleDownQuietTime);
+                String scaleDownParameters = "command=destroyVirtualMachine" + "&" + "lbruleid=" + loadBalancerTO.getUuid();
+                scaleDownAction.set_parameters(scaleDownParameters);
+                scaleDownAction.set_vmdestroygraceperiod(destroyVmGracePeriod);
+                autoscaleaction.add(_netscalerService, scaleDownAction);
+            } catch (Exception e) {
+                // Ignore Exception on cleanup
+                if (!isCleanUp)
+                    throw e;
+            }
+
+            /* Create min member policy */
+            String minMemberPolicyName = generateAutoScaleMinPolicyName(vmGroupIdentifier);
+            String minMemberPolicyExp =
+                    "SYS.VSERVER(\"" + nsVirtualServerName + "\").ACTIVESERVICES.LT(SYS.VSERVER(\"" + nsVirtualServerName + "\").MINAUTOSCALEMEMBERS)";
+            addAutoScalePolicy(timerName, minMemberPolicyName, cur_prirotiy++, minMemberPolicyExp, scaleUpActionName, interval, interval, isCleanUp);
+
+            /* Create max member policy */
+            String maxMemberPolicyName = generateAutoScaleMaxPolicyName(vmGroupIdentifier);
+            String maxMemberPolicyExp =
+                    "SYS.VSERVER(\"" + nsVirtualServerName + "\").ACTIVESERVICES.GT(SYS.VSERVER(\"" + nsVirtualServerName + "\").MAXAUTOSCALEMEMBERS)";
+            addAutoScalePolicy(timerName, maxMemberPolicyName, cur_prirotiy++, maxMemberPolicyExp, scaleDownActionName, interval, interval, isCleanUp);
+
+            /* Create Counters */
+            HashMap<String, Integer> snmpMetrics = new HashMap<String, Integer>();
+            for (AutoScalePolicyTO autoScalePolicyTO : policies) {
+                List<ConditionTO> conditions = autoScalePolicyTO.getConditions();
+                String policyExpression = "";
+                int snmpCounterNumber = 0;
+                for (ConditionTO conditionTO : conditions) {
+                    CounterTO counterTO = conditionTO.getCounter();
+                    String counterName = counterTO.getName();
+                    String operator = conditionTO.getRelationalOperator();
+                    long threshold = conditionTO.getThreshold();
+
+                    StringBuilder conditionExpression = new StringBuilder();
+                    Formatter formatter = new Formatter(conditionExpression, Locale.US);
+
+                    if (counterTO.getSource().equals("snmp")) {
+                        counterName = generateSnmpMetricName(counterName);
+                        if (snmpMetrics.size() == 0) {
+                            // Create Metric Table
+                            //add lb metricTable lb_metric_table
+                            lbmetrictable metricTable = new lbmetrictable();
+                            try {
+                                metricTable.set_metrictable(mtName);
+                                lbmetrictable.add(_netscalerService, metricTable);
+                            } catch (Exception e) {
+                                // Ignore Exception on cleanup
+                                if (!isCleanUp)
+                                    throw e;
+                            }
+
+                            // Create Monitor
+                            // add lb monitor lb_metric_table_mon LOAD -destPort 161 -snmpCommunity public -metricTable
+                            // lb_metric_table -interval <policy_interval == 80% >
+                            lbmonitor monitor = new lbmonitor();
+                            try {
+                                monitor.set_monitorname(monitorName);
+                                monitor.set_type("LOAD");
+                                monitor.set_destport(snmpPort);
+                                monitor.set_snmpcommunity(snmpCommunity);
+                                monitor.set_metrictable(mtName);
+                                monitor.set_interval((int)(interval * 0.8));
+                                lbmonitor.add(_netscalerService, monitor);
+                            } catch (Exception e) {
+                                // Ignore Exception on cleanup
+                                if (!isCleanUp)
+                                    throw e;
+                            }
+
+                            // Bind monitor to servicegroup.
+                            // bind lb monitor lb_metric_table_mon lb_autoscaleGroup -passive
+                            servicegroup_lbmonitor_binding servicegroup_monitor_binding = new servicegroup_lbmonitor_binding();
+                            try {
+                                servicegroup_monitor_binding.set_servicegroupname(serviceGroupName);
+                                servicegroup_monitor_binding.set_monitor_name(monitorName);
+
+                                // Use the monitor for autoscaling purpose only.
+                                // Don't mark service members down when metric breaches threshold
+                                servicegroup_monitor_binding.set_passive(true);
+
+                                servicegroup_lbmonitor_binding.add(_netscalerService, servicegroup_monitor_binding);
+                            } catch (Exception e) {
+                                // Ignore Exception on cleanup
+                                if (!isCleanUp)
+                                    throw e;
+                            }
+                        }
+
+                        boolean newMetric = !snmpMetrics.containsKey(counterName);
+                        if (newMetric) {
+                            snmpMetrics.put(counterName, snmpCounterNumber++);
+                        }
+
+                        if (newMetric) {
+                            // bind lb metricTable lb_metric_table mem 1.3.6.1.4.1.2021.11.9.0
+                            String counterOid = counterTO.getValue();
+                            lbmetrictable_metric_binding metrictable_metric_binding = new lbmetrictable_metric_binding();
+                            try {
+                                metrictable_metric_binding.set_metrictable(mtName);
+                                metrictable_metric_binding.set_metric(counterName);
+                                metrictable_metric_binding.set_Snmpoid(counterOid);
+                                lbmetrictable_metric_binding.add(_netscalerService, metrictable_metric_binding);
+                            } catch (Exception e) {
+                                // Ignore Exception on cleanup
+                                if (!isCleanUp)
+                                    throw e;
+                            }
+
+                            // bind lb monitor lb_metric_table_mon -metric cpu -metricThreshold 1
+                            lbmonitor_metric_binding monitor_metric_binding = new lbmonitor_metric_binding();
+                            ;
+                            try {
+                                monitor_metric_binding.set_monitorname(monitorName);
+                                monitor_metric_binding.set_metric(counterName);
+                                /*
+                                 * Setting it to max to make sure traffic is not affected due to 'LOAD' monitoring.
+                                 * For Ex. if CPU is tracked and CPU is greater than 80, it is still < than Integer.MAX_VALUE
+                                 * so traffic will continue to flow.
+                                 */
+                                monitor_metric_binding.set_metricthreshold(Integer.MAX_VALUE);
+                                lbmonitor_metric_binding.add(_netscalerService, monitor_metric_binding);
+                            } catch (Exception e) {
+                                // Ignore Exception on cleanup
+                                if (!isCleanUp)
+                                    throw e;
+                            }
+                        }
+                        // SYS.VSERVER("abcd").SNMP_TABLE(0).AVERAGE_VALUE.GT(80)
+                        int counterIndex = snmpMetrics.get(counterName); // TODO: temporary fix. later on counter name
+                        // will be added as a param to SNMP_TABLE.
+                        formatter.format("SYS.VSERVER(\"%s\").SNMP_TABLE(%d).AVERAGE_VALUE.%s(%d)", nsVirtualServerName, counterIndex, operator, threshold);
+                    } else if (counterTO.getSource().equals("netscaler")) {
+                        //SYS.VSERVER("abcd").RESPTIME.GT(10)
+                        formatter.format("SYS.VSERVER(\"%s\").%s.%s(%d)", nsVirtualServerName, counterTO.getValue(), operator, threshold);
+                    }
+                    if (policyExpression.length() != 0) {
+                        policyExpression += " && ";
+                    }
+                    policyExpression += conditionExpression;
+                }
+                policyExpression = "(" + policyExpression + ")";
+
+                String policyId = Long.toString(autoScalePolicyTO.getId());
+                String policyName = generateAutoScalePolicyName(vmGroupIdentifier, policyId);
+                String action = null;
+                if (isScaleUpPolicy(autoScalePolicyTO)) {
+                    action = scaleUpActionName;
+                    String scaleUpCondition =
+                            "SYS.VSERVER(\"" + nsVirtualServerName + "\").ACTIVESERVICES.LT(SYS.VSERVER(\"" + nsVirtualServerName + "\").MAXAUTOSCALEMEMBERS)";
+                    policyExpression = scaleUpCondition + " && " + policyExpression;
+                } else {
+                    action = scaleDownActionName;
+                    String scaleDownCondition =
+                            "SYS.VSERVER(\"" + nsVirtualServerName + "\").ACTIVESERVICES.GT(SYS.VSERVER(\"" + nsVirtualServerName + "\").MINAUTOSCALEMEMBERS)";
+                    policyExpression = scaleDownCondition + " && " + policyExpression;
+                }
+
+                addAutoScalePolicy(timerName, policyName, cur_prirotiy++, policyExpression, action, autoScalePolicyTO.getDuration(), interval, isCleanUp);
+
+            }
+        } catch (Exception ex) {
+            if (!isCleanUp) {
+                // Normal course, exception has occurred
+                disableAutoScaleConfig(loadBalancerTO, true);
+                throw ex;
+
+            } else {
+                // Programming error. Exception should never be thrown afterall.
+                throw ex;
+            }
+        }
+
+        return true;
+    }
+
+    @SuppressWarnings("static-access")
+    private synchronized boolean disableAutoScaleConfig(LoadBalancerTO loadBalancerTO, boolean isCleanUp) throws Exception {
+
+        String vmGroupIdentifier = generateAutoScaleVmGroupIdentifier(loadBalancerTO);
+
+        String profileName = generateAutoScaleProfileName(vmGroupIdentifier);
+        String timerName = generateAutoScaleTimerName(vmGroupIdentifier);
+        String scaleDownActionName = generateAutoScaleScaleDownActionName(vmGroupIdentifier);
+        String scaleUpActionName = generateAutoScaleScaleUpActionName(vmGroupIdentifier);
+        String mtName = generateSnmpMetricTableName(vmGroupIdentifier);
+        String monitorName = generateSnmpMonitorName(vmGroupIdentifier);
+        String serviceGroupName = generateAutoScaleServiceGroupName(loadBalancerTO);
+        AutoScaleVmGroupTO vmGroupTO = loadBalancerTO.getAutoScaleVmGroupTO();
+        List<AutoScalePolicyTO> policies = vmGroupTO.getPolicies();
+        String minMemberPolicyName = generateAutoScaleMinPolicyName(vmGroupIdentifier);
+        String maxMemberPolicyName = generateAutoScaleMaxPolicyName(vmGroupIdentifier);
+
+        try {
+
+            /* Delete min/max member policies */
+
+            removeAutoScalePolicy(timerName, minMemberPolicyName, isCleanUp);
+
+            removeAutoScalePolicy(timerName, maxMemberPolicyName, isCleanUp);
+
+            boolean isSnmp = false;
+            /* Create Counters */
+            for (AutoScalePolicyTO autoScalePolicyTO : policies) {
+                List<ConditionTO> conditions = autoScalePolicyTO.getConditions();
+                for (ConditionTO conditionTO : conditions) {
+                    CounterTO counterTO = conditionTO.getCounter();
+                    if (counterTO.getSource().equals("snmp")) {
+                        isSnmp = true;
+                        break;
+                    }
+                }
+                String policyId = Long.toString(autoScalePolicyTO.getId());
+                String policyName = generateAutoScalePolicyName(vmGroupIdentifier, policyId);
+
+                // Removing Timer policy
+                removeAutoScalePolicy(timerName, policyName, isCleanUp);
+            }
+
+            /* Delete AutoScale Config */
+            // Delete AutoScale ScaleDown action
+            com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction scaleDownAction =
+                    new com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction();
+            try {
+                scaleDownAction.set_name(scaleDownActionName);
+                autoscaleaction.delete(_netscalerService, scaleDownAction);
+            } catch (Exception e) {
+                // Ignore Exception on cleanup
+                if (!isCleanUp)
+                    throw e;
+            }
+
+            // Delete AutoScale ScaleUp action
+            com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction scaleUpAction =
+                    new com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction();
+            try {
+                scaleUpAction.set_name(scaleUpActionName);
+                autoscaleaction.delete(_netscalerService, scaleUpAction);
+            } catch (Exception e) {
+                // Ignore Exception on cleanup
+                if (!isCleanUp)
+                    throw e;
+            }
+
+            // Delete Timer
+            nstimer timer = new nstimer();
+            try {
+                timer.set_name(timerName);
+                nstimer.delete(_netscalerService, timer);
+            } catch (Exception e) {
+                // Ignore Exception on cleanup
+                if (!isCleanUp)
+                    throw e;
+            }
+
+            // Delete AutoScale Profile
+            autoscaleprofile autoscaleProfile = new autoscaleprofile();
+            try {
+                autoscaleProfile.set_name(profileName);
+                autoscaleprofile.delete(_netscalerService, autoscaleProfile);
+            } catch (Exception e) {
+                // Ignore Exception on cleanup
+                if (!isCleanUp)
+                    throw e;
+            }
+
+            if (isSnmp) {
+                servicegroup_lbmonitor_binding servicegroup_monitor_binding = new servicegroup_lbmonitor_binding();
+                try {
+                    servicegroup_monitor_binding.set_monitor_name(monitorName);
+                    servicegroup_monitor_binding.set_servicegroupname(serviceGroupName);
+                    servicegroup_lbmonitor_binding.delete(_netscalerService, servicegroup_monitor_binding);
+                } catch (Exception e) {
+                    // Ignore Exception on cleanup
+                    if (!isCleanUp)
+                        throw e;
+                }
+
+                // Delete Monitor
+                // rm lb monitor lb_metric_table_mon
+                com.citrix.netscaler.nitro.resource.config.lb.lbmonitor monitor = new com.citrix.netscaler.nitro.resource.config.lb.lbmonitor();
+                try {
+                    monitor.set_monitorname(monitorName);
+                    monitor.set_type("LOAD");
+                    lbmonitor.delete(_netscalerService, monitor);
+                } catch (Exception e) {
+                    // Ignore Exception on cleanup
+                    if (!isCleanUp)
+                        throw e;
+                }
+
+                // Delete Metric Table
+                com.citrix.netscaler.nitro.resource.config.lb.lbmetrictable metricTable = new com.citrix.netscaler.nitro.resource.config.lb.lbmetrictable();
+                try {
+                    metricTable.set_metrictable(mtName);
+                    lbmetrictable.delete(_netscalerService, metricTable);
+                } catch (Exception e) {
+                    // Ignore Exception on cleanup
+                    if (!isCleanUp)
+                        throw e;
+                }
+            }
+        } catch (Exception ex) {
+            if (!isCleanUp) {
+                // Normal course, exception has occurred
+                enableAutoScaleConfig(loadBalancerTO, true);
+                throw ex;
+            } else {
+                // Programming error
+                throw ex;
+            }
+        }
+
+        return true;
+    }
+
+    private synchronized void addAutoScalePolicy(String timerName, String policyName, long priority, String policyExpression, String action, int duration, int interval,
+            boolean isCleanUp) throws Exception {
+        // Adding a autoscale policy
+        // add timer policy lb_policy_scaleUp_cpu_mem -rule - (SYS.CUR_VSERVER.METRIC_TABLE(cpu).AVG_VAL.GT(80)-
+        // -action lb_scaleUpAction
+        autoscalepolicy timerPolicy = new autoscalepolicy();
+        try {
+            timerPolicy.set_name(policyName);
+            timerPolicy.set_action(action);
+            timerPolicy.set_rule(policyExpression);
+            autoscalepolicy.add(_netscalerService, timerPolicy);
+        } catch (Exception e) {
+            // Ignore Exception on cleanup
+            if (!isCleanUp)
+                throw e;
+        }
+
+        // bind timer policy
+        // For now it is bound globally.
+        // bind timer trigger lb_astimer -policyName lb_policy_scaleUp -vserver lb -priority 1 -samplesize 5
+        // TODO: later bind to lbvserver. bind timer trigger lb_astimer -policyName lb_policy_scaleUp -vserver lb
+        // -priority 1 -samplesize 5
+        // -thresholdsize 5
+        nstimer_autoscalepolicy_binding timer_policy_binding = new nstimer_autoscalepolicy_binding();
+        int sampleSize = duration / interval;
+        try {
+            timer_policy_binding.set_name(timerName);
+            timer_policy_binding.set_policyname(policyName);
+            timer_policy_binding.set_samplesize(sampleSize);
+            timer_policy_binding.set_threshold(sampleSize); // We are not exposing this parameter as of now.
+            // i.e. n(m) is not exposed to CS user. So thresholdSize == sampleSize
+            timer_policy_binding.set_priority(priority);
+            nstimer_autoscalepolicy_binding.add(_netscalerService, timer_policy_binding);
+        } catch (Exception e) {
+            // Ignore Exception on cleanup
+            if (!isCleanUp)
+                throw e;
+        }
+    }
+
+    private void removeAutoScalePolicy(String timerName, String policyName, boolean isCleanUp) throws Exception {
+        // unbind timer policy
+        // unbbind timer trigger lb_astimer -policyName lb_policy_scaleUp
+        nstimer_autoscalepolicy_binding timer_policy_binding = new nstimer_autoscalepolicy_binding();
+        try {
+            timer_policy_binding.set_name(timerName);
+            timer_policy_binding.set_policyname(policyName);
+            nstimer_autoscalepolicy_binding.delete(_netscalerService, timer_policy_binding);
+        } catch (Exception e) {
+            // Ignore Exception on cleanup
+            if (!isCleanUp)
+                throw e;
+        }
+
+        // Removing Timer policy
+        // rm timer policy lb_policy_scaleUp_cpu_mem
+        autoscalepolicy timerPolicy = new autoscalepolicy();
+        try {
+            timerPolicy.set_name(policyName);
+            autoscalepolicy.delete(_netscalerService, timerPolicy);
+        } catch (Exception e) {
+            // Ignore Exception on cleanup
+            if (!isCleanUp)
+                throw e;
+        }
+
+    }
+
+    private boolean isAutoScaleSupportedInNetScaler() throws ExecutionException {
+        new autoscaleprofile();
+        try {
+            autoscaleprofile.get(_netscalerService);
+        } catch (Exception ex) {
+            // Looks like autoscale is not supported in this netscaler.
+            // TODO: Config team has introduce a new command to check
+            // the list of entities supported in a NetScaler. Can use that
+            // once it is present in AutoScale branch.
+            s_logger.warn("AutoScale is not supported in NetScaler");
+            return false;
+        }
+        return true;
+    }
+
+    private boolean isScaleUpPolicy(AutoScalePolicyTO autoScalePolicyTO) {
+        return autoScalePolicyTO.getAction().equals("scaleup");
+    }
+
+    private boolean isScaleDownPolicy(AutoScalePolicyTO autoScalePolicyTO) {
+        return autoScalePolicyTO.getAction().equals("scaledown");
+    }
+
+    private void saveConfiguration() throws ExecutionException {
+        try {
+            apiCallResult = nsconfig.save(_netscalerService);
+            if (apiCallResult.errorcode != 0) {
+                throw new ExecutionException("Error occured while saving configuration changes to Netscaler device due to " + apiCallResult.message);
+            }
+        } catch (nitro_exception e) {
+            throw new ExecutionException("Failed to save configuration changes to Netscaler device due to " + e.getMessage());
+        } catch (Exception e) {
+            throw new ExecutionException("Failed to save configuration changes to Netscaler device due to " + e.getMessage());
+        }
+    }
+
+    private ExternalNetworkResourceUsageAnswer getPublicIpBytesSentAndReceived(ExternalNetworkResourceUsageCommand cmd) throws ExecutionException {
+        ExternalNetworkResourceUsageAnswer answer = new ExternalNetworkResourceUsageAnswer(cmd);
+
+        try {
+            lbvserver_stats[] stats = lbvserver_stats.get(_netscalerService);
+
+            if (stats == null || stats.length == 0) {
+                return answer;
+            }
+
+            for (lbvserver_stats stat_entry : stats) {
+                String lbvserverName = stat_entry.get_name();
+                lbvserver vserver = lbvserver.get(_netscalerService, lbvserverName);
+                if (vserver != null) {
+                    String lbVirtualServerIp = vserver.get_ipv46();
+
+                    long[] bytesSentAndReceived = answer.ipBytes.get(lbVirtualServerIp);
+                    if (bytesSentAndReceived == null) {
+                        bytesSentAndReceived = new long[] {0, 0};
+                    }
+                    bytesSentAndReceived[0] += stat_entry.get_totalrequestbytes();
+                    bytesSentAndReceived[1] += stat_entry.get_totalresponsebytes();
+
+                    if (bytesSentAndReceived[0] >= 0 && bytesSentAndReceived[1] >= 0) {
+                        answer.ipBytes.put(lbVirtualServerIp, bytesSentAndReceived);
+                    }
+                }
+            }
+        } 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 device at " + _ip + " due to " + e.getMessage());
+        }
+        return false;
+    }
+
+    private String generateInatRuleName(String srcIp, String dstIP) {
+        return genObjectName("Cloud-Inat", srcIp);
+    }
+
+    private String generateRnatRuleName(String srcIp, String dstIP) {
+        return genObjectName("Cloud-Rnat", srcIp);
+    }
+
+    private String generateNSVirtualServerName(String srcIp, long srcPort) {
+        return genObjectName("Cloud-VirtualServer", srcIp, srcPort);
+    }
+
+    private String generateNSMonitorName(String srcIp, long srcPort) {
+        // maximum length supported by NS is 31
+        return genObjectName("Cloud-Hc", srcIp, srcPort);
+    }
+
+    private String generateNSServerName(String serverIP) {
+        return genObjectName("Cloud-Server-", serverIP);
+    }
+
+    private String generateNSServiceName(String ip, long port) {
+        return genObjectName("Cloud-Service", ip, port);
+    }
+
+    private String generateAutoScaleVmGroupIdentifier(LoadBalancerTO lbTO) {
+        return lbTO.getSrcIp() + "-" + lbTO.getSrcPort();
+    }
+
+    private String generateAutoScaleServiceGroupName(LoadBalancerTO lbTO) {
+        /*
+         *  ServiceGroup name in NetScaler wont support long names. Providing special name.
+         *  Need for introducing uuid because every vmgroup creation should be distinguished.
+         *  Ex. (1) create a vm group, delete a vmgroup, create a vmgroup on same lb ip and port
+         *  This will reuse all vms from the original vm group in step (1)
+         */
+
+        return "Cloud" + lbTO.getAutoScaleVmGroupTO().getUuid().replace("-", "");
+    }
+
+    private String generateAutoScaleTimerName(String vmGroupIdentifier) {
+        return genObjectName("Cloud-AutoScale-Timer", vmGroupIdentifier);
+    }
+
+    private String generateAutoScaleProfileName(String vmGroupIdentifier) {
+        return genObjectName("Cloud-AutoScale-Profile", vmGroupIdentifier);
+    }
+
+    private String generateAutoScaleScaleUpActionName(String vmGroupIdentifier) {
+        return genObjectName("Cloud-AutoScale-ScaleUpAction", vmGroupIdentifier);
+    }
+
+    private String generateAutoScaleScaleDownActionName(String vmGroupIdentifier) {
+        return genObjectName("Cloud-AutoScale-ScaleDownAction", vmGroupIdentifier);
+    }
+
+    private String generateAutoScalePolicyName(String vmGroupIdentifier, String poilcyId) {
+        return genObjectName("Cloud-AutoScale-Policy", vmGroupIdentifier, poilcyId);
+    }
+
+    private String generateAutoScaleMinPolicyName(String vmGroupIdentifier) {
+        return genObjectName("Cloud-AutoScale-Policy-Min", vmGroupIdentifier);
+    }
+
+    private String generateAutoScaleMaxPolicyName(String vmGroupIdentifier) {
+        return genObjectName("Cloud-AutoScale-Policy-Max", vmGroupIdentifier);
+    }
+
+    private String generateSnmpMetricTableName(String vmGroupIdentifier) {
+        return genObjectName("Cloud-MTbl", vmGroupIdentifier);
+    }
+
+    private String generateSnmpMonitorName(String vmGroupIdentifier) {
+        return genObjectName("Cloud-Mon", vmGroupIdentifier);
+    }
+
+    private String generateSnmpMetricName(String counterName) {
+        return counterName.replace(' ', '_');
+    }
+
+    private String generateSslCertName(String fingerPrint) {
+        // maximum length supported by NS is 31
+        // the first 20 characters of the SHA-1 checksum are the unique id
+        String uniqueId = fingerPrint.replace(":", "").substring(0, 20);
+
+        return genObjectName("Cloud-Cert", uniqueId);
+    }
+
+    private String generateSslKeyName(String fingerPrint) {
+        String uniqueId = fingerPrint.replace(":", "").substring(0, 20);
+        return genObjectName("Cloud-Key", uniqueId);
+    }
+
+    private String generateSslCertKeyName(String fingerPrint) {
+        String uniqueId = fingerPrint.replace(":", "").substring(0, 20);
+        return genObjectName("Cloud-Cert", uniqueId);
+    }
+
+    private String genObjectName(Object... args) {
+        StringBuffer buff = new StringBuffer();
+        for (int i = 0; i < args.length; i++) {
+            buff.append(args[i]);
+            if (i != args.length - 1) {
+                buff.append(_objectNamePathSep);
+            }
+        }
+        return buff.toString();
+    }
+
+    @Override
+    public IAgentControl getAgentControl() {
+        return null;
+    }
+
+    @Override
+    public PingCommand getCurrentStatus(long id) {
+        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 boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public void disconnected() {
+        return;
+    }
+
+    @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
+
+    }
+
+    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) {
+        // 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 {
+            //HttpPost request = new HttpPost(agentUri);
+            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);
+            //request.setEntity(cmdJson);
+            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);
+                return null;
+            } 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) {
+        // 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 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 type 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);
+                return null;
+            } 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/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java
index 551c61e..50e3e7a 100644
--- a/server/src/com/cloud/configuration/Config.java
+++ b/server/src/com/cloud/configuration/Config.java
@@ -811,7 +811,14 @@ public enum Config {
             "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,
diff --git a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
index 75267c7..f417283 100644
--- a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
+++ b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
@@ -1112,7 +1112,12 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
         if (!(startup[0] instanceof StartupExternalLoadBalancerCommand)) {
             return null;
         }
-        host.setType(Host.Type.ExternalLoadBalancer);
+        if(host.getName().equalsIgnoreCase("NetScalerControlCenter")) {
+            host.setType(Host.Type.NetScalerControlCenter);
+        }
+        else {
+            host.setType(Host.Type.ExternalLoadBalancer);
+        }
         return host;
     }
 
diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java
index b5d67c7..f47123d 100644
--- a/server/src/com/cloud/server/StatsCollector.java
+++ b/server/src/com/cloud/server/StatsCollector.java
@@ -396,6 +396,7 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc
                 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());
diff --git a/setup/db/db/schema-4930to41000.sql b/setup/db/db/schema-4930to41000.sql
index 59c452f..edc9d60 100644
--- a/setup/db/db/schema-4930to41000.sql
+++ b/setup/db/db/schema-4930to41000.sql
@@ -254,4 +254,27 @@ CREATE TABLE `cloud`.`firewall_rules_dcidrs`(
   UNIQUE KEY `unique_rule_dcidrs` (`firewall_rule_id`, `destination_cidr`),
   KEY `fk_firewall_dcidrs_firewall_rules` (`firewall_rule_id`),
   CONSTRAINT `fk_firewall_dcidrs_firewall_rules` FOREIGN KEY (`firewall_rule_id`) REFERENCES `firewall_rules` (`id`) ON DELETE CASCADE
-)ENGINE=InnoDB DEFAULT CHARSET=utf8;
\ No newline at end of file
+)ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+DROP TABLE IF EXISTS `cloud`.`netscaler_servicepackages`;
+CREATE TABLE `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;
+
+DROP TABLE IF EXISTS `cloud`.`external_netscaler_controlcenter`;
+CREATE TABLE `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;
+
+ALTER TABLE `cloud`.`sslcerts` ADD COLUMN `name` varchar(255) NULL default NULL COMMENT 'Name of the Certificate';
+ALTER TABLE `cloud`.`network_offerings` ADD COLUMN `service_package_id` varchar(255) NULL default NULL COMMENT 'Netscaler ControlCenter Service Package';
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
"commits@cloudstack.apache.org" <co...@cloudstack.apache.org>.

[cloudstack] 02/05: CLOUDSTACK-8672 : NCC Integration with CloudStack.

Posted by sa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sateesh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit b2f7f9abb6f710e1ec0ba9b03a645023abd0d649
Author: Priyank Parihar <pr...@citrix.com>
AuthorDate: Fri Aug 7 16:40:00 2015 +0530

    CLOUDSTACK-8672 : NCC Integration with CloudStack.
---
 api/src/com/cloud/agent/api/to/LoadBalancerTO.java |  18 +
 .../admin/address/AcquirePodIpCmdByAdmin.java      |  91 +++
 .../admin/address/ReleasePodIpCmdByAdmin.java      |  79 +++
 .../api/response/AcquireIPAddressResponse.java     | 291 ++++++++++
 .../api/response/AcquirePodIpCmdResponse.java      | 113 ++++
 .../src/com/cloud/network/IpAddressManager.java    |  44 +-
 .../com/cloud/dc/dao/DataCenterIpAddressDao.java   |   2 +
 .../cloud/dc/dao/DataCenterIpAddressDaoImpl.java   |  16 +
 engine/schema/src/com/cloud/dc/dao/HostPodDao.java |   2 +
 .../src/com/cloud/dc/dao/HostPodDaoImpl.java       |   8 +
 .../commands/DeleteServicePackageOfferingCmd.java  |  95 ++++
 .../commands/ListRegisteredServicePackageCmd.java  |  81 +++
 .../api/commands/RegisterServicePackageCmd.java    |  14 +-
 .../response/NetScalerServicePackageResponse.java  |   6 +-
 .../cloud/network/element/NetscalerElement.java    | 617 ++++++++++++++-------
 .../NetscalerLoadBalancerElementService.java       |  46 +-
 .../resource/NetScalerControlCenterResource.java   | 522 +++++++----------
 .../ExternalLoadBalancerDeviceManagerImpl.java     |  45 +-
 .../com/cloud/network/IpAddressManagerImpl.java    | 575 ++++++++++---------
 .../test/com/cloud/vpc/MockNetworkManagerImpl.java |  22 +
 20 files changed, 1880 insertions(+), 807 deletions(-)

diff --git a/api/src/com/cloud/agent/api/to/LoadBalancerTO.java b/api/src/com/cloud/agent/api/to/LoadBalancerTO.java
index 4d5a2c0..aabff2f 100644
--- a/api/src/com/cloud/agent/api/to/LoadBalancerTO.java
+++ b/api/src/com/cloud/agent/api/to/LoadBalancerTO.java
@@ -45,6 +45,8 @@ public class LoadBalancerTO {
     boolean revoked;
     boolean alreadyAdded;
     boolean inline;
+    String srcIpVlan;
+    Long networkId;
     DestinationTO[] destinations;
     private StickinessPolicyTO[] stickinessPolicies;
     private HealthCheckPolicyTO[] healthCheckPolicies;
@@ -194,6 +196,22 @@ public class LoadBalancerTO {
         return this.sslCert;
     }
 
+    public String getSrcIpVlan() {
+        return srcIpVlan;
+    }
+
+    public void setSrcIpVlan(String srcIpVlan) {
+        this.srcIpVlan = srcIpVlan;
+    }
+
+    public Long getNetworkId() {
+        return networkId;
+    }
+
+    public void setNetworkId(long id) {
+        this.networkId = id;
+    }
+
     public static class StickinessPolicyTO {
         private String _methodName;
         private List<Pair<String, String>> _paramsList;
diff --git a/api/src/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java
new file mode 100644
index 0000000..a461367
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java
@@ -0,0 +1,91 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// 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.address;
+
+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.AcquirePodIpCmdResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+
+@APICommand(name = "acquirePodIpAddresses", description = "Allocates IP addresses in respective Pod of a Zone", responseObject = AcquirePodIpCmdResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class AcquirePodIpCmdByAdmin extends BaseCmd {
+
+    public static final Logger s_logger = Logger.getLogger(AcquirePodIpCmdByAdmin.class.getName());
+    private static final String s_name = "acquirepodipaddress";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "the ID of the  zone in which your pod lies")
+    private Long zoneId;
+
+    @Parameter(name = ApiConstants.GUEST_CIDR_ADDRESS, type = CommandType.STRING, entityType = ZoneResponse.class, required = false, description = "CIDR for finding Pod")
+    private String cidr;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    private long getZoneId() {
+        return zoneId;
+    }
+
+    private String getCidr() {
+        return cidr;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, ResourceAllocationException, ConcurrentOperationException {
+        AcquirePodIpCmdResponse pod_ip = null;
+        pod_ip = _networkService.allocatePodIp(_accountService.getAccount(getEntityOwnerId()), getZoneId(), getCidr());
+        if (pod_ip != null) {
+            pod_ip.setResponseName(getCommandName());
+            pod_ip.setObjectName(getCommandName());
+            setResponseObject(pod_ip);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to assign IP address");
+        }
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        // TODO Auto-generated method stub
+        return CallContext.current().getCallingAccount().getAccountId();
+    }
+
+}
\ No newline at end of file
diff --git a/api/src/org/apache/cloudstack/api/command/admin/address/ReleasePodIpCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/address/ReleasePodIpCmdByAdmin.java
new file mode 100644
index 0000000..750a85d
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/admin/address/ReleasePodIpCmdByAdmin.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.address;
+
+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.command.admin.vlan.ReleasePublicIpRangeCmd;
+import org.apache.cloudstack.api.response.AcquireIPAddressResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+
+import com.cloud.user.Account;
+
+@APICommand(name = "releasePodIpAddress", description = "Releases a Pod IP back to the Pod", responseObject = SuccessResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class ReleasePodIpCmdByAdmin extends BaseCmd {
+    public static final Logger s_logger = Logger.getLogger(ReleasePublicIpRangeCmd.class.getName());
+
+    private static final String s_name = "releasepodipresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.LONG, entityType = AcquireIPAddressResponse.class, required = true, description = "UUID of the Pod IP")
+    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 = _networkService.releasePodIp(this);
+        if (result) {
+            SuccessResponse response = new SuccessResponse(getCommandName());
+            response.setDisplayText("IP is released sucessfully");
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to release  Pod ip ");
+        }
+    }
+}
\ No newline at end of file
diff --git a/api/src/org/apache/cloudstack/api/response/AcquireIPAddressResponse.java b/api/src/org/apache/cloudstack/api/response/AcquireIPAddressResponse.java
new file mode 100644
index 0000000..6d6a035
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/response/AcquireIPAddressResponse.java
@@ -0,0 +1,291 @@
+//Licensed to the Apache Software Foundation (ASF) under one
+//or more contributor license agreements.  See the NOTICE file
+//distributed with this work for additional information
+//regarding copyright ownership.  The ASF licenses this file
+//to you under the Apache License, Version 2.0 (the
+//"License"); you may not use this file except in compliance
+//with the License.  You may obtain a copy of the License at
+//
+//http://www.apache.org/licenses/LICENSE-2.0
+//
+//Unless required by applicable law or agreed to in writing,
+//software distributed under the License is distributed on an
+//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+//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.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.IpAddress;
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+
+@EntityReference(value = IpAddress.class)
+@SuppressWarnings("unused")
+public class AcquireIPAddressResponse  extends BaseResponse implements ControlledEntityResponse {
+ @SerializedName(ApiConstants.ID)
+ @Param(description = "public IP address id")
+ private String id;
+
+ @SerializedName(ApiConstants.IP_ADDRESS)
+ @Param(description = "public IP address")
+ private String ipAddress;
+
+ @SerializedName("allocated")
+ @Param(description = "date the public IP address was acquired")
+ private Date allocated;
+
+ @SerializedName(ApiConstants.ZONE_ID)
+ @Param(description = "the ID of the zone the public IP address belongs to")
+ private String zoneId;
+
+ @SerializedName(ApiConstants.ZONE_NAME)
+ @Param(description = "the name of the zone the public IP address belongs to")
+ private String zoneName;
+
+ @SerializedName("issourcenat")
+ @Param(description = "true if the IP address is a source nat address, false otherwise")
+ private Boolean sourceNat;
+
+ @SerializedName(ApiConstants.ACCOUNT)
+ @Param(description = "the account the public IP address is associated with")
+ private String accountName;
+
+ @SerializedName(ApiConstants.PROJECT_ID)
+ @Param(description = "the project id of the ipaddress")
+ private String projectId;
+
+ @SerializedName(ApiConstants.PROJECT)
+ @Param(description = "the project name of the address")
+ private String projectName;
+
+ @SerializedName(ApiConstants.DOMAIN_ID)
+ @Param(description = "the domain ID the public IP address is associated with")
+ private String domainId;
+
+ @SerializedName(ApiConstants.DOMAIN)
+ @Param(description = "the domain the public IP address is associated with")
+ private String domainName;
+
+ @SerializedName(ApiConstants.FOR_VIRTUAL_NETWORK)
+ @Param(description = "the virtual network for the IP address")
+ private Boolean forVirtualNetwork;
+
+ @SerializedName(ApiConstants.VLAN_ID)
+ @Param(description = "the ID of the VLAN associated with the IP address." + " This parameter is visible to ROOT admins only")
+ private String vlanId;
+
+ @SerializedName("vlanname")
+ @Param(description = "the VLAN associated with the IP address")
+ private String vlanName;
+
+ @SerializedName("isstaticnat")
+ @Param(description = "true if this ip is for static nat, false otherwise")
+ private Boolean staticNat;
+
+ @SerializedName(ApiConstants.IS_SYSTEM)
+ @Param(description = "true if this ip is system ip (was allocated as a part of deployVm or createLbRule)")
+ private Boolean isSystem;
+
+ @SerializedName(ApiConstants.VIRTUAL_MACHINE_ID)
+ @Param(description = "virutal machine id the ip address is assigned to (not null only for static nat Ip)")
+ private String virtualMachineId;
+
+ @SerializedName("vmipaddress")
+ @Param(description = "virutal machine (dnat) ip address (not null only for static nat Ip)")
+ private String virtualMachineIp;
+
+ @SerializedName("virtualmachinename")
+ @Param(description = "virutal machine name the ip address is assigned to (not null only for static nat Ip)")
+ private String virtualMachineName;
+
+ @SerializedName("virtualmachinedisplayname")
+ @Param(description = "virutal machine display name the ip address is assigned to (not null only for static nat Ip)")
+ private String virtualMachineDisplayName;
+
+ @SerializedName(ApiConstants.ASSOCIATED_NETWORK_ID)
+ @Param(description = "the ID of the Network associated with the IP address")
+ private String associatedNetworkId;
+
+ @SerializedName(ApiConstants.ASSOCIATED_NETWORK_NAME)
+ @Param(description = "the name of the Network associated with the IP address")
+ private String associatedNetworkName;
+
+ @SerializedName(ApiConstants.NETWORK_ID)
+ @Param(description = "the ID of the Network where ip belongs to")
+ private String networkId;
+
+ @SerializedName(ApiConstants.STATE)
+ @Param(description = "State of the ip address. Can be: Allocatin, Allocated and Releasing")
+ private String state;
+
+ @SerializedName(ApiConstants.PHYSICAL_NETWORK_ID)
+ @Param(description = "the physical network this belongs to")
+ private String physicalNetworkId;
+
+ @SerializedName(ApiConstants.PURPOSE)
+ @Param(description = "purpose of the IP address. In Acton this value is not null for Ips with isSystem=true, and can have either StaticNat or LB value")
+ private String purpose;
+
+ @SerializedName(ApiConstants.VPC_ID)
+ @Param(description = "VPC the ip belongs to")
+ private String vpcId;
+ @SerializedName(ApiConstants.TAGS)
+ @Param(description = "the list of resource tags associated with ip address", responseObject = ResourceTagResponse.class)
+ private List<ResourceTagResponse> tags;
+
+ @SerializedName(ApiConstants.IS_PORTABLE)
+ @Param(description = "is public IP portable across the zones")
+ private Boolean isPortable;
+
+ @SerializedName(ApiConstants.FOR_DISPLAY)
+ @Param(description = "is public ip for display to the regular user", since = "4.4", authorized = {RoleType.Admin})
+ private Boolean forDisplay;
+
+ /*
+     @SerializedName(ApiConstants.JOB_ID) @Param(description="shows the current pending asynchronous job ID. This tag is not returned if no current pending jobs are acting on the volume")
+     private IdentityProxy jobId = new IdentityProxy("async_job");
+ */
+
+ public void setIpAddress(String ipAddress) {
+     this.ipAddress = ipAddress;
+ }
+
+ @Override
+ public String getObjectId() {
+     return this.getId();
+ }
+
+ public void setAllocated(Date allocated) {
+     this.allocated = allocated;
+ }
+
+ public void setZoneId(String zoneId) {
+     this.zoneId = zoneId;
+ }
+
+ public void setZoneName(String zoneName) {
+     this.zoneName = zoneName;
+ }
+
+ public void setSourceNat(Boolean sourceNat) {
+     this.sourceNat = sourceNat;
+ }
+
+ @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 setForVirtualNetwork(Boolean forVirtualNetwork) {
+     this.forVirtualNetwork = forVirtualNetwork;
+ }
+
+ public void setVlanId(String vlanId) {
+     this.vlanId = vlanId;
+ }
+
+ public void setVlanName(String vlanName) {
+     this.vlanName = vlanName;
+ }
+
+ public void setStaticNat(Boolean staticNat) {
+     this.staticNat = staticNat;
+ }
+
+ public void setAssociatedNetworkId(String networkId) {
+     this.associatedNetworkId = networkId;
+ }
+
+ public void setNetworkId(String networkId) {
+     this.networkId = networkId;
+ }
+
+ public void setVirtualMachineId(String virtualMachineId) {
+     this.virtualMachineId = virtualMachineId;
+ }
+
+ public void setVirtualMachineIp(String virtualMachineIp) {
+     this.virtualMachineIp = virtualMachineIp;
+ }
+
+ public void setVirtualMachineName(String virtualMachineName) {
+     this.virtualMachineName = virtualMachineName;
+ }
+
+ public void setVirtualMachineDisplayName(String virtualMachineDisplayName) {
+     this.virtualMachineDisplayName = virtualMachineDisplayName;
+ }
+
+ public String getId() {
+     return id;
+ }
+
+ public void setId(String id) {
+     this.id = id;
+ }
+
+ 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 setPhysicalNetworkId(String physicalNetworkId) {
+     this.physicalNetworkId = physicalNetworkId;
+ }
+
+ public void setIsSystem(Boolean isSystem) {
+     this.isSystem = isSystem;
+ }
+
+ public void setPurpose(String purpose) {
+     this.purpose = purpose;
+ }
+
+ public void setVpcId(String vpcId) {
+     this.vpcId = vpcId;
+ }
+
+ public void setTags(List<ResourceTagResponse> tags) {
+     this.tags = tags;
+ }
+
+ public void setAssociatedNetworkName(String associatedNetworkName) {
+     this.associatedNetworkName = associatedNetworkName;
+ }
+
+ public void setPortable(Boolean portable) {
+     this.isPortable = portable;
+ }
+
+ public void setForDisplay(Boolean forDisplay) {
+     this.forDisplay = forDisplay;
+ }
+}
diff --git a/api/src/org/apache/cloudstack/api/response/AcquirePodIpCmdResponse.java b/api/src/org/apache/cloudstack/api/response/AcquirePodIpCmdResponse.java
new file mode 100644
index 0000000..3eece1d
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/response/AcquirePodIpCmdResponse.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 org.apache.cloudstack.api.response;
+
+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 AcquirePodIpCmdResponse extends BaseResponse {
+
+    @SerializedName(ApiConstants.IP_ADDRESS)
+    @Param(description = "Allocated IP address")
+    private String ipAddress;
+
+    @SerializedName(ApiConstants.POD_ID)
+    @Param(description = "the ID of the pod the  IP address belongs to")
+    private Long podId;
+
+    @SerializedName(ApiConstants.GATEWAY)
+    @Param(description = "Gateway for Pod ")
+    private String gateway;
+
+    @SerializedName(ApiConstants.CIDR)
+    @Param(description = "CIDR of the Pod")
+    private String cidrAddress;
+
+    @SerializedName(ApiConstants.NIC_ID)
+    @Param(description = "the ID of the nic")
+    private Long instanceId;
+
+    @SerializedName(ApiConstants.HOST_MAC)
+    @Param(description = "MAC address of the pod the  IP")
+    private Long macAddress;
+
+    @SerializedName(ApiConstants.ID)
+    @Param(description = "the ID of the pod the  IP address")
+    private long id;
+
+    public void setIpAddress(String ipAddress) {
+        this.ipAddress = ipAddress;
+    }
+
+    public void setInstanceId(Long instanceId) {
+        this.instanceId = instanceId;
+    }
+
+    public void setPodId(long podId) {
+        this.podId = podId;
+    }
+
+    public void setMacAddress(long macAddress) {
+        this.macAddress = macAddress;
+    }
+
+    public void setGateway(String gateway) {
+        this.gateway = gateway;
+    }
+
+    public void setCidrAddress(String cidrAddress) {
+        this.cidrAddress = cidrAddress;
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public Long getInstanceId() {
+        return instanceId;
+    }
+
+    public long getPodId() {
+        return podId;
+    }
+
+    public String getIpAddress() {
+        return ipAddress;
+    }
+
+    public long getMacAddress() {
+        return macAddress;
+    }
+
+    public String getCidrAddress() {
+        return cidrAddress;
+    }
+
+    public String getGateway() {
+        return gateway;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+}
\ No newline at end of file
diff --git a/engine/components-api/src/com/cloud/network/IpAddressManager.java b/engine/components-api/src/com/cloud/network/IpAddressManager.java
index 0ab5ccc..bf97b34 100644
--- a/engine/components-api/src/com/cloud/network/IpAddressManager.java
+++ b/engine/components-api/src/com/cloud/network/IpAddressManager.java
@@ -18,7 +18,7 @@ package com.cloud.network;
 
 import java.util.List;
 
-import com.cloud.utils.db.DB;
+import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse;
 import org.apache.cloudstack.framework.config.ConfigKey;
 
 import com.cloud.dc.DataCenter;
@@ -34,14 +34,16 @@ 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 {
     static final String UseSystemPublicIpsCK = "use.system.public.ips";
     static final 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);
+            "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);
 
     static final ConfigKey<Boolean> RulesContinueOnError = new ConfigKey<Boolean>("Advanced", Boolean.class, "network.rule.delete.ignoreerror", "true",
             "When true, ip address delete (ipassoc) failures are  ignored", true);
@@ -63,7 +65,7 @@ public interface IpAddressManager {
      * @throws InsufficientAddressCapacityException
      */
     PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, boolean isSystem)
-        throws InsufficientAddressCapacityException;
+            throws InsufficientAddressCapacityException;
 
     /**
      * Do all of the work of releasing public ip addresses. Note that if this method fails, there can be side effects.
@@ -77,7 +79,7 @@ public interface IpAddressManager {
     boolean disassociatePublicIpAddress(long id, long userId, Account caller);
 
     boolean applyRules(List<? extends FirewallRule> rules, FirewallRule.Purpose purpose, NetworkRuleApplier applier, boolean continueOnError)
-        throws ResourceUnavailableException;
+            throws ResourceUnavailableException;
 
     /**
      * @throws ResourceAllocationException TODO
@@ -93,12 +95,12 @@ public interface IpAddressManager {
      * @throws
      */
     boolean associateIpAddressListToAccount(long userId, long accountId, long zoneId, Long vlanId, Network guestNetwork) throws InsufficientCapacityException,
-        ConcurrentOperationException, ResourceUnavailableException, ResourceAllocationException;
+            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;
+            throws ResourceUnavailableException;
 
     IPAddressVO markIpAsUnavailable(long addrId);
 
@@ -111,7 +113,7 @@ public interface IpAddressManager {
     boolean handleSystemIpRelease(IpAddress ip);
 
     void allocateDirectIp(NicProfile nic, DataCenter dc, VirtualMachineProfile vm, Network network, String requestedIpv4, String requestedIpv6)
-        throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException;
+            throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException;
 
     /**
      * @param owner
@@ -128,23 +130,23 @@ public interface IpAddressManager {
      * @param releaseOnFailure TODO
      */
     IPAddressVO associateIPToGuestNetwork(long ipAddrId, long networkId, boolean releaseOnFailure) throws ResourceAllocationException, ResourceUnavailableException,
-        InsufficientAddressCapacityException, ConcurrentOperationException;
+            InsufficientAddressCapacityException, ConcurrentOperationException;
 
     IpAddress allocatePortableIp(Account ipOwner, Account caller, long dcId, Long networkId, Long vpcID) throws ConcurrentOperationException,
-        ResourceAllocationException, InsufficientAddressCapacityException;
+            ResourceAllocationException, InsufficientAddressCapacityException;
 
     boolean releasePortableIpAddress(long addrId);
 
     IPAddressVO associatePortableIPToGuestNetwork(long ipAddrId, long networkId, boolean releaseOnFailure) throws ResourceAllocationException,
-        ResourceUnavailableException, InsufficientAddressCapacityException, ConcurrentOperationException;
+            ResourceUnavailableException, InsufficientAddressCapacityException, ConcurrentOperationException;
 
     IPAddressVO disassociatePortableIPToGuestNetwork(long ipAddrId, long networkId) throws ResourceAllocationException, ResourceUnavailableException,
-        InsufficientAddressCapacityException, ConcurrentOperationException;
+            InsufficientAddressCapacityException, ConcurrentOperationException;
 
     boolean isPortableIpTransferableFromNetwork(long ipAddrId, long networkId);
 
     void transferPortableIP(long ipAddrId, long currentNetworkId, long newNetworkId) throws ResourceAllocationException, ResourceUnavailableException,
-        InsufficientAddressCapacityException, ConcurrentOperationException;;
+            InsufficientAddressCapacityException, ConcurrentOperationException;;
 
     /**
      * @param addr
@@ -162,17 +164,18 @@ public interface IpAddressManager {
      * @throws InsufficientAddressCapacityException
      */
     PublicIp assignDedicateIpAddress(Account owner, Long guestNtwkId, Long vpcId, long dcId, boolean isSourceNat) throws ConcurrentOperationException,
-        InsufficientAddressCapacityException;
+            InsufficientAddressCapacityException;
 
     IpAddress allocateIp(Account ipOwner, boolean isSystem, Account caller, long callerId, DataCenter zone, Boolean displayIp) throws ConcurrentOperationException,
-        ResourceAllocationException, InsufficientAddressCapacityException;
+            ResourceAllocationException, InsufficientAddressCapacityException;
+
 
     PublicIp assignPublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List<Long> vlanDbIds, Long networkId, String requestedIp,
-        boolean isSystem) throws InsufficientAddressCapacityException;
+            boolean isSystem) throws InsufficientAddressCapacityException;
 
     @DB
     void allocateNicValues(NicProfile nic, DataCenter dc, VirtualMachineProfile vm, Network network, String requestedIpv4,
-                           String requestedIpv6) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException;
+            String requestedIpv6) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException;
 
     int getRuleCountForIp(Long addressId, FirewallRule.Purpose purpose, FirewallRule.State state);
 
@@ -180,4 +183,11 @@ public interface IpAddressManager {
 
     String allocatePublicIpForGuestNic(Network network, Long podId, Account ipOwner, String requestedIp) throws InsufficientAddressCapacityException;
 
+    public AcquirePodIpCmdResponse allocatePodIp(Long zoneId, String cidr) throws ConcurrentOperationException,
+            ResourceAllocationException;
+
+    public void releasePodIp(Long id) throws CloudRuntimeException;
+
+
 }
+
diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDao.java b/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDao.java
index e5843b6..3b988da 100644
--- a/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDao.java
+++ b/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDao.java
@@ -47,4 +47,6 @@ public interface DataCenterIpAddressDao extends GenericDao<DataCenterIpAddressVO
 
     boolean deleteIpAddressByPod(long podId);
 
+    void releasePodIpAddress(long id);
+
 }
diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDaoImpl.java
index ae8ae0c..1feb6ad 100644
--- a/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDaoImpl.java
+++ b/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDaoImpl.java
@@ -177,6 +177,22 @@ public class DataCenterIpAddressDaoImpl extends GenericDaoBase<DataCenterIpAddre
     }
 
     @Override
+    public void releasePodIpAddress(long id) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Releasing ip address for ID=" + id);
+        }
+//        SearchCriteria<DataCenterIpAddressVO> sc = AllFieldsSearch.create();
+//        sc.setParameters("id", id);
+
+        DataCenterIpAddressVO vo = this.findById(id);
+        vo.setTakenAt(null);
+        vo.setInstanceId(null);
+        vo.setReservationId(null);
+        persist(vo);
+        //update(vo, sc);
+    }
+
+    @Override
     public void releaseIpAddress(long nicId) {
         if (s_logger.isDebugEnabled()) {
             s_logger.debug("Releasing ip address for instance=" + nicId);
diff --git a/engine/schema/src/com/cloud/dc/dao/HostPodDao.java b/engine/schema/src/com/cloud/dc/dao/HostPodDao.java
index 1a000d8..b2e9b89 100644
--- a/engine/schema/src/com/cloud/dc/dao/HostPodDao.java
+++ b/engine/schema/src/com/cloud/dc/dao/HostPodDao.java
@@ -32,4 +32,6 @@ public interface HostPodDao extends GenericDao<HostPodVO, Long> {
     public List<Long> listDisabledPods(long zoneId);
 
     public List<Long> listAllPods(Long zoneId);
+
+    public List<HostPodVO> listAllPodsByCidr(long zoneId, String cidr);
 }
diff --git a/engine/schema/src/com/cloud/dc/dao/HostPodDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/HostPodDaoImpl.java
index 1c83b3a..3fbeb58 100644
--- a/engine/schema/src/com/cloud/dc/dao/HostPodDaoImpl.java
+++ b/engine/schema/src/com/cloud/dc/dao/HostPodDaoImpl.java
@@ -137,4 +137,12 @@ public class HostPodDaoImpl extends GenericDaoBase<HostPodVO, Long> implements H
         }
         return customSearch(sc, null);
     }
+    @Override
+    public List<HostPodVO> listAllPodsByCidr(long zoneId, String cidr) {
+        SearchCriteria<HostPodVO> sc = DataCenterAndNameSearch.create();
+        sc.setParameters("dataCenterId", zoneId);
+        sc.setParameters("cidr_address", cidr);
+        return listBy(sc);
+    }
+
 }
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteServicePackageOfferingCmd.java b/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteServicePackageOfferingCmd.java
new file mode 100644
index 0000000..1fbd899
--- /dev/null
+++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteServicePackageOfferingCmd.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 org.apache.cloudstack.api.response.SuccessResponse;
+
+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 = "deleteServicePackageOffering", responseObject = SuccessResponse.class, description = "Delete Service Package Offering")
+public class DeleteServicePackageOfferingCmd extends BaseCmd {
+
+    public static final Logger s_logger = Logger.getLogger(DeleteServicePackageOfferingCmd.class.getName());
+    private static final String s_name = "deleteServicePackageOffering";
+    @Inject
+    NetscalerLoadBalancerElementService _netsclarLbService;
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.STRING, entityType = NetScalerServicePackageResponse.class, required = true, description = "the service offering ID")
+    private String ID;
+
+    @Override
+    public void execute() throws ServerApiException, ConcurrentOperationException, EntityExistsException {
+        SuccessResponse response = new SuccessResponse();
+        try {
+            boolean result = _netsclarLbService.deleteServicePackageOffering(this);
+
+            if (response != null && result) {
+                response.setDisplayText("Deleted Successfully");
+                response.setSuccess(result);
+                response.setResponseName(getCommandName());
+                this.setResponseObject(response);
+            }
+        } catch (CloudRuntimeException runtimeExcp) {
+            response.setDisplayText(runtimeExcp.getMessage());
+            response.setSuccess(false);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+            return;
+        } catch (Exception e) {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete Service Package due to internal error.");
+        }
+    }
+
+    public String getId() {
+        return ID;
+    }
+
+    @Override
+    public String getCommandName() {
+        // TODO Auto-generated method stub
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        // TODO Auto-generated method stub
+        return CallContext.current().getCallingAccount().getId();
+    }
+
+}
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/ListRegisteredServicePackageCmd.java b/plugins/network-elements/netscaler/src/com/cloud/api/commands/ListRegisteredServicePackageCmd.java
new file mode 100644
index 0000000..6838833
--- /dev/null
+++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/ListRegisteredServicePackageCmd.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.api.commands;
+
+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.BaseListCmd;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.ListResponse;
+
+import com.cloud.api.response.NetScalerServicePackageResponse;
+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.element.NetscalerLoadBalancerElementService;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.network.NetScalerServicePackageVO;
+
+@APICommand(name = "listRegisteredServicePackages", responseObject = NetScalerServicePackageResponse.class, description = "lists registered service packages", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class ListRegisteredServicePackageCmd extends BaseListCmd {
+
+    public static final Logger s_logger = Logger.getLogger(ListRegisteredServicePackageCmd.class.getName());
+    private static final String s_name = "listregisteredservicepackage";
+    @Inject
+    NetscalerLoadBalancerElementService _netsclarLbService;
+
+    @Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException,
+            ConcurrentOperationException, ResourceAllocationException {
+        try {
+            List<NetScalerServicePackageVO> lrsPackages = _netsclarLbService.listRegisteredServicePackages(this);
+            ListResponse<NetScalerServicePackageResponse> response = new ListResponse<NetScalerServicePackageResponse>();
+            List<NetScalerServicePackageResponse> lbDevicesResponse = new ArrayList<NetScalerServicePackageResponse>();
+
+            if (lrsPackages != null && !lrsPackages.isEmpty()) {
+                for (NetScalerServicePackageVO lrsPackageVO : lrsPackages) {
+                    NetScalerServicePackageResponse lbdeviceResponse = _netsclarLbService
+                            .createRegisteredServicePackageResponse(lrsPackageVO);
+                    lbDevicesResponse.add(lbdeviceResponse);
+                }
+            }
+
+            response.setResponses(lbDevicesResponse);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } catch (InvalidParameterValueException invalidParamExcp) {
+            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage());
+        } catch (CloudRuntimeException runtimeExcp) {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage());
+        }
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+}
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
index 52e8e5a..67c1c57 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterServicePackageCmd.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterServicePackageCmd.java
@@ -33,8 +33,7 @@ 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")
+@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());
@@ -50,10 +49,10 @@ public class RegisterServicePackageCmd extends BaseCmd {
     @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")
+    @Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, required = true, description = "Description of Service Package")
     private String description;
 
-/*    @Override
+    /*    @Override
     public String getEventType() {
         return EventTypes.EVENT_NETSCALER_SERVICEPACKAGE_ADD;
     }
@@ -62,12 +61,11 @@ public class RegisterServicePackageCmd extends BaseCmd {
     public String getEventDescription() {
         return "Adding Netscaler Service Package";
     }
-*/
+     */
     @Override
     public void execute() throws ServerApiException, ConcurrentOperationException, EntityExistsException {
         try {
-            NetScalerServicePackageResponse response =  _netsclarLbService.registerNetscalerServicePackage(this);
-
+            NetScalerServicePackageResponse response = _netsclarLbService.registerNetscalerServicePackage(this);
             if (response != null) {
                 //NetScalerServicePackageResponse response = _netsclarLbService.createNetscalerServicePackageResponse(servicePackageVO);
                 response.setObjectName("netscalerservicepackage");
@@ -81,7 +79,7 @@ public class RegisterServicePackageCmd extends BaseCmd {
         } 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() );
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Service Pacakge Already Exists with Name " + getSpName());
         }
 
     }
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/response/NetScalerServicePackageResponse.java b/plugins/network-elements/netscaler/src/com/cloud/api/response/NetScalerServicePackageResponse.java
index 4950875..ccd814b 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/api/response/NetScalerServicePackageResponse.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/api/response/NetScalerServicePackageResponse.java
@@ -24,6 +24,7 @@ import com.cloud.network.NetScalerServicePackageVO;
 import com.cloud.serializer.Param;
 
 public class NetScalerServicePackageResponse extends BaseResponse {
+
     @SerializedName(ApiConstants.ID)
     @Param(description = "Service Package UUID")
     private String id;
@@ -36,7 +37,8 @@ public class NetScalerServicePackageResponse extends BaseResponse {
     @Param(description = "Description of Service Package")
     private String description;
 
-    public NetScalerServicePackageResponse() {}
+    public NetScalerServicePackageResponse() {
+    }
 
     public NetScalerServicePackageResponse(NetScalerServicePackageVO servicePackage) {
         this.id = servicePackage.getUuid();
@@ -68,4 +70,4 @@ public class NetScalerServicePackageResponse extends BaseResponse {
         this.description = 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
index 60baa89..6f5a9a1 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java
@@ -35,6 +35,10 @@ 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.api.command.admin.address.AcquirePodIpCmdByAdmin;
+import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin;
 import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice;
@@ -54,12 +58,17 @@ 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.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.response.NetScalerServicePackageResponse;
+import com.cloud.api.response.NetscalerControlCenterResponse;
 import com.cloud.api.response.NetscalerLoadBalancerResponse;
 import com.cloud.configuration.Config;
 import com.cloud.configuration.ConfigurationManager;
@@ -112,6 +121,7 @@ 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.dao.RegisteredServicePackageVO;
 import com.cloud.network.lb.LoadBalancingRule;
 import com.cloud.network.lb.LoadBalancingRule.LbDestination;
 import com.cloud.network.resource.NetScalerControlCenterResource;
@@ -124,9 +134,11 @@ import com.cloud.network.rules.StaticNat;
 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.utils.NumbersUtil;
 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.TransactionCallbackNoReturn;
@@ -160,6 +172,12 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
     DataCenterDao _dcDao;
     @Inject
     ExternalLoadBalancerDeviceDao _lbDeviceDao;
+
+    // @Inject
+    // NetScalerServicePackageDao _lrsPackagesDao;
+
+    @Inject
+    NetScalerControlCenterDao _netscalerControlCenterDao;
     @Inject
     NetworkExternalLoadBalancerDao _networkLBDao;
     @Inject
@@ -179,8 +197,6 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
     @Inject
     NetScalerServicePackageDao _netscalerServicePackageDao;
     @Inject
-    NetScalerControlCenterDao _netscalerControlCenterDao;
-    @Inject
     ResourceManager _resourceMgr;
     @Inject
     HostDetailsDao _hostDetailDao;
@@ -195,73 +211,83 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         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);
+        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());
+            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));
+        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);
+        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 {
+    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());
+        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) {
+            if (offering.getServicePackage() == null) {
                 return manageGuestNetworkWithExternalLoadBalancer(true, guestConfig);
             } else {
-                // if the network offering has service package implement it with Netscaler Control Center
+                // if the network offering has service package implement it with
+                // Netscaler Control Center
                 manageGuestNetworkWithNetscalerControlCenter(true, guestConfig, offering);
                 return true;
             }
         } 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());
+            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());
+            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();
+        List<NetScalerControlCenterVO> ncc = _netscalerControlCenterDao.listAll();
         HostVO hostVO = null;
-        Map<String, Object> params ;
-        if(ncc.size() > 0) {
+        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";
+            String hostName = "NetscalerControlCenter";
             hostDetails.put("name", hostName);
             hostDetails.put("guid", UUID.randomUUID().toString());
             hostDetails.put("zoneId", Long.toString(guestConfig.getDataCenterId()));
@@ -278,7 +304,9 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         return hostVO;
     }
 
-    public boolean manageGuestNetworkWithNetscalerControlCenter(boolean add, Network guestConfig, NetworkOffering offering) throws ResourceUnavailableException, InsufficientCapacityException, ConfigurationException {
+    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.");
@@ -291,19 +319,23 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
 
         if (add) {
             HostVO lbDeviceVO = null;
-            // on restart network, device could have been allocated already, skip allocation if a device is assigned
+            // 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();
+                    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());
+                    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());
+            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
 
@@ -311,13 +343,14 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
             // 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.");
+                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??";
+            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();
@@ -339,7 +372,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
                 throw new InsufficientNetworkCapacityException(msg, Network.class, guestConfig.getId());
             }
             networkDetails.put("snip", selfIp);
-            //TODO region is hardcoded make it dynamic
+            // TODO region is hardcoded make it dynamic
             networkDetails.put("region_id", 1);
             networkDetails.put("name", guestConfig.getName());
             networkPayload.put("network", networkDetails);
@@ -350,35 +383,33 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
 
         NetScalerImplementNetworkCommand cmd = new NetScalerImplementNetworkCommand(zoneId, 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 (add) {
-                     // Insert a new NIC for this guest network to reserve the self IP
-                     _networkService.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
-             return true;
-             //write code to remove the self nic or the clean up work
-         }
+        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 (add) {
+                    // Insert a new NIC for this guest network to reserve the self IP
+                    _networkService.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
+            return true;
+            //write code to remove the self nic or the clean up work
+        }
         // Send a command to the external load balancer to implement or shutdown the guest network
-/*        long guestVlanTag = Long.parseLong(BroadcastDomainType.getValue(guestConfig.getBroadcastUri()));
+        /*        long guestVlanTag = Long.parseLong(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) {
@@ -396,17 +427,17 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
             }
             selfIp = selfipNic.getIp4Address();
         }
-*/
+        */
         // It's a hack, using isOneToOneNat field for indicate if it's inline or not
-/*        boolean inline = _networkMgr.isNetworkInlineMode(guestConfig);
+        /*        boolean inline = _networkMgr.isNetworkInlineMode(guestConfig);
         IpAddressTO ip =
             new IpAddressTO(guestConfig.getAccountId(), null, add, false, true, String.valueOf(guestVlanTag), selfIp, guestVlanNetmask, null, networkRate, inline);
         IpAddressTO[] ips = new IpAddressTO[1];
         ips[0] = ip;
         IpAssocCommand cmd = new IpAssocCommand(ips);
         Answer answer = _agentMgr.easySend(netscalerControlCenter.getId(), cmd);
-*/
-/*        if (answer == null || !answer.getResult()) {
+        */
+        /*        if (answer == null || !answer.getResult()) {
             String action = add ? "implement" : "shutdown";
             String answerDetails = (answer != null) ? answer.getDetails() : null;
             answerDetails = (answerDetails != null) ? " due to " + answerDetails : "";
@@ -414,36 +445,95 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
             s_logger.error(msg);
             throw new ResourceUnavailableException(msg, Network.class, guestConfig.getId());
         }
-
+        =======
+        NetScalerImplementNetworkCommand cmd = new NetScalerImplementNetworkCommand(zoneId,
+                netscalerControlCenter.getId(), networkPayload.toString());
+        >>>>>>> Stashed changes
         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);
+            Answer answer = _agentMgr.easySend(netscalerControlCenter.getId(), cmd);
+            // 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 (add) {
+                    // Insert a new NIC for this guest network to reserve the
+                    // self IP
+                    _networkService.savePlaceholderNic(guestConfig, selfIp, null, null);
+                }
             }
         }
-
-        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);
-        }*/
+        // Send a command to the external load balancer to implement or shutdown
+        // the guest network
+        /*
+         * long guestVlanTag =
+         * Long.parseLong(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.getIp4Address(); }
+         */
+        // 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, String.valueOf(guestVlanTag), selfIp,
+         * guestVlanNetmask, null, networkRate, inline); IpAddressTO[] ips = new
+         * IpAddressTO[1]; ips[0] = ip; IpAssocCommand cmd = new
+         * IpAssocCommand(ips); Answer answer =
+         * _agentMgr.easySend(netscalerControlCenter.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 prepare(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
-        throws ConcurrentOperationException, InsufficientNetworkCapacityException, ResourceUnavailableException {
+    public boolean prepare(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest,
+            ReservationContext context) throws ConcurrentOperationException, InsufficientNetworkCapacityException,
+                    ResourceUnavailableException {
         return true;
     }
 
@@ -453,7 +543,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
     }
 
     @Override
-    public boolean shutdown(Network guestConfig, ReservationContext context, boolean cleanup) throws ResourceUnavailableException, ConcurrentOperationException {
+    public boolean shutdown(Network guestConfig, ReservationContext context, boolean cleanup)
+            throws ResourceUnavailableException, ConcurrentOperationException {
         if (!canHandle(guestConfig, Service.Lb)) {
             return false;
         }
@@ -461,7 +552,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         try {
 
             NetworkOffering networkOffering = _networkOfferingDao.findById(guestConfig.getNetworkOfferingId());
-            if(networkOffering.getServicePackage() == null) {
+            if (networkOffering.getServicePackage() == null) {
                 return manageGuestNetworkWithExternalLoadBalancer(true, guestConfig);
             } else {
                 // if the network offering has service package implement it with Netscaler Control Center
@@ -470,7 +561,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
             }
             //return manageGuestNetworkWithExternalLoadBalancer(false, guestConfig);
         } catch (InsufficientCapacityException capacityException) {
-            // TODO: handle out of capacity exception gracefully in case of multple providers available
+            // TODO: handle out of capacity exception gracefully in case of
+            // multple providers available
             return false;
         } catch (ConfigurationException e) {
             // TODO Auto-generated catch block
@@ -520,27 +612,33 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         // 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
+        // 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
+        // Specifies that load balancing rules can be made for either TCP or UDP
+        // traffic
         lbCapabilities.put(Capability.SupportedProtocols, "tcp,udp");
 
-        // Specifies that this element can measure network usage on a per public IP basis
+        // 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
+        // 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());
 
         // 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("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);
@@ -552,15 +650,18 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
 
         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");
+        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");
+        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.");
+        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);
 
@@ -568,7 +669,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         lbCapabilities.put(Capability.SupportedStickinessMethods, stickyMethodList);
 
         lbCapabilities.put(Capability.ElasticLb, "true");
-        //Setting HealthCheck Capability to True for Netscaler element
+        // Setting HealthCheck Capability to True for Netscaler element
         lbCapabilities.put(Capability.HealthCheckPolicy, "true");
         capabilities.put(Service.Lb, lbCapabilities);
 
@@ -601,15 +702,15 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         try {
             uri = new URI(cmd.getUrl());
         } catch (Exception e) {
-            String msg = "Error parsing the url parameter specified in addNetscalerLoadBalancer command due to " + e.getMessage();
+            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;
+        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";
@@ -619,7 +720,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
 
         if (cmd.isGslbProvider()) {
 
-            if (!deviceName.equals(NetworkDevice.NetscalerVPXLoadBalancer.getName()) && !deviceName.equals(NetworkDevice.NetscalerMPXLoadBalancer.getName())) {
+            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);
@@ -632,19 +734,21 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
             }
 
             if (dedicatedUse) {
-                throw new InvalidParameterValueException("NetScaler provisioned to be GSLB service provider can only be configured for shared usage.");
+                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.");
+            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());
+        ExternalLoadBalancerDeviceVO lbDeviceVO = addExternalLoadBalancer(cmd.getPhysicalNetworkId(), cmd.getUrl(),
+                cmd.getUsername(), cmd.getPassword(), deviceName, new NetscalerResource(), cmd.isGslbProvider(),
+                cmd.isExclusiveGslbProvider(), cmd.getSitePublicIp(), cmd.getSitePrivateIp());
 
         return lbDeviceVO;
     }
@@ -675,7 +779,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
     }
 
     @DB
-    private ExternalLoadBalancerDeviceVO configureNetscalerLoadBalancer(final long lbDeviceId, Long capacity, Boolean dedicatedUse, List<Long> newPodsConfig) {
+    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());
 
@@ -716,10 +821,11 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
 
         String deviceName = lbDeviceVo.getDeviceName();
         if (dedicatedUse != null || capacity != null) {
-            if (NetworkDevice.NetscalerSDXLoadBalancer.getName().equalsIgnoreCase(deviceName) ||
-                NetworkDevice.NetscalerMPXLoadBalancer.getName().equalsIgnoreCase(deviceName)) {
+            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.");
+                    throw new InvalidParameterValueException(
+                            "Netscaler MPX and SDX device should be shared and can not be dedicated to a single account.");
                 }
             }
 
@@ -727,11 +833,13 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
             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");
+                    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");
+                    throw new CloudRuntimeException(
+                            "There are networks already using this netscaler device to make device dedicated");
                 }
             }
         }
@@ -784,7 +892,12 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         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(ReleasePodIpCmdByAdmin.class);
+        cmdList.add(AcquirePodIpCmdByAdmin.class);
         return cmdList;
     }
 
@@ -795,7 +908,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
 
         ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId);
         if (lbDeviceVo == null || !isNetscalerDevice(lbDeviceVo.getDeviceName())) {
-            throw new InvalidParameterValueException("Could not find Netscaler load balancer device with ID " + lbDeviceId);
+            throw new InvalidParameterValueException(
+                    "Could not find Netscaler load balancer device with ID " + lbDeviceId);
         }
 
         List<NetworkExternalLoadBalancerVO> networkLbMaps = _networkLBDao.listByLoadBalancerDeviceId(lbDeviceId);
@@ -817,13 +931,15 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         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");
+            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);
+                throw new InvalidParameterValueException(
+                        "Could not find Netscaler load balancer device with ID: " + lbDeviceId);
             }
             lbDevices.add(lbDeviceVo);
             return lbDevices;
@@ -832,7 +948,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         if (physcialNetworkId != null) {
             pNetwork = _physicalNetworkDao.findById(physcialNetworkId);
             if (pNetwork == null) {
-                throw new InvalidParameterValueException("Could not find phyical network with ID: " + physcialNetworkId);
+                throw new InvalidParameterValueException(
+                        "Could not find phyical network with ID: " + physcialNetworkId);
             }
             lbDevices = _lbDeviceDao.listByPhysicalNetworkAndProvider(physcialNetworkId, Provider.Netscaler.getName());
             return lbDevices;
@@ -842,11 +959,90 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
     }
 
     @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;
+        try {
+            result = _netscalerServicePackageDao.findByUuid(cmd.getId());
+            flag = _netscalerServicePackageDao.remove(result.getId());
+        } catch (Exception e) {
+            if (e instanceof InvalidParameterValueException)
+                throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
+            else if (result == null)
+                throw new CloudRuntimeException("Record does not Exists in the Table");
+            else
+                throw new CloudRuntimeException("Network offering is using the service package. First delete the nework offering and then delete ServicePackage");
+        }
+        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 {
+            List<Long> id_set_1 = _networkOfferingDao.listServicePackageUuid();
+            if (id_set_1.size() != 0) {
+                List<NetworkVO> id_set_2 = _networkDao.listNetworkOfferingId(id_set_1);
+                if (id_set_2 != null && id_set_2.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
+        SearchCriteria<HostVO> sc = _hostDao.createSearchCriteria();
+        sc.addAnd("type", SearchCriteria.Op.EQ, Host.Type.NetScalerControlCenter);
+        List<HostVO> ncc_list = _hostDao.search(sc, null);
+
+        if (ncc_list == null) {
+            throw new CloudRuntimeException("Could not find Netscaler Control Center in Database");
+        }
+        for (HostVO ncc : ncc_list) {
+            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());
@@ -857,7 +1053,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         response.setPrivateInterface(lbDetails.get("privateInterface"));
         response.setDeviceName(lbDeviceVO.getDeviceName());
         if (lbDeviceVO.getCapacity() == 0) {
-            long defaultLbCapacity = NumbersUtil.parseLong(_configDao.getValue(Config.DefaultExternalLoadBalancerCapacity.key()), 50);
+            long defaultLbCapacity = NumbersUtil
+                    .parseLong(_configDao.getValue(Config.DefaultExternalLoadBalancerCapacity.key()), 50);
             response.setDeviceCapacity(defaultLbCapacity);
         } else {
             response.setDeviceCapacity(lbDeviceVO.getCapacity());
@@ -884,15 +1081,35 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
     }
 
     @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());
+        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)
+        // 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) {
@@ -905,9 +1122,10 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
     }
 
     @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
+    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;
     }
 
@@ -917,9 +1135,9 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
     }
 
     private boolean isNetscalerDevice(String deviceName) {
-        if ((deviceName == null) ||
-            ((!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerMPXLoadBalancer.getName())) &&
-                (!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerSDXLoadBalancer.getName())) && (!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerVPXLoadBalancer.getName())))) {
+        if ((deviceName == null) || ((!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerMPXLoadBalancer.getName()))
+                && (!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerSDXLoadBalancer.getName()))
+                && (!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerVPXLoadBalancer.getName())))) {
             return false;
         } else {
             return true;
@@ -934,15 +1152,21 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
 
         // 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.");
+            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.");
+            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;
         }
 
@@ -950,8 +1174,10 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
     }
 
     @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
+    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;
     }
 
@@ -965,7 +1191,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         return this;
     }
 
-    public boolean applyElasticLoadBalancerRules(Network network, List<LoadBalancingRule> loadBalancingRules) throws ResourceUnavailableException {
+    public boolean applyElasticLoadBalancerRules(Network network, List<LoadBalancingRule> loadBalancingRules)
+            throws ResourceUnavailableException {
 
         if (loadBalancingRules == null || loadBalancingRules.isEmpty()) {
             return true;
@@ -977,7 +1204,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
             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();
+                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);
             }
@@ -1001,9 +1229,9 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
             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());
+                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());
                 }
@@ -1013,16 +1241,16 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
 
         if (loadBalancersToApply.size() > 0) {
             int numLoadBalancersForCommand = loadBalancersToApply.size();
-            LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply.toArray(new LoadBalancerTO[numLoadBalancersForCommand]);
+            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 +
-                        ".";
+                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());
             }
@@ -1032,13 +1260,15 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
     }
 
     @Override
-    public boolean applyStaticNats(Network config, List<? extends StaticNat> rules) throws ResourceUnavailableException {
+    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()));
+        boolean multiNetScalerDeployment = Boolean
+                .valueOf(_configDao.getValue(Config.EIPWithMultipleNetScalersEnabled.key()));
 
         try {
             if (!multiNetScalerDeployment) {
@@ -1048,7 +1278,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
                     try {
                         lbDevice = allocateLoadBalancerForNetwork(config);
                     } catch (Exception e) {
-                        errMsg = "Could not allocate a NetSclaer load balancer for configuring static NAT rules due to" + e.getMessage();
+                        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);
                     }
@@ -1065,8 +1296,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
                     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);
+                        StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, null,
+                                rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false);
                         rulesTO.add(ruleTO);
                     }
                 }
@@ -1084,20 +1315,23 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
                         // 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();
+                            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);
+                        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);
+                        // 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);
@@ -1114,7 +1348,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         }
     }
 
-    // returns configured NetScaler device that is associated with the pod that owns guest IP
+    // 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();
@@ -1133,7 +1368,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         return null;
     }
 
-    public List<LoadBalancerTO> getElasticLBRulesHealthCheck(Network network, List<LoadBalancingRule> loadBalancingRules) throws ResourceUnavailableException {
+    public List<LoadBalancerTO> getElasticLBRulesHealthCheck(Network network,
+            List<LoadBalancingRule> loadBalancingRules) throws ResourceUnavailableException {
 
         HealthCheckLBConfigAnswer answer = null;
 
@@ -1145,7 +1381,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         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");
+            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;
         }
 
@@ -1167,16 +1404,17 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
             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());
+                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]);
+            LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply
+                    .toArray(new LoadBalancerTO[numLoadBalancersForCommand]);
             HealthCheckLBConfigCommand cmd = new HealthCheckLBConfigCommand(loadBalancersForCommand);
             HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
             answer = (HealthCheckLBConfigAnswer)_agentMgr.easySend(externalLoadBalancer.getId(), cmd);
@@ -1211,16 +1449,37 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
     }
 
     @Override
-    public List<LoadBalancerTO> getLBHealthChecks(Network network, List<LoadBalancingRule> rules) throws ResourceUnavailableException {
+    public List<LoadBalancerTO> getLBHealthChecks(Network network, List<LoadBalancingRule> rules)
+            throws ResourceUnavailableException {
         return super.getLBHealthChecks(network, rules);
     }
 
     @Override
-    public boolean applyGlobalLoadBalancerRule(long zoneId, long physicalNetworkId, GlobalLoadBalancerConfigCommand gslbConfigCmd) throws ResourceUnavailableException {
+    public NetScalerServicePackageResponse listNetscalerServicePackage(RegisterServicePackageCmd cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public NetScalerServicePackageResponse deleteNetscalerServicePackage(RegisterServicePackageCmd cmd) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public NetScalerServicePackageResponse createNetscalerServicePackageResponse(NetScalerServicePackageVO servicePackageVO) {
+        // TODO Auto-generated method stub
+        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
+        // 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;
@@ -1228,7 +1487,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
             throw new ResourceUnavailableException(msg, DataCenter.class, zoneId);
         }
 
-        // get the host Id corresponding to NetScaler acting as GSLB service provider in the zone
+        // get the host Id corresponding to NetScaler acting as GSLB service
+        // provider in the zone
         zoneGslbProviderHosId = nsGslbProvider.getHostId();
 
         // send gslb configuration to NetScaler device
@@ -1246,13 +1506,14 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         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);
+            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());
+                    ExternalLoadBalancerDeviceVO nsGslbProvider = _externalLoadBalancerDeviceDao
+                            .findGslbServiceProvider(physNetwork.getId(), Provider.Netscaler.getName());
                     return nsGslbProvider;
                 }
             }
@@ -1265,7 +1526,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
     public boolean isServiceEnabledInZone(long zoneId, long physicalNetworkId) {
 
         ExternalLoadBalancerDeviceVO nsGslbProvider = findGslbProvider(zoneId, physicalNetworkId);
-        //return true if a NetScaler device is configured in the zone
+        // return true if a NetScaler device is configured in the zone
         return (nsGslbProvider != null);
     }
 
@@ -1288,13 +1549,14 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
     }
 
     private boolean canHandleLbRules(List<LoadBalancingRule> rules) {
-        Map<Capability, String> lbCaps = this.getCapabilities().get(Service.Lb);
+        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 " + this.getName());
+                        s_logger.debug("Scheme " + rules.get(0).getScheme() + " is not supported by the provider "
+                                + getName());
                         return false;
                     }
                 }
@@ -1313,35 +1575,17 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
     }
 
     @Override
-    public NetScalerServicePackageResponse deleteNetscalerServicePackage(RegisterServicePackageCmd cmd) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public NetScalerServicePackageResponse listNetscalerServicePackage(RegisterServicePackageCmd cmd) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public NetScalerServicePackageResponse createNetscalerServicePackageResponse(NetScalerServicePackageVO servicePackageVO) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
     @DB
     public NetScalerControlCenterVO registerNetscalerControlCenter(RegisterNetscalerControlCenterCmd cmd) {
 
         final RegisterNetscalerControlCenterCmd cmdinfo = cmd;
         String ipAddress = cmd.getIpaddress();
         Map hostDetails = new HashMap<String, String>();
-        String hostName =  "NetscalerControlCenter";
+        String hostName = "NetscalerControlCenter";
         hostDetails.put("name", hostName);
         hostDetails.put("guid", UUID.randomUUID().toString());
         List<DataCenterVO> dcVO = _dcDao.listEnabledZones();
-        if(dcVO.size() == 0) {
+        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");
@@ -1351,7 +1595,6 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         hostDetails.put("deviceName", "Netscaler ControlCenter");
         ServerResource resource = new NetScalerControlCenterResource();
         try {
-
             resource.configure(hostName, hostDetails);
             return Transaction.execute(new TransactionCallback<NetScalerControlCenterVO>() {
                 @Override
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerLoadBalancerElementService.java b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerLoadBalancerElementService.java
index 81c5b7c..c635f78 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerLoadBalancerElementService.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerLoadBalancerElementService.java
@@ -20,22 +20,61 @@ import java.util.List;
 
 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.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.response.NetscalerLoadBalancerResponse;
 import com.cloud.api.response.NetScalerServicePackageResponse;
+import com.cloud.api.response.NetscalerControlCenterResponse;
 import com.cloud.network.NetScalerControlCenterVO;
 import com.cloud.network.NetScalerServicePackageVO;
 import com.cloud.network.Network;
 import com.cloud.network.dao.ExternalLoadBalancerDeviceVO;
 import com.cloud.utils.component.PluggableService;
+import com.cloud.utils.exception.CloudRuntimeException;
 
 public interface NetscalerLoadBalancerElementService extends PluggableService {
 
     /**
+     * lists all Netscaler Control Center user Details
+     * @param ListNetscalerControlCenterCmd
+     * @return list of NetScalerControlCenterVO for Net Scaler Control Center which contains information about user and their network
+     * control center ID etc.
+     *
+     */
+    public List<NetScalerControlCenterVO> listNetscalerControlCenter(ListNetscalerControlCenterCmd cmd);
+
+    /**
+     * Lists all the list Registered Service Packages details in the Network.
+     * @param ListRegisteredServicePackageCmd
+     * @return list of NetScalerServicePackageVO for registered services in the network which contains details of services
+     */
+
+    public List<NetScalerServicePackageVO> listRegisteredServicePackages(ListRegisteredServicePackageCmd cmd);
+
+    /**
+     * Deletes Service Package Offering
+     *
+     * @param DeleteServicePackageOffering
+     * @return boolean value which tells deletion is successful or not.
+     */
+    public boolean deleteServicePackageOffering(DeleteServicePackageOfferingCmd cmd) throws CloudRuntimeException;
+
+    /**
+     * Deletes Netscaler Control Center if it is  not in use.
+     *
+     * @param (DeleteNetscalerControlCenter
+     * @return boolean value which tells deletion is successful or not.
+     */
+    public boolean deleteNetscalerControlCenter(DeleteNetscalerControlCenterCmd cmd) throws CloudRuntimeException;
+
+    /**
      * adds a Netscaler load balancer device in to a physical network
      * @param AddNetscalerLoadBalancerCmd
      * @return ExternalLoadBalancerDeviceVO object for the device added
@@ -84,6 +123,10 @@ public interface NetscalerLoadBalancerElementService extends PluggableService {
      */
     public NetScalerServicePackageResponse registerNetscalerServicePackage(RegisterServicePackageCmd cmd);
 
+    public NetscalerControlCenterResponse createNetscalerControlCenterResponse(NetScalerControlCenterVO lncCentersVO);
+
+    public NetScalerServicePackageResponse createRegisteredServicePackageResponse(NetScalerServicePackageVO lrsPackageVO);
+
     public NetScalerServicePackageResponse deleteNetscalerServicePackage(RegisterServicePackageCmd cmd);
 
     public NetScalerServicePackageResponse listNetscalerServicePackage(RegisterServicePackageCmd cmd);
@@ -91,4 +134,5 @@ public interface NetscalerLoadBalancerElementService extends PluggableService {
     public NetScalerServicePackageResponse createNetscalerServicePackageResponse(NetScalerServicePackageVO servicePackageVO);
 
     public NetScalerControlCenterVO registerNetscalerControlCenter(RegisterNetscalerControlCenterCmd registerNetscalerControlCenterCmd);
-}
+
+}
\ 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
index 15342dc..a8b3fbf 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetScalerControlCenterResource.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetScalerControlCenterResource.java
@@ -17,14 +17,12 @@
 package com.cloud.network.resource;
 
 import java.io.IOException;
-import java.io.StringWriter;
 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.Certificate;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
@@ -37,7 +35,6 @@ import java.util.Map;
 
 import javax.naming.ConfigurationException;
 
-import org.apache.commons.io.output.ByteArrayOutputStream;
 import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
@@ -56,7 +53,7 @@ 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.bouncycastle.openssl.PEMWriter;
+import org.json.JSONException;
 import org.json.JSONObject;
 
 import com.citrix.netscaler.nitro.exception.nitro_exception;
@@ -64,7 +61,6 @@ import com.citrix.netscaler.nitro.resource.base.base_response;
 import com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction;
 import com.citrix.netscaler.nitro.resource.config.autoscale.autoscalepolicy;
 import com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleprofile;
-import com.citrix.netscaler.nitro.resource.config.basic.server_service_binding;
 import com.citrix.netscaler.nitro.resource.config.basic.service_lbmonitor_binding;
 import com.citrix.netscaler.nitro.resource.config.basic.servicegroup;
 import com.citrix.netscaler.nitro.resource.config.basic.servicegroup_lbmonitor_binding;
@@ -100,7 +96,6 @@ import com.citrix.netscaler.nitro.service.nitro_service;
 import com.citrix.netscaler.nitro.util.filtervalue;
 import com.citrix.sdx.nitro.resource.config.ns.ns;
 import com.citrix.sdx.nitro.resource.config.xen.xen_nsvpx_image;
-import com.google.common.collect.Lists;
 import com.google.gson.Gson;
 
 import org.apache.cloudstack.api.ApiConstants;
@@ -144,7 +139,6 @@ import com.cloud.agent.api.to.LoadBalancerTO.StickinessPolicyTO;
 import com.cloud.agent.api.to.StaticNatRuleTO;
 import com.cloud.host.Host;
 import com.cloud.host.Host.Type;
-import com.cloud.network.lb.LoadBalancingRule.LbSslCert;
 import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType;
 import com.cloud.resource.ServerResource;
 import com.cloud.serializer.GsonHelper;
@@ -153,7 +147,6 @@ import com.cloud.utils.Pair;
 import com.cloud.utils.StringUtils;
 import com.cloud.utils.exception.ExecutionException;
 import com.cloud.utils.net.NetUtils;
-import com.cloud.utils.security.CertificateHelper;
 import com.cloud.utils.ssh.SshHelper;
 
 /*class NitroError {
@@ -178,6 +171,7 @@ public class NetScalerControlCenterResource implements ServerResource {
     private String _publicInterface;
     private String _privateInterface;
     private Integer _numRetries;
+    private Long _nccCmdTimeout;
     private String _guid;
     private boolean _inline;
     private boolean _isSdx;
@@ -194,7 +188,7 @@ public class NetScalerControlCenterResource implements ServerResource {
     protected Gson _gson;
     private final String _objectNamePathSep = "-";
     final String protocol="https";
-
+    private static String nccsession;
     // interface to interact with VPX and MPX devices
     com.citrix.netscaler.nitro.service.nitro_service _netscalerService;
 
@@ -207,6 +201,17 @@ public class NetScalerControlCenterResource implements ServerResource {
         _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;
@@ -221,11 +226,6 @@ public class NetScalerControlCenterResource implements ServerResource {
                 throw new ConfigurationException("Unable to find zone Id  in the configuration parameters");
             }
 
-/*            _physicalNetworkId = (String)params.get("physicalNetworkId");
-            if (_physicalNetworkId == null) {
-                throw new ConfigurationException("Unable to find physical network 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");
@@ -252,23 +252,25 @@ public class NetScalerControlCenterResource implements ServerResource {
             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
-            String response = login();
+            login();
+            /*String response =
             if(response == null) {
                 throw new ConfigurationException("No Response Received from the NetScalerControlCenter Device");
             } else {
                 jsonResponse = new JSONObject(response);
               org.json.JSONArray loginResponse = jsonResponse.getJSONArray("login");
-              //loginResponse.getJSONObject(0);
               _sessionid = jsonResponse.getJSONArray("login").getJSONObject(0).getString("sessionid");
-            }
-            // Make GET request with the new session to verify
-            s_logger.debug("Making Request to get all Service packages");
-            getServicePackages();
+            }*/
+
             return true;
-        } catch (Exception e) {
+        } 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.");
         }
     }
 
@@ -320,8 +322,9 @@ public class NetScalerControlCenterResource implements ServerResource {
         }
     }
 
-    private String login() throws ExecutionException {
+    private synchronized String login() throws ExecutionException{// , ConfigurationException {
         String result = null;
+        JSONObject jsonResponse = null;
         try {
             // If a previous session was open, log it out.
             //logout();
@@ -339,12 +342,26 @@ public class NetScalerControlCenterResource implements ServerResource {
             jsonBody.put("login", jsonCredentials);
 
             result = postHttpRequest(jsonBody.toString(), agentUri, _sessionid);
-            s_logger.debug("NCC Device got Added:: " + result);
+            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 ConfigurationException("Failed to add the device. Please check the device is NCC and It is reachable from Management Server.");
+                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());
         }
@@ -406,6 +423,75 @@ public class NetScalerControlCenterResource implements ServerResource {
         return new MaintainAnswer(cmd);
     }
 
+    private String queryAsyncJob(String jobId) {
+        String result = null;
+        try {
+            // If a previous session was open, log it out.
+            //logout();
+/*            Polling for async tasks:
+                URL: http://10.102.31.78/admin/v1/journalcontexts/ <job-id>
+                Rwsponse:
+
+                {
+                  "journalcontext": {
+                    "id": "ctxt-6cfd63ba-b4d2-413d-af2d-caa6f1dc5cd9",
+                    "start_time": "2015-07-16T09:47:50.596664",
+                    "end_time": "2015-07-16T09:47:50.636356",
+                    "name": "Update devices",
+                    "service_name": "admin",
+                    "is_default": false,
+                    "scopes": [],
+                    "status": "Finished",
+                    "message": "Done"
+                  }
+                }
+*/
+
+            URI agentUri = null;
+            //String url = protocol + "://" + _ip +"/nitro/v2/config/login";
+            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");
+                    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;
+                        //return status;
+                    case "ERROR, ROLLBACK_COMPLETED":
+                        break;
+                        //return status;
+                    case "ERROR, ROLLBACK_FAILED":
+                        break;
+                        //return status;
+                    }
+                }
+            }
+
+            //s_logger.debug("List of Service Packages in NCC:: " + result);
+            //return result;
+        } catch (URISyntaxException e) {
+            String errMsg = "Could not generate URI for NetScaler ControlCenter";
+            s_logger.error(errMsg, e);
+
+        } catch (Exception e) {
+            //throw new ExecutionException("Failed to log in to NCC device at " + _ip + " due to " + e.getMessage());
+        }
+        return result;
+    }
     private synchronized Answer execute(NetScalerImplementNetworkCommand cmd, int numRetries) {
         String result = null;
         try {
@@ -417,16 +503,35 @@ public class NetScalerControlCenterResource implements ServerResource {
             //url: <ip>/cs/cca/networks
             agentUri =
                     new URI("https", null, _ip, DEFAULT_PORT,
-                            "/cs/cca/networks", null, null);
+                            "/cs/cca/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);
-            //return 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 Hyper-V agent";
+                String errMsg = "Could not generate URI for NetScaler ControlCenter ";
                 s_logger.error(errMsg, e);
+            } catch (ExecutionException e) {
+                if(e.getMessage().equalsIgnoreCase("NOTFOUND")) {
+                    return new Answer(cmd, true, "Successfully unallocated the device");
+                } 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);
@@ -539,8 +644,16 @@ public class NetScalerControlCenterResource implements ServerResource {
             if (loadBalancers == null) {
                 return new Answer(cmd);
             }
+            JSONObject jsonCmd = new JSONObject(cmd);
+            URI agentUri = null;
+            //String url = protocol + "://" + _ip +"/nitro/v2/config/login";
+            agentUri =
+                    new URI("https", null, _ip, DEFAULT_PORT,
+                            "/nitro/v2/config/" + "login", null, null);
 
-            for (LoadBalancerTO loadBalancer : loadBalancers) {
+            s_logger.debug("LB config cmd: " + jsonCmd.toString());
+            String result = postHttpRequest(jsonCmd.toString(), agentUri, _sessionid);
+            /*for (LoadBalancerTO loadBalancer : loadBalancers) {
                 String srcIp = loadBalancer.getSrcIp();
                 int srcPort = loadBalancer.getSrcPort();
                 String lbProtocol = getNetScalerProtocol(loadBalancer);
@@ -565,305 +678,11 @@ public class NetScalerControlCenterResource implements ServerResource {
                     }
                 }
 
-                if (!loadBalancer.isRevoked() && destinationsToAdd) {
-
-                    // create a load balancing virtual server
-                    addLBVirtualServer(nsVirtualServerName, srcIp, srcPort, lbAlgorithm, lbProtocol, loadBalancer.getStickinessPolicies(), null);
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Created load balancing virtual server " + nsVirtualServerName + " on the Netscaler device");
-                    }
-
-                    // create a new monitor
-                    HealthCheckPolicyTO[] healthCheckPolicies = loadBalancer.getHealthCheckPolicies();
-                    if ((healthCheckPolicies != null) && (healthCheckPolicies.length > 0) && (healthCheckPolicies[0] != null)) {
-
-                        for (HealthCheckPolicyTO healthCheckPolicyTO : healthCheckPolicies) {
-                            if (!healthCheckPolicyTO.isRevoked()) {
-                                addLBMonitor(nsMonitorName, lbProtocol, healthCheckPolicyTO);
-                                hasMonitor = true;
-                            } else {
-                                deleteMonitor = true;
-                                hasMonitor = false;
-                            }
-                        }
-
-                    }
-
-                    for (DestinationTO destination : loadBalancer.getDestinations()) {
-
-                        String nsServerName = generateNSServerName(destination.getDestIp());
-                        String nsServiceName = generateNSServiceName(destination.getDestIp(), destination.getDestPort());
-                        if (!destination.isRevoked()) {
-                            // add a new destination to deployed load balancing rule
-
-                            // add a new server
-                            if (!nsServerExists(nsServerName)) {
-                                com.citrix.netscaler.nitro.resource.config.basic.server nsServer = new com.citrix.netscaler.nitro.resource.config.basic.server();
-                                nsServer.set_name(nsServerName);
-                                nsServer.set_ipaddress(destination.getDestIp());
-                                apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.add(_netscalerService, nsServer);
-                                if ((apiCallResult.errorcode != 0) && (apiCallResult.errorcode != NitroError.NS_RESOURCE_EXISTS)) {
-                                    throw new ExecutionException("Failed to add server " + destination.getDestIp() + " due to" + apiCallResult.message);
-                                }
-                            }
-
-                            // create a new service using the server added
-                            if (!nsServiceExists(nsServiceName)) {
-                                com.citrix.netscaler.nitro.resource.config.basic.service newService = new com.citrix.netscaler.nitro.resource.config.basic.service();
-                                newService.set_name(nsServiceName);
-                                newService.set_port(destination.getDestPort());
-                                newService.set_servername(nsServerName);
-                                newService.set_state("ENABLED");
-                                if(lbProtocol.equalsIgnoreCase(NetUtils.SSL_PROTO)) {
-                                    newService.set_servicetype(NetUtils.HTTP_PROTO);
-                                } else {
-                                    newService.set_servicetype(lbProtocol);
-                                }
-
-                                apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.service.add(_netscalerService, newService);
-                                if (apiCallResult.errorcode != 0) {
-                                    throw new ExecutionException("Failed to create service " + nsServiceName + " using server " + nsServerName + " due to" +
-                                            apiCallResult.message);
-                                }
-                            }
-
-                            //bind service to load balancing virtual server
-                            if (!nsServiceBindingExists(nsVirtualServerName, nsServiceName)) {
-                                com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding svcBinding =
-                                        new com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding();
-                                svcBinding.set_name(nsVirtualServerName);
-                                svcBinding.set_servicename(nsServiceName);
-                                apiCallResult = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.add(_netscalerService, svcBinding);
-
-                                if (apiCallResult.errorcode != 0) {
-                                    throw new ExecutionException("Failed to bind service: " + nsServiceName + " to the lb virtual server: " + nsVirtualServerName +
-                                            " on Netscaler device");
-                                }
-                            }
-
-                            // After binding the service to the LB Vserver
-                            // successfully, bind the created monitor to the
-                            // service.
-                            if (hasMonitor) {
-                                if (!isServiceBoundToMonitor(nsServiceName, nsMonitorName)) {
-                                    bindServiceToMonitor(nsServiceName, nsMonitorName);
-                                }
-                            } else {
-                                // check if any monitor created by CS is already
-                                // existing, if yes, unbind it from services and
-                                // delete it.
-                                if (nsMonitorExist(nsMonitorName)) {
-                                    // unbind the service from the monitor and
-                                    // delete the monitor
-                                    unBindServiceToMonitor(nsServiceName, nsMonitorName);
-                                    deleteMonitor = true;
-                                }
-
-                            }
-
-                            if (sslCert != null && lbProtocol.equalsIgnoreCase(NetUtils.SSL_PROTO)) {
-                                if (sslCert.isRevoked()) {
-                                    deleteCert = true;
-                                } else {
-
-                                    // If there is a chain, that should go first to the NS
-
-                                    String previousCertKeyName = null;
-
-                                    if (sslCert.getChain() != null) {
-                                        List<Certificate> chainList = CertificateHelper.parseChain(sslCert.getChain());
-                                        // go from ROOT to intermediate CAs
-                                        for (Certificate intermediateCert : Lists.reverse(chainList)) {
-
-                                            String fingerPrint = CertificateHelper.generateFingerPrint(intermediateCert);
-                                            String intermediateCertKeyName = generateSslCertKeyName(fingerPrint);
-                                            String intermediateCertFileName = intermediateCertKeyName + ".pem";
-
-                                            if (!SSL.isSslCertKeyPresent(_netscalerService, intermediateCertKeyName)) {
-                                                intermediateCert.getEncoded();
-                                                StringWriter textWriter = new StringWriter();
-                                                PEMWriter pemWriter = new PEMWriter(textWriter);
-                                                pemWriter.writeObject(intermediateCert);
-                                                pemWriter.flush();
-
-                                                SSL.uploadCert(_ip, _username, _password, intermediateCertFileName, textWriter.toString().getBytes());
-                                                SSL.createSslCertKey(_netscalerService, intermediateCertFileName, null, intermediateCertKeyName, null);
-                                            }
-
-                                            if (previousCertKeyName != null && !SSL.certLinkExists(_netscalerService, intermediateCertKeyName, previousCertKeyName)) {
-                                                SSL.linkCerts(_netscalerService, intermediateCertKeyName, previousCertKeyName);
-                                            }
-
-                                            previousCertKeyName = intermediateCertKeyName;
-                                        }
-                                    }
-
-                                    String certFilename = generateSslCertName(sslCert.getFingerprint()) + ".pem"; //netscaler uses ".pem" format for "bundle" files
-                                    String keyFilename = generateSslKeyName(sslCert.getFingerprint()) + ".pem"; //netscaler uses ".pem" format for "bundle" files
-                                    String certKeyName = generateSslCertKeyName(sslCert.getFingerprint());
-
-                                    ByteArrayOutputStream certDataStream = new ByteArrayOutputStream();
-                                    certDataStream.write(sslCert.getCert().getBytes());
-
-                                    if (!SSL.isSslCertKeyPresent(_netscalerService, certKeyName)) {
-
-                                        SSL.uploadCert(_ip, _username, _password, certFilename, certDataStream.toByteArray());
-                                        SSL.uploadKey(_ip, _username, _password, keyFilename, sslCert.getKey().getBytes());
-                                        SSL.createSslCertKey(_netscalerService, certFilename, keyFilename, certKeyName, sslCert.getPassword());
-                                    }
-
-                                    if (previousCertKeyName != null && !SSL.certLinkExists(_netscalerService, certKeyName, previousCertKeyName)) {
-                                        SSL.linkCerts(_netscalerService, certKeyName, previousCertKeyName);
-                                    }
-
-                                    SSL.bindCertKeyToVserver(_netscalerService, certKeyName, nsVirtualServerName);
-                                }
-
-                            }
-
-                            if (s_logger.isDebugEnabled()) {
-                                s_logger.debug("Successfully added LB destination: " + destination.getDestIp() + ":" + destination.getDestPort() + " to load balancer " +
-                                        srcIp + ":" + srcPort);
-                            }
-
-                        } else {
-                            // remove a destination from the deployed load balancing rule
-                            com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding[] serviceBindings =
-                                    com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.get(_netscalerService, nsVirtualServerName);
-                            if (serviceBindings != null) {
-                                for (com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding binding : serviceBindings) {
-                                    if (nsServiceName.equalsIgnoreCase(binding.get_servicename())) {
-                                        // delete the binding
-                                        apiCallResult = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.delete(_netscalerService, binding);
-                                        if (apiCallResult.errorcode != 0) {
-                                            throw new ExecutionException("Failed to delete the binding between the virtual server: " + nsVirtualServerName +
-                                                    " and service:" + nsServiceName + " due to" + apiCallResult.message);
-                                        }
-
-                                        // check if service is bound to any other virtual server
-                                        if (!isServiceBoundToVirtualServer(nsServiceName)) {
-                                            // no lb virtual servers are bound to this service so delete it
-                                            apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.service.delete(_netscalerService, nsServiceName);
-                                            if (apiCallResult.errorcode != 0) {
-                                                throw new ExecutionException("Failed to delete service: " + nsServiceName + " due to " + apiCallResult.message);
-                                            }
-                                        }
-
-                                        // delete the server if there is no associated services
-                                        server_service_binding[] services = server_service_binding.get(_netscalerService, nsServerName);
-                                        if ((services == null) || (services.length == 0)) {
-                                            apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.delete(_netscalerService, nsServerName);
-                                            if (apiCallResult.errorcode != 0) {
-                                                throw new ExecutionException("Failed to remove server:" + nsServerName + " due to " + apiCallResult.message);
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                } else {
-                    // delete the implemented load balancing rule and its destinations
-                    lbvserver lbserver = getVirtualServerIfExisits(nsVirtualServerName);
-                    if (lbserver != null) {
-                        //unbind the all services associated with this virtual server
-                        com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding[] serviceBindings =
-                                com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.get(_netscalerService, nsVirtualServerName);
-
-                        if (serviceBindings != null) {
-                            for (com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding binding : serviceBindings) {
-                                String serviceName = binding.get_servicename();
-                                apiCallResult = com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.delete(_netscalerService, binding);
-                                if (apiCallResult.errorcode != 0) {
-                                    throw new ExecutionException("Failed to unbind service from the lb virtual server: " + nsVirtualServerName + " due to " +
-                                            apiCallResult.message);
-                                }
-
-                                com.citrix.netscaler.nitro.resource.config.basic.service svc =
-                                        com.citrix.netscaler.nitro.resource.config.basic.service.get(_netscalerService, serviceName);
-                                String nsServerName = svc.get_servername();
-
-                                // check if service is bound to any other virtual server
-                                if (!isServiceBoundToVirtualServer(serviceName)) {
-                                    // no lb virtual servers are bound to this service so delete it
-                                    apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.service.delete(_netscalerService, serviceName);
-                                    if (apiCallResult.errorcode != 0) {
-                                        throw new ExecutionException("Failed to delete service: " + serviceName + " due to " + apiCallResult.message);
-                                    }
-                                }
-
-                                //delete the server if no more services attached
-                                server_service_binding[] services = server_service_binding.get(_netscalerService, nsServerName);
-                                if ((services == null) || (services.length == 0)) {
-                                    apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.delete(_netscalerService, nsServerName);
-                                    if (apiCallResult.errorcode != 0) {
-                                        throw new ExecutionException("Failed to remove server:" + nsServerName + " due to " + apiCallResult.message);
-                                    }
-                                }
-                            }
-                        }
-                        removeLBVirtualServer(nsVirtualServerName);
-                        deleteMonitor = true;
-                        deleteCert = true;
-                    }
-                }
-                if (deleteMonitor) {
-                    removeLBMonitor(nsMonitorName);
-                }
-                if (sslCert != null && deleteCert) {
-
-                    String certFilename = generateSslCertName(sslCert.getFingerprint()) + ".pem"; //netscaler uses ".pem" format for "bundle" files
-                    String keyFilename = generateSslKeyName(sslCert.getFingerprint()) + ".pem"; //netscaler uses ".pem" format for "bundle" files
-                    String certKeyName = generateSslCertKeyName(sslCert.getFingerprint());
-
-                    // unbind before deleting
-                    if (nsVirtualServerExists(nsVirtualServerName) &&
-                            SSL.isSslCertKeyPresent(_netscalerService, certKeyName) &&
-                            SSL.isBoundToVserver(_netscalerService, certKeyName, nsVirtualServerName)) {
-                        SSL.unbindCertKeyFromVserver(_netscalerService, certKeyName, nsVirtualServerName);
-                    }
-
-                    if (SSL.isSslCertKeyPresent(_netscalerService, certKeyName)) {
-
-                        SSL.deleteSslCertKey(_netscalerService, certKeyName);
-                        SSL.deleteCertFile(_ip, _username, _password, certFilename);
-                        SSL.deleteKeyFile(_ip, _username, _password, keyFilename);
-                    }
-
-                    /*
-                     * Check and delete intermediate certs:
-                     * we can delete an intermediate cert if no other
-                     * cert references it as the athority
-                     */
-
-                    if (sslCert.getChain() != null) {
-                        List<Certificate> chainList = CertificateHelper.parseChain(sslCert.getChain());
-                        //go from intermediate CAs to ROOT
-                        for (Certificate intermediateCert : chainList) {
-
-                            String fingerPrint = CertificateHelper.generateFingerPrint(intermediateCert);
-                            String intermediateCertKeyName = generateSslCertKeyName(fingerPrint);
-                            String intermediateCertFileName = intermediateCertKeyName + ".pem";
-
-                            if (SSL.isSslCertKeyPresent(_netscalerService, intermediateCertKeyName) &&
-                                    !SSL.isCaforCerts(_netscalerService, intermediateCertKeyName)) {
-                                SSL.deleteSslCertKey(_netscalerService, intermediateCertKeyName);
-                                SSL.deleteCertFile(_ip, _username, _password, intermediateCertFileName);
-                            } else {
-                                break;// if this cert has another certificate as a child then stop at this point because we need the whole chain
-                            }
-
-                        }
-                    }
-                }
-
-            }
-
             if (s_logger.isInfoEnabled()) {
                 s_logger.info("Successfully executed resource LoadBalancerConfigCommand: " + _gson.toJson(cmd));
-            }
+            }*/
 
-            saveConfiguration();
+            //saveConfiguration();
             return new Answer(cmd);
         } catch (ExecutionException e) {
             s_logger.error("Failed to execute LoadBalancerConfigCommand due to ", e);
@@ -3641,13 +3460,23 @@ public class NetScalerControlCenterResource implements ServerResource {
     }
 
     private boolean shouldRetry(int numRetries) {
+        //JSONObject jsonResponse = null;
         try {
             if (numRetries > 0) {
                 login();
+                /*if (response == null) {
+                    throw new ConfigurationException("No Response Received from the NetScalerControlCenter Device");
+                } else {
+                    jsonResponse = new JSONObject(response);
+                    org.json.JSONArray loginResponse = jsonResponse.getJSONArray("login");
+                    _sessionid = jsonResponse.getJSONArray("login").getJSONObject(0).getString("sessionid");
+                }*/
                 return true;
             }
         } catch (Exception e) {
-            s_logger.error("Failed to log in to Netscaler device at " + _ip + " due to " + e.getMessage());
+            s_logger.error("Failed to log in to Netscaler ControlCenter device at " + _ip + " due to " + e.getMessage());
+            return false;
+            //throw new ConfigurationException("No Response Received from the NetScalerControlCenter Device");
         }
         return false;
     }
@@ -3766,8 +3595,22 @@ public class NetScalerControlCenterResource implements ServerResource {
         return null;
     }
 
+    private boolean refreshNCCConnection() {
+        boolean ret = false;
+        try {
+            login();
+            return true;
+        } catch (ExecutionException ex) {
+            s_logger.error("Login to NCC failed", ex);
+        }
+        return ret;
+    }
+
     @Override
     public PingCommand getCurrentStatus(long id) {
+        /*if (!refreshNCCConnection()) {
+            return null;
+        }*/
         return new PingCommand(Host.Type.NetScalerControlCenter, id);
     }
 
@@ -3881,7 +3724,7 @@ public class NetScalerControlCenterResource implements ServerResource {
         return httpClient;
     }
 
-    public static String getHttpRequest(final String jsonCmd, final URI agentUri, String sessionID) {
+    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
@@ -3923,7 +3766,8 @@ public class NetScalerControlCenterResource implements ServerResource {
             } 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);
-                return null;
+                throw new ExecutionException("UNAUTHORIZED");
+                //return null;
             } else {
                 result = EntityUtils.toString(response.getEntity());
                 String logResult = cleanPassword(StringEscapeUtils.unescapeJava(result));
@@ -3941,7 +3785,7 @@ public class NetScalerControlCenterResource implements ServerResource {
         return result;
     }
 
-    public static String postHttpRequest(final String jsonCmd, final URI agentUri, String sessionID) {
+    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
@@ -3954,7 +3798,7 @@ public class NetScalerControlCenterResource implements ServerResource {
 
         // Create request
         HttpClient httpClient = getHttpClient();
-/*        TrustStrategy easyStrategy = new TrustStrategy() {
+        TrustStrategy easyStrategy = new TrustStrategy() {
             @Override
             public boolean isTrusted(X509Certificate[] chain, String authType)
                     throws CertificateException {
@@ -3977,7 +3821,7 @@ public class NetScalerControlCenterResource implements ServerResource {
         } 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?
@@ -3998,15 +3842,25 @@ public class NetScalerControlCenterResource implements ServerResource {
             // 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);
+                throw new ExecutionException("NOT_FOUND");
+                /*s_logger.error(errMsg);
                 String unsupportMsg = "Unsupported command " + agentUri.getPath() + ".  Are you sure you got the right type 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) {
+                s_logger.error(ans);*/
+                //result = s_gson.toJson(new Answer[] {ans});
+            } else if ((response.getStatusLine().getStatusCode() != HttpStatus.SC_OK ) && (response.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED )) {
                 String errMsg = "Failed send to " + agentUri.toString() + " : HTTP error code : " + response.getStatusLine().getStatusCode();
                 s_logger.error(errMsg);
-                return null;
+                throw new ExecutionException("UNAUTHORIZED");
+                //return null;
+            } 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("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("Job_id").getValue();
+                //"jobid : " +
             } else {
                 result = EntityUtils.toString(response.getEntity());
                 String logResult = cleanPassword(StringEscapeUtils.unescapeJava(result));
diff --git a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
index f417283..85eda6b 100644
--- a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
+++ b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
@@ -53,6 +53,7 @@ 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;
@@ -63,6 +64,7 @@ import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.host.DetailVO;
 import com.cloud.host.Host;
 import com.cloud.host.HostVO;
+import com.cloud.host.Host.Type;
 import com.cloud.host.dao.HostDao;
 import com.cloud.host.dao.HostDetailsDao;
 import com.cloud.network.Network.Provider;
@@ -101,6 +103,7 @@ 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;
@@ -864,6 +867,21 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
         return nic;
     }
 
+    private boolean isNccServiceProvider(Network network) {
+        NetworkOffering networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
+        if(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
@@ -874,13 +892,21 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
             return true;
         }
 
-        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;
+        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());
+            }
         }
 
-        HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
+
 
         boolean externalLoadBalancerIsInline = _networkMgr.isNetworkInlineMode(network);
 
@@ -900,6 +926,13 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
             String algorithm = rule.getAlgorithm();
             String uuid = rule.getUuid();
             String srcIp = rule.getSourceIp().addr();
+            String srcIpVlan = null;
+            //IpAddress ipAddress =  _networkModel.getPublicIpAddress(rule.getSourceIp().addr(), network.getDataCenterId()).getVlanId();
+            Long vlanid =  _networkModel.getPublicIpAddress(rule.getSourceIp().addr(), network.getDataCenterId()).getVlanId();
+            if(vlanid != null ) {
+              VlanVO publicVlan =   _vlanDao.findById(vlanid);
+              srcIpVlan =  publicVlan.getVlanTag();
+            }
             int srcPort = rule.getSourcePortStart();
             List<LbDestination> destinations = rule.getDestinations();
 
@@ -921,6 +954,8 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
                 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);
                 if (rule.isAutoScaleConfig()) {
                     loadBalancer.setAutoScaleVmGroup(rule.getAutoScaleVmGroup());
                 }
diff --git a/server/src/com/cloud/network/IpAddressManagerImpl.java b/server/src/com/cloud/network/IpAddressManagerImpl.java
index 8068421..d950cc4 100644
--- a/server/src/com/cloud/network/IpAddressManagerImpl.java
+++ b/server/src/com/cloud/network/IpAddressManagerImpl.java
@@ -29,8 +29,11 @@ import java.util.UUID;
 
 import javax.inject.Inject;
 
+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;
@@ -40,7 +43,6 @@ 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 org.apache.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.alert.AlertManager;
@@ -51,6 +53,8 @@ import com.cloud.dc.AccountVlanMapVO;
 import com.cloud.dc.DataCenter;
 import com.cloud.dc.DataCenter.NetworkType;
 import com.cloud.dc.DomainVlanMapVO;
+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;
@@ -58,8 +62,10 @@ 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;
@@ -279,6 +285,10 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
     PortableIpDao _portableIpDao;
     @Inject
     VpcDao _vpcDao;
+    @Inject
+    DataCenterIpAddressDao _privateIPAddressDao;
+    HostPodDao _hpDao;
+
     SearchBuilder<IPAddressVO> AssignIpAddressSearch;
     SearchBuilder<IPAddressVO> AssignIpAddressFromPodVlanSearch;
 
@@ -401,7 +411,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
         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);
+                JoinType.INNER);
         AssignIpAddressFromPodVlanSearch.join("vlan", podVlanSearch, podVlanSearch.entity().getId(), AssignIpAddressFromPodVlanSearch.entity().getVlanId(), JoinType.INNER);
         AssignIpAddressFromPodVlanSearch.done();
 
@@ -417,7 +427,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
     }
 
     private IpAddress allocateIP(Account ipOwner, boolean isSystem, long zoneId) throws ResourceAllocationException, InsufficientAddressCapacityException,
-        ConcurrentOperationException {
+            ConcurrentOperationException {
         Account caller = CallContext.current().getCallingAccount();
         long callerUserId = CallContext.current().getCallingUserId();
         // check permissions
@@ -492,7 +502,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
 
     @Override
     public boolean applyRules(List<? extends FirewallRule> rules, FirewallRule.Purpose purpose, NetworkRuleApplier applier, boolean continueOnError)
-        throws ResourceUnavailableException {
+            throws ResourceUnavailableException {
         if (rules == null || rules.size() == 0) {
             s_logger.debug("There are no rules to forward to the network elements");
             return true;
@@ -641,21 +651,21 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
             return Transaction.execute(new TransactionCallback<Boolean>() {
                 @Override
                 public Boolean doInTransaction(TransactionStatus status) {
-            portableIpLock.lock(5);
-            IPAddressVO ip = _ipAddressDao.findById(addrId);
+                    portableIpLock.lock(5);
+                    IPAddressVO ip = _ipAddressDao.findById(addrId);
 
-            // unassign portable IP
-            PortableIpVO portableIp = _portableIpDao.findByIpAddress(ip.getAddress().addr());
-            _portableIpDao.unassignIpAddress(portableIp.getId());
+                    // 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());
+                    // removed the provisioned vlan
+                    VlanVO vlan = _vlanDao.findById(ip.getVlanId());
+                    _vlanDao.remove(vlan.getId());
 
-            // remove the provisioned public ip address
-            _ipAddressDao.remove(ip.getId());
+                    // remove the provisioned public ip address
+                    _ipAddressDao.remove(ip.getId());
 
-            return true;
+                    return true;
                 }
             });
         } finally {
@@ -665,20 +675,20 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
 
     @Override
     public PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, boolean isSystem)
-        throws InsufficientAddressCapacityException {
+            throws InsufficientAddressCapacityException {
         return fetchNewPublicIp(dcId, podId, null, owner, type, networkId, false, true, requestedIp, isSystem, null, null);
     }
 
     @Override
     public PublicIp assignPublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List<Long> vlanDbIds, Long networkId, String requestedIp, boolean isSystem)
-        throws InsufficientAddressCapacityException {
+            throws InsufficientAddressCapacityException {
         return fetchNewPublicIp(dcId, podId, vlanDbIds, owner, type, networkId, false, true, requestedIp, isSystem, null, null);
     }
 
     @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)
-            throws InsufficientAddressCapacityException {
+                    throws InsufficientAddressCapacityException {
         IPAddressVO addr = Transaction.execute(new TransactionCallbackWithException<IPAddressVO, InsufficientAddressCapacityException>() {
             @Override
             public IPAddressVO doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException {
@@ -709,11 +719,6 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                             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()))
@@ -722,10 +727,10 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                 if (dedicatedVlanDbIds != null && !dedicatedVlanDbIds.isEmpty()) {
                     fetchFromDedicatedRange = true;
                     sc.setParameters("vlanId", dedicatedVlanDbIds.toArray());
-                            errorMessage.append(", vlanId id=" + Arrays.toString(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()));
+                    errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray()));
                 } else {
                     if (podId != null) {
                         InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId);
@@ -763,7 +768,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                     if (useSystemIps && nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
                         fetchFromDedicatedRange = false;
                         sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
-                                errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray()));
+                        errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray()));
                         addrs = _ipAddressDao.lockRows(sc, filter, true);
                     }
                 }
@@ -781,7 +786,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                     throw ex;
                 }
 
-                assert (addrs.size() == 1) : "Return size is incorrect: " + addrs.size();
+                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
@@ -835,29 +840,30 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
         Transaction.execute(new TransactionCallbackNoReturn() {
             @Override
             public void doInTransactionWithoutResult(TransactionStatus status) {
-            Account owner = _accountMgr.getAccount(addr.getAllocatedToAccountId());
-            synchronized (this) {
-                if (_ipAddressDao.lockRow(addr.getId(),true) != null) {
-                    IPAddressVO userIp = _ipAddressDao.findById(addr.getId());
-                    if (userIp.getState() == IpAddress.State.Allocating || addr.getState() == IpAddress.State.Free) {
-                        addr.setState(IpAddress.State.Allocated);
-                        _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);
+                Account owner = _accountMgr.getAccount(addr.getAllocatedToAccountId());
+                synchronized (this) {
+                    if (_ipAddressDao.lockRow(addr.getId(), true) != null) {
+                        IPAddressVO userIp = _ipAddressDao.findById(addr.getId());
+                        if (userIp.getState() == IpAddress.State.Allocating || addr.getState() == IpAddress.State.Free) {
+                            addr.setState(IpAddress.State.Allocated);
+                            _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);
+                                }
                             }
                         }
                     }
                 }
             }
-        }
         });
     }
 
@@ -870,8 +876,8 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
 
     @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?";
+        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());
@@ -900,15 +906,15 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                 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");
-            }
+                    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);
@@ -919,10 +925,10 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                     }
 
                     PublicIp ip = fetchNewPublicIp(dcId, null, null, owner, VlanType.VirtualNetwork, guestNtwkId, isSourceNat, false, null, false, vpcId, displayIp);
-            IPAddressVO publicIp = ip.ip();
+                    IPAddressVO publicIp = ip.ip();
 
-            markPublicIpAsAllocated(publicIp);
-            _ipAddressDao.update(publicIp.getId(), publicIp);
+                    markPublicIpAsAllocated(publicIp);
+                    _ipAddressDao.update(publicIp.getId(), publicIp);
 
                     return ip;
                 }
@@ -974,7 +980,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
     // 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 {
+            throws ResourceUnavailableException {
         boolean success = true;
 
         Map<PublicIpAddress, Set<Service>> ipToServices = _networkModel.getIpToServices(publicIps, postApplyRules, true);
@@ -1018,9 +1024,72 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
 
     @DB
     @Override
+    public AcquirePodIpCmdResponse allocatePodIp(Long zoneId, String cidr) throws ConcurrentOperationException, ResourceAllocationException {
+
+        DataCenter zone = _entityMgr.findById(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 (cidr != null) {
+            List<HostPodVO> pod_list = _hpDao.listAllPodsByCidr(zoneId, cidr);
+            if (pod_list.get(0) == null)
+                throw new ResourceAllocationException("No sush pod exists", ResourceType.network);
+            vo = _privateIPAddressDao.takeIpAddress(zoneId, pod_list.get(0).getId(), 0, caller.getId() + "");
+            if (vo.getIpAddress() == null)
+                throw new ResourceAllocationException("Unable to allocate IP from this Pod", ResourceType.network);
+        } else
+            vo = _privateIPAddressDao.takeDataCenterIpAddress(zoneId, caller.getId() + "");
+
+        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 {
+            ResourceAllocationException, InsufficientAddressCapacityException {
 
         final VlanType vlanType = VlanType.VirtualNetwork;
         final boolean assign = false;
@@ -1054,16 +1123,17 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                 public PublicIp doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException {
                     PublicIp ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, null, false, assign, null, isSystem, null, displayIp);
 
-            if (ip == null) {
+                    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();
+                        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());
+                    s_logger.debug("Got " + ipAddress + " to assign for account " + ipOwner.getId() + " in zone " + zone.getId());
 
                     return ip;
                 }
@@ -1098,40 +1168,40 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                 public IPAddressVO doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException {
                     PortableIpVO allocatedPortableIp;
 
-            List<PortableIpVO> portableIpVOs = _portableIpDao.listByRegionIdAndState(1, PortableIp.State.Free);
-            if (portableIpVOs == null || portableIpVOs.isEmpty()) {
+                    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;
-            }
+                        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();
+                    // 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);
+                    vlan = _vlanDao.persist(vlan);
 
-            // provision the portable IP in to user_ip_address table
+                    // 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);
+                    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());
@@ -1168,7 +1238,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                 }
             }
 
-            assert (sourceNatIp != null) : "How do we get a bunch of ip addresses but none of them are source nat? " + "account=" + ownerId + "; networkId=" + networkId;
+            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;
@@ -1177,7 +1247,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
     @DB
     @Override
     public IPAddressVO associateIPToGuestNetwork(long ipId, long networkId, boolean releaseOnFailure) throws ResourceAllocationException, ResourceUnavailableException,
-        InsufficientAddressCapacityException, ConcurrentOperationException {
+            InsufficientAddressCapacityException, ConcurrentOperationException {
         Account caller = CallContext.current().getCallingAccount();
         Account owner = null;
 
@@ -1196,7 +1266,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                                 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");
+                                + "network services Source Nat, Static Nat, Port Forwarding, Load balancing, firewall are enabled in the network");
                     }
                 }
             } else {
@@ -1307,7 +1377,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                         || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.StaticNat)
                         || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.Firewall)
                         || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.PortForwarding) || _networkModel.areServicesSupportedByNetworkOffering(
-                        networkOfferingId, Service.Lb))) {
+                                networkOfferingId, Service.Lb))) {
             return true;
         }
         return false;
@@ -1315,14 +1385,14 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
 
     @Override
     public IPAddressVO associatePortableIPToGuestNetwork(long ipAddrId, long networkId, boolean releaseOnFailure) throws ResourceAllocationException, ResourceUnavailableException,
-        InsufficientAddressCapacityException, ConcurrentOperationException {
+            InsufficientAddressCapacityException, ConcurrentOperationException {
         return associateIPToGuestNetwork(ipAddrId, networkId, releaseOnFailure);
     }
 
     @DB
     @Override
     public IPAddressVO disassociatePortableIPToGuestNetwork(long ipId, long networkId) throws ResourceAllocationException, ResourceUnavailableException,
-        InsufficientAddressCapacityException, ConcurrentOperationException {
+            InsufficientAddressCapacityException, ConcurrentOperationException {
 
         Account caller = CallContext.current().getCallingAccount();
         Account owner = null;
@@ -1346,7 +1416,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
             DataCenter zone = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
             if (zone.getNetworkType() == NetworkType.Advanced) {
                 if (network.getGuestType() == Network.GuestType.Shared) {
-                    assert (isSharedNetworkOfferingWithServices(network.getNetworkOfferingId()));
+                    assert(isSharedNetworkOfferingWithServices(network.getNetworkOfferingId()));
                     _accountMgr.checkAccess(CallContext.current().getCallingAccount(), AccessType.UseEntry, false,
                             network);
                 }
@@ -1430,7 +1500,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
     @DB
     @Override
     public void transferPortableIP(final long ipAddrId, long currentNetworkId, long newNetworkId) throws ResourceAllocationException, ResourceUnavailableException,
-        InsufficientAddressCapacityException, ConcurrentOperationException {
+            InsufficientAddressCapacityException, ConcurrentOperationException {
 
         Network srcNetwork = _networksDao.findById(currentNetworkId);
         if (srcNetwork == null) {
@@ -1447,7 +1517,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
             throw new InvalidParameterValueException("Invalid portable ip address id is given");
         }
 
-        assert (isPortableIpTransferableFromNetwork(ipAddrId, currentNetworkId));
+        assert(isPortableIpTransferableFromNetwork(ipAddrId, currentNetworkId));
 
         // disassociate portable IP with current network/VPC network
         if (srcNetwork.getVpcId() != null) {
@@ -1462,19 +1532,19 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
             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);
+                    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);
                 }
             });
         }
@@ -1483,22 +1553,24 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
         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);
-        }
+                if (dstNetwork.getVpcId() != null) {
+                    ip.setVpcId(dstNetwork.getVpcId());
+                } else {
+                    ip.setVpcId(null);
+                }
 
-        _ipAddressDao.update(ipAddrId, ip);
+                _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);
+                "Portable IP associated is transferred from network " + currentNetworkId + " to " + newNetworkId);
     }
 
     protected List<? extends Network> getIsolatedNetworksWithSourceNATOwnedByAccountInZone(long zoneId, Account owner) {
@@ -1525,30 +1597,30 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                     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");
-            }
-        }
+                    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) {
+                    // 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) {
+                    }
+                    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());
                             }
@@ -1557,44 +1629,44 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                                     + " as a part of createVlanIpRange process");
                             guestNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName()
                                     + "-network", null, null, null, null, owner, null, physicalNetwork, zoneId, ACLType.Account, null, null, null, null, true, null);
-                if (guestNetwork == null) {
-                    s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId);
+                            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);
-            }
-        }
+                            }
+                        } 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;
-        }
+                    // 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);
-            }
-        }
+                    // 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);
                 }
             });
@@ -1629,7 +1701,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
             } 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");
+                        + " elements and resources as a part of network provision for persistent network");
                 e.addProxyObject(guestNetwork.getUuid(), "networkId");
                 throw e;
             }
@@ -1652,20 +1724,20 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                 @Override
                 public IPAddressVO doInTransaction(TransactionStatus status) {
                     if (updateIpResourceCount(ip)) {
-                _resourceLimitMgr.decrementResourceCount(_ipAddressDao.findById(addrId).getAllocatedToAccountId(), ResourceType.public_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());
+                    // 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;
+                        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);
                 }
@@ -1880,80 +1952,77 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
         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);
-                    }
-                }
+                //This method allocates direct ip for the Shared network in Advance zones
+                boolean ipv4 = false;
 
-                if (ip == null) {
-                    ip = assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.DirectAttached, network.getId(), requestedIpv4, false);
-                }
+                if (network.getGateway() != null) {
+                    if (nic.getIp4Address() == 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.getIp4Address());
+                                ip = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
+                                s_logger.debug("Nic got an ip address " + placeholderNic.getIp4Address() + " stored in placeholder nic for the network " + network);
+                            }
+                        }
 
-                nic.setIPv4Address(ip.getAddress().toString());
-                nic.setIPv4Gateway(ip.getGateway());
-                nic.setIPv4Netmask(ip.getNetmask());
-                nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag()));
-                //nic.setBroadcastType(BroadcastDomainType.Vlan);
-                //nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag()));
-                nic.setBroadcastType(network.getBroadcastDomainType());
+                        if (ip == null) {
+                            ip = assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.DirectAttached, network.getId(), requestedIpv4, false);
+                        }
+
+                        nic.setIp4Address(ip.getAddress().toString());
+                        nic.setGateway(ip.getGateway());
+                        nic.setNetmask(ip.getNetmask());
+                        nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag()));
+                        //nic.setBroadcastType(BroadcastDomainType.Vlan);
+                        //nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag()));
+                        nic.setBroadcastType(network.getBroadcastDomainType());
                         if (network.getBroadcastUri() != null)
-                nic.setBroadcastUri(network.getBroadcastUri());
+                            nic.setBroadcastUri(network.getBroadcastUri());
                         else
                             nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag()));
-                nic.setFormat(AddressFormat.Ip4);
-                nic.setReservationId(String.valueOf(ip.getVlanTag()));
-                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()));
-                    nic.setMacAddress(ip.getMacAddress());
+                        nic.setFormat(AddressFormat.Ip4);
+                        nic.setReservationId(String.valueOf(ip.getVlanTag()));
+                        nic.setMacAddress(ip.getMacAddress());
+                    }
+                    nic.setDns1(dc.getDns1());
+                    nic.setDns2(dc.getDns2());
+                }
+
+                //FIXME - get ipv6 address from the placeholder if it's stored there
+                if (network.getIp6Gateway() != null) {
+                    if (nic.getIp6Address() == null) {
+                        UserIpv6Address ip = _ipv6Mgr.assignDirectIp6Address(dc.getId(), vm.getOwner(), network.getId(), requestedIpv6);
+                        Vlan vlan = _vlanDao.findById(ip.getVlanId());
+                        nic.setIp6Address(ip.getAddress().toString());
+                        nic.setIp6Gateway(vlan.getIp6Gateway());
+                        nic.setIp6Cidr(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.setIp6Dns1(dc.getIp6Dns1());
+                    nic.setIp6Dns2(dc.getIp6Dns2());
                 }
-            }
-            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 {
+            final String requestedIpv6) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
         Transaction.execute(new TransactionCallbackWithExceptionNoReturn<InsufficientAddressCapacityException>() {
             @Override
             public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientAddressCapacityException {
@@ -1967,7 +2036,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
 
                         //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);
+                            s_logger.debug("There won't be nic assignment for VR id " + vm.getId() + "  in this network " + network);
 
                         }
 
@@ -1978,7 +2047,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                         List<VlanVO> vlan = _vlanDao.listVlansByNetworkId(network.getId());
 
                         //TODO: get vlan tag for the ntwork
-                        if (vlan != null && ! vlan.isEmpty()) {
+                        if (vlan != null && !vlan.isEmpty()) {
                             nic.setIsolationUri(IsolationType.Vlan.toUri(vlan.get(0).getVlanTag()));
                         }
 
diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
index d61378b..75c181f 100644
--- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
+++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
@@ -907,8 +907,30 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches
     }
 
     @Override
+<<<<<<< db052a96b18391ae5f972960d1f496f5396b8684
     public List<? extends NicSecondaryIp> listVmNicSecondaryIps(ListNicsCmd listNicsCmd) {
         return null;
+=======
+    public AcquirePodIpCmdResponse allocatePodIp(Account ipOwner, long zoneId, String cidr) throws ResourceAllocationException, ConcurrentOperationException {
+
+        Account caller = CallContext.current().getCallingAccount();
+        long callerUserId = CallContext.current().getCallingUserId();
+        DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
+
+        if (zone == null)
+            throw new InvalidParameterValueException("Invalid zone Id is Null");
+        if (_accountMgr.checkAccessAndSpecifyAuthority(caller, zoneId) != zoneId)
+            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, cidr);
+    }
+
+    @Override
+    public boolean releasePodIp(ReleasePodIpCmdByAdmin ip) throws CloudRuntimeException {
+        _ipAddrMgr.releasePodIp(ip.getId());
+        return true;
+>>>>>>> CLOUDSTACK-8672 : NCC Integration with CloudStack.
     }
 
 }

-- 
To stop receiving notification emails like this one, please contact
"commits@cloudstack.apache.org" <co...@cloudstack.apache.org>.

[cloudstack] 04/05: CLOUDSTACK-8672 : NCC Integration with CloudStack. Marvin Integration Tests for Shared and Dedicated Workflow.

Posted by sa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sateesh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit 6535949383c31fc492ff9b1728bd0362bfdd7546
Author: Sowmya Krishnan <so...@accelerite.com>
AuthorDate: Wed Jan 25 17:17:43 2017 +0530

    CLOUDSTACK-8672 : NCC Integration with CloudStack.
    Marvin Integration Tests for Shared and Dedicated Workflow.
---
 .../component/test_ncc_integration_dedicated.py    | 269 +++++++++++++++++
 .../component/test_ncc_integration_shared.py       | 323 +++++++++++++++++++++
 tools/marvin/marvin/config/test_data.py            |  48 +++
 tools/marvin/marvin/lib/base.py                    |  21 ++
 tools/marvin/marvin/lib/ncc.py                     | 317 ++++++++++++++++++++
 5 files changed, 978 insertions(+)

diff --git a/test/integration/component/test_ncc_integration_dedicated.py b/test/integration/component/test_ncc_integration_dedicated.py
new file mode 100755
index 0000000..b02d051
--- /dev/null
+++ b/test/integration/component/test_ncc_integration_dedicated.py
@@ -0,0 +1,269 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT 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 NCC integration with cloudstack
+"""
+#Import Local Modules
+from marvin.cloudstackTestCase import cloudstackTestCase
+from marvin.lib.common import get_domain, get_zone, get_template
+from marvin.lib import ncc
+from marvin.lib.base import (Account,
+                             VirtualMachine,
+                             PublicIPAddress,
+                             LoadBalancerRule,
+                             ServiceOffering,
+                             NetworkOffering,
+                             Network,
+                             NATRule,
+                            PhysicalNetwork,
+                            NetworkServiceProvider,
+	                        RegisteredServicePackage)
+from marvin.lib.utils import cleanup_resources
+from nose.plugins.attrib import attr
+import logging
+
+
+class TestNccIntegrationDedicated(cloudstackTestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.testClient = super(TestNccIntegrationDedicated, cls).getClsTestClient()
+        cls.api_client = cls.testClient.getApiClient()
+        cls.services = cls.testClient.getParsedTestDataConfig()
+        cls._cleanup = []
+
+        cls.logger = logging.getLogger('TestNccIntegrationDedicated')
+        cls.stream_handler = logging.StreamHandler()
+        cls.logger.setLevel(logging.DEBUG)
+        cls.logger.addHandler(cls.stream_handler)
+
+        # Get Zone, Domain and templates
+        cls.domain = get_domain(cls.api_client)
+        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"] )
+        ncc_ip = cls.services["NCC"]["NCCIP"]
+        ns_ip = cls.services["NSDedicated"]["NSIP"]
+        cls.debug("NS IP - Dedicated: %s" % ns_ip)
+
+        mgmt_srv_ip = cls.config.__dict__["mgtSvr"][0].__dict__["mgtSvrIp"]
+        #ncc_ip = "10.102.195.215"
+        #ns_ip = "10.102.195.210"
+        cls.ns = ncc.NCC(ncc_ip, ns_ip, mgmt_srv_ip, logger=cls.logger)
+        cls.ns.registerCCP(cls.api_client)
+        cls.ns.registerNS()
+        cls.ns.assignNStoCSZone()
+        spname = cls.services["servicepackage_dedicated"]["name"]
+
+        # Create Service package and get device group id, tenant group id and service package id
+        # These would be needed later for clean up
+
+        (cls.dv_group_id, cls.tnt_group_id, cls.srv_pkg_id) = cls.ns.createServicePackages(
+            spname,
+            "NetScalerVPX",
+            ns_ip,
+            isolation_policy="dedicated")
+        cls.debug("Created service package in NCC")
+        cls.debug("dv_group, tnt_group, srv_pkg_id: %s %s %s" %(cls.dv_group_id,cls.tnt_group_id, cls.srv_pkg_id))
+
+        srv_pkg_list = RegisteredServicePackage.list(cls.api_client)
+        # Choose the one created
+        cls.srv_pkg_uuid = None
+        for sp in srv_pkg_list:
+            if sp.name == spname:
+                cls.srv_pkg_uuid = sp.id
+        #srv_pkg_id = srv_pkg_list[0].id
+
+        cls.account = Account.create(
+            cls.api_client,
+            cls.services["account"]
+        )
+        cls._cleanup.append(cls.account)
+
+        try:
+            cls.services["nw_off_ncc_DedicatedSP"]["servicepackageuuid"] = cls.srv_pkg_uuid
+            cls.services["nw_off_ncc_DedicatedSP"]["servicepackagedescription"] = "A NetScalerVPX is dedicated per network."
+            cls.network_offering = NetworkOffering.create(
+                cls.api_client,
+                cls.services["nw_off_ncc_DedicatedSP"])
+        except Exception as e:
+            raise Exception ("Unable to create network offering with Service package % s due to exception % s"
+                             % (cls.srv_pkg_uuid, e))
+
+        # Network offering should be removed so that service package may be deleted later
+        cls._cleanup.append(cls.network_offering)
+
+        cls.network_offering.update(cls.api_client, state = "Enabled")
+        cls.service_offering = ServiceOffering.create(
+                cls.api_client,
+                cls.services["service_offering"]
+            )
+        cls.services["small"]["template"] = cls.template.id
+
+        # Enable Netscaler Service Provider
+
+        cls.phy_nws = PhysicalNetwork.list(cls.api_client,zoneid=cls.zone.id)
+        if isinstance(cls.phy_nws, list):
+            physical_network = cls.phy_nws[0]
+
+        try:
+            cls.ns_service_provider = NetworkServiceProvider.list(cls.api_client,name='Netscaler')
+            if isinstance(cls.ns_service_provider, list):
+                ns_provider = cls.ns_service_provider[0]
+        except:
+            raise Exception ("Netscaler service provider not found!!")
+
+        try:
+            if ns_provider.state != "Enabled":
+                NetworkServiceProvider.update(cls.api_client, id=ns_provider.id, physicalnetworkid=physical_network.id, state="Enabled")
+        except:
+            raise Exception ("Enabling Netscaler Service provider failed. Unable to proceed")
+
+        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)
+         cls.ns.cleanup_ncc(cls.dv_group_id, cls.srv_pkg_uuid, cls.srv_pkg_id, cls.tnt_group_id)
+         return
+
+    def setUp(self):
+        self.apiclient = self.testClient.getApiClient()
+        return
+
+    def tearDown(self):
+        return
+
+
+    @attr(tags=["ncc"], required_hardware="true")
+    def test_01_dedicated_first_network(self):
+        # Create network
+        self.debug("Creating network with network offering: %s" % self.network_offering.id)
+        self.network = Network.create(
+            self.apiclient,
+            self.services["network"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            networkofferingid=self.network_offering.id,
+            zoneid=self.zone.id
+        )
+        self.debug("Created network: %s" % self.network.id)
+
+        self.debug("Trying VM deploy with network created on account: %s" % self.account.name)
+
+        self.virtual_machine = VirtualMachine.create(
+            self.apiclient,
+            self.services["small"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            zoneid=self.zone.id,
+            networkids=self.network.id,
+            serviceofferingid=self.service_offering.id
+        )
+        self.debug("Deployed VM in network: %s" % self.network.id)
+        list_vm_response = VirtualMachine.list(
+            self.apiclient,
+            id=self.virtual_machine.id
+        )
+        self.debug(
+            "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")
+        vm_response = list_vm_response[0]
+
+        self.assertEqual(
+            vm_response.state,
+            "Running",
+            "VM state should be running after deployment"
+        )
+
+        self.debug("Aquiring public IP for network: %s" % self.network.id)
+
+        ip_with_lb_rule = PublicIPAddress.create(
+            self.apiclient,
+            accountid=self.account.name,
+            zoneid=self.zone.id,
+            domainid=self.account.domainid,
+            networkid=self.network.id)
+
+        self.debug(
+            "Creating LB rule for IP address: %s with round robin algo" %
+            ip_with_lb_rule.ipaddress.ipaddress)
+
+        self.services["lbrule"]["alg"] = 'roundrobin'
+        lb_rule = LoadBalancerRule.create(
+            self.apiclient,
+            self.services["lbrule"],
+            ipaddressid=ip_with_lb_rule.ipaddress.id,
+            accountid=self.account.name,
+            networkid=self.network.id
+        )
+
+        lb_rules = LoadBalancerRule.list(
+            self.apiclient,
+            id=lb_rule.id,
+            listall=True
+        )
+        self.assertEqual(
+            isinstance(lb_rules, list),
+            True,
+            "List LB rules should return a newly created LB rule"
+        )
+        self.debug("Adding %s to the LB rule %s" % (
+            self.virtual_machine.name,
+            lb_rule.name
+        ))
+        lb_rule.assign(self.apiclient, [self.virtual_machine])
+
+    @attr(tags=["ncc"], required_hardware="true")
+    def test_02_dedicated_another_network(self):
+        # Create network
+        self.network = Network.create(
+            self.apiclient,
+            self.services["network"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            networkofferingid=self.network_offering.id,
+            zoneid=self.zone.id
+        )
+        self.debug("Created network: %s" % self.network.id)
+
+        self.debug("Trying VM deploy with network created on account: %s" % self.account.name)
+
+        with self.assertRaises(Exception):
+            self.virtual_machine = VirtualMachine.create(
+            self.apiclient,
+            self.services["small"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            networkids=self.network.id,
+            zoneid=self.zone.id,
+            serviceofferingid=self.service_offering.id
+            )
+        return
diff --git a/test/integration/component/test_ncc_integration_shared.py b/test/integration/component/test_ncc_integration_shared.py
new file mode 100755
index 0000000..cb5b90c
--- /dev/null
+++ b/test/integration/component/test_ncc_integration_shared.py
@@ -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.
+"""
+BVT tests for NCC integration with cloudstack
+"""
+#Import Local Modules
+from marvin.cloudstackTestCase import cloudstackTestCase
+from marvin.lib.common import get_domain, get_zone, get_template
+from marvin.lib import ncc
+from marvin.lib.base import (Account,
+                             VirtualMachine,
+                             PublicIPAddress,
+                             LoadBalancerRule,
+                             ServiceOffering,
+                             NetworkOffering,
+                             Network,
+                             NATRule,
+                            PhysicalNetwork,
+                            NetworkServiceProvider,
+	                        RegisteredServicePackage)
+from marvin.lib.utils import cleanup_resources
+from nose.plugins.attrib import attr
+import logging
+
+
+class TestNccIntegrationShared(cloudstackTestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.testClient = super(TestNccIntegrationShared, cls).getClsTestClient()
+        cls.api_client = cls.testClient.getApiClient()
+        cls.services = cls.testClient.getParsedTestDataConfig()
+        cls._cleanup = []
+
+        cls.logger = logging.getLogger('TestNccIntegrationShared')
+        cls.stream_handler = logging.StreamHandler()
+        cls.logger.setLevel(logging.DEBUG)
+        cls.logger.addHandler(cls.stream_handler)
+
+        # Get Zone, Domain and templates
+        cls.domain = get_domain(cls.api_client)
+        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"] )
+        ncc_ip=cls.services["NCC"]["NCCIP"]
+        ns_ip=cls.services["NSShared"]["NSIP"]
+        cls.debug("NS IP: Shared: %s" % ns_ip)
+
+        mgmt_srv_ip = cls.config.__dict__["mgtSvr"][0].__dict__["mgtSvrIp"]
+        #ncc_ip = "10.102.195.215"
+        #ns_ip = "10.102.195.210"
+        cls.ns = ncc.NCC(ncc_ip, ns_ip, mgmt_srv_ip, logger=cls.logger)
+        cls.ns.registerCCP(cls.api_client)
+        cls.ns.registerNS()
+        cls.ns.assignNStoCSZone()
+        spname = cls.services["servicepackage_shared"]["name"]
+        cls.debug("SPname (Shared): %s" % spname)
+        #spname="SharedSP9"
+        # Create Service package and get device group id, tenant group id and service package id
+        # These would be needed later for clean up
+
+        (cls.dv_group_id, cls.tnt_group_id, cls.srv_pkg_id) = cls.ns.createServicePackages(
+            spname,
+            "NetScalerVPX",
+            ns_ip)
+        srv_pkg_list = RegisteredServicePackage.list(cls.api_client)
+        # Choose the one created
+        cls.srv_pkg_uuid = None
+        for sp in srv_pkg_list:
+            if sp.name == spname:
+                cls.srv_pkg_uuid = sp.id
+        #srv_pkg_id = srv_pkg_list[0].id
+
+        cls.account = Account.create(
+            cls.api_client,
+            cls.services["account"]
+        )
+        cls._cleanup.append(cls.account)
+
+        try:
+            cls.services["nw_off_ncc_SharedSP"]["servicepackageuuid"] = cls.srv_pkg_uuid
+            cls.services["nw_off_ncc_SharedSP"]["servicepackagedescription"] = "A NetScalerVPX is shared across all networks."
+            cls.network_offering = NetworkOffering.create(
+                cls.api_client,
+                cls.services["nw_off_ncc_SharedSP"])
+        except Exception as e:
+            raise Exception ("Unable to create network offering with Service package % s due to exception % s"
+                             % (cls.srv_pkg_uuid, e))
+
+        # Network offering should be removed so that service package may be deleted later
+        cls._cleanup.append(cls.network_offering)
+
+        cls.network_offering.update(cls.api_client, state = "Enabled")
+        cls.service_offering_shared = ServiceOffering.create(
+                cls.api_client,
+                cls.services["service_offering"]
+            )
+        cls.services["small"]["template"] = cls.template.id
+
+        # Enable Netscaler Service Provider
+
+        cls.phy_nws = PhysicalNetwork.list(cls.api_client,zoneid=cls.zone.id)
+        if isinstance(cls.phy_nws, list):
+            physical_network = cls.phy_nws[0]
+
+        try:
+            cls.ns_service_provider = NetworkServiceProvider.list(cls.api_client,name='Netscaler')
+            if isinstance(cls.ns_service_provider, list):
+                ns_provider = cls.ns_service_provider[0]
+        except:
+            raise Exception ("Netscaler service provider not found!!")
+
+        try:
+            if ns_provider.state != "Enabled":
+                NetworkServiceProvider.update(cls.api_client, id=ns_provider.id, physicalnetworkid=physical_network.id, state="Enabled")
+        except:
+            raise Exception ("Enabling Netscaler Service provider failed. Unable to proceed")
+
+        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)
+         cls.ns.cleanup_ncc(cls.dv_group_id, cls.srv_pkg_uuid, cls.srv_pkg_id, cls.tnt_group_id)
+         return
+
+    def setUp(self):
+        self.apiclient = self.testClient.getApiClient()
+        return
+
+    def tearDown(self):
+        return
+
+    @attr(tags=["ncc"], required_hardware="true")
+    def test_01_shared_first_network(self):
+        # Create network
+        self.debug("Creating network with network offering: %s" % self.network_offering.id)
+        self.network = Network.create(
+            self.apiclient,
+            self.services["network"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            networkofferingid=self.network_offering.id,
+            zoneid=self.zone.id
+        )
+        self.debug("Created network: %s" % self.network.id)
+
+        self.debug("Trying VM deploy with network created on account: %s" % self.account.name)
+
+        self.virtual_machine = VirtualMachine.create(
+            self.apiclient,
+            self.services["small"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            zoneid=self.zone.id,
+            networkids=self.network.id,
+            serviceofferingid=self.service_offering_shared.id)
+        self.debug("Deployed VM in network: %s" % self.network.id)
+        list_vm_response = VirtualMachine.list(
+            self.apiclient,
+            id=self.virtual_machine.id
+        )
+        self.debug(
+            "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")
+        vm_response = list_vm_response[0]
+
+        self.assertEqual(
+            vm_response.state,
+            "Running",
+            "VM state should be running after deployment"
+        )
+
+        self.debug("Acquiring public IP for network: %s" % self.network.id)
+
+        ip_with_lb_rule = PublicIPAddress.create(
+            self.apiclient,
+            accountid=self.account.name,
+            zoneid=self.zone.id,
+            domainid=self.account.domainid,
+            networkid=self.network.id)
+
+        self.debug(
+            "Creating LB rule for IP address: %s with round robin algo" %
+            ip_with_lb_rule.ipaddress.ipaddress)
+
+        self.services["lbrule"]["alg"] = 'roundrobin'
+        lb_rule = LoadBalancerRule.create(
+            self.apiclient,
+            self.services["lbrule"],
+            ipaddressid=ip_with_lb_rule.ipaddress.id,
+            accountid=self.account.name,
+            networkid=self.network.id
+        )
+
+        lb_rules = LoadBalancerRule.list(
+            self.apiclient,
+            id=lb_rule.id,
+            listall=True
+        )
+        self.assertEqual(
+            isinstance(lb_rules, list),
+            True,
+            "List LB rules should return a newly created LB rule"
+        )
+        self.debug("Adding %s to the LB rule %s" % (
+            self.virtual_machine.name,
+            lb_rule.name
+        ))
+        lb_rule.assign(self.apiclient, [self.virtual_machine])
+
+    @attr(tags=["ncc"], required_hardware="true")
+    def test_02_shared_another_network(self):
+        # Create network
+        self.debug("Creating network with network offering: %s" % self.network_offering.id)
+        self.network = Network.create(
+            self.apiclient,
+            self.services["network"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            networkofferingid=self.network_offering.id,
+            zoneid=self.zone.id
+        )
+        self.debug("Created network: %s" % self.network.id)
+
+        self.debug("Trying VM deploy with network created on account: %s" % self.account.name)
+
+        self.virtual_machine = VirtualMachine.create(
+            self.apiclient,
+            self.services["small"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            networkids=self.network.id,
+            zoneid=self.zone.id,
+            serviceofferingid=self.service_offering_shared.id
+        )
+        self.debug("Deployed VM in network: %s" % self.network.id)
+        list_vm_response = VirtualMachine.list(
+            self.apiclient,
+            id=self.virtual_machine.id
+        )
+        self.debug(
+            "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")
+        vm_response = list_vm_response[0]
+
+        self.assertEqual(
+            vm_response.state,
+            "Running",
+            "VM state should be running after deployment"
+        )
+
+        self.debug("Aquiring public IP for network: %s" % self.network.id)
+
+        ip_with_lb_rule = PublicIPAddress.create(
+            self.apiclient,
+            accountid=self.account.name,
+            zoneid=self.zone.id,
+            domainid=self.account.domainid,
+            networkid=self.network.id)
+
+        self.debug(
+            "Creating LB rule for IP address: %s with round robin algo" %
+            ip_with_lb_rule.ipaddress.ipaddress)
+
+        self.services["lbrule"]["alg"] = 'roundrobin'
+        lb_rule = LoadBalancerRule.create(
+            self.apiclient,
+            self.services["lbrule"],
+            ipaddressid=ip_with_lb_rule.ipaddress.id,
+            accountid=self.account.name,
+            networkid=self.network.id
+        )
+
+        lb_rules = LoadBalancerRule.list(
+            self.apiclient,
+            id=lb_rule.id,
+            listall=True
+        )
+        self.assertEqual(
+            isinstance(lb_rules, list),
+            True,
+            "List LB rules should return a newly created LB rule"
+        )
+        self.debug("Adding %s to the LB rule %s" % (
+            self.virtual_machine.name,
+            lb_rule.name
+        ))
+        lb_rule.assign(self.apiclient, [self.virtual_machine])
+        return
diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py
index d1ec1ba..0f67ce8 100644
--- a/tools/marvin/marvin/config/test_data.py
+++ b/tools/marvin/marvin/config/test_data.py
@@ -674,6 +674,54 @@ test_data = {
         "cidr": "0.0.0.0/0",
         "protocol": "TCP"
     },
+    "nw_off_ncc_SharedSP": {
+        "name": 'SharedSP',
+        "displaytext": 'SharedSP',
+        "guestiptype": 'Isolated',
+        "supportedservices":
+            'Dhcp,Dns,SourceNat,Lb,StaticNat',
+        "traffictype": 'GUEST',
+        "availability": 'Optional',
+        "serviceProviderList": {
+            "Dhcp": 'VirtualRouter',
+            "Dns": 'VirtualRouter',
+            "SourceNat": 'VirtualRouter',
+            "Lb": 'Netscaler',
+            "StaticNat": 'VirtualRouter'
+        }
+    },
+    "nw_off_ncc_DedicatedSP": {
+        "name": 'DedicatedSP',
+        "displaytext": 'DedicatedSP',
+        "guestiptype": 'Isolated',
+        "supportedservices":
+            'Dhcp,Dns,SourceNat,Lb,StaticNat',
+        "traffictype": 'GUEST',
+        "availability": 'Optional',
+        "serviceProviderList": {
+            "Dhcp": 'VirtualRouter',
+            "Dns": 'VirtualRouter',
+            "SourceNat": 'VirtualRouter',
+            "Lb": 'Netscaler',
+            "StaticNat": 'VirtualRouter'
+        }
+    },
+    "NCC": {
+        "NCCIP": '10.102.195.215',
+    },
+    "NSShared": {
+        "NSIP": '10.102.195.210',
+    },
+    "NSDedicated": {
+        "NSIP": '10.102.195.212'
+    },
+    "servicepackage_shared": {
+        "name": "SharedSP",
+    },
+    "servicepackage_dedicated": {
+        "name": "DedicatedSP",
+    },
+
     "nw_off_isolated_persistent_netscaler": {
         "name": 'Netscaler',
         "displaytext": 'Netscaler',
diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py
index 3283911..6a00c67 100755
--- a/tools/marvin/marvin/lib/base.py
+++ b/tools/marvin/marvin/lib/base.py
@@ -2201,6 +2201,12 @@ class NetworkOffering:
             cmd.ispersistent = services["ispersistent"]
         if "egress_policy" in services:
             cmd.egressdefaultpolicy = services["egress_policy"]
+        cmd.details = [{}]
+        if "servicepackageuuid" in services:
+            cmd.details[0]["servicepackageuuid"] = services["servicepackageuuid"]
+        if "servicepackagedescription" in services:
+            cmd.details[0]["servicepackagedescription"] = services["servicepackagedescription"]
+
 
         cmd.availability = 'Optional'
 
@@ -5190,3 +5196,18 @@ class StorageNetworkIpRange:
         cmd = listStorageNetworkIpRange.listStorageNetworkIpRangeCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         return(apiclient.listStorageNetworkIpRange(cmd))
+
+class RegisteredServicePackage:
+    """Manage ServicePackage registered with NCC"""
+
+    def __init__(self, items):
+        self.__dict__.update(items)
+
+    @classmethod
+    def list(cls, apiclient, **kwargs):
+        """Lists service packages published by NCC"""
+
+        cmd = listRegisteredServicePackages.listRegisteredServicePackagesCmd()
+        [setattr(cmd, k, v) for k, v in kwargs.items()]
+        return(apiclient.listRegisteredServicePackages(cmd))
+
diff --git a/tools/marvin/marvin/lib/ncc.py b/tools/marvin/marvin/lib/ncc.py
new file mode 100755
index 0000000..5c0ae32
--- /dev/null
+++ b/tools/marvin/marvin/lib/ncc.py
@@ -0,0 +1,317 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+"""
+Base class for NCC Orchestration
+"""
+from marvin.cloudstackTestCase import cloudstackTestCase
+from marvin.cloudstackAPI import *
+from marvin.lib.base import Domain, Account
+from marvin.lib.utils import validateList
+from marvin.codes import PASS,FAILED
+from marvin.cloudstackException import (InvalidParameterException,
+                                        GetDetailExceptionInfo)
+from os import system
+from subprocess import call
+import requests, json, urllib
+
+class NCC:
+
+    def __init__(self, nccip, nsip, csip, logger=None):
+        self.nccip = nccip
+        self.nsip = nsip
+        self.csip = csip
+        self.logger = logger
+        self.__lastError = ''
+
+    def registerCCP(self, apiclient):
+        """
+        Register CCP with NCC
+        """
+        auth_keys = self.getAdminKeys(apiclient)
+        url = "http://"+self.nccip+"/cs/cca/v1/cloudstacks"
+        cs_url = "http://"+self.csip+":8080/"
+        payload = {"cloudstack": {
+            "name": "Cloudstack",
+            "apikey": auth_keys[0],
+            "secretkey": auth_keys[1],
+            "driver_username": "admin",
+            "driver_password": "nsroot",
+            "cloudstack_uri": cs_url
+            }
+        }
+        cmd_response = self.sendCmdToNCC(url, payload)
+        if cmd_response == FAILED:
+            raise Exception("Error:  %s" % self.__lastError)
+
+    def registerNS(self):
+        url = "http://"+self.nccip+"/nitro/v1/config/managed_device/"
+        payload = 'object={"params":{"action":"add_device"}, "managed_device":{"ip_address":"%s",\
+                  "profile_name":"ns_nsroot_profile", "sync_operation":"false"}}' % self.nsip
+        headers = {'Content-Type': 'application/x-www-form-urlencoded'}
+        cmd_response = self.sendCmdToNS(url, payload, header=headers)
+        if cmd_response == FAILED:
+            raise Exception("Error:  %s" % self.__lastError)
+
+    def assignNStoCSZone(self):
+        cs_zone = self.getCSZoneFromNCC()
+        if cs_zone == FAILED:
+            raise Exception("Error:  %s" % self.__lastError)
+        url = "http://"+self.nccip+"/nitro/v1/config/tag/"
+        payload = 'object={"tag": {"entity_type": "managed_device", "entity_id": "%s",\
+                  "tag_key": "zone", "tag_value": "%s"}}' % (self.nsip, cs_zone)
+        header = {'Content-Type':'application/x-www-form-urlencoded'}
+        cmd_response = self.sendCmdToNS(url, payload, header=header)
+        if cmd_response == FAILED:
+            raise Exception("Error:  %s" % self.__lastError)
+
+    def createServicePackages(self, name, platform_type, device_ip, isolation_policy="shared"):
+        tnt_group = self.createTenantGroup(name)
+        if tnt_group.status_code != 201:
+            raise Exception("Error:  %s" % self.__lastError)
+        tnt_group_id = json.loads(tnt_group.content)["tenantgroups"][0]["id"]
+        dv_group = self.createDeviceGroup(name, platform_type)
+        if dv_group.status_code != 201:
+            raise Exception("Error:  %s" % self.__lastError)
+        dv_group_id = json.loads(dv_group.content)["devicegroups"][0]["id"]
+        if isolation_policy.lower() == "shared":
+            srv_pkg = self.createServicePackageShared(name, tnt_group_id, dv_group_id, isolation_policy )
+        elif isolation_policy.lower() == "dedicated":
+            srv_pkg = self.createServicePackageDedicated(name, tnt_group_id, dv_group_id, isolation_policy )
+        else:
+            raise  Exception("NS device must be either in shared or dedicated mode")
+        if srv_pkg.status_code != 201:
+            raise Exception("Error:  %s" % self.__lastError)
+        dev_add_res =self.addDevicetoServicePackage(dv_group_id, device_ip)
+        if dev_add_res == FAILED:
+            raise Exception ("Error:  %s" % self.__lastError)
+        srv_pkg_id = json.loads(srv_pkg.content)["servicepackages"][0]["id"]
+        publish_srv_pkg_res = self.publishServicePackage(srv_pkg_id)
+        if publish_srv_pkg_res == FAILED:
+            raise Exception("Error:  %s" % self.__lastError)
+        return (dv_group_id, tnt_group_id, srv_pkg_id)
+
+    def createTenantGroup(self, name):
+        url = "http://"+self.nccip+"/admin/v1/tenantgroups"
+        payload = {"tenantgroups": [{"name": name}]}
+        res = self.sendCmdToNCC(url, payload)
+        return res
+
+    def createDeviceGroup(self, name, platform_type, device_type="netscaler"):
+        url = "http://"+self.nccip+"/admin/v1/devicegroups"
+        payload = {"devicegroups":[{"name": name,
+                                    "device_type": device_type,
+                                    "platform_type": platform_type
+                                   }]
+        }
+        res = self.sendCmdToNCC(url, payload)
+        return res
+
+    def createServicePackageShared(self, name, tenant_group, device_group, allocation, device_type="netscaler"):
+        url = "http://"+self.nccip+"/admin/v1/servicepackages"
+        payload = {"servicepackages":[{"allocationgroups": [{"device_type": device_type,
+                                                             "allocationpolicy":allocation,
+                                                             "placement_scheme": "ROUNDROBIN",
+                                                             "deviceaffinity": "onedevice",
+                                                             "devicegroup":{"ref": device_group}
+                                                             }],
+                                       "name": name,
+                                       "isdefault": "false",
+                                       "tenantgroup": {"ref": tenant_group}
+                                      }]
+        }
+        res = self.sendCmdToNCC(url, payload)
+        return res
+
+    def createServicePackageDedicated(self, name, tenant_group, device_group, allocation, device_type="netscaler"):
+        url = "http://"+self.nccip+"/admin/v1/servicepackages"
+        payload = {"servicepackages":[{"allocationgroups": [{"device_type": device_type,
+                                                             "allocationpolicy":allocation,
+                                                             #"placement_scheme": "roundrobin or leastentity",
+                                                             "devicegroup":{"ref": device_group}
+                                                            }],
+                                       "name": name,
+                                       "isdefault": "false",
+                                       "tenantgroup": {"ref": tenant_group}
+                                      }]
+        }
+        res = self.sendCmdToNCC(url, payload)
+        return res
+   
+    def addDevicetoServicePackage(self, devicegroup_id, device_ip):
+        url = "http://"+self.nccip+"/admin/v1/devicegroups/"+devicegroup_id+"/devices"
+        payload = {"devices":[{"ref":device_ip }]}
+        res = self.sendCmdToNCC(url, payload, method="PUT")
+        return res
+
+    def removeDevicefromServicePackage(self, devicegroup_id):
+        url = "http://"+self.nccip+"/admin/v1/devicegroups/"+devicegroup_id+"/devices"
+        payload = {"devices":[]}
+        res = self.sendCmdToNCC(url, payload, method="PUT")
+        return res
+
+    def publishServicePackage(self, pkg_id):
+        url = "http://"+self.nccip+"/cs/cca/v1/servicepackages"
+        payload = {"servicepackages":[{"servicepackageid":pkg_id}]}
+        res = self.sendCmdToNCC(url, payload)
+        return res
+
+    def getCSZoneFromNCC(self):
+        url = "http://"+self.nccip+"/cs/cca/v1/zones"
+        res = self.sendCmdToNCC(url, method="GET")
+        if res != FAILED:
+            zoneid = json.loads(res.content)["zones"][0]
+            return zoneid
+        else:
+            return FAILED
+
+    def sendCmdToNCC(self, url, payload={}, method="POST", header={'content-type': 'application/json'}):
+        try:
+            # self.logger.debug("url :%s" % url)
+            # self.logger.debug("payload: %s" % payload)
+            if method == "POST":
+                #self.logger.debug("====Sending POST Request====")
+                return self.sendPostRequstToNCC(url, payload, header)
+            if method == "GET":
+                #self.logger.debug("====Sending GET Request====")
+                return self.sendGetRequestToNCC(url, payload, header)
+            if method == "PUT":
+                return self.sendPutRequestToNCC(url, payload, header)
+            if method == "DELETE":
+                self.logger.debug("Trying delete")
+                return self.sendDeleteRequestToNCC(url, header)
+        except Exception as e:
+            self.__lastError = e
+            # self.logger.exception("sendCmdToNCC: Exception:%s" %
+            #                       GetDetailExceptionInfo(e))
+            return FAILED
+
+
+    def sendGetRequestToNCC(self, url, payload, header):
+        try:
+            res = requests.get(url, json=payload, auth=("nsroot", "nsroot"), headers=header)
+            return res
+        except Exception as e:
+            self.__lastError = e
+            # self.logger.exception("sendGetRequestToNCC : Exception Occured: %s" %
+            #                       str(self.__lastError))
+            return FAILED
+
+    def sendPostRequstToNCC(self, url, payload, header):
+        try:
+            res = requests.post(url, json=payload, auth=("nsroot", "nsroot"), headers=header)
+            return res
+        except Exception as e:
+            self.__lastError = e
+            # self.logger.exception("sendPostRequstToNCC: Exception Occured: %s" %
+            #                       str(self.__lastError))
+            return FAILED
+
+    def sendPutRequestToNCC(self, url, payload, header):
+         try:
+            res = requests.put(url, json=payload, auth=("nsroot", "nsroot"), headers=header)
+            return res
+         except Exception as e:
+            self.__lastError = e
+            # self.logger.exception("sendPostRequstToNCC: Exception Occured: %s" %
+            #                       str(self.__lastError))
+            return FAILED
+
+    def sendDeleteRequestToNCC(self, url, header):
+         try:
+            res = requests.delete (url, auth=("nsroot", "nsroot"), headers=header)
+            return res
+         except Exception as e:
+            self.__lastError = e
+            # self.logger.exception("sendPostRequstToNCC: Exception Occured: %s" %
+            #                       str(self.__lastError))
+            return FAILED
+
+    def sendCmdToNS(self, url, payload={}, method="POST", header={'content-type': 'application/json'}):
+        try:
+            # self.logger.debug("url :%s" % url)
+            # self.logger.debug("payload: %s" % payload)
+            if method == "POST":
+                #self.logger.debug("====Sending POST Request====")
+                return self.sendPostRequstToNS(url, payload, header)
+            if method == "GET":
+                #self.logger.debug("====Sending GET Request====")
+                return self.sendGetRequestToNS(url, payload, header)
+        except Exception as e:
+            self.__lastError = e
+            # self.logger.exception("sendCmdToNCC: Exception:%s" %
+            #                       GetDetailExceptionInfo(e))
+            return FAILED
+
+    def sendPostRequstToNS(self, url, payload, header):
+        try:
+            res = requests.post(url, data=payload, auth=("nsroot", "nsroot"), headers=header)
+            return res
+        except Exception as e:
+            self.__lastError = e
+            # self.logger.exception("sendPostRequstToNCC: Exception Occured: %s" %
+            #                       str(self.__lastError))
+            return FAILED
+
+    def sendGetRequestToNS(self, url, payload, header):
+        try:
+            res = requests.get(url, data=payload, auth=("nsroot", "nsroot"), headers=header)
+            return res
+        except Exception as e:
+            self.__lastError = e
+            # self.logger.exception("sendGetRequestToNCC : Exception Occured: %s" %
+            #                       str(self.__lastError))
+            return FAILED
+
+    def getAdminKeys(self, apiClient):
+        domains = Domain.list(apiClient, name="ROOT")
+        listuser = listUsers.listUsersCmd()
+        listuser.username = "admin"
+        listuser.domainid = domains[0].id
+        listuser.listall = True
+        listuserRes = apiClient.listUsers(listuser)
+        userId = listuserRes[0].id
+        apiKey = listuserRes[0].apikey
+        securityKey = listuserRes[0].secretkey
+        return [apiKey, securityKey]
+
+    def cleanup_ncc(self, device_gp_id, srv_pkg_uuid, srv_pkg_id, tnt_group_id):
+        self.removeDevicefromServicePackage(device_gp_id)
+        # Remove service package reference from Cloudplatform
+        url = "http://"+self.nccip+"/cs/cca/v1/servicepackages/"+srv_pkg_uuid
+        self.logger.debug("Sending DELETE SP uuid: %s " % url)
+        res = self.sendCmdToNCC(url, method="DELETE")
+
+
+        # Remove Service package from NCC
+        url = "http://"+self.nccip+"/admin/v1/servicepackages/"+srv_pkg_id
+        self.logger.debug("Sending DELETE SP : %s " % url)
+        res = self.sendCmdToNCC(url, method="DELETE")
+
+
+        # Remove Device group
+        url = "http://"+self.nccip+"/admin/v1/devicegroups/"+device_gp_id
+        self.logger.debug("Sending DELETE devicegroup: %s " % url)
+        res = self.sendCmdToNCC(url, method="DELETE")
+
+
+        # Remove Tenant group
+        url = "http://"+self.nccip+"/admin/v1/tenantgroups/"+tnt_group_id
+        self.logger.debug("Sending DELETE tenant group: %s " % url)
+        res = self.sendCmdToNCC(url, method="DELETE")
+        self.logger.debug("Result: %s" % res)
+        return res

-- 
To stop receiving notification emails like this one, please contact
"commits@cloudstack.apache.org" <co...@cloudstack.apache.org>.

[cloudstack] 03/05: CLOUDSTACK-8672 : NCC Integration with CloudStack.

Posted by sa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sateesh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit b2b422c7d7a19efec8037044fe9dbf014742daaf
Author: Nitin Kumar Maharana <ni...@citrix.com>
AuthorDate: Fri Aug 7 17:10:13 2015 +0530

    CLOUDSTACK-8672 : NCC Integration with CloudStack.
---
 api/src/com/cloud/agent/api/to/LoadBalancerTO.java |   53 +-
 api/src/com/cloud/event/EventTypes.java            |    7 +
 api/src/com/cloud/network/NetworkService.java      |    7 +
 .../com/cloud/network/VirtualRouterProvider.java   |    2 +-
 .../com/cloud/network/router/VirtualRouter.java    |    2 +-
 api/src/com/cloud/offering/NetworkOffering.java    |    4 +-
 api/src/com/cloud/vm/VirtualMachine.java           |    1 +
 .../admin/address/AcquirePodIpCmdByAdmin.java      |   30 +-
 .../admin/network/CreateNetworkOfferingCmd.java    |   15 +-
 .../loadbalancer/UpdateLoadBalancerRuleCmd.java    |    7 +
 .../user/loadbalancer/UploadSslCertCmd.java        |    8 +
 .../api/response/AcquireIPAddressResponse.java     |    5 -
 .../cloudstack/api/response/SslCertResponse.java   |    8 +
 .../cloudstack/api/response/SystemVmResponse.java  |   25 +-
 .../org/apache/cloudstack/network/tls/SslCert.java |    2 +-
 .../api/ExternalNetworkResourceUsageCommand.java   |    9 +
 .../api/NetScalerImplementNetworkCommand.java      |    8 +-
 .../api/routing/HealthCheckLBConfigCommand.java    |    8 +-
 .../src/com/cloud/network/IpAddressManager.java    |    2 +-
 .../com/cloud/vm/VirtualMachineManagerImpl.java    |    3 +-
 .../engine/orchestration/NetworkOrchestrator.java  |   18 +-
 .../cloud/dc/dao/DataCenterIpAddressDaoImpl.java   |    3 -
 .../src/com/cloud/network/dao/NetworkDao.java      |    2 +
 .../src/com/cloud/network/dao/NetworkDaoImpl.java  |   16 +-
 .../src/com/cloud/network/dao/SslCertVO.java       |   11 +-
 .../src/com/cloud/offerings/NetworkOfferingVO.java |   12 +
 .../cloud/offerings/dao/NetworkOfferingDao.java    |    3 +
 .../offerings/dao/NetworkOfferingDaoImpl.java      |   30 +
 .../src/com/cloud/hypervisor/guru/VMwareGuru.java  |    4 +
 .../hypervisor/vmware/resource/VmwareResource.java |   10 +
 .../xenserver/resource/CitrixResourceBase.java     |   16 +-
 .../wrapper/xenbase/CitrixStartCommandWrapper.java |    1 -
 .../netscaler/spring-netscaler-context.xml         |    2 +-
 ...d.java => DeleteNetscalerControlCenterCmd.java} |   30 +-
 .../commands/DeleteNetscalerLoadBalancerCmd.java   |    2 +-
 .../commands/DeleteServicePackageOfferingCmd.java  |    5 +-
 ...olCenterCmd.java => DeployNetscalerVpxCmd.java} |  112 +-
 .../commands/ListNetscalerControlCenterCmd.java    |   93 +
 .../RegisterNetscalerControlCenterCmd.java         |   11 +-
 .../api/commands/RegisterServicePackageCmd.java    |    9 -
 .../com/cloud/api/commands/StopNetScalerVMCmd.java |  132 +
 .../response/NetscalerControlCenterResponse.java   |   98 +
 .../cloud/network/NetScalerControlCenterVO.java    |    7 +-
 .../cloud/network/NetScalerServicePackageVO.java   |    6 +-
 .../network/dao/NetScalerServicePackageDao.java    |    2 +
 .../dao/NetScalerServicePackageDaoImpl.java        |    9 +-
 .../cloud/network/element/NetscalerElement.java    |  274 +-
 .../NetscalerLoadBalancerElementService.java       |   11 +-
 .../resource/NetScalerControlCenterResource.java   | 3527 ++------------------
 .../com/cloud/network/vm/NetScalerVMManager.java   |   41 +
 .../cloud/network/vm/NetScalerVMManagerImpl.java   |  448 +++
 server/src/com/cloud/alert/AlertManagerImpl.java   |  204 +-
 server/src/com/cloud/api/ApiResponseHelper.java    |    6 +-
 .../configuration/ConfigurationManagerImpl.java    |   39 +-
 .../com/cloud/hypervisor/HypervisorGuruBase.java   |    4 +
 .../network/ExternalDeviceUsageManagerImpl.java    |   40 +-
 .../ExternalLoadBalancerDeviceManagerImpl.java     |   55 +-
 .../com/cloud/network/IpAddressManagerImpl.java    |   57 +-
 .../src/com/cloud/network/NetworkServiceImpl.java  |   25 +
 .../network/lb/LoadBalancingRulesManagerImpl.java  |   14 +-
 .../src/com/cloud/server/ManagementServerImpl.java |    5 +
 .../cloudstack/network/ssl/CertServiceImpl.java    |    7 +-
 .../ExternalLoadBalancerDeviceManagerImplTest.java |   19 +-
 .../test/com/cloud/vpc/MockNetworkManagerImpl.java |   24 +-
 .../test/com/cloud/vpc/dao/MockNetworkDaoImpl.java |    6 +
 tools/apidoc/gen_toc.py                            |   10 +
 ui/index.html                                      |    1 +
 ui/l10n/en.js                                      |   24 +
 ui/scripts/accounts.js                             |  193 ++
 ui/scripts/configuration.js                        |   93 +-
 ui/scripts/docs.js                                 |    4 +
 ui/scripts/lbCertificatePolicy.js                  |  183 +
 ui/scripts/network.js                              |  349 +-
 ui/scripts/regions.js                              |  222 ++
 ui/scripts/system.js                               |   63 +-
 75 files changed, 2862 insertions(+), 3936 deletions(-)

diff --git a/api/src/com/cloud/agent/api/to/LoadBalancerTO.java b/api/src/com/cloud/agent/api/to/LoadBalancerTO.java
index aabff2f..3a3dfa4 100644
--- a/api/src/com/cloud/agent/api/to/LoadBalancerTO.java
+++ b/api/src/com/cloud/agent/api/to/LoadBalancerTO.java
@@ -46,6 +46,8 @@ public class LoadBalancerTO {
     boolean alreadyAdded;
     boolean inline;
     String srcIpVlan;
+    String srcIpGateway;
+    String srcIpNetmask;
     Long networkId;
     DestinationTO[] destinations;
     private StickinessPolicyTO[] stickinessPolicies;
@@ -84,6 +86,15 @@ public class LoadBalancerTO {
         this(id, srcIp, srcPort, protocol, algorithm, revoked, alreadyAdded, inline, argDestinations, stickinessPolicies, null, null, null);
     }
 
+    public LoadBalancerTO(String id, List<DestinationTO> destinations) {
+        this.uuid = id;
+        int i = 0;
+        this.destinations = new DestinationTO[destinations.size()];
+        for (DestinationTO destination : destinations) {
+            this.destinations[i++] = new DestinationTO(destination.getDestIp(), destination.getDestPort(), destination.getMonitorState());
+        }
+    }
+
     public LoadBalancerTO(String id, String srcIp, int srcPort, String protocol, String algorithm, boolean revoked, boolean alreadyAdded, boolean inline,
             List<LbDestination> argDestinations, List<LbStickinessPolicy> stickinessPolicies, List<LbHealthCheckPolicy> healthCheckPolicies, LbSslCert sslCert,
             String lbProtocol) {
@@ -212,21 +223,37 @@ public class LoadBalancerTO {
         this.networkId = id;
     }
 
+    public String getSrcIpGateway() {
+        return srcIpGateway;
+    }
+
+    public void setSrcIpGateway(String srcIpGateway) {
+        this.srcIpGateway = srcIpGateway;
+    }
+
+    public String getSrcIpNetmask() {
+        return srcIpNetmask;
+    }
+
+    public void setSrcIpNetmask(String srcIpNetmask) {
+        this.srcIpNetmask = srcIpNetmask;
+    }
+
     public static class StickinessPolicyTO {
-        private String _methodName;
-        private List<Pair<String, String>> _paramsList;
+        private String methodName;
+        private List<Pair<String, String>> params;
 
         public String getMethodName() {
-            return _methodName;
+            return methodName;
         }
 
         public List<Pair<String, String>> getParams() {
-            return _paramsList;
+            return params;
         }
 
         public StickinessPolicyTO(String methodName, List<Pair<String, String>> paramsList) {
-            this._methodName = methodName;
-            this._paramsList = paramsList;
+            this.methodName = methodName;
+            this.params = paramsList;
         }
     }
 
@@ -237,7 +264,7 @@ public class LoadBalancerTO {
         private int healthcheckInterval;
         private int healthcheckThresshold;
         private int unhealthThresshold;
-        private boolean revoke = false;
+        private boolean revoked = false;
 
         public HealthCheckPolicyTO(String pingPath, String description, int responseTime, int healthcheckInterval, int healthcheckThresshold, int unhealthThresshold,
                 boolean revoke) {
@@ -248,7 +275,7 @@ public class LoadBalancerTO {
             this.healthcheckInterval = healthcheckInterval;
             this.healthcheckThresshold = healthcheckThresshold;
             this.unhealthThresshold = unhealthThresshold;
-            this.revoke = revoke;
+            this.revoked = revoke;
         }
 
         public HealthCheckPolicyTO() {
@@ -280,11 +307,11 @@ public class LoadBalancerTO {
         }
 
         public void setRevoke(boolean revoke) {
-            this.revoke = revoke;
+            this.revoked = revoke;
         }
 
         public boolean isRevoked() {
-            return revoke;
+            return revoked;
         }
 
     }
@@ -303,6 +330,12 @@ public class LoadBalancerTO {
             this.alreadyAdded = alreadyAdded;
         }
 
+        public DestinationTO(String destIp, int destPort, String monitorState) {
+            this.destIp = destIp;
+            this.destPort = destPort;
+            this.monitorState = monitorState;
+        }
+
         protected DestinationTO() {
         }
 
diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java
index b46b352..32a3138 100644
--- a/api/src/com/cloud/event/EventTypes.java
+++ b/api/src/com/cloud/event/EventTypes.java
@@ -391,6 +391,10 @@ public class EventTypes {
     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";
@@ -549,6 +553,9 @@ public class EventTypes {
     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";
+
 
     static {
 
diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java
index 598b77f..0ad42b5 100644
--- a/api/src/com/cloud/network/NetworkService.java
+++ b/api/src/com/cloud/network/NetworkService.java
@@ -19,6 +19,7 @@ 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;
@@ -26,6 +27,7 @@ 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;
@@ -38,6 +40,7 @@ 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;
 
@@ -182,4 +185,8 @@ public interface NetworkService {
     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/VirtualRouterProvider.java b/api/src/com/cloud/network/VirtualRouterProvider.java
index 8e2fa70..aca526b 100644
--- a/api/src/com/cloud/network/VirtualRouterProvider.java
+++ b/api/src/com/cloud/network/VirtualRouterProvider.java
@@ -21,7 +21,7 @@ import org.apache.cloudstack.api.InternalIdentity;
 
 public interface VirtualRouterProvider extends InternalIdentity, Identity {
     public enum Type {
-        VirtualRouter, ElasticLoadBalancerVm, VPCVirtualRouter, InternalLbVm
+        VirtualRouter, ElasticLoadBalancerVm, VPCVirtualRouter, InternalLbVm, NetScalerVm
     }
 
     public Type getType();
diff --git a/api/src/com/cloud/network/router/VirtualRouter.java b/api/src/com/cloud/network/router/VirtualRouter.java
index 060ef0f..84c85ce 100644
--- a/api/src/com/cloud/network/router/VirtualRouter.java
+++ b/api/src/com/cloud/network/router/VirtualRouter.java
@@ -23,7 +23,7 @@ import com.cloud.vm.VirtualMachine;
  */
 public interface VirtualRouter extends VirtualMachine {
     public enum Role {
-        VIRTUAL_ROUTER, LB, INTERNAL_LB_VM
+        VIRTUAL_ROUTER, LB, INTERNAL_LB_VM, NETSCALER_VM
     }
 
     public enum UpdateState {
diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java
index 5eab98a..59045dc 100644
--- a/api/src/com/cloud/offering/NetworkOffering.java
+++ b/api/src/com/cloud/offering/NetworkOffering.java
@@ -38,7 +38,7 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity,
     }
 
     public enum Detail {
-        InternalLbProvider, PublicLbProvider
+        InternalLbProvider, PublicLbProvider, servicepackageuuid, servicepackagedescription
     }
 
     public final static String SystemPublicNetwork = "System-Public-Network";
@@ -133,4 +133,6 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity,
     boolean getSupportsStrechedL2();
 
     boolean getSupportsPublicAccess();
+
+    String getServicePackage();
 }
diff --git a/api/src/com/cloud/vm/VirtualMachine.java b/api/src/com/cloud/vm/VirtualMachine.java
index b45ac7c..c70197a 100644
--- a/api/src/com/cloud/vm/VirtualMachine.java
+++ b/api/src/com/cloud/vm/VirtualMachine.java
@@ -214,6 +214,7 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I
 
     public enum Type {
         User(false), DomainRouter(true), ConsoleProxy(true), SecondaryStorageVm(true), ElasticIpVm(true), ElasticLoadBalancerVm(true), InternalLoadBalancerVm(true),
+        NetScalerVm(true),
 
         /*
          * UserBareMetal is only used for selecting VirtualMachineGuru, there is no
diff --git a/api/src/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java
index a461367..eba41b4 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java
@@ -32,7 +32,7 @@ import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.ResourceAllocationException;
 import com.cloud.exception.ResourceUnavailableException;
 
-@APICommand(name = "acquirePodIpAddresses", description = "Allocates IP addresses in respective Pod of a Zone", responseObject = AcquirePodIpCmdResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+@APICommand(name = "acquirePodIpAddress", description = "Allocates IP addresses in respective Pod of a Zone", responseObject = AcquirePodIpCmdResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
 public class AcquirePodIpCmdByAdmin extends BaseCmd {
 
     public static final Logger s_logger = Logger.getLogger(AcquirePodIpCmdByAdmin.class.getName());
@@ -42,28 +42,30 @@ public class AcquirePodIpCmdByAdmin extends BaseCmd {
     //////////////// API parameters /////////////////////
     /////////////////////////////////////////////////////
 
-    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "the ID of the  zone in which your pod lies")
-    private Long zoneId;
+    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.STRING, entityType = ZoneResponse.class, required = true, description = "the ID of the  zone")
+    private String zoneId;
 
-    @Parameter(name = ApiConstants.GUEST_CIDR_ADDRESS, type = CommandType.STRING, entityType = ZoneResponse.class, required = false, description = "CIDR for finding Pod")
-    private String cidr;
+    @Parameter(name = ApiConstants.POD_ID, type = CommandType.STRING, entityType = ZoneResponse.class, required = false, description = "Pod ID")
+    private String podId;
 
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
     /////////////////////////////////////////////////////
 
-    private long getZoneId() {
+    private String getZoneId() {
         return zoneId;
     }
 
-    private String getCidr() {
-        return cidr;
+    public String getPodId() {
+        return podId;
     }
 
+
     /////////////////////////////////////////////////////
     /////////////// API Implementation///////////////////
     /////////////////////////////////////////////////////
 
+
     @Override
     public String getCommandName() {
         return s_name;
@@ -71,12 +73,12 @@ public class AcquirePodIpCmdByAdmin extends BaseCmd {
 
     @Override
     public void execute() throws ResourceUnavailableException, ResourceAllocationException, ConcurrentOperationException {
-        AcquirePodIpCmdResponse pod_ip = null;
-        pod_ip = _networkService.allocatePodIp(_accountService.getAccount(getEntityOwnerId()), getZoneId(), getCidr());
-        if (pod_ip != null) {
-            pod_ip.setResponseName(getCommandName());
-            pod_ip.setObjectName(getCommandName());
-            setResponseObject(pod_ip);
+        AcquirePodIpCmdResponse podIp = null;
+        podIp = _networkService.allocatePodIp(_accountService.getAccount(getEntityOwnerId()), getZoneId(), getPodId());
+        if (podIp != null) {
+            podIp.setResponseName(getCommandName());
+            podIp.setObjectName(getCommandName());
+            setResponseObject(podIp);
         } else {
             throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to assign IP address");
         }
diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
index a09c979..d1a3418 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
@@ -273,10 +273,23 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
         }
 
         Collection paramsCollection = details.values();
-        Map<String, String> params = (Map<String, String>)(paramsCollection.toArray())[0];
+        Object objlist[]= paramsCollection.toArray();
+        Map<String, String> params = (Map<String, String>)(objlist[0]);
+        for(int i=1; i< objlist.length; i++)
+        {
+            params.putAll((Map<String, String>)(objlist[i]));
+        }
+
         return params;
     }
 
+    public String getServicePackageId() {
+        Map<String, String> data = getDetails();
+        if (data == null)
+            return null;
+        return data.get(NetworkOffering.Detail.servicepackageuuid+ "");
+    }
+
     /////////////////////////////////////////////////////
     /////////////// API Implementation///////////////////
     /////////////////////////////////////////////////////
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerRuleCmd.java
index 6b1e0fd..6ee277a 100644
--- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerRuleCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerRuleCmd.java
@@ -64,6 +64,9 @@ public class UpdateLoadBalancerRuleCmd extends BaseAsyncCustomIdCmd {
     @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.PROTOCOL, type = CommandType.STRING, description = "The protocol for the LB")
+    private String lbProtocol;
+
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
     /////////////////////////////////////////////////////
@@ -88,6 +91,10 @@ public class UpdateLoadBalancerRuleCmd extends BaseAsyncCustomIdCmd {
         return display;
     }
 
+    public String getLbProtocol() {
+       return lbProtocol;
+    }
+
     /////////////////////////////////////////////////////
     /////////////// API Implementation///////////////////
     /////////////////////////////////////////////////////
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UploadSslCertCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UploadSslCertCmd.java
index a6d71c7..309e43f 100644
--- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UploadSslCertCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UploadSslCertCmd.java
@@ -73,6 +73,9 @@ public class UploadSslCertCmd extends BaseCmd {
     @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "domain ID of the account owning the SSL certificate")
     private Long domainId;
 
+    @Parameter(name = ApiConstants.NAME , type = CommandType.STRING, required = true, description = "Name for the uploaded certificate")
+    private String name;
+
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
     /////////////////////////////////////////////////////
@@ -105,10 +108,15 @@ public class UploadSslCertCmd extends BaseCmd {
         return projectId;
     }
 
+    public String getName() {
+        return name;
+    }
+
     /////////////////////////////////////////////////////
     /////////////// API Implementation///////////////////
     /////////////////////////////////////////////////////
 
+
     @Override
     public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
         ResourceAllocationException, NetworkRuleConflictException {
diff --git a/api/src/org/apache/cloudstack/api/response/AcquireIPAddressResponse.java b/api/src/org/apache/cloudstack/api/response/AcquireIPAddressResponse.java
index 6d6a035..70cbd7f 100644
--- a/api/src/org/apache/cloudstack/api/response/AcquireIPAddressResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/AcquireIPAddressResponse.java
@@ -150,11 +150,6 @@ public class AcquireIPAddressResponse  extends BaseResponse implements Controlle
  @Param(description = "is public ip for display to the regular user", since = "4.4", authorized = {RoleType.Admin})
  private Boolean forDisplay;
 
- /*
-     @SerializedName(ApiConstants.JOB_ID) @Param(description="shows the current pending asynchronous job ID. This tag is not returned if no current pending jobs are acting on the volume")
-     private IdentityProxy jobId = new IdentityProxy("async_job");
- */
-
  public void setIpAddress(String ipAddress) {
      this.ipAddress = ipAddress;
  }
diff --git a/api/src/org/apache/cloudstack/api/response/SslCertResponse.java b/api/src/org/apache/cloudstack/api/response/SslCertResponse.java
index d722e98..aa729f1 100644
--- a/api/src/org/apache/cloudstack/api/response/SslCertResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/SslCertResponse.java
@@ -72,6 +72,10 @@ public class SslCertResponse extends BaseResponse {
     @Param(description = "List of loabalancers this certificate is bound to")
     List<String> lbIds;
 
+    @SerializedName(ApiConstants.NAME)
+    @Param(description = "name")
+    private String name;
+
     public SslCertResponse() {
     }
 
@@ -83,6 +87,10 @@ public class SslCertResponse extends BaseResponse {
         this.certificate = cert;
     }
 
+    public void setName(String name) {
+        this.name = name;
+    }
+
     public void setAccountName(String accountName) {
         this.accountName = accountName;
     }
diff --git a/api/src/org/apache/cloudstack/api/response/SystemVmResponse.java b/api/src/org/apache/cloudstack/api/response/SystemVmResponse.java
index 9e20b49..49ab473 100644
--- a/api/src/org/apache/cloudstack/api/response/SystemVmResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/SystemVmResponse.java
@@ -17,6 +17,7 @@
 package org.apache.cloudstack.api.response;
 
 import java.util.Date;
+import java.util.List;
 
 import com.google.gson.annotations.SerializedName;
 
@@ -141,7 +142,13 @@ public class SystemVmResponse extends BaseResponse {
     @Param(description = "the number of active console sessions for the console proxy system vm")
     private Integer activeViewerSessions;
 
-    // private Long objectId;
+    @SerializedName("guestvlan")
+    @Param(description = "guest vlan range")
+    private String guestVlan;
+
+    @SerializedName("publicvlan")
+    @Param(description = "public vlan range")
+    private List<String> publicVlan;
 
     @Override
     public String getObjectId() {
@@ -355,4 +362,20 @@ public class SystemVmResponse extends BaseResponse {
     public void setLinkLocalNetmask(String linkLocalNetmask) {
         this.linkLocalNetmask = linkLocalNetmask;
     }
+
+    public String getGuestVlan() {
+        return guestVlan;
+    }
+
+    public void setGuestVlan(String guestVlan) {
+        this.guestVlan = guestVlan;
+    }
+
+    public List<String> getPublicVlan() {
+        return publicVlan;
+    }
+
+    public void setPublicVlan(List<String> publicVlan) {
+        this.publicVlan = publicVlan;
+    }
 }
diff --git a/api/src/org/apache/cloudstack/network/tls/SslCert.java b/api/src/org/apache/cloudstack/network/tls/SslCert.java
index fb1590c..074bba6 100644
--- a/api/src/org/apache/cloudstack/network/tls/SslCert.java
+++ b/api/src/org/apache/cloudstack/network/tls/SslCert.java
@@ -31,5 +31,5 @@ public interface SslCert extends InternalIdentity, Identity, ControlledEntity {
     public String getPassword();
 
     public String getFingerPrint();
-
+    public String getName();
 }
diff --git a/core/src/com/cloud/agent/api/ExternalNetworkResourceUsageCommand.java b/core/src/com/cloud/agent/api/ExternalNetworkResourceUsageCommand.java
index 09dc80b..6986c40 100644
--- a/core/src/com/cloud/agent/api/ExternalNetworkResourceUsageCommand.java
+++ b/core/src/com/cloud/agent/api/ExternalNetworkResourceUsageCommand.java
@@ -20,12 +20,21 @@
 package com.cloud.agent.api;
 
 public class ExternalNetworkResourceUsageCommand extends Command {
+    Long networkid;
 
     public ExternalNetworkResourceUsageCommand() {
     }
 
+    public ExternalNetworkResourceUsageCommand(Long networkid) {
+        this.networkid = networkid;
+    }
+
     @Override
     public boolean executeInSequence() {
         return false;
     }
+
+    public Long getNetworkid() {
+        return networkid;
+    }
 }
diff --git a/core/src/com/cloud/agent/api/NetScalerImplementNetworkCommand.java b/core/src/com/cloud/agent/api/NetScalerImplementNetworkCommand.java
index ea6afa1..06e4eb8 100644
--- a/core/src/com/cloud/agent/api/NetScalerImplementNetworkCommand.java
+++ b/core/src/com/cloud/agent/api/NetScalerImplementNetworkCommand.java
@@ -26,15 +26,15 @@ public class NetScalerImplementNetworkCommand extends Command {
         super();
     }
 
-    private Long dcId;
+    private String dcId;
     private Long hostId;
 
-    public NetScalerImplementNetworkCommand(Long dcId) {
+    public NetScalerImplementNetworkCommand(String dcId) {
         super();
         this.dcId = dcId;
     }
 
-    public NetScalerImplementNetworkCommand(Long dcId, Long hostId, String networkDetails) {
+    public NetScalerImplementNetworkCommand(String dcId, Long hostId, String networkDetails) {
         this(dcId);
         this.hostId = hostId;
         this._networkDetails = networkDetails;
@@ -48,7 +48,7 @@ public class NetScalerImplementNetworkCommand extends Command {
         return _networkDetails;
     }
 
-    public Long getDataCenterId() {
+    public String getDataCenterId() {
         return dcId;
     }
 
diff --git a/core/src/com/cloud/agent/api/routing/HealthCheckLBConfigCommand.java b/core/src/com/cloud/agent/api/routing/HealthCheckLBConfigCommand.java
index d30fed4..ee401f6 100644
--- a/core/src/com/cloud/agent/api/routing/HealthCheckLBConfigCommand.java
+++ b/core/src/com/cloud/agent/api/routing/HealthCheckLBConfigCommand.java
@@ -26,16 +26,20 @@ import com.cloud.agent.api.to.LoadBalancerTO;
  */
 public class HealthCheckLBConfigCommand extends NetworkElementCommand {
     LoadBalancerTO[] loadBalancers;
-
+    long networkId;
     protected HealthCheckLBConfigCommand() {
     }
 
-    public HealthCheckLBConfigCommand(LoadBalancerTO[] loadBalancers) {
+    public HealthCheckLBConfigCommand(LoadBalancerTO[] loadBalancers, long networkid) {
         this.loadBalancers = loadBalancers;
+        this.networkId = networkid;
     }
 
     public LoadBalancerTO[] getLoadBalancers() {
         return loadBalancers;
     }
 
+    public long getNetworkId() {
+        return networkId;
+    }
 }
diff --git a/engine/components-api/src/com/cloud/network/IpAddressManager.java b/engine/components-api/src/com/cloud/network/IpAddressManager.java
index bf97b34..30976e5 100644
--- a/engine/components-api/src/com/cloud/network/IpAddressManager.java
+++ b/engine/components-api/src/com/cloud/network/IpAddressManager.java
@@ -183,7 +183,7 @@ public interface IpAddressManager {
 
     String allocatePublicIpForGuestNic(Network network, Long podId, Account ipOwner, String requestedIp) throws InsufficientAddressCapacityException;
 
-    public AcquirePodIpCmdResponse allocatePodIp(Long zoneId, String cidr) throws ConcurrentOperationException,
+    public AcquirePodIpCmdResponse allocatePodIp(String zoneId, String podId) throws ConcurrentOperationException,
             ResourceAllocationException;
 
     public void releasePodIp(Long id) throws CloudRuntimeException;
diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
index 8cc8de1..f370111 100755
--- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
+++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -404,7 +404,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
                 }
 
                 try {
-                    _networkMgr.allocate(vmProfile, auxiliaryNetworks);
+                    if (!vmProfile.getBootArgs().contains("ExternalLoadBalancerVm"))
+                        _networkMgr.allocate(vmProfile, auxiliaryNetworks);
                 } catch (final ConcurrentOperationException e) {
                     throw new CloudRuntimeException("Concurrent operation while trying to allocate resources for the VM", e);
                 }
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
index 7f43b52..37f5330 100644
--- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
+++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
@@ -442,7 +442,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
                 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, null);
+                            false, null, false, null, true);
                     offering.setState(NetworkOffering.State.Enabled);
                     _networkOfferingDao.update(offering.getId(), offering);
                 }
@@ -451,7 +451,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
                 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, null);
+                            null, true, false, null, false, null, true);
                     offering.setState(NetworkOffering.State.Enabled);
                     _networkOfferingDao.update(offering.getId(), offering);
                 }
@@ -460,7 +460,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
                 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, null);
+                            null, true);
                     offering.setState(NetworkOffering.State.Enabled);
                     _networkOfferingDao.update(offering.getId(), offering);
                 }
@@ -470,7 +470,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
                     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, null);
+                            true);
 
                     offering.setState(NetworkOffering.State.Enabled);
                     _networkOfferingDao.update(offering.getId(), offering);
@@ -480,7 +480,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
                 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, null);
+                            defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true);
                     offering.setState(NetworkOffering.State.Enabled);
                     _networkOfferingDao.update(offering.getId(), offering);
                 }
@@ -491,7 +491,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
                     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, null);
+                            null, defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true);
                     offering.setState(NetworkOffering.State.Enabled);
                     _networkOfferingDao.update(offering.getId(), offering);
                 }
@@ -500,7 +500,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
                 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, null);
+                            true, null, true, false, null, false, null, true);
                     offering.setState(NetworkOffering.State.Enabled);
                     _networkOfferingDao.update(offering.getId(), offering);
                 }
@@ -524,7 +524,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
                 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, null);
+                            true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true);
                     offering.setState(NetworkOffering.State.Enabled);
                     offering.setInternalLb(true);
                     offering.setPublicLb(false);
@@ -556,7 +556,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
                 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, null);
+                            netscalerServiceProviders, true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true, false, null, false, null, true);
                     offering.setState(NetworkOffering.State.Enabled);
                     offering.setDedicatedLB(false);
                     _networkOfferingDao.update(offering.getId(), offering);
diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDaoImpl.java
index 1feb6ad..e840a4d 100644
--- a/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDaoImpl.java
+++ b/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDaoImpl.java
@@ -181,15 +181,12 @@ public class DataCenterIpAddressDaoImpl extends GenericDaoBase<DataCenterIpAddre
         if (s_logger.isDebugEnabled()) {
             s_logger.debug("Releasing ip address for ID=" + id);
         }
-//        SearchCriteria<DataCenterIpAddressVO> sc = AllFieldsSearch.create();
-//        sc.setParameters("id", id);
 
         DataCenterIpAddressVO vo = this.findById(id);
         vo.setTakenAt(null);
         vo.setInstanceId(null);
         vo.setReservationId(null);
         persist(vo);
-        //update(vo, sc);
     }
 
     @Override
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkDao.java b/engine/schema/src/com/cloud/network/dao/NetworkDao.java
index 684a94f..85544e7 100644
--- a/engine/schema/src/com/cloud/network/dao/NetworkDao.java
+++ b/engine/schema/src/com/cloud/network/dao/NetworkDao.java
@@ -120,4 +120,6 @@ public interface NetworkDao extends GenericDao<NetworkVO, Long>, StateDao<State,
     List<NetworkVO> listByAclId(long aclId);
 
     int getNonSystemNetworkCountByVpcId(long vpcId);
+
+    List<NetworkVO> listNetworkVO(List<Long> idset);
 }
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java b/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java
index 29d0e8f..49a5944 100644
--- a/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java
+++ b/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java
@@ -24,9 +24,10 @@ 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 org.apache.cloudstack.acl.ControlledEntity.ACLType;
+
 import com.cloud.network.Network;
 import com.cloud.network.Network.Event;
 import com.cloud.network.Network.GuestType;
@@ -42,6 +43,7 @@ import com.cloud.offerings.dao.NetworkOfferingDao;
 import com.cloud.server.ResourceTag.ResourceObjectType;
 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;
@@ -56,7 +58,7 @@ import com.cloud.utils.net.NetUtils;
 
 @Component
 @DB()
-public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements NetworkDao {
+public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long>implements NetworkDao {
     SearchBuilder<NetworkVO> AllFieldsSearch;
     SearchBuilder<NetworkVO> AccountSearch;
     SearchBuilder<NetworkVO> RelatedConfigSearch;
@@ -275,7 +277,6 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
         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);
@@ -680,4 +681,13 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
         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/SslCertVO.java b/engine/schema/src/com/cloud/network/dao/SslCertVO.java
index 1d72180..2aaa6a2 100644
--- a/engine/schema/src/com/cloud/network/dao/SslCertVO.java
+++ b/engine/schema/src/com/cloud/network/dao/SslCertVO.java
@@ -60,11 +60,14 @@ public class SslCertVO implements SslCert {
     @Column(name = "fingerprint")
     String fingerPrint;
 
+    @Column(name = "name")
+    String name;
+
     public SslCertVO() {
         uuid = UUID.randomUUID().toString();
     }
 
-    public SslCertVO(String cert, String key, String password, String chain, Long accountId, Long domainId, String fingerPrint) {
+    public SslCertVO(String cert, String key, String password, String chain, Long accountId, Long domainId, String fingerPrint, String name) {
         certificate = cert;
         this.key = key;
         this.chain = chain;
@@ -73,6 +76,7 @@ public class SslCertVO implements SslCert {
         this.domainId = domainId;
         this.fingerPrint = fingerPrint;
         uuid = UUID.randomUUID().toString();
+        this.name = name;
     }
 
     // Getters
@@ -122,6 +126,11 @@ public class SslCertVO implements SslCert {
     }
 
     @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
     public Class<?> getEntityType() {
         return SslCert.class;
     }
diff --git a/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java b/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java
index 4325287..f40f710 100644
--- a/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java
+++ b/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java
@@ -156,6 +156,9 @@ public class NetworkOfferingVO implements NetworkOffering {
     @Column(name = "public_lb")
     boolean publicLb;
 
+    @Column(name="service_package_id")
+    String servicePackageUuid = null;
+
     @Override
     public boolean isKeepAliveEnabled() {
         return keepAliveEnabled;
@@ -500,8 +503,17 @@ public class NetworkOfferingVO implements NetworkOffering {
         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/NetworkOfferingDao.java b/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDao.java
index b7aa94b..19beddd 100644
--- a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDao.java
+++ b/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDao.java
@@ -61,4 +61,7 @@ public interface NetworkOfferingDao extends GenericDao<NetworkOfferingVO, Long>
 
     NetworkOfferingVO persist(NetworkOfferingVO off, Map<Detail, String> details);
 
+    List<Long> listNetworkOfferingID();
+
+    boolean isUsingServicePackage(String uuid);
 }
diff --git a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java b/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java
index 5a6092e..c7298f2 100644
--- a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java
+++ b/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java
@@ -16,6 +16,7 @@
 // under the License.
 package com.cloud.offerings.dao;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
@@ -32,6 +33,7 @@ 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;
@@ -189,4 +191,32 @@ public class NetworkOfferingDaoImpl extends GenericDaoBase<NetworkOfferingVO, Lo
         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(list!=null && !list.isEmpty())
+            return true;
+
+        return false;
+    }
 }
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
index 64ca406..668f4ac 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
@@ -216,6 +216,10 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
             }
         }
 
+        if (vm.getType() == VirtualMachine.Type.NetScalerVm) {
+            details.put(VmDetailConstants.ROOT_DISK_CONTROLLER, "scsi");
+        }
+
         List<NicProfile> nicProfiles = vm.getNics();
 
         for (NicProfile nicProfile : nicProfiles) {
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
index 5c87309..8b78534 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
@@ -2022,6 +2022,16 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
             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)
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java
index ccb18a2..10c4307 100644
--- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java
+++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java
@@ -86,6 +86,7 @@ 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;
@@ -1319,6 +1320,18 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
 
         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("vm-data/ip", mgmtNic.getIp().toString().trim());
+                xenstoreData.put("vm-data/gateway", mgmtNic.getGateway().toString().trim());
+                xenstoreData.put("vm-data/netmask", mgmtNic.getNetmask().toString().trim());
+                vmr.xenstoreData = xenstoreData;
+            }
+        }
 
         final VM vm = VM.create(conn, vmr);
         if (s_logger.isDebugEnabled()) {
@@ -1329,8 +1342,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
 
         final Integer speed = vmSpec.getMinSpeed();
         if (speed != null) {
-
-            int cpuWeight = _maxWeight; // cpu_weight
+        int cpuWeight = _maxWeight; // cpu_weight
             int utilization = 0; // max CPU cap, default is unlimited
 
             // weight based allocation, CPU weight is calculated per VCPU
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixStartCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixStartCommandWrapper.java
index 073f000..5d8d0e7 100644
--- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixStartCommandWrapper.java
+++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixStartCommandWrapper.java
@@ -87,7 +87,6 @@ public final class CitrixStartCommandWrapper extends CommandWrapper<StartCommand
 
             final Host host = Host.getByUuid(conn, citrixResourceBase.getHost().getUuid());
             vm = citrixResourceBase.createVmFromTemplate(conn, vmSpec, host);
-
             final GPUDeviceTO gpuDevice = vmSpec.getGpuDevice();
             if (gpuDevice != null) {
                 s_logger.debug("Creating VGPU for of VGPU type: " + gpuDevice.getVgpuType() + " in GPU group " + gpuDevice.getGpuGroup() + " for VM " + vmName);
diff --git a/plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/spring-netscaler-context.xml b/plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/spring-netscaler-context.xml
index 5727304..ae19c92 100644
--- a/plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/spring-netscaler-context.xml
+++ b/plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/spring-netscaler-context.xml
@@ -32,5 +32,5 @@
     <bean id="netscalerElement" class="com.cloud.network.element.NetscalerElement" >
         <property name="name" value="Netscaler"/>
     </bean>
-
+    <bean id="NetScalerVMManager" class="com.cloud.network.vm.NetScalerVMManagerImpl" />
 </beans>
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteServicePackageOfferingCmd.java b/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerControlCenterCmd.java
similarity index 78%
copy from plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteServicePackageOfferingCmd.java
copy to plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerControlCenterCmd.java
index 1fbd899..00d4b32 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteServicePackageOfferingCmd.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerControlCenterCmd.java
@@ -28,21 +28,19 @@ 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 org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.context.CallContext;
 
-import com.cloud.api.response.NetScalerServicePackageResponse;
+import com.cloud.api.response.NetscalerControlCenterResponse;
 import com.cloud.exception.ConcurrentOperationException;
-//import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.network.element.NetscalerLoadBalancerElementService;
 import com.cloud.utils.exception.CloudRuntimeException;
 
-@APICommand(name = "deleteServicePackageOffering", responseObject = SuccessResponse.class, description = "Delete Service Package Offering")
-public class DeleteServicePackageOfferingCmd extends BaseCmd {
+@APICommand(name = "deleteNetscalerControlCenter", responseObject = SuccessResponse.class, description = "Delete Netscaler Control Center")
+public class DeleteNetscalerControlCenterCmd extends BaseCmd {
 
     public static final Logger s_logger = Logger.getLogger(DeleteServicePackageOfferingCmd.class.getName());
-    private static final String s_name = "deleteServicePackageOffering";
+    private static final String s_name = "deleteNetscalerControlCenter";
     @Inject
     NetscalerLoadBalancerElementService _netsclarLbService;
 
@@ -50,32 +48,36 @@ public class DeleteServicePackageOfferingCmd extends BaseCmd {
     //////////////// API parameters /////////////////////
     /////////////////////////////////////////////////////
 
-    @Parameter(name = ApiConstants.ID, type = CommandType.STRING, entityType = NetScalerServicePackageResponse.class, required = true, description = "the service offering ID")
+    @Parameter(name = ApiConstants.ID, type = CommandType.STRING, entityType = NetscalerControlCenterResponse.class, required = true, description = "Netscaler Control Center ID")
     private String ID;
 
     @Override
     public void execute() throws ServerApiException, ConcurrentOperationException, EntityExistsException {
         SuccessResponse response = new SuccessResponse();
         try {
-            boolean result = _netsclarLbService.deleteServicePackageOffering(this);
-
+            boolean result = _netsclarLbService.deleteNetscalerControlCenter(this);
             if (response != null && result) {
-                response.setDisplayText("Deleted Successfully");
+                response.setDisplayText("Netscaler Control Center Deleted Successfully");
                 response.setSuccess(result);
                 response.setResponseName(getCommandName());
-                this.setResponseObject(response);
+                setResponseObject(response);
             }
         } catch (CloudRuntimeException runtimeExcp) {
             response.setDisplayText(runtimeExcp.getMessage());
             response.setSuccess(false);
             response.setResponseName(getCommandName());
-            this.setResponseObject(response);
+            setResponseObject(response);
             return;
         } catch (Exception e) {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete Service Package due to internal error.");
+            e.printStackTrace();
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
         }
     }
 
+    public String setId(String iD) {
+        return ID = iD;
+    }
+
     public String getId() {
         return ID;
     }
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerLoadBalancerCmd.java b/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerLoadBalancerCmd.java
index 1baa7b0..16990c5 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerLoadBalancerCmd.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerLoadBalancerCmd.java
@@ -96,7 +96,7 @@ public class DeleteNetscalerLoadBalancerCmd extends BaseAsyncCmd {
 
     @Override
     public String getEventType() {
-        return EventTypes.EVENT_LOAD_BALANCER_DELETE;
+        return EventTypes.EVENT_EXTERNAL_NCC_DEVICE_DELETE;
     }
 
     @Override
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteServicePackageOfferingCmd.java b/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteServicePackageOfferingCmd.java
index 1fbd899..96cd16e 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteServicePackageOfferingCmd.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteServicePackageOfferingCmd.java
@@ -34,15 +34,14 @@ import org.apache.cloudstack.api.response.SuccessResponse;
 
 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 = "deleteServicePackageOffering", responseObject = SuccessResponse.class, description = "Delete Service Package Offering")
+@APICommand(name = "deleteServicePackageOffering", responseObject = SuccessResponse.class, description = "Delete Service Package")
 public class DeleteServicePackageOfferingCmd extends BaseCmd {
 
     public static final Logger s_logger = Logger.getLogger(DeleteServicePackageOfferingCmd.class.getName());
-    private static final String s_name = "deleteServicePackageOffering";
+    private static final String s_name = "deleteServicePackage";
     @Inject
     NetscalerLoadBalancerElementService _netsclarLbService;
 
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterNetscalerControlCenterCmd.java b/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeployNetscalerVpxCmd.java
similarity index 54%
copy from plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterNetscalerControlCenterCmd.java
copy to plugins/network-elements/netscaler/src/com/cloud/api/commands/DeployNetscalerVpxCmd.java
index 8887736..8089599 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterNetscalerControlCenterCmd.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeployNetscalerVpxCmd.java
@@ -15,16 +15,25 @@
 
 package com.cloud.api.commands;
 
+import java.util.List;
+import java.util.Map;
+
 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.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.NetworkResponse;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
+import org.apache.cloudstack.api.response.SystemVmResponse;
+import org.apache.cloudstack.api.response.TemplateResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
 import org.apache.cloudstack.context.CallContext;
 
 import com.cloud.api.response.NetscalerLoadBalancerResponse;
@@ -34,16 +43,17 @@ import com.cloud.exception.InsufficientCapacityException;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.ResourceAllocationException;
 import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.network.NetScalerControlCenterVO;
 import com.cloud.network.element.NetscalerLoadBalancerElementService;
+import com.cloud.user.Account;
 import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VirtualMachine;
 
-@APICommand(name = "registerNetscalerControlCenter", responseObject = NetscalerLoadBalancerResponse.class, description = "Adds a netscaler control center device",
+@APICommand(name = "deployNetscalerVpx", responseObject = NetscalerLoadBalancerResponse.class, description = "Creates new NS Vpx",
         requestHasSensitiveInfo = true, responseHasSensitiveInfo = false)
-public class RegisterNetscalerControlCenterCmd extends BaseAsyncCmd {
+public class DeployNetscalerVpxCmd extends BaseAsyncCmd {
 
-    public static final Logger s_logger = Logger.getLogger(RegisterNetscalerControlCenterCmd.class.getName());
-    private static final String s_name = "registernetscalercontrolcenterrresponse";
+    public static final Logger s_logger = Logger.getLogger(DeployNetscalerVpxCmd.class.getName());
+    private static final String s_name = "deployNetscalerVpx";
     @Inject
     NetscalerLoadBalancerElementService _netsclarLbService;
 
@@ -51,52 +61,27 @@ public class RegisterNetscalerControlCenterCmd extends BaseAsyncCmd {
     //////////////// API parameters /////////////////////
     /////////////////////////////////////////////////////
 
-    @Parameter(name = ApiConstants.IP_ADDRESS , type = CommandType.STRING, required = true, description = "URL of the netscaler controlcenter appliance.")
-    private String ipaddress;
-
-    @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = true, description = "Credentials to reach netscaler controlcenter device")
-    private String username;
+    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "availability zone for the virtual machine")
+    private Long zoneId;
 
-    @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, required = true, description = "Credentials to reach netscaler controlcenter  device")
-    private String password;
-
-    @Parameter(name = ApiConstants.NUM_RETRIES , type = CommandType.INTEGER, required = true, description = "Credentials to reach netscaler controlcenter device")
-    private int numretries;
+    @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.NETWORK_ID,
+            type = CommandType.UUID,
+            entityType = NetworkResponse.class, required=false,
+            description = "The network this ip address should be associated to.")
+    private Long networkId;
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
     /////////////////////////////////////////////////////
 
 
-    public String getUsername() {
-        return username;
-    }
-
-    public String getPassword() {
-        return password;
-    }
-
-
-    public static Logger getsLogger() {
-        return s_logger;
-    }
-
-    public static String getsName() {
-        return s_name;
-    }
-
-    public NetscalerLoadBalancerElementService get_netsclarLbService() {
-        return _netsclarLbService;
-    }
-
-    public String getIpaddress() {
-        return ipaddress;
-    }
-
-    public int getNumretries() {
-        return numretries;
-    }
 
     /////////////////////////////////////////////////////
     /////////////// API Implementation///////////////////
@@ -106,15 +91,17 @@ public class RegisterNetscalerControlCenterCmd extends BaseAsyncCmd {
     public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
         ResourceAllocationException {
         try {
-            NetScalerControlCenterVO nccVO = _netsclarLbService.registerNetscalerControlCenter(this);
-            if (nccVO != null) {
-                /*NetscalerLoadBalancerResponse response = _netsclarLbService.createNetscalerLoadBalancerResponse(lbDeviceVO);
-                response.setObjectName("netscalerloadbalancer");
-                response.setResponseName(getCommandName());
-                this.setResponseObject(response);*/
-            } else {
-                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add netscaler load balancer due to internal error.");
-            }
+            Map<String,Object> resp = _netsclarLbService.deployNetscalerServiceVm(this);
+           if (resp.size() > 0) {
+               SystemVmResponse response =  _responseGenerator.createSystemVmResponse((VirtualMachine)resp.get("vm"));
+               response.setGuestVlan((String)resp.get("guestvlan"));
+               response.setPublicVlan((List<String>)resp.get("publicvlan"));
+               response.setResponseName(getCommandName());
+               setResponseObject(response);
+           } else {
+               throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Fail to start system vm");
+           }
+
         } catch (InvalidParameterValueException invalidParamExcp) {
             throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage());
         } catch (CloudRuntimeException runtimeExcp) {
@@ -122,6 +109,14 @@ public class RegisterNetscalerControlCenterCmd extends BaseAsyncCmd {
         }
     }
 
+    public Long getServiceOfferingId() {
+        return serviceOfferingId;
+    }
+
+    public Long getTemplateId() {
+        return templateId;
+    }
+
     @Override
     public String getEventDescription() {
         return "Adding a netscaler load balancer device";
@@ -129,7 +124,7 @@ public class RegisterNetscalerControlCenterCmd extends BaseAsyncCmd {
 
     @Override
     public String getEventType() {
-        return EventTypes.EVENT_EXTERNAL_LB_DEVICE_ADD;
+        return EventTypes.EVENT_NETSCALER_VM_START;
     }
 
     @Override
@@ -137,8 +132,17 @@ public class RegisterNetscalerControlCenterCmd extends BaseAsyncCmd {
         return s_name;
     }
 
+    public Long getZoneId() {
+        return zoneId;
+    }
+
     @Override
     public long getEntityOwnerId() {
         return CallContext.current().getCallingAccount().getId();
     }
-}
\ No newline at end of file
+    public Account getAccount(){
+        return _accountService.getActiveAccountById(getEntityOwnerId());
+    }
+    public void getReservationContext() {
+    }
+}
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/ListNetscalerControlCenterCmd.java b/plugins/network-elements/netscaler/src/com/cloud/api/commands/ListNetscalerControlCenterCmd.java
new file mode 100644
index 0000000..1ff119a
--- /dev/null
+++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/ListNetscalerControlCenterCmd.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 com.cloud.api.commands;
+
+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.BaseListCmd;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.ListResponse;
+import com.cloud.api.response.NetscalerControlCenterResponse;
+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.NetScalerControlCenterVO;
+import com.cloud.network.element.NetscalerLoadBalancerElementService;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@APICommand(name = "listNetscalerControlCenter", responseObject = NetscalerControlCenterResponse.class, description = "list control center", requestHasSensitiveInfo = true, responseHasSensitiveInfo = false)
+public class ListNetscalerControlCenterCmd extends BaseListCmd {
+
+    public static final Logger s_logger = Logger.getLogger(ListNetscalerControlCenterCmd.class.getName());
+    private static final String s_name = "listNetscalerControlCenter";
+
+    @Inject
+    NetscalerLoadBalancerElementService _netsclarLbService;
+
+    public static String getsName() {
+        return s_name;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException,
+            ConcurrentOperationException, ResourceAllocationException {
+        try {
+            List<NetScalerControlCenterVO> lncCenters = _netsclarLbService.listNetscalerControlCenter(this);
+            if (lncCenters != null) {
+                ListResponse<NetscalerControlCenterResponse> response = new ListResponse<NetscalerControlCenterResponse>();
+                List<NetscalerControlCenterResponse> lncCentersResponse = new ArrayList<NetscalerControlCenterResponse>();
+                if (lncCenters != null && !lncCenters.isEmpty()) {
+                    for (NetScalerControlCenterVO lncCentersVO : lncCenters) {
+                        NetscalerControlCenterResponse lncCentreResponse = _netsclarLbService
+                                .createNetscalerControlCenterResponse(lncCentersVO);
+                        lncCentersResponse.add(lncCentreResponse);
+                    }
+                }
+
+                response.setResponses(lncCentersResponse);
+                response.setResponseName(getCommandName());
+                this.setResponseObject(response);
+            } else {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR,
+                        "Failed to list Net scalar Control Center due to some  internal error.");
+            }
+        } catch (InvalidParameterValueException invalidParamExcp) {
+            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage());
+        } catch (CloudRuntimeException runtimeExcp) {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage());
+        }
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+}
\ No newline at end of file
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterNetscalerControlCenterCmd.java b/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterNetscalerControlCenterCmd.java
index 8887736..fe98a7a 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterNetscalerControlCenterCmd.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterNetscalerControlCenterCmd.java
@@ -27,6 +27,7 @@ import org.apache.cloudstack.api.Parameter;
 import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.context.CallContext;
 
+import com.cloud.api.response.NetscalerControlCenterResponse;
 import com.cloud.api.response.NetscalerLoadBalancerResponse;
 import com.cloud.event.EventTypes;
 import com.cloud.exception.ConcurrentOperationException;
@@ -43,7 +44,7 @@ import com.cloud.utils.exception.CloudRuntimeException;
 public class RegisterNetscalerControlCenterCmd extends BaseAsyncCmd {
 
     public static final Logger s_logger = Logger.getLogger(RegisterNetscalerControlCenterCmd.class.getName());
-    private static final String s_name = "registernetscalercontrolcenterrresponse";
+    private static final String s_name = "registernetscalercontrolcenterresponse";
     @Inject
     NetscalerLoadBalancerElementService _netsclarLbService;
 
@@ -108,10 +109,10 @@ public class RegisterNetscalerControlCenterCmd extends BaseAsyncCmd {
         try {
             NetScalerControlCenterVO nccVO = _netsclarLbService.registerNetscalerControlCenter(this);
             if (nccVO != null) {
-                /*NetscalerLoadBalancerResponse response = _netsclarLbService.createNetscalerLoadBalancerResponse(lbDeviceVO);
+                NetscalerControlCenterResponse  response = _netsclarLbService.createNetscalerControlCenterResponse(nccVO);
                 response.setObjectName("netscalerloadbalancer");
                 response.setResponseName(getCommandName());
-                this.setResponseObject(response);*/
+                this.setResponseObject(response);
             } else {
                 throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add netscaler load balancer due to internal error.");
             }
@@ -124,12 +125,12 @@ public class RegisterNetscalerControlCenterCmd extends BaseAsyncCmd {
 
     @Override
     public String getEventDescription() {
-        return "Adding a netscaler load balancer device";
+        return "Adding a Netscaler Control Center Device";
     }
 
     @Override
     public String getEventType() {
-        return EventTypes.EVENT_EXTERNAL_LB_DEVICE_ADD;
+        return EventTypes.EVENT_EXTERNAL_NCC_DEVICE_ADD;
     }
 
     @Override
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
index 67c1c57..9fabe8d 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterServicePackageCmd.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterServicePackageCmd.java
@@ -52,17 +52,8 @@ public class RegisterServicePackageCmd extends BaseCmd {
     @Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, required = true, description = "Description of Service Package")
     private String description;
 
-    /*    @Override
-    public String getEventType() {
-        return EventTypes.EVENT_NETSCALER_SERVICEPACKAGE_ADD;
-    }
 
     @Override
-    public String getEventDescription() {
-        return "Adding Netscaler Service Package";
-    }
-     */
-    @Override
     public void execute() throws ServerApiException, ConcurrentOperationException, EntityExistsException {
         try {
             NetScalerServicePackageResponse response = _netsclarLbService.registerNetscalerServicePackage(this);
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/StopNetScalerVMCmd.java b/plugins/network-elements/netscaler/src/com/cloud/api/commands/StopNetScalerVMCmd.java
new file mode 100644
index 0000000..af95255
--- /dev/null
+++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/StopNetScalerVMCmd.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.api.commands;
+
+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.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.element.NetscalerLoadBalancerElementService;
+import com.cloud.network.router.VirtualRouter;
+import com.cloud.network.router.VirtualRouter.Role;
+import com.cloud.vm.VirtualMachine;
+
+@APICommand(name = "stopNetScalerVpx", description = "Stops a NetScalervm.", responseObject = DomainRouterResponse.class, entityType = {VirtualMachine.class},
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class StopNetScalerVMCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(StopNetScalerVMCmd.class.getName());
+    private static final String s_name = "stopNetScalerVmresponse";
+
+    @Inject
+    NetscalerLoadBalancerElementService _netsclarLbService;
+    // ///////////////////////////////////////////////////
+    // ////////////// API parameters /////////////////////
+    // ///////////////////////////////////////////////////
+    @ACL(accessType = AccessType.OperateEntry)
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DomainRouterResponse.class, required = true, description = "the ID of the NetScaler vm")
+    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 vm = _entityMgr.findById(VirtualRouter.class, getId());
+        if (vm != null && vm.getRole() == Role.NETSCALER_VM) {
+            return vm.getAccountId();
+        } else {
+            throw new InvalidParameterValueException("Unable to find NetScaler vm by id");
+        }
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_NETSCALER_VM_STOP;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "stopping Netscaler vm: " + 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("NetScaler vm Id: " + getId());
+        VirtualRouter result = null;
+        VirtualRouter vm = _routerService.findRouter(getId());
+        if (vm == null || vm.getRole() != Role.NETSCALER_VM) {
+            throw new InvalidParameterValueException("Can't find NetScaler lb vm by id");
+        } else {
+            result =   _netsclarLbService.stopNetscalerServiceVm(getId(), isForced(), CallContext.current().getCallingAccount(), CallContext.current().getCallingUserId());
+        }
+
+        if (result != null) {
+            DomainRouterResponse response = _responseGenerator.createDomainRouterResponse(result);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to stop Netscaler vm");
+        }
+    }
+}
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/response/NetscalerControlCenterResponse.java b/plugins/network-elements/netscaler/src/com/cloud/api/response/NetscalerControlCenterResponse.java
new file mode 100644
index 0000000..b4e4446
--- /dev/null
+++ b/plugins/network-elements/netscaler/src/com/cloud/api/response/NetscalerControlCenterResponse.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.api.response;
+
+import com.google.gson.annotations.SerializedName;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+import com.cloud.network.NetScalerControlCenterVO;
+import com.cloud.serializer.Param;
+
+public class NetscalerControlCenterResponse extends BaseResponse {
+
+    @SerializedName(ApiConstants.ID)
+    @Param(description = "id")
+    private String id;
+
+    @SerializedName(ApiConstants.USERNAME)
+    @Param(description = "username")
+    private String username;
+
+    @SerializedName(ApiConstants.UUID)
+    @Param(description = "uuid")
+    private String uuid;
+
+    @SerializedName(ApiConstants.IP_ADDRESS)
+    @Param(description = "ncc_ip")
+    private String nccip;
+
+    @SerializedName(ApiConstants.NUM_RETRIES)
+    @Param(description = "num_retries")
+    private String numretries;
+
+    public NetscalerControlCenterResponse() {
+    }
+
+    public NetscalerControlCenterResponse(NetScalerControlCenterVO controlcenter) {
+        this.id = controlcenter.getUuid();
+        this.username = controlcenter.getUsername();
+        this.uuid = controlcenter.getUuid();
+        this.username = controlcenter.getUsername();
+        this.nccip = controlcenter.getNccip();
+        this.numretries = String.valueOf(controlcenter.getNumRetries());
+    }
+
+    public String getUuid() {
+        return uuid;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public String getNccip() {
+        return nccip;
+    }
+
+    public void setNccip(String nccip) {
+        this.nccip = nccip;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getNumRetries() {
+        return numretries;
+    }
+
+    public void setNumRetries(String numRetries) {
+        this.numretries = numRetries;
+    }
+}
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerControlCenterVO.java b/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerControlCenterVO.java
index e1cd13d..84766bc 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerControlCenterVO.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerControlCenterVO.java
@@ -29,10 +29,9 @@ import org.apache.cloudstack.api.InternalIdentity;
 
 
 /**
- * NetScalerPodVO contains information about a EIP deployment where on datacenter L3 router a PBR (policy
- * based routing) is setup between a POD's subnet IP range to a NetScaler device. This VO object
- * represents a mapping between a POD and NetScaler device where PBR is setup.
- *
+ * NetScalerControlCenterVO contains information about a NetScaler Control Center(NCC) such as Username,
+ * Password used for login, the NCC IP and maximum number of unsuccessful tries a user can make.
+ * By using this information CloudStack can access the NCC.
  */
 @Entity
 @Table(name = "external_netscaler_controlcenter")
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerServicePackageVO.java b/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerServicePackageVO.java
index 758d5a3..82b3fef 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerServicePackageVO.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerServicePackageVO.java
@@ -30,10 +30,8 @@ import org.apache.cloudstack.api.InternalIdentity;
 import com.cloud.api.commands.RegisterServicePackageCmd;
 
 /**
- * NetScalerPodVO contains information about a EIP deployment where on datacenter L3 router a PBR (policy
- * based routing) is setup between a POD's subnet IP range to a NetScaler device. This VO object
- * represents a mapping between a POD and NetScaler device where PBR is setup.
- *
+ * NetScalerServicePackageVO contains information about service packages from NetScaler Control Center(NCC).
+ * By using the service package, CloudStack can choose the kind of NetScaler offering it wants to use.
  */
 @Entity
 @Table(name = " netscaler_servicepackages")
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDao.java b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDao.java
index fcda584..73fb263 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDao.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDao.java
@@ -26,4 +26,6 @@ public interface NetScalerServicePackageDao extends GenericDao<NetScalerServiceP
     NetScalerServicePackageVO findByPodId(long podId);
 
     List<NetScalerServicePackageVO> listByNetScalerDeviceId(long netscalerDeviceId);
+
+    public void removeAll();
 }
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDaoImpl.java b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDaoImpl.java
index df99b49..db3b5c0 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDaoImpl.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDaoImpl.java
@@ -40,11 +40,9 @@ public class NetScalerServicePackageDaoImpl extends GenericDaoBase<NetScalerServ
         super();
 
         podIdSearch = createSearchBuilder();
-        //podIdSearch.and("pod_id", podIdSearch.entity().getPodId(), Op.EQ);
         podIdSearch.done();
 
         deviceIdSearch = createSearchBuilder();
-        //deviceIdSearch.and("netscalerDeviceId", deviceIdSearch.entity().getNetscalerDeviceId(), Op.EQ);
         deviceIdSearch.done();
     }
 
@@ -62,4 +60,11 @@ public class NetScalerServicePackageDaoImpl extends GenericDaoBase<NetScalerServ
         return search(sc, null);
     }
 
+    @Override
+    public void removeAll() {
+        List<NetScalerServicePackageVO> list_NetScalerServicePackageVO = this.listAll();
+        for (NetScalerServicePackageVO row : list_NetScalerServicePackageVO) {
+            this.remove(row.getId());
+        }
+    }
 }
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
index 6f5a9a1..3371cf8 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java
@@ -37,8 +37,6 @@ 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.api.command.admin.address.AcquirePodIpCmdByAdmin;
-import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin;
 import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice;
@@ -61,12 +59,14 @@ 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;
@@ -79,7 +79,11 @@ 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;
@@ -121,24 +125,26 @@ 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.dao.RegisteredServicePackageVO;
 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.SearchCriteria;
 import com.cloud.utils.db.Transaction;
 import com.cloud.utils.db.TransactionCallback;
 import com.cloud.utils.db.TransactionCallbackNoReturn;
@@ -149,8 +155,9 @@ 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 {
+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");
@@ -172,10 +179,6 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
     DataCenterDao _dcDao;
     @Inject
     ExternalLoadBalancerDeviceDao _lbDeviceDao;
-
-    // @Inject
-    // NetScalerServicePackageDao _lrsPackagesDao;
-
     @Inject
     NetScalerControlCenterDao _netscalerControlCenterDao;
     @Inject
@@ -206,6 +209,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
     NetworkOrchestrationService _networkService;
     @Inject
     NetworkOfferingDao _networkOfferingDao = null;
+    @Inject
+    NetScalerVMManager _netScalerVMManager;
 
     private boolean canHandle(Network config, Service service) {
         DataCenter zone = _dcDao.findById(config.getDataCenterId());
@@ -256,8 +261,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
             } else {
                 // if the network offering has service package implement it with
                 // Netscaler Control Center
-                manageGuestNetworkWithNetscalerControlCenter(true, guestConfig, offering);
-                return true;
+                return manageGuestNetworkWithNetscalerControlCenter(true, guestConfig, offering);
             }
         } catch (InsufficientCapacityException capacityException) {
             throw new ResourceUnavailableException(
@@ -293,7 +297,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
             hostDetails.put("zoneId", Long.toString(guestConfig.getDataCenterId()));
             hostDetails.put("ip", ipAddress);
             hostDetails.put("username", nccVO.getUsername());
-            hostDetails.put("password", nccVO.getPassword());
+            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();
@@ -362,7 +366,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
             networkDetails.put("cidr", guestConfig.getCidr());
             networkDetails.put("gateway", guestConfig.getGateway());
             networkDetails.put("servicepackage_id", offering.getServicePackage());
-            networkDetails.put("zone_id", zoneId);
+            networkDetails.put("zone_id", zone.getUuid());
             networkDetails.put("account_id", guestConfig.getAccountId());
             networkDetails.put("add", Boolean.toString(add));
             selfIp = _ipAddrMgr.acquireGuestIpAddress(guestConfig, null);
@@ -381,152 +385,30 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
             e.printStackTrace();
         }
 
-        NetScalerImplementNetworkCommand cmd = new NetScalerImplementNetworkCommand(zoneId, netscalerControlCenter.getId(), networkPayload.toString());
+        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 (add) {
-                    // Insert a new NIC for this guest network to reserve the self IP
-                    _networkService.savePlaceholderNic(guestConfig, selfIp, null, 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 {
-            // release the self-ip obtained from guest network
-            /*Nic selfipNic = getPlaceholderNic(guestConfig);
-            _nicDao.remove(selfipNic.getId());*/
-            // release the load balancer allocated for the network
-            return true;
-            //write code to remove the self nic or the clean up work
-        }
-        // Send a command to the external load balancer to implement or shutdown the guest network
-        /*        long guestVlanTag = Long.parseLong(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.getIp4Address();
-        }
-        */
-        // 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, String.valueOf(guestVlanTag), selfIp, guestVlanNetmask, null, networkRate, inline);
-        IpAddressTO[] ips = new IpAddressTO[1];
-        ips[0] = ip;
-        IpAssocCommand cmd = new IpAssocCommand(ips);
-        Answer answer = _agentMgr.easySend(netscalerControlCenter.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());
-        }
-        =======
-        NetScalerImplementNetworkCommand cmd = new NetScalerImplementNetworkCommand(zoneId,
-                netscalerControlCenter.getId(), networkPayload.toString());
-        >>>>>>> Stashed changes
-        if (add) {
-            Answer answer = _agentMgr.easySend(netscalerControlCenter.getId(), cmd);
-            // 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 (add) {
-                    // Insert a new NIC for this guest network to reserve the
-                    // self IP
-                    _networkService.savePlaceholderNic(guestConfig, selfIp, null, null);
+                if (answer.getResult() == true) {
+                    return true;
+                } else {
+                    return false;
                 }
             }
+            return false;
         }
-        // Send a command to the external load balancer to implement or shutdown
-        // the guest network
-        /*
-         * long guestVlanTag =
-         * Long.parseLong(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.getIp4Address(); }
-         */
-        // 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, String.valueOf(guestVlanTag), selfIp,
-         * guestVlanNetmask, null, networkRate, inline); IpAddressTO[] ips = new
-         * IpAddressTO[1]; ips[0] = ip; IpAssocCommand cmd = new
-         * IpAssocCommand(ips); Answer answer =
-         * _agentMgr.easySend(netscalerControlCenter.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;
     }
 
@@ -557,9 +439,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
             } else {
                 // if the network offering has service package implement it with Netscaler Control Center
                 return manageGuestNetworkWithNetscalerControlCenter(false, guestConfig, networkOffering);
-                //return true;
             }
-            //return manageGuestNetworkWithExternalLoadBalancer(false, guestConfig);
         } catch (InsufficientCapacityException capacityException) {
             // TODO: handle out of capacity exception gracefully in case of
             // multple providers available
@@ -618,7 +498,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
 
         // Specifies that load balancing rules can be made for either TCP or UDP
         // traffic
-        lbCapabilities.put(Capability.SupportedProtocols, "tcp,udp");
+        lbCapabilities.put(Capability.SupportedProtocols, "tcp,udp,http");
 
         // Specifies that this element can measure network usage on a per public
         // IP basis
@@ -896,8 +776,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         cmdList.add(ListNetscalerControlCenterCmd.class);
         cmdList.add(DeleteServicePackageOfferingCmd.class);
         cmdList.add(DeleteNetscalerControlCenterCmd.class);
-        cmdList.add(ReleasePodIpCmdByAdmin.class);
-        cmdList.add(AcquirePodIpCmdByAdmin.class);
+        cmdList.add(DeployNetscalerVpxCmd.class);
+        cmdList.add(StopNetScalerVMCmd.class);
         return cmdList;
     }
 
@@ -974,17 +854,25 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
     @Override
     public boolean deleteServicePackageOffering(DeleteServicePackageOfferingCmd cmd) throws CloudRuntimeException {
         NetScalerServicePackageVO result = null;
-        boolean flag;
+        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 if (result == null)
-                throw new CloudRuntimeException("Record does not Exists in the Table");
             else
-                throw new CloudRuntimeException("Network offering is using the service package. First delete the nework offering and then delete ServicePackage");
+               throw e;
+
         }
         return flag;
 
@@ -998,10 +886,13 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         if (result == null)
             throw new CloudRuntimeException("External Netscaler Control Center Table does not contain record with this ID");
         else {
-            List<Long> id_set_1 = _networkOfferingDao.listServicePackageUuid();
-            if (id_set_1.size() != 0) {
-                List<NetworkVO> id_set_2 = _networkDao.listNetworkOfferingId(id_set_1);
-                if (id_set_2 != null && id_set_2.size() != 0)
+            //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.");
             }
@@ -1016,25 +907,23 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
         _netscalerControlCenterDao.remove(result.getId());
 
         //Removal of  NCC from Host Table
-        SearchCriteria<HostVO> sc = _hostDao.createSearchCriteria();
-        sc.addAnd("type", SearchCriteria.Op.EQ, Host.Type.NetScalerControlCenter);
-        List<HostVO> ncc_list = _hostDao.search(sc, null);
-
+        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) {
-            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;
+            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;
     }
 
@@ -1415,7 +1304,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
             int numLoadBalancersForCommand = loadBalancersToApply.size();
             LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply
                     .toArray(new LoadBalancerTO[numLoadBalancersForCommand]);
-            HealthCheckLBConfigCommand cmd = new HealthCheckLBConfigCommand(loadBalancersForCommand);
+            HealthCheckLBConfigCommand cmd = new HealthCheckLBConfigCommand(loadBalancersForCommand, network.getId());
             HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
             answer = (HealthCheckLBConfigAnswer)_agentMgr.easySend(externalLoadBalancer.getId(), cmd);
             return answer.getLoadBalancers();
@@ -1566,6 +1455,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
     }
 
     @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;
@@ -1578,6 +1468,9 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
     @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>();
@@ -1599,11 +1492,9 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
             return Transaction.execute(new TransactionCallback<NetScalerControlCenterVO>() {
                 @Override
                 public NetScalerControlCenterVO doInTransaction(TransactionStatus status) {
-                    NetScalerControlCenterVO nccVO = new NetScalerControlCenterVO(cmdinfo.getUsername(), cmdinfo.getPassword(),
+                    NetScalerControlCenterVO nccVO = new NetScalerControlCenterVO(cmdinfo.getUsername(), DBEncryptionUtil.encrypt(cmdinfo.getPassword()),
                             cmdinfo.getIpaddress(), cmdinfo.getNumretries());
                     _netscalerControlCenterDao.persist(nccVO);
-                    /*DetailVO hostDetail = new DetailVO(host.getId(), ApiConstants.NETSCALER_CONTROLCENTER_ID , String.valueOf(nccVO.getId()));
-                    _hostDetailDao.persist(hostDetail);*/
                     return nccVO;
                 }
             });
@@ -1612,4 +1503,27 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl
             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) {
+            // TODO Auto-generated catch block
+            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/com/cloud/network/element/NetscalerLoadBalancerElementService.java
index c635f78..308b56d 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerLoadBalancerElementService.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerLoadBalancerElementService.java
@@ -17,25 +17,31 @@
 package com.cloud.network.element;
 
 import java.util.List;
+import java.util.Map;
 
 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.response.NetscalerLoadBalancerResponse;
 import com.cloud.api.response.NetScalerServicePackageResponse;
 import com.cloud.api.response.NetscalerControlCenterResponse;
+import com.cloud.api.response.NetscalerLoadBalancerResponse;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.network.NetScalerControlCenterVO;
 import com.cloud.network.NetScalerServicePackageVO;
 import com.cloud.network.Network;
 import com.cloud.network.dao.ExternalLoadBalancerDeviceVO;
+import com.cloud.network.router.VirtualRouter;
+import com.cloud.user.Account;
 import com.cloud.utils.component.PluggableService;
 import com.cloud.utils.exception.CloudRuntimeException;
 
@@ -135,4 +141,7 @@ public interface NetscalerLoadBalancerElementService extends PluggableService {
 
     public NetScalerControlCenterVO registerNetscalerControlCenter(RegisterNetscalerControlCenterCmd registerNetscalerControlCenterCmd);
 
+    public Map<String, Object> deployNetscalerServiceVm(DeployNetscalerVpxCmd cmd);
+
+    public VirtualRouter stopNetscalerServiceVm(Long id, boolean forced, Account callingAccount, long callingUserId) throws ConcurrentOperationException, ResourceUnavailableException;
 }
\ 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
index a8b3fbf..1132b6c 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetScalerControlCenterResource.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetScalerControlCenterResource.java
@@ -27,10 +27,7 @@ import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Formatter;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Locale;
 import java.util.Map;
 
 import javax.naming.ConfigurationException;
@@ -53,53 +50,12 @@ 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.citrix.netscaler.nitro.exception.nitro_exception;
-import com.citrix.netscaler.nitro.resource.base.base_response;
-import com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction;
-import com.citrix.netscaler.nitro.resource.config.autoscale.autoscalepolicy;
-import com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleprofile;
-import com.citrix.netscaler.nitro.resource.config.basic.service_lbmonitor_binding;
-import com.citrix.netscaler.nitro.resource.config.basic.servicegroup;
-import com.citrix.netscaler.nitro.resource.config.basic.servicegroup_lbmonitor_binding;
-import com.citrix.netscaler.nitro.resource.config.gslb.gslbservice;
-import com.citrix.netscaler.nitro.resource.config.gslb.gslbservice_lbmonitor_binding;
-import com.citrix.netscaler.nitro.resource.config.gslb.gslbsite;
-import com.citrix.netscaler.nitro.resource.config.gslb.gslbsite_gslbservice_binding;
-import com.citrix.netscaler.nitro.resource.config.gslb.gslbvserver;
-import com.citrix.netscaler.nitro.resource.config.gslb.gslbvserver_domain_binding;
-import com.citrix.netscaler.nitro.resource.config.gslb.gslbvserver_gslbservice_binding;
-import com.citrix.netscaler.nitro.resource.config.lb.lbmetrictable;
-import com.citrix.netscaler.nitro.resource.config.lb.lbmetrictable_metric_binding;
-import com.citrix.netscaler.nitro.resource.config.lb.lbmonitor;
-import com.citrix.netscaler.nitro.resource.config.lb.lbmonitor_metric_binding;
-import com.citrix.netscaler.nitro.resource.config.lb.lbvserver;
-import com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding;
-import com.citrix.netscaler.nitro.resource.config.lb.lbvserver_servicegroup_binding;
-import com.citrix.netscaler.nitro.resource.config.network.inat;
-import com.citrix.netscaler.nitro.resource.config.network.rnat;
-import com.citrix.netscaler.nitro.resource.config.network.vlan;
-import com.citrix.netscaler.nitro.resource.config.network.vlan_interface_binding;
-import com.citrix.netscaler.nitro.resource.config.network.vlan_nsip_binding;
-import com.citrix.netscaler.nitro.resource.config.ns.nsconfig;
-import com.citrix.netscaler.nitro.resource.config.ns.nsip;
-import com.citrix.netscaler.nitro.resource.config.ns.nstimer;
-import com.citrix.netscaler.nitro.resource.config.ns.nstimer_autoscalepolicy_binding;
-import com.citrix.netscaler.nitro.resource.config.ssl.sslcertkey;
-import com.citrix.netscaler.nitro.resource.config.ssl.sslcertkey_sslvserver_binding;
-import com.citrix.netscaler.nitro.resource.config.ssl.sslcertlink;
-import com.citrix.netscaler.nitro.resource.config.ssl.sslvserver_sslcertkey_binding;
-import com.citrix.netscaler.nitro.resource.stat.lb.lbvserver_stats;
-import com.citrix.netscaler.nitro.service.nitro_service;
-import com.citrix.netscaler.nitro.util.filtervalue;
-import com.citrix.sdx.nitro.resource.config.ns.ns;
-import com.citrix.sdx.nitro.resource.config.xen.xen_nsvpx_image;
 import com.google.gson.Gson;
 
-import org.apache.cloudstack.api.ApiConstants;
-
 import com.cloud.agent.IAgentControl;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.Command;
@@ -114,57 +70,40 @@ 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.CreateLoadBalancerApplianceCommand;
 import com.cloud.agent.api.routing.DestroyLoadBalancerApplianceCommand;
-import com.cloud.agent.api.routing.GlobalLoadBalancerConfigAnswer;
 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.SetStaticNatRulesAnswer;
 import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
-import com.cloud.agent.api.routing.SiteLoadBalancerConfig;
 import com.cloud.agent.api.to.IpAddressTO;
 import com.cloud.agent.api.to.LoadBalancerTO;
-import com.cloud.agent.api.to.LoadBalancerTO.AutoScalePolicyTO;
-import com.cloud.agent.api.to.LoadBalancerTO.AutoScaleVmGroupTO;
-import com.cloud.agent.api.to.LoadBalancerTO.AutoScaleVmProfileTO;
-import com.cloud.agent.api.to.LoadBalancerTO.ConditionTO;
-import com.cloud.agent.api.to.LoadBalancerTO.CounterTO;
 import com.cloud.agent.api.to.LoadBalancerTO.DestinationTO;
-import com.cloud.agent.api.to.LoadBalancerTO.HealthCheckPolicyTO;
 import com.cloud.agent.api.to.LoadBalancerTO.StickinessPolicyTO;
-import com.cloud.agent.api.to.StaticNatRuleTO;
 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.Pair;
 import com.cloud.utils.StringUtils;
 import com.cloud.utils.exception.ExecutionException;
 import com.cloud.utils.net.NetUtils;
-import com.cloud.utils.ssh.SshHelper;
 
-/*class NitroError {
-    static final int NS_RESOURCE_EXISTS = 273;
-    static final int NS_RESOURCE_NOT_EXISTS = 258;
-    static final int NS_NO_SERIVCE = 344;
-    static final int NS_OPERATION_NOT_PERMITTED = 257;
-    static final int NS_INTERFACE_ALREADY_BOUND_TO_VLAN = 2080;
-    static final int NS_GSLB_DOMAIN_ALREADY_BOUND = 1842;
-}*/
+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 {
 
-    public final static int DEFAULT_SNMP_PORT = 161;
     // deployment configuration
     private String _name;
     private String _zoneId;
-    private String _physicalNetworkId;
     private String _ip;
     private String _username;
     private String _password;
@@ -174,13 +113,7 @@ public class NetScalerControlCenterResource implements ServerResource {
     private Long _nccCmdTimeout;
     private String _guid;
     private boolean _inline;
-    private boolean _isSdx;
-    private boolean _cloudManaged;
     private String _deviceName;
-    private String _publicIP;
-    private String _publicIPNetmask;
-    private String _publicIPGateway;
-    private String _publicIPVlan;
     private String _sessionid;
     public static final int DEFAULT_PORT = 443;
     private static final Gson s_gson = GsonHelper.getGson();
@@ -189,13 +122,7 @@ public class NetScalerControlCenterResource implements ServerResource {
     private final String _objectNamePathSep = "-";
     final String protocol="https";
     private static String nccsession;
-    // interface to interact with VPX and MPX devices
-    com.citrix.netscaler.nitro.service.nitro_service _netscalerService;
-
-    // interface to interact with service VM of the SDX appliance
-    com.citrix.sdx.nitro.service.nitro_service _netscalerSdxService;
-
-    base_response apiCallResult;
+    private int pingCount = 0;
 
     public NetScalerControlCenterResource() {
         _gson = GsonHelper.getGsonLogger();
@@ -236,7 +163,7 @@ public class NetScalerControlCenterResource implements ServerResource {
                 throw new ConfigurationException("Unable to find username in the configuration parameters");
             }
 
-            _password = (String)params.get("password");
+            _password =  (String)params.get("password");
             if (_password == null) {
                 throw new ConfigurationException("Unable to find password in the configuration parameters");
             }
@@ -256,14 +183,6 @@ public class NetScalerControlCenterResource implements ServerResource {
 
             // validate device configuration parameters
             login();
-            /*String response =
-            if(response == null) {
-                throw new ConfigurationException("No Response Received from the NetScalerControlCenter Device");
-            } else {
-                jsonResponse = new JSONObject(response);
-              org.json.JSONArray loginResponse = jsonResponse.getJSONArray("login");
-              _sessionid = jsonResponse.getJSONArray("login").getJSONObject(0).getString("sessionid");
-            }*/
 
             return true;
         } catch (ConfigurationException e) {
@@ -277,25 +196,15 @@ public class NetScalerControlCenterResource implements ServerResource {
     public void getServicePackages() throws ExecutionException {
             String result = null;
             try {
-                // If a previous session was open, log it out.
-                //logout();
-                //http://10.102.31.78/nitro/v2/config/login
                 URI agentUri = null;
-                //String url = protocol + "://" + _ip +"/nitro/v2/config/login";
                 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();
-                //String loginBody= "{ \"login\": {\"username\":\"" + _username  +"\", \"password\":\"" + _password +"\" }}";
-/*                jsonCredentials.put("username", _username);
-                jsonCredentials.put("password", _password);
-                jsonBody.put("login", jsonCredentials);
-*/
                 result = getHttpRequest(jsonBody.toString(), agentUri, _sessionid);
                 s_logger.debug("List of Service Packages in NCC:: " + result);
-                //return result;
                 } catch (URISyntaxException e) {
                     String errMsg = "Could not generate URI for Hyper-V agent";
                     s_logger.error(errMsg, e);
@@ -303,40 +212,18 @@ public class NetScalerControlCenterResource implements ServerResource {
                 } catch (Exception e) {
                 throw new ExecutionException("Failed to log in to NCC device at " + _ip + " due to " + e.getMessage());
             }
-            //return result;
-    }
-
-    private void logout() throws ExecutionException {
-        try {
-            if (!_isSdx) {
-                if (_netscalerService != null) {
-                    _netscalerService.logout();
-                }
-            } else {
-                if (_netscalerSdxService != null) {
-                    _netscalerSdxService.logout();
-                }
-            }
-        } catch (Exception e) {
-            // Ignore logout exceptions
-        }
     }
 
     private synchronized String login() throws ExecutionException{// , ConfigurationException {
         String result = null;
         JSONObject jsonResponse = null;
         try {
-            // If a previous session was open, log it out.
-            //logout();
-            //http://10.102.31.78/nitro/v2/config/login
             URI agentUri = null;
-            //String url = protocol + "://" + _ip +"/nitro/v2/config/login";
             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();
-            //String loginBody= "{ \"login\": {\"username\":\"" + _username  +"\", \"password\":\"" + _password +"\" }}";
             jsonCredentials.put("username", _username);
             jsonCredentials.put("password", _password);
             jsonBody.put("login", jsonCredentials);
@@ -360,7 +247,6 @@ public class NetScalerControlCenterResource implements ServerResource {
 
             } catch (JSONException e) {
                 s_logger.debug("JSON Exception :" +  e.getMessage());
-                //throw new ConfigurationException("Failed to add the device. Please check the device is NCC and It is reachable from Management Server.");
                 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());
@@ -397,14 +283,12 @@ public class NetScalerControlCenterResource implements ServerResource {
             return execute((LoadBalancerConfigCommand)cmd, numRetries);
         } else if (cmd instanceof ExternalNetworkResourceUsageCommand) {
             return execute((ExternalNetworkResourceUsageCommand)cmd, numRetries);
-        } else if (cmd instanceof CreateLoadBalancerApplianceCommand) {
-            return execute((CreateLoadBalancerApplianceCommand)cmd, numRetries);
         } else if (cmd instanceof DestroyLoadBalancerApplianceCommand) {
-            return execute((DestroyLoadBalancerApplianceCommand)cmd, numRetries);
+            return Answer.createUnsupportedCommandAnswer(cmd);
         } else if (cmd instanceof SetStaticNatRulesCommand) {
             return execute((SetStaticNatRulesCommand)cmd, numRetries);
         } else if (cmd instanceof GlobalLoadBalancerConfigCommand) {
-            return execute((GlobalLoadBalancerConfigCommand)cmd, numRetries);
+            return Answer.createUnsupportedCommandAnswer(cmd);
         } else if (cmd instanceof HealthCheckLBConfigCommand) {
             return execute((HealthCheckLBConfigCommand)cmd, numRetries);
         } else if (cmd instanceof NetScalerImplementNetworkCommand ) {
@@ -423,32 +307,25 @@ public class NetScalerControlCenterResource implements ServerResource {
         return new MaintainAnswer(cmd);
     }
 
-    private String queryAsyncJob(String jobId) {
-        String result = null;
+    private void keepSessionAlive() throws ExecutionException {
+        URI agentUri = null;
         try {
-            // If a previous session was open, log it out.
-            //logout();
-/*            Polling for async tasks:
-                URL: http://10.102.31.78/admin/v1/journalcontexts/ <job-id>
-                Rwsponse:
-
-                {
-                  "journalcontext": {
-                    "id": "ctxt-6cfd63ba-b4d2-413d-af2d-caa6f1dc5cd9",
-                    "start_time": "2015-07-16T09:47:50.596664",
-                    "end_time": "2015-07-16T09:47:50.636356",
-                    "name": "Update devices",
-                    "service_name": "admin",
-                    "is_default": false,
-                    "scopes": [],
-                    "status": "Finished",
-                    "message": "Done"
-                  }
-                }
-*/
+            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) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
 
+    private String queryAsyncJob(String jobId) throws ExecutionException {
+        String result = null;
+        try {
             URI agentUri = null;
-            //String url = protocol + "://" + _ip +"/nitro/v2/config/login";
             agentUri =
                     new URI("https", null, _ip, DEFAULT_PORT,
                             "/admin/v1/journalcontexts/" + jobId, null, null);
@@ -461,49 +338,40 @@ public class NetScalerControlCenterResource implements ServerResource {
                 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");
+                    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":
+                    case "FINISHED":
                             return status;
-                    case "In Progress":
-                        break;
-                    case "ERROR, ROLLBACK_IN_PROGRESS":
+                    case "IN PROGRESS":
                         break;
-                        //return status;
-                    case "ERROR, ROLLBACK_COMPLETED":
+                    case "ERROR, ROLLBACK IN PROGRESS":
                         break;
-                        //return status;
-                    case "ERROR, ROLLBACK_FAILED":
-                        break;
-                        //return status;
+                    case "ERROR, ROLLBACK COMPLETED":
+                        throw new ExecutionException("ERROR, ROLLBACK COMPLETED " + message);
+                    case "ERROR, ROLLBACK FAILED":
+                        throw new ExecutionException("ERROR, ROLLBACK FAILED " + message);
                     }
                 }
             }
 
-            //s_logger.debug("List of Service Packages in NCC:: " + result);
-            //return result;
         } catch (URISyntaxException e) {
             String errMsg = "Could not generate URI for NetScaler ControlCenter";
             s_logger.error(errMsg, e);
-
-        } catch (Exception e) {
-            //throw new ExecutionException("Failed to log in to NCC device at " + _ip + " due to " + e.getMessage());
+          } catch (JSONException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
         }
         return result;
     }
     private synchronized Answer execute(NetScalerImplementNetworkCommand cmd, int numRetries) {
         String result = null;
         try {
-            // If a previous session was open, log it out.
-            //logout();
-            //http://10.102.31.78/nitro/v2/config/login
             URI agentUri = null;
-            //String url = protocol + "://" + _ip +"/nitro/v2/config/login";
-            //url: <ip>/cs/cca/networks
             agentUri =
                     new URI("https", null, _ip, DEFAULT_PORT,
-                            "/cs/cca/v1/networks", null, null);
+                            "/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);
@@ -515,9 +383,13 @@ public class NetScalerControlCenterResource implements ServerResource {
                 String errMsg = "Could not generate URI for NetScaler ControlCenter ";
                 s_logger.error(errMsg, e);
             } catch (ExecutionException e) {
-                if(e.getMessage().equalsIgnoreCase("NOTFOUND")) {
+                if(e.getMessage().equalsIgnoreCase(NccHttpCode.NOT_FOUND)) {
                     return new Answer(cmd, true, "Successfully unallocated the device");
-                } else {
+                }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);
@@ -538,41 +410,12 @@ public class NetScalerControlCenterResource implements ServerResource {
     }
 
     private synchronized Answer execute(IpAssocCommand cmd,  int numRetries) {
-        if (_isSdx) {
-            return Answer.createUnsupportedCommandAnswer(cmd);
-        }
 
         String[] results = new String[cmd.getIpAddresses().length];
         int i = 0;
-        try {
-            IpAddressTO[] ips = cmd.getIpAddresses();
-            for (IpAddressTO ip : ips) {
-                long guestVlanTag = Long.parseLong(ip.getBroadcastUri());
-                String vlanSelfIp = ip.getVlanGateway();
-                String vlanNetmask = ip.getVlanNetmask();
-
-                if (ip.isAdd()) {
-                    // Add a new guest VLAN and its subnet and bind it to private interface
-                    addGuestVlanAndSubnet(guestVlanTag, vlanSelfIp, vlanNetmask, true);
-                } else {
-                    // Check and delete guest VLAN with this tag, self IP, and netmask
-                    deleteGuestVlan(guestVlanTag, vlanSelfIp, vlanNetmask);
-                }
-
-                saveConfiguration();
-                results[i++] = ip.getPublicIp() + " - success";
-                String action = ip.isAdd() ? "associate" : "remove";
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Netscaler load balancer " + _ip + " successfully executed IPAssocCommand to " + action + " IP " + ip);
-                }
-            }
-        } catch (ExecutionException e) {
-            s_logger.error("Netscaler loadbalancer " + _ip + " failed to execute IPAssocCommand due to " + e.getMessage());
-            if (shouldRetry(numRetries)) {
-                return retry(cmd, numRetries);
-            } else {
-                results[i++] = IpAssocAnswer.errorResult;
-            }
+        IpAddressTO[] ips = cmd.getIpAddresses();
+        for (IpAddressTO ip : ips) {
+            results[i++] = ip.getPublicIp() + " - success";
         }
 
         return new IpAssocAnswer(cmd, results);
@@ -583,39 +426,29 @@ public class NetScalerControlCenterResource implements ServerResource {
         List<LoadBalancerTO> hcLB = new ArrayList<LoadBalancerTO>();
         try {
 
-            if (_isSdx) {
-                return Answer.createUnsupportedCommandAnswer(cmd);
-            }
-
             LoadBalancerTO[] loadBalancers = cmd.getLoadBalancers();
 
             if (loadBalancers == null) {
                 return new HealthCheckLBConfigAnswer(hcLB);
             }
-
-            for (LoadBalancerTO loadBalancer : loadBalancers) {
-                HealthCheckPolicyTO[] healthCheckPolicies = loadBalancer.getHealthCheckPolicies();
-                if ((healthCheckPolicies != null) && (healthCheckPolicies.length > 0) && (healthCheckPolicies[0] != null)) {
-                    String nsVirtualServerName = generateNSVirtualServerName(loadBalancer.getSrcIp(), loadBalancer.getSrcPort());
-
-                    com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding[] serviceBindings =
-                            com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.get(_netscalerService, nsVirtualServerName);
-
-                    if (serviceBindings != null) {
-                        for (DestinationTO destination : loadBalancer.getDestinations()) {
-                            String nsServiceName = generateNSServiceName(destination.getDestIp(), destination.getDestPort());
-                            for (com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding binding : serviceBindings) {
-                                if (nsServiceName.equalsIgnoreCase(binding.get_servicename())) {
-                                    destination.setMonitorState(binding.get_curstate());
-                                    break;
-                                }
-                            }
-                        }
-                        hcLB.add(loadBalancer);
+            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;// new LoadBalancerTO(lbstat.getString("lb_uuid"));
+                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)) {
@@ -634,3063 +467,296 @@ public class NetScalerControlCenterResource implements ServerResource {
         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) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        return response;
+    }
     private synchronized Answer execute(LoadBalancerConfigCommand cmd, int numRetries) {
         try {
-            if (_isSdx) {
-                return Answer.createUnsupportedCommandAnswer(cmd);
-            }
-
             LoadBalancerTO[] loadBalancers = cmd.getLoadBalancers();
             if (loadBalancers == null) {
                 return new Answer(cmd);
             }
-            JSONObject jsonCmd = new JSONObject(cmd);
+            JSONObject lbConfigPaylod = new JSONObject(cmd);
+            String gsonLBConfig =  _gson.toJson(cmd);
             URI agentUri = null;
-            //String url = protocol + "://" + _ip +"/nitro/v2/config/login";
             agentUri =
                     new URI("https", null, _ip, DEFAULT_PORT,
-                            "/nitro/v2/config/" + "login", null, null);
-
-            s_logger.debug("LB config cmd: " + jsonCmd.toString());
-            String result = postHttpRequest(jsonCmd.toString(), agentUri, _sessionid);
-            /*for (LoadBalancerTO loadBalancer : loadBalancers) {
-                String srcIp = loadBalancer.getSrcIp();
-                int srcPort = loadBalancer.getSrcPort();
-                String lbProtocol = getNetScalerProtocol(loadBalancer);
-                String lbAlgorithm = loadBalancer.getAlgorithm();
-                String nsVirtualServerName = generateNSVirtualServerName(srcIp, srcPort);
-                String nsMonitorName = generateNSMonitorName(srcIp, srcPort);
-                LbSslCert sslCert = loadBalancer.getSslCert();
-
-                if (loadBalancer.isAutoScaleVmGroupTO()) {
-                    applyAutoScaleConfig(loadBalancer);
-                    // Continue to process all the rules.
-                    continue;
-                }
-                boolean hasMonitor = false;
-                boolean deleteMonitor = false;
-                boolean destinationsToAdd = false;
-                boolean deleteCert = false;
-                for (DestinationTO destination : loadBalancer.getDestinations()) {
-                    if (!destination.isRevoked()) {
-                        destinationsToAdd = true;
-                        break;
-                    }
-                }
-
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("Successfully executed resource LoadBalancerConfigCommand: " + _gson.toJson(cmd));
-            }*/
-
-            //saveConfiguration();
+                            "/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, e);
+                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, e);
+                return new Answer(cmd, false, e.getMessage());
             }
         }
     }
 
-    private synchronized Answer execute(CreateLoadBalancerApplianceCommand cmd, int numRetries) {
-
-        if (!_isSdx) {
-            return Answer.createUnsupportedCommandAnswer(cmd);
-        }
+    private synchronized Answer execute(SetStaticNatRulesCommand cmd, int numRetries) {
+        return Answer.createUnsupportedCommandAnswer(cmd);
+    }
 
+    private synchronized Answer execute(ExternalNetworkResourceUsageCommand cmd, int numRetries) {
         try {
-            String vpxName = "Cloud-VPX-" + cmd.getLoadBalancerIP();
-            String username = "admin";
-            String password = "admin";
-
-            ns ns_obj = new ns();
-            ns_obj.set_name(vpxName);
-            ns_obj.set_ip_address(cmd.getLoadBalancerIP());
-            ns_obj.set_netmask(cmd.getNetmask());
-            ns_obj.set_gateway(cmd.getGateway());
-            ns_obj.set_username(username);
-            ns_obj.set_password(password);
-
-            // configure VPX instances with defaults
-            ns_obj.set_license("Standard");
-            ns_obj.set_vm_memory_total(new Double(2048));
-            ns_obj.set_throughput(new Double(1000));
-            ns_obj.set_pps(new Double(1000000));
-            ns_obj.set_number_of_ssl_cores(0);
-            ns_obj.set_profile_name("ns_nsroot_profile");
-
-            // use the first VPX image of the available VPX images on the SDX to create an instance of VPX
-            // TODO: should enable the option to choose the template while adding the SDX device in to CloudStack
-            xen_nsvpx_image[] vpxImages = xen_nsvpx_image.get(_netscalerSdxService);
-            if (!(vpxImages != null && vpxImages.length >= 1)) {
-                new Answer(cmd, new ExecutionException("Failed to create VPX instance on the netscaler SDX device " + _ip +
-                        " as there are no VPX images on SDX to use for creating VPX."));
-            }
-            String imageName = vpxImages[0].get_file_name();
-            ns_obj.set_image_name(imageName);
 
-            String publicIf = _publicInterface;
-            String privateIf = _privateInterface;
+            return getPublicIpBytesSentAndReceived(cmd);
 
-            // enable only the interfaces that will be used by VPX
-            enableVPXInterfaces(_publicInterface, _privateInterface, ns_obj);
+        } catch (ExecutionException e) {
+            if (shouldRetry(numRetries)) {
+                return retry(cmd, numRetries);
+            } else {
+                return new ExternalNetworkResourceUsageAnswer(cmd, e);
+            }
+        }
+    }
 
-            // create new VPX instance
-            ns newVpx = ns.add(_netscalerSdxService, ns_obj);
 
-            if (newVpx == null) {
-                return new Answer(cmd, new ExecutionException("Failed to create VPX instance on the netscaler SDX device " + _ip));
-            }
+    private String getNetScalerProtocol(LoadBalancerTO loadBalancer) throws ExecutionException {
+        String port = Integer.toString(loadBalancer.getSrcPort());
+        String lbProtocol = loadBalancer.getLbProtocol();
+        StickinessPolicyTO[] stickyPolicies = loadBalancer.getStickinessPolicies();
+        String nsProtocol = "TCP";
 
-            // wait for VPX instance to start-up
-            long startTick = System.currentTimeMillis();
-            long startWaitMilliSeconds = 600000;
-            while (!newVpx.get_instance_state().equalsIgnoreCase("up") && System.currentTimeMillis() - startTick < startWaitMilliSeconds) {
-                try {
-                    Thread.sleep(10000);
-                } catch (InterruptedException e) {
-                }
-                ns refreshNsObj = new ns();
-                refreshNsObj.set_id(newVpx.get_id());
-                newVpx = ns.get(_netscalerSdxService, refreshNsObj);
-            }
+        if (lbProtocol == null)
+            lbProtocol = loadBalancer.getProtocol();
 
-            // if vpx instance never came up then error out
-            if (!newVpx.get_instance_state().equalsIgnoreCase("up")) {
-                return new Answer(cmd, new ExecutionException("Failed to start VPX instance " + vpxName + " created on the netscaler SDX device " + _ip));
+        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;
             }
+        }
 
-            // wait till NS service in side VPX is actually ready
-            startTick = System.currentTimeMillis();
-            boolean nsServiceUp = false;
-            long nsServiceWaitMilliSeconds = 60000;
-            while (System.currentTimeMillis() - startTick < nsServiceWaitMilliSeconds) {
-                try {
-                    nitro_service _netscalerService = new nitro_service(cmd.getLoadBalancerIP(), "https");
-                    _netscalerService.set_certvalidation(false);
-                    _netscalerService.set_hostnameverification(false);
-                    _netscalerService.set_credential(username, password);
-                    apiCallResult = _netscalerService.login();
-                    if (apiCallResult.errorcode == 0) {
-                        nsServiceUp = true;
-                        break;
-                    }
-                } catch (Exception e) {
-                    Thread.sleep(10000);
-                    continue;
-                }
-            }
+        if (lbProtocol.equalsIgnoreCase(NetUtils.SSL_PROTO) || lbProtocol.equalsIgnoreCase(NetUtils.HTTP_PROTO))
+            return lbProtocol.toUpperCase();
 
-            if (!nsServiceUp) {
-                return new Answer(cmd, new ExecutionException("Failed to create VPX instance " + vpxName + " on the netscaler SDX device " + _ip));
-            }
+        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";
+        }
 
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("Successfully provisioned VPX instance " + vpxName + " on the Netscaler SDX device " + _ip);
-            }
+        return nsProtocol;
+    }
 
-            // physical interfaces on the SDX range from 10/1 to 10/8 & 1/1 to 1/8 of which two different port or same port can be used for public and private interfaces
-            // However the VPX instances created will have interface range start from 10/1 but will only have as many interfaces enabled while creating the VPX instance
-            // So due to this, we need to map public & private interface on SDX to correct public & private interface of VPX
 
-            int publicIfnum = Integer.parseInt(_publicInterface.substring(_publicInterface.lastIndexOf("/") + 1));
-            int privateIfnum = Integer.parseInt(_privateInterface.substring(_privateInterface.lastIndexOf("/") + 1));
+    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
 
-            if (_publicInterface.startsWith("10/") && _privateInterface.startsWith("10/")) {
-                if (publicIfnum == privateIfnum) {
-                    publicIf = "10/1";
-                    privateIf = "10/1";
-                } else if (publicIfnum > privateIfnum) {
-                    privateIf = "10/1";
-                    publicIf = "10/2";
-                } else {
-                    publicIf = "10/1";
-                    privateIf = "10/2";
-                }
-            } else if (_publicInterface.startsWith("1/") && _privateInterface.startsWith("1/")) {
-                if (publicIfnum == privateIfnum) {
-                    publicIf = "1/1";
-                    privateIf = "1/1";
-                } else if (publicIfnum > privateIfnum) {
-                    privateIf = "1/1";
-                    publicIf = "1/2";
-                } else {
-                    publicIf = "1/1";
-                    privateIf = "1/2";
+            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);
+                            }
+                       }
+                    }
                 }
-            } else if (_publicInterface.startsWith("1/") && _privateInterface.startsWith("10/")) {
-                publicIf = "1/1";
-                privateIf = "10/1";
-            } else if (_publicInterface.startsWith("10/") && _privateInterface.startsWith("1/")) {
-                publicIf = "10/1";
-                privateIf = "1/1";
+                s_logger.debug("IPStats Response :" + response);
+            } catch (URISyntaxException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            } catch (ExecutionException e) {
+                // TODO Auto-generated catch block
+                s_logger.debug("Seesion Alive" + e.getMessage());
+                e.printStackTrace();
             }
 
-            return new CreateLoadBalancerApplianceAnswer(cmd, true, "provisioned VPX instance", "NetscalerVPXLoadBalancer", "Netscaler", new NetScalerControlCenterResource(),
-                    publicIf, privateIf, _username, _password);
         } catch (Exception e) {
-            if (shouldRetry(numRetries)) {
-                return retry(cmd, numRetries);
-            }
-            return new CreateLoadBalancerApplianceAnswer(cmd, false, "failed to provisioned VPX instance due to " + e.getMessage(), null, null, null, null, null, null,
-                    null);
+            s_logger.error("Failed to get bytes sent and recived statistics due to " + e);
+            throw new ExecutionException(e.getMessage());
         }
-    }
 
-    private Answer execute(GlobalLoadBalancerConfigCommand gslbCmd, int numRetries) {
-
-        String lbMethod = gslbCmd.getLoadBalancerMethod();
-        String persistenceType = gslbCmd.getPersistenceType();
-        String serviceType = gslbCmd.getServiceType();
-        boolean forRevoke = gslbCmd.isForRevoke();
-        long gslbId = gslbCmd.getGslbId();
-        List<SiteLoadBalancerConfig> sites = gslbCmd.getSiteDetails();
+        return answer;
+    }
 
-        String domainName = gslbCmd.getDomainName();
-        String vserverName = GSLB.generateVirtualServerName(domainName);
+    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;
+    }
 
-            if (!forRevoke) { //check if the global load balancer rule is being added
-
-                // Add a GSLB virtual server
-                GSLB.createVirtualServer(_netscalerService, vserverName, lbMethod, persistenceType, gslbId, serviceType);
-
-                if (sites != null) { // check if there are any sites that are participating in global load balancing
-                    for (SiteLoadBalancerConfig site : sites) {
-
-                        String sitePrivateIP = site.getGslbProviderPrivateIp();
-                        String sitePublicIP = site.getGslbProviderPublicIp();
-                        String servicePublicIp = site.getServicePublicIp();
-                        String servicePublicPort = site.getServicePort();
-                        String siteName = GSLB.generateUniqueSiteName(sitePrivateIP, sitePublicIP, site.getDataCenterId());
-
-                        // Add/Delete GSLB local and remote sites that are part of GSLB virtual server
-                        if (!site.forRevoke()) {
-                            String siteType = (site.isLocal()) ? "LOCAL" : "REMOTE";
-                            if (GSLB.getSiteObject(_netscalerService, siteName) != null) {
-                                GSLB.updateSite(_netscalerService, siteType, siteName, site.getGslbProviderPrivateIp(), site.getGslbProviderPublicIp());
-                            } else {
-                                GSLB.createSite(_netscalerService, siteName, siteType, site.getGslbProviderPrivateIp(), site.getGslbProviderPublicIp());
-                            }
-                        }
-
-                        // Add/Delete GSLB service corresponding the service running on each site
-                        String serviceName = GSLB.generateUniqueServiceName(siteName, servicePublicIp, servicePublicPort);
-                        String monitorName = GSLB.generateGslbServiceMonitorName(servicePublicIp);
-                        if (!site.forRevoke()) {
-                            // create a 'gslbservice' object
-                            GSLB.createService(_netscalerService, serviceName, site.getServiceType(), servicePublicIp, servicePublicPort, siteName);
-
-                            // Bind 'gslbservice' service object to GSLB virtual server
-                            GSLB.createVserverServiceBinding(_netscalerService, serviceName, vserverName, site.getWeight());
 
-                            // create a monitor for the service running on the site
-                            GSLB.createGslbServiceMonitor(_netscalerService, servicePublicIp, serviceName);
+    @Override
+    public IAgentControl getAgentControl() {
+        return null;
+    }
 
-                            // bind the monitor to the GSLB service
-                            GSLB.createGslbServiceGslbMonitorBinding(_netscalerService, monitorName, serviceName);
+    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;
+    }
 
-                        } else {
+    @Override
+    public PingCommand getCurrentStatus(long id) {
+        pingCount++;
+        if (pingCount > 10 && refreshNCCConnection()) {
+            pingCount = 0;
+        }
+        return new PingCommand(Host.Type.NetScalerControlCenter, id);
+    }
 
-                            // delete GSLB service and GSLB monitor binding
-                            GSLB.deleteGslbServiceGslbMonitorBinding(_netscalerService, monitorName, serviceName);
+    @Override
+    public Type getType() {
+        return Host.Type.NetScalerControlCenter ;
+    }
 
-                            // Unbind GSLB service with GSLB virtual server
-                            GSLB.deleteVserverServiceBinding(_netscalerService, serviceName, vserverName);
+    @Override
+    public void setAgentControl(IAgentControl agentControl) {
+        return;
+    }
 
-                            GSLB.getServiceObject(_netscalerService, serviceName);
-                            GSLB.deleteService(_netscalerService, serviceName);
+    @Override
+    public String getName() {
+        return _name;
+    }
 
-                            // delete the GSLB service monitor
-                            GSLB.deleteGslbServiceMonitor(_netscalerService, monitorName);
-                        }
+    @Override
+    public boolean start() {
+        return true;
+    }
 
-                        if (site.forRevoke()) { // delete the site if its for revoke
-                            GSLB.deleteSite(_netscalerService, siteName);
-                        }
-                    }
-                }
+    @Override
+    public boolean stop() {
+        return true;
+    }
 
-                // Bind GSLB vserver to domain
-                GSLB.createVserverDomainBinding(_netscalerService, vserverName, domainName);
+    @Override
+    public void disconnected() {
+        return;
+    }
 
-            } else {  // global load balancer rule is being deleted, so clean up all objects created
+    @Override
+    public void setName(String name) {
+        // TODO Auto-generated method stub
 
-                // remove binding between virtual server and the domain name
-                GSLB.deleteVserverDomainBinding(_netscalerService, vserverName, domainName);
+    }
 
-                if (sites != null) {
-                    for (SiteLoadBalancerConfig site : sites) {
+    @Override
+    public void setConfigParams(Map<String, Object> params) {
+        // TODO Auto-generated method stub
 
-                        String sitePrivateIP = site.getGslbProviderPrivateIp();
-                        String sitePublicIP = site.getGslbProviderPublicIp();
-                        String servicePublicIp = site.getServicePublicIp();
-                        String servicePublicPort = site.getServicePort();
-                        String siteName = GSLB.generateUniqueSiteName(sitePrivateIP, sitePublicIP, site.getDataCenterId());
-                        String serviceName = GSLB.generateUniqueServiceName(siteName, servicePublicIp, servicePublicPort);
-                        String monitorName = GSLB.generateGslbServiceMonitorName(servicePublicIp);
+    }
 
-                        // delete GSLB service and GSLB monitor binding
-                        GSLB.deleteGslbServiceGslbMonitorBinding(_netscalerService, monitorName, serviceName);
+    @Override
+    public Map<String, Object> getConfigParams() {
+        // TODO Auto-generated method stub
+        return null;
+    }
 
-                        // remove binding between virtual server and services
-                        GSLB.deleteVserverServiceBinding(_netscalerService, serviceName, vserverName);
+    @Override
+    public int getRunLevel() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
 
-                        // delete service object
-                        GSLB.deleteService(_netscalerService, serviceName);
+    @Override
+    public void setRunLevel(int level) {
+        // TODO Auto-generated method stub
 
-                        // delete GSLB site object
-                        GSLB.deleteSite(_netscalerService, siteName);
+    }
 
-                        // delete the GSLB service monitor
-                        GSLB.deleteGslbServiceMonitor(_netscalerService, monitorName);
-                    }
+    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++;
                 }
-
-                // delete GSLB virtual server
-                GSLB.deleteVirtualServer(_netscalerService, vserverName);
-            }
-
-            saveConfiguration();
-
-        } catch (Exception e) {
-            String errMsg = "Failed to apply GSLB configuration due to " + e.getMessage();
-            if (shouldRetry(numRetries)) {
-                return retry(gslbCmd, numRetries);
-            }
-            return new GlobalLoadBalancerConfigAnswer(false, errMsg);
-        }
-
-        return new GlobalLoadBalancerConfigAnswer(true, "Successfully applied GSLB configuration.");
-    }
-
-    /*
-     * convenience class to create/update/delete/get the GSLB specific NetScaler objects
-     *     - gslbsite
-     *     - gslbvserver
-     *     - gslbservice
-     *     - vserver-service binding
-     *     - vserver-domain bindings
-     */
-    private static class GSLB {
-
-        // create a 'gslbsite' object representing a site
-        private static void createSite(nitro_service client, String siteName, String siteType, String siteIP, String sitePublicIP) throws ExecutionException {
-            try {
-                gslbsite site;
-                site = getSiteObject(client, siteName);
-
-                boolean isUpdateSite = false;
-                if (site == null) {
-                    site = new gslbsite();
-                } else {
-                    isUpdateSite = true;
-                }
-
-                assert ("LOCAL".equalsIgnoreCase(siteType) || "REMOTE".equalsIgnoreCase(siteType));
-                site.set_sitetype(siteType);
-                site.set_sitename(siteName);
-                site.set_siteipaddress(siteIP);
-                site.set_publicip(sitePublicIP);
-                site.set_metricexchange("ENABLED");
-                site.set_nwmetricexchange("ENABLED");
-                site.set_sessionexchange("ENABLED");
-                if (isUpdateSite) {
-                    gslbsite.update(client, site);
-                } else {
-                    gslbsite.add(client, site);
-                }
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Successfully created GSLB site: " + siteName);
-                }
-            } catch (Exception e) {
-                String errMsg = "Failed to create GSLB site: " + siteName + " due to " + e.getMessage();
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(errMsg);
-                }
-                throw new ExecutionException(errMsg);
-            }
-        }
-
-        // delete 'gslbsite' object representing a site
-        private static void deleteSite(nitro_service client, String siteName) throws ExecutionException {
-            try {
-                gslbsite site = getSiteObject(client, siteName);
-                if (site != null) {
-                    gslbsite_gslbservice_binding[] serviceBindings = gslbsite_gslbservice_binding.get(client, siteName);
-                    if (serviceBindings != null && serviceBindings.length > 0) {
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug("There are services associated with GSLB site: " + siteName + " so ignoring site deletion");
-                        }
-                    }
-                    gslbsite.delete(client, siteName);
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Successfully deleted GSLB site: " + siteName);
-                    }
-                } else {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.warn("Ignoring delete request for non existing  GSLB site: " + siteName);
-                    }
-                }
-            } catch (Exception e) {
-                String errMsg = "Failed to delete GSLB site: " + siteName + " due to " + e.getMessage();
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(errMsg);
-                }
-                throw new ExecutionException(errMsg);
-            }
-        }
-
-        // update 'gslbsite' object representing a site
-        private static void updateSite(nitro_service client, String siteType, String siteName, String siteIP, String sitePublicIP) throws ExecutionException {
-            try {
-                gslbsite site;
-                site = getSiteObject(client, siteName);
-                if (site == null) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.warn("Ignoring update request for non existing  GSLB site: " + siteName);
-                    }
-                    return;
-                }
-                assert ("LOCAL".equalsIgnoreCase(siteType) || "REMOTE".equalsIgnoreCase(siteType));
-                site.set_sitetype(siteType);
-                site.set_sitename(siteName);
-                site.set_siteipaddress(siteIP);
-                site.set_publicip(sitePublicIP);
-                site.set_metricexchange("ENABLED");
-                site.set_nwmetricexchange("ENABLED");
-                site.set_sessionexchange("ENABLED");
-                gslbsite.update(client, site);
-
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Successfully updated GSLB site: " + siteName);
-                }
-
-            } catch (Exception e) {
-                String errMsg = "Failed to update GSLB site: " + siteName + " due to " + e.getMessage();
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(errMsg);
-                }
-                throw new ExecutionException(errMsg);
-            }
-        }
-
-        // create a 'gslbvserver' object representing a globally load balanced service
-        private static void
-        createVirtualServer(nitro_service client, String vserverName, String lbMethod, String persistenceType, long persistenceId, String serviceType)
-                throws ExecutionException {
-            try {
-                gslbvserver vserver;
-                vserver = getVserverObject(client, vserverName);
-
-                boolean isUpdateSite = false;
-                if (vserver == null) {
-                    vserver = new gslbvserver();
-                } else {
-                    isUpdateSite = true;
-                }
-
-                vserver.set_name(vserverName);
-                if ("RoundRobin".equalsIgnoreCase(lbMethod)) {
-                    vserver.set_lbmethod("ROUNDROBIN");
-                } else if ("LeastConn".equalsIgnoreCase(lbMethod)) {
-                    vserver.set_lbmethod("LEASTCONNECTION");
-                } else if ("Proximity".equalsIgnoreCase(lbMethod)) {
-                    vserver.set_lbmethod("RTT");
-                } else {
-                    throw new ExecutionException("Unsupported LB method");
-                }
-                vserver.set_persistencetype(persistenceType);
-                if ("SOURCEIP".equalsIgnoreCase(persistenceType)) {
-                    vserver.set_persistenceid(persistenceId);
-                }
-                vserver.set_servicetype(serviceType);
-                vserver.set_state("ENABLED");
-                vserver.set_cookietimeout(null);
-                vserver.set_domainname(null);
-                if (isUpdateSite) {
-                    // both netmask and LB method can not be specified while update so set to null
-                    vserver.set_netmask(null);
-                    vserver.set_v6netmasklen(null);
-                    gslbvserver.update(client, vserver);
-                } else {
-                    gslbvserver.add(client, vserver);
-                }
-
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Successfully added GSLB virtual server: " + vserverName);
-                }
-
-            } catch (Exception e) {
-                String errMsg = "Failed to add GSLB virtual server: " + vserverName + " due to " + e.getMessage();
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(errMsg);
-                }
-                throw new ExecutionException(errMsg);
-            }
-        }
-
-        // delete 'gslbvserver' object representing a globally load balanced service
-        private static void deleteVirtualServer(nitro_service client, String vserverName) throws ExecutionException {
-            try {
-                gslbvserver vserver = getVserverObject(client, vserverName);
-                if (vserver != null) {
-                    gslbvserver.delete(client, vserver);
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Successfully deleted GSLB virtual server: " + vserverName);
-                    }
-                } else {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.warn("Ignoring delete request for non existing  GSLB virtual server: " + vserverName);
-                    }
-                }
-            } catch (Exception e) {
-                String errMsg = "Failed to delete GSLB virtual server: " + vserverName + " due to " + e.getMessage();
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(errMsg);
-                }
-                throw new ExecutionException(errMsg);
-            }
-        }
-
-        // enable 'gslbvserver' object representing a globally load balanced service
-        private static void enableVirtualServer(nitro_service client, String vserverName) throws ExecutionException {
-            try {
-                gslbvserver vserver = getVserverObject(client, vserverName);
-                if (vserver != null) {
-                    gslbvserver.enable(client, vserver);
-                }
-            } catch (Exception e) {
-                String errMsg = "Failed to enable GSLB virtual server: " + vserverName + " due to " + e.getMessage();
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(errMsg);
-                }
-                throw new ExecutionException(errMsg);
-            }
-        }
-
-        // disable 'gslbvserver' object representing a globally load balanced service
-        private static void disableVirtualServer(nitro_service client, String vserverName) throws ExecutionException {
-            try {
-                gslbvserver vserver = getVserverObject(client, vserverName);
-                if (vserver != null) {
-                    gslbvserver.disable(client, vserver);
-                }
-            } catch (Exception e) {
-                String errMsg = "Failed to disable GSLB virtual server: " + vserverName + " due to " + e.getMessage();
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(errMsg);
-                }
-                throw new ExecutionException(errMsg);
-            }
-        }
-
-        // update 'gslbvserver' object representing a globally load balanced service
-        private static void updateVirtualServer(nitro_service client, String vserverName, String lbMethod, String persistenceType, String serviceType)
-                throws ExecutionException {
-            try {
-                gslbvserver vServer = getVserverObject(client, vserverName);
-                if (vServer != null) {
-                    vServer.set_lbmethod(lbMethod);
-                    vServer.set_persistencetype(persistenceType);
-                    vServer.set_servicetype(serviceType);
-                    gslbvserver.update(client, vServer);
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Successfully updated GSLB virtual server: " + vserverName);
-                    }
-                }
-            } catch (Exception e) {
-                String errMsg = "Failed to update GSLB virtual server: " + vserverName + " due to " + e.getMessage();
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(errMsg);
-                }
-                throw new ExecutionException(errMsg);
-            }
-        }
-
-        // create, delete, update, get the GSLB services
-        private static void createService(nitro_service client, String serviceName, String serviceType, String serviceIp, String servicePort, String siteName)
-                throws ExecutionException {
-            try {
-                gslbservice service;
-                service = getServiceObject(client, serviceName);
-                String gslbServerName = generateGslbServerName(serviceIp);
-
-                if (!gslbServerExists(client, gslbServerName)) {
-                    base_response apiCallResult;
-                    com.citrix.netscaler.nitro.resource.config.basic.server nsServer = new com.citrix.netscaler.nitro.resource.config.basic.server();
-                    nsServer.set_name(gslbServerName);
-                    nsServer.set_ipaddress(serviceIp);
-                    apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.add(client, nsServer);
-                    if ((apiCallResult.errorcode != 0) && (apiCallResult.errorcode != NitroError.NS_RESOURCE_EXISTS)) {
-                        throw new ExecutionException("Failed to add server " + gslbServerName + " due to" + apiCallResult.message);
-                    }
-                }
-
-                boolean isUpdateSite = false;
-                if (service == null) {
-                    service = new gslbservice();
-                } else {
-                    isUpdateSite = true;
-                }
-
-                service.set_sitename(siteName);
-                service.set_servername(gslbServerName);
-                int port = Integer.parseInt(servicePort);
-                service.set_port(port);
-                service.set_servicename(serviceName);
-                service.set_servicetype(serviceType);
-                if (isUpdateSite) {
-                    service.set_viewip(null);
-                    service.set_viewname(null);
-                    gslbservice.update(client, service);
-                } else {
-                    gslbservice.add(client, service);
-                }
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Successfully created service: " + serviceName + " at site: " + siteName);
-                }
-            } catch (Exception e) {
-                String errMsg = "Failed to created service: " + serviceName + " at site: " + siteName + " due to " + e.getMessage();
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(errMsg);
-                }
-                throw new ExecutionException(errMsg);
-            }
-        }
-
-        private static void deleteService(nitro_service client, String serviceName) throws ExecutionException {
-            try {
-                gslbservice service = getServiceObject(client, serviceName);
-                if (service != null) {
-                    gslbservice.delete(client, serviceName);
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Successfully deleted service: " + serviceName);
-                    }
-                } else {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.warn("Ignoring delete request for non existing  service: " + serviceName);
-                    }
-                }
-            } catch (Exception e) {
-                String errMsg = "Failed to delete service: " + serviceName + " due to " + e.getMessage();
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(errMsg);
-                }
-                throw new ExecutionException(errMsg);
-            }
-        }
-
-        private static void updateService(nitro_service client, String serviceName, String serviceType, String publicIp, String publicPort, String siteName)
-                throws ExecutionException {
-            try {
-                gslbservice service;
-                service = getServiceObject(client, serviceName);
-
-                if (service != null) {
-                    service.set_sitename(siteName);
-                    service.set_publicip(publicIp);
-                    service.set_publicport(Integer.getInteger(publicPort));
-                    service.set_servicename(serviceName);
-                    service.set_servicetype(serviceType);
-                    gslbservice.update(client, service);
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Successfully updated service: " + serviceName + " at site: " + siteName);
-                    }
-                }
-            } catch (Exception e) {
-                String errMsg = "Failed to update service: " + serviceName + " at site: " + siteName + "due to " + e.getMessage();
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(errMsg);
-                }
-                throw new ExecutionException(errMsg);
-            }
-        }
-
-        private static void createVserverServiceBinding(nitro_service client, String serviceName, String vserverName, long weight) throws ExecutionException {
-            String errMsg;
-            try {
-                assert (weight >= 1 && weight <= 100);
-                gslbvserver_gslbservice_binding binding = new gslbvserver_gslbservice_binding();
-                binding.set_name(vserverName);
-                binding.set_servicename(serviceName);
-                binding.set_weight(weight);
-                gslbvserver_gslbservice_binding.add(client, binding);
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Successfully created service: " + serviceName + " and virtual server: " + vserverName + " binding");
-                }
-            } catch (nitro_exception ne) {
-                if (ne.getErrorCode() == 273) {
-                    return;
-                }
-                errMsg = "Failed to create service: " + serviceName + " and virtual server: " + vserverName + " binding due to " + ne.getMessage();
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(errMsg);
-                }
-                throw new ExecutionException(errMsg);
-            } catch (Exception e) {
-                errMsg = "Failed to create service: " + serviceName + " and virtual server: " + vserverName + " binding due to " + e.getMessage();
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(errMsg);
-                }
-                throw new ExecutionException(errMsg);
-            }
-        }
-
-        private static void deleteVserverServiceBinding(nitro_service client, String serviceName, String vserverName) throws ExecutionException {
-            try {
-                gslbvserver_gslbservice_binding[] bindings = gslbvserver_gslbservice_binding.get(client, vserverName);
-                if (bindings != null) {
-                    for (gslbvserver_gslbservice_binding binding : bindings) {
-                        if (binding.get_servicename().equalsIgnoreCase(serviceName) && binding.get_name().equals(vserverName)) {
-                            gslbvserver_gslbservice_binding.delete(client, binding);
-                            if (s_logger.isDebugEnabled()) {
-                                s_logger.debug("Successfully deleted service: " + serviceName + " and virtual server: " + vserverName + " binding");
-                            }
-                            break;
-                        }
-                    }
-                }
-            } catch (Exception e) {
-                String errMsg = "Failed to create service: " + serviceName + " and virtual server: " + vserverName + " binding due to " + e.getMessage();
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(errMsg);
-                }
-                throw new ExecutionException(errMsg);
-            }
-        }
-
-        // create, delete GSLB virtual server and domain bindings
-        private static void createVserverDomainBinding(nitro_service client, String vserverName, String domainName) throws ExecutionException {
-            String errMsg;
-            try {
-                gslbvserver_domain_binding binding = new gslbvserver_domain_binding();
-                binding.set_domainname(domainName);
-                binding.set_name(vserverName);
-                gslbvserver_domain_binding.add(client, binding);
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Successfully added virtual server: " + vserverName + " domain name: " + domainName + " binding");
-                }
-                return;
-            } catch (nitro_exception e) {
-                if (e.getErrorCode() == NitroError.NS_GSLB_DOMAIN_ALREADY_BOUND) {
-                    return;
-                }
-                errMsg = e.getMessage();
-            } catch (Exception e) {
-                errMsg = e.getMessage();
-            }
-            errMsg = "Failed to create virtual server: " + vserverName + " domain name: " + domainName + " binding" + errMsg;
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug(errMsg);
-            }
-            throw new ExecutionException(errMsg);
-        }
-
-        private static void deleteVserverDomainBinding(nitro_service client, String vserverName, String domainName) throws ExecutionException {
-            try {
-                gslbvserver_domain_binding[] bindings = gslbvserver_domain_binding.get(client, vserverName);
-                if (bindings != null) {
-                    for (gslbvserver_domain_binding binding : bindings) {
-                        if (binding.get_domainname().equalsIgnoreCase(domainName)) {
-                            gslbvserver_domain_binding.delete(client, binding);
-                            if (s_logger.isDebugEnabled()) {
-                                s_logger.debug("Successfully deleted virtual server: " + vserverName + " and " + " domain: " + domainName + " binding");
-                            }
-                            break;
-                        }
-                    }
-                }
-            } catch (Exception e) {
-                String errMsg = "Failed to delete virtual server: " + vserverName + " and domain " + domainName + " binding due to " + e.getMessage();
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(errMsg);
-                }
-                throw new ExecutionException(errMsg);
-            }
-        }
-
-        private static void createGslbServiceMonitor(nitro_service nsService, String servicePublicIp, String serviceName) throws ExecutionException {
-            try {
-                lbmonitor newmonitor = new lbmonitor();
-                String monitorName = generateGslbServiceMonitorName(servicePublicIp);
-                newmonitor.set_type("TCP");
-                newmonitor.set_servicename(serviceName);
-                newmonitor.set_monitorname(monitorName);
-                newmonitor.set_state("ENABLED");
-                lbmonitor.add(nsService, newmonitor);
-            } catch (nitro_exception ne) {
-                if (ne.getErrorCode() == NitroError.NS_RESOURCE_EXISTS) {
-                    return;
-                }
-            } catch (Exception e) {
-                String errMsg = "Failed to create GSLB monitor for service public ip" + servicePublicIp;
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(errMsg);
-                }
-                throw new ExecutionException(errMsg);
-            }
-        }
-
-        private static void deleteGslbServiceMonitor(nitro_service nsService, String monitorName) throws ExecutionException {
-            try {
-                lbmonitor serviceMonitor = lbmonitor.get(nsService, monitorName);
-                if (serviceMonitor != null) {
-                    lbmonitor.delete(nsService, serviceMonitor);
-                }
-            } catch (nitro_exception ne) {
-                if (ne.getErrorCode() != NitroError.NS_RESOURCE_NOT_EXISTS) {
-                    String errMsg = "Failed to delete monitor " + monitorName + " for GSLB service due to " + ne.getMessage();
-                    s_logger.debug(errMsg);
-                    throw new com.cloud.utils.exception.ExecutionException(errMsg);
-                }
-            } catch (Exception e) {
-                String errMsg = "Failed to delete monitor " + monitorName + " for GSLB service due to " + e.getMessage();
-                s_logger.debug(errMsg);
-                throw new com.cloud.utils.exception.ExecutionException(errMsg);
-            }
-        }
-
-        private static void createGslbServiceGslbMonitorBinding(nitro_service nsService, String monitorName, String serviceName) {
-            try {
-                gslbservice_lbmonitor_binding monitorBinding = new gslbservice_lbmonitor_binding();
-                monitorBinding.set_monitor_name(monitorName);
-                monitorBinding.set_servicename(serviceName);
-                gslbservice_lbmonitor_binding.add(nsService, monitorBinding);
-            } catch (Exception e) {
-                // TODO: Nitro API version 10.* is not compatible for NetScalers 9.*, so may fail
-                // against NetScaler version lesser than 10 hence ignore the exception
-                s_logger.warn("Failed to bind monitor to GSLB service due to " + e.getMessage());
-            }
-        }
-
-        private static void deleteGslbServiceGslbMonitorBinding(nitro_service nsService, String monitorName, String serviceName) {
-            try {
-                gslbservice_lbmonitor_binding[] monitorBindings = gslbservice_lbmonitor_binding.get(nsService, serviceName);
-                if (monitorBindings != null && monitorBindings.length > 0) {
-                    for (gslbservice_lbmonitor_binding binding : monitorBindings) {
-                        if (binding.get_monitor_name().equalsIgnoreCase(monitorName)) {
-                            s_logger.info("Found a binding between monitor " + binding.get_monitor_name() + " and " + binding.get_servicename());
-                            gslbservice_lbmonitor_binding.delete(nsService, binding);
-                        }
-                    }
-                }
-            } catch (Exception e) {
-                s_logger.debug("Failed to delete GSLB monitor " + monitorName + " and GSLB service " + serviceName + " binding due to " + e.getMessage() +
-                        " but moving on ..., will be cleaned up as part of GSLB " + " service delete any way..");
-            }
-        }
-
-        // get 'gslbsite' object corresponding to a site name
-        private static gslbsite getSiteObject(nitro_service client, String siteName) {
-            try {
-                gslbsite site = gslbsite.get(client, siteName);
-                if (site != null) {
-                    return site;
-                }
-            } catch (Exception e) {
-
-            }
-            return null;
-        }
-
-        private static gslbvserver getVserverObject(nitro_service client, String vserverName) {
-            try {
-                gslbvserver vserver = gslbvserver.get(client, vserverName);
-                return vserver;
-            } catch (Exception e) {
-                return null;
-            }
-        }
-
-        private static gslbservice getServiceObject(nitro_service client, String serviceName) {
-            try {
-                gslbservice service = gslbservice.get(client, serviceName);
-                return service;
-            } catch (Exception e) {
-                return null;
-            }
-        }
-
-        private static String generateUniqueSiteName(String sitePrivateIp, String sitePublicIP, long dataCenterId) {
-            return "cloudsite" + String.valueOf(dataCenterId);
-        }
-
-        private static String generateVirtualServerName(String domainName) {
-            return "cloud-gslb-vserver-" + domainName;
-        }
-
-        private static String generateUniqueServiceName(String siteName, String publicIp, String publicPort) {
-            return "cloud-gslb-service-" + siteName + "-" + publicIp + "-" + publicPort;
-        }
-
-        private static String generateGslbServiceMonitorName(String publicIp) {
-            return "cloud-monitor-" + publicIp;
-        }
-
-        private static boolean gslbServerExists(nitro_service client, String serverName) throws ExecutionException {
-            try {
-                if (com.citrix.netscaler.nitro.resource.config.basic.server.get(client, serverName) != null) {
-                    return true;
-                } else {
-                    return false;
-                }
-            } catch (nitro_exception e) {
-                if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
-                    return false;
-                } else {
-                    throw new ExecutionException("Failed to verify Server " + serverName + " exists on the NetScaler device due to " + e.getMessage());
-                }
-            } catch (Exception e) {
-                throw new ExecutionException("Failed to verify Server " + serverName + " exists on the NetScaler device due to " + e.getMessage());
-            }
-        }
-
-        private static String generateGslbServerName(String serverIP) {
-            return genGslbObjectName("Cloud-Server-", serverIP);
-        }
-
-        private static String genGslbObjectName(Object... args) {
-            StringBuffer buff = new StringBuffer();
-            for (int i = 0; i < args.length; i++) {
-                buff.append(args[i]);
-                if (i != args.length - 1) {
-                    buff.append("-");
-                }
-            }
-            return buff.toString();
-        }
-    }
-
-    /* SSL Termination */
-    private static class SSL {
-
-        private static final String SSL_CERT_PATH = "/nsconfig/ssl/";
-        private static final int SSH_PORT = 22;
-
-        private static boolean isSslCertKeyPresent(nitro_service ns, String certKeyName) throws ExecutionException {
-
-            String filter = "certkey:" + certKeyName;
-
-            try {
-                if (sslcertkey.count_filtered(ns, filter) > 0)
-                    return true;
-            } catch (nitro_exception e) {
-                throw new ExecutionException("Failed to get certkey " + e.getMessage());
-            } catch (Exception e) {
-                throw new ExecutionException("Failed to get certkey " + e.getMessage());
-            }
-
-            return false;
-        }
-
-        private static void deleteSslCertKey(nitro_service ns, String certKeyName) throws ExecutionException {
-            try {
-
-                sslcertkey certkey = new sslcertkey();
-                certkey.set_certkey(certKeyName);
-                sslcertkey.delete(ns, certkey);
-
-            } catch (nitro_exception e) {
-                throw new ExecutionException("Failed to delete certkey " + e.getMessage());
-            } catch (Exception e) {
-                throw new ExecutionException("Failed to delete certkey " + e.getMessage());
-            }
-
-        }
-
-        private static void deleteCertFile(String nsIp, String username, String password, String certFilename) throws Exception {
-            SshHelper.sshExecute(nsIp, SSH_PORT, username, null, password, "shell rm " + SSL_CERT_PATH + certFilename);
-        }
-
-        private static void deleteKeyFile(String nsIp, String username, String password, String keyFilename) throws Exception {
-            SshHelper.sshExecute(nsIp, SSH_PORT, username, null, password, "shell rm " + SSL_CERT_PATH + keyFilename);
-        }
-
-        private static void createSslCertKey(nitro_service ns, String certFilename, String keyFilename, String certKeyName, String password) throws ExecutionException {
-            s_logger.debug("Adding cert to netscaler");
-            try {
-                sslcertkey certkey = new sslcertkey();
-                certkey.set_certkey(certKeyName);
-                certkey.set_cert(SSL_CERT_PATH + certFilename);
-
-                if (keyFilename != null)
-                    certkey.set_key(SSL_CERT_PATH + keyFilename);
-
-                if (password != null) {
-                    certkey.set_passplain(password);
-                }
-
-                certkey.perform_operation(ns);
-
-            } catch (nitro_exception e) {
-                throw new ExecutionException("Failed to add certkey binding " + e.getMessage());
-            } catch (Exception e) {
-                throw new ExecutionException("Failed to add certkey binding " + e.getMessage());
-            }
-
-        }
-
-        public static void updateCertKey(nitro_service ns, String certKeyName, String cert, String key, String password) throws ExecutionException {
-            try {
-                sslcertkey certkey = sslcertkey.get(ns, certKeyName);
-                if (cert != null)
-                    certkey.set_cert(cert);
-                if (key != null)
-                    certkey.set_key(cert);
-                if (password != null)
-                    certkey.set_passplain(cert);
-
-                sslcertkey.change(ns, certkey);
-
-            } catch (nitro_exception e) {
-                throw new ExecutionException("Failed to update ssl on load balancer due to " + e.getMessage());
-            } catch (Exception e) {
-                throw new ExecutionException("Failed to update ssl on load balancer due to " + e.getMessage());
-            }
-        }
-
-        private static void bindCertKeyToVserver(nitro_service ns, String certKeyName, String vserver) throws ExecutionException {
-            s_logger.debug("Adding cert to netscaler");
-
-            try {
-                sslvserver_sslcertkey_binding cert_binding = new sslvserver_sslcertkey_binding();
-                cert_binding.set_certkeyname(certKeyName);
-                cert_binding.set_vservername(vserver);
-                cert_binding.perform_operation(ns);
-            } catch (nitro_exception e) {
-                throw new ExecutionException("Failed to bind certkey to vserver due to " + e.getMessage());
-            } catch (Exception e) {
-                throw new ExecutionException("Failed to bind certkey to vserver due to " + e.getMessage());
-            }
-        }
-
-        private static void unbindCertKeyFromVserver(nitro_service ns, String certKeyName, String vserver) throws ExecutionException {
-            try {
-
-                sslvserver_sslcertkey_binding cert_binding = new sslvserver_sslcertkey_binding();
-                cert_binding.set_certkeyname(certKeyName);
-                cert_binding.set_vservername(vserver);
-                sslvserver_sslcertkey_binding.delete(ns, cert_binding);
-
-            } catch (nitro_exception e) {
-                throw new ExecutionException("Failed to unbind certkey to vserver due to " + e.getMessage());
-            } catch (Exception e) {
-                throw new ExecutionException("Failed to unbind certkey to vserver due to " + e.getMessage());
-            }
-
-        }
-
-        private static void uploadCert(String nsIp, String user, String password, String certFilename, byte[] certData) throws ExecutionException {
-            try {
-                SshHelper.scpTo(nsIp, SSH_PORT, user, null, password, SSL_CERT_PATH, certData, certFilename, null);
-            } catch (Exception e) {
-                throw new ExecutionException("Failed to copy private key to device " + e.getMessage());
-            }
-        }
-
-        private static void uploadKey(String nsIp, String user, String password, String keyFilename, byte[] keyData) throws ExecutionException {
-            try {
-                SshHelper.scpTo(nsIp, SSH_PORT, user, null, password, SSL_CERT_PATH, keyData, keyFilename, null);
-            } catch (Exception e) {
-                throw new ExecutionException("Failed to copy private key to device " + e.getMessage());
-            }
-        }
-
-        private static void enableSslFeature(nitro_service ns, boolean isSdx) throws ExecutionException {
-            if (isSdx) {
-                return;
-            }
-            try {
-                base_response result = ns.enable_features(new String[] {"SSL"});
-                if (result.errorcode != 0)
-                    throw new ExecutionException("Unable to enable SSL on LB");
-            } catch (nitro_exception e) {
-                throw new ExecutionException("Failed to enable ssl feature on load balancer due to " + e.getMessage());
-            } catch (Exception e) {
-                throw new ExecutionException("Failed to enable ssl feature on load balancer due to " + e.getMessage());
-            }
-        }
-
-        public static boolean checkSslFeature(nitro_service ns) throws ExecutionException {
-            try {
-                String[] features = ns.get_enabled_features();
-                if (features != null) {
-                    for (String feature : features) {
-                        if (feature.equalsIgnoreCase("SSL")) {
-                            return true;
-                        }
-                    }
-                }
-                return false;
-            } catch (nitro_exception e) {
-                throw new ExecutionException("Failed to check ssl feature on load balancer due to " + e.getMessage());
-            } catch (Exception e) {
-                throw new ExecutionException("Failed to check ssl feature on load balancer due to " + e.getMessage());
-            }
-        }
-
-        public static boolean certLinkExists(nitro_service ns, String userCertName, String caCertName) throws ExecutionException {
-            try {
-                // check if there is a link from userCertName to caCertName
-
-                sslcertkey userCert = sslcertkey.get(ns, userCertName);
-                String nsCaCert = userCert.get_linkcertkeyname();
-
-                if (nsCaCert != null && nsCaCert.equals(caCertName))
-                    return true;
-
-            } catch (nitro_exception e) {
-                throw new ExecutionException("Failed to check cert link on load balancer to " + e.getMessage());
-            } catch (Exception e) {
-                throw new ExecutionException("Failed to check cert link on load balancer due to " + e.getMessage());
-            }
-            return false;
-        }
-
-        public static void linkCerts(nitro_service ns, String userCertName, String caCertName) throws ExecutionException {
-            try {
-
-                // the assumption is that that both userCertName and caCertName are present on NS
-
-                sslcertkey caCert = sslcertkey.get(ns, caCertName);
-                sslcertkey userCert = sslcertkey.get(ns, userCertName);
-
-                sslcertkey linkResource = new sslcertkey();
-
-                // link user cert to CA cert
-                linkResource.set_certkey(userCert.get_certkey());
-                linkResource.set_linkcertkeyname(caCert.get_certkey());
-                sslcertkey.link(ns, linkResource);
-
-            } catch (nitro_exception e) {
-                throw new ExecutionException("Failed to check cert link on load balancer to " + e.getMessage());
-            } catch (Exception e) {
-                throw new ExecutionException("Failed to check cert link on load balancer due to " + e.getMessage());
-            }
-
-        }
-
-        public static boolean isCaforCerts(nitro_service ns, String caCertName) throws ExecutionException {
-            // check if this certificate  serves as a CA for other certificates
-            try {
-                sslcertlink[] childLinks = sslcertlink.get_filtered(ns, "linkcertkeyname:" + caCertName);
-                if (childLinks != null && childLinks.length > 0) {
-                    return true;
-                }
-
-            } catch (nitro_exception e) {
-                throw new ExecutionException("Failed to check cert link on load balancer to " + e.getMessage());
-            } catch (Exception e) {
-                throw new ExecutionException("Failed to check cert link on load balancer due to " + e.getMessage());
-            }
-            return false;
-
-        }
-
-        public static boolean isBoundToVserver(nitro_service ns, String certKeyName, String nsVirtualServerName) throws ExecutionException {
-            try {
-
-                sslcertkey_sslvserver_binding[] cert_vs_binding = sslcertkey_sslvserver_binding.get_filtered(ns, certKeyName, "vservername:" + nsVirtualServerName);
-                if (cert_vs_binding != null && cert_vs_binding.length > 0) {
-                    return true;
-                }
-
-            } catch (nitro_exception e) {
-                throw new ExecutionException("Failed to check cert link on load balancer to " + e.getMessage());
-            } catch (Exception e) {
-                throw new ExecutionException("Failed to check cert link on load balancer due to " + e.getMessage());
-            }
-            return false;
-
-        }
-    }
-
-    private void enableVPXInterfaces(String publicIf, String privateIf, ns nsObj) {
-        // enable VPX to use 10 gigabit Ethernet interfaces if public/private interface
-        // on SDX is a 10Gig interface
-        if (publicIf.equals("10/1") || privateIf.equals("10/1")) {
-            nsObj.set_if_10_1(new Boolean(true));
-        }
-
-        if (publicIf.equals("10/2") || privateIf.equals("10/2")) {
-            nsObj.set_if_10_2(new Boolean(true));
-        }
-
-        if (publicIf.equals("10/3") || privateIf.equals("10/3")) {
-            nsObj.set_if_10_3(new Boolean(true));
-        }
-
-        if (publicIf.equals("10/4") || privateIf.equals("10/4")) {
-            nsObj.set_if_10_4(new Boolean(true));
-        }
-
-        if (publicIf.equals("10/5") || privateIf.equals("10/5")) {
-            nsObj.set_if_10_5(new Boolean(true));
-        }
-
-        if (publicIf.equals("10/6") || privateIf.equals("10/6")) {
-            nsObj.set_if_10_6(new Boolean(true));
-        }
-
-        if (publicIf.equals("10/7") || privateIf.equals("10/7")) {
-            nsObj.set_if_10_7(new Boolean(true));
-        }
-
-        if (publicIf.equals("10/8") || privateIf.equals("10/8")) {
-            nsObj.set_if_10_8(new Boolean(true));
-        }
-
-        // enable VPX to use 1 gigabit Ethernet interfaces if public/private interface
-        // on SDX is a 1Gig interface
-        if (publicIf.equals("1/1") || privateIf.equals("1/1")) {
-            nsObj.set_if_1_1(new Boolean(true));
-        }
-
-        if (publicIf.equals("1/2") || privateIf.equals("1/2")) {
-            nsObj.set_if_1_2(new Boolean(true));
-        }
-
-        if (publicIf.equals("1/3") || privateIf.equals("1/3")) {
-            nsObj.set_if_1_3(new Boolean(true));
-        }
-
-        if (publicIf.equals("1/4") || privateIf.equals("1/4")) {
-            nsObj.set_if_1_4(new Boolean(true));
-        }
-
-        if (publicIf.equals("1/5") || privateIf.equals("1/5")) {
-            nsObj.set_if_1_5(new Boolean(true));
-        }
-
-        if (publicIf.equals("1/6") || privateIf.equals("1/6")) {
-            nsObj.set_if_1_6(new Boolean(true));
-        }
-
-        if (publicIf.equals("1/7") || privateIf.equals("1/7")) {
-            nsObj.set_if_1_7(new Boolean(true));
-        }
-
-        if (publicIf.equals("1/8") || privateIf.equals("1/8")) {
-            nsObj.set_if_1_8(new Boolean(true));
-        }
-    }
-
-    private synchronized Answer execute(DestroyLoadBalancerApplianceCommand cmd, int numRetries) {
-        String vpxName = "Cloud-VPX-" + cmd.getLoadBalancerIP();
-        if (!_isSdx) {
-            return Answer.createUnsupportedCommandAnswer(cmd);
-        }
-
-        try {
-            ns vpxToDelete = null;
-            ns[] vpxInstances = ns.get(_netscalerSdxService);
-            for (ns vpx : vpxInstances) {
-                if (vpx.get_name().equals(vpxName)) {
-                    vpxToDelete = vpx;
-                    break;
-                }
-            }
-
-            if (vpxToDelete == null) {
-                String msg = "There is no VPX instance " + vpxName + " on the Netscaler SDX device " + _ip + " to delete";
-                s_logger.warn(msg);
-                return new DestroyLoadBalancerApplianceAnswer(cmd, true, msg);
-            }
-
-            // destroy the VPX instance
-            ns nsDelObj = new ns();
-            nsDelObj.set_id(vpxToDelete.get_id());
-            vpxToDelete = ns.delete(_netscalerSdxService, nsDelObj);
-            String msg = "Deleted VPX instance " + vpxName + " on Netscaler SDX " + _ip + " successfully.";
-            s_logger.info(msg);
-            return new DestroyLoadBalancerApplianceAnswer(cmd, true, msg);
-        } catch (Exception e) {
-            if (shouldRetry(numRetries)) {
-                return retry(cmd, numRetries);
-            }
-            return new DestroyLoadBalancerApplianceAnswer(cmd, false, "Failed to delete VPX instance " + vpxName + " on Netscaler SDX " + _ip);
-        }
-    }
-
-    private synchronized Answer execute(SetStaticNatRulesCommand cmd, int numRetries) {
-
-        if (_isSdx) {
-            return Answer.createUnsupportedCommandAnswer(cmd);
-        }
-
-        String[] results = new String[cmd.getRules().length];
-        int i = 0;
-        boolean endResult = true;
-
-        try {
-            for (StaticNatRuleTO rule : cmd.getRules()) {
-                String srcIp = rule.getSrcIp();
-                String dstIP = rule.getDstIp();
-                String iNatRuleName = generateInatRuleName(srcIp, dstIP);
-                String rNatRuleName = generateRnatRuleName(srcIp, dstIP);
-                inat iNatRule = null;
-                rnat rnatRule = null;
-
-                if (!rule.revoked()) {
-                    try {
-                        iNatRule = inat.get(_netscalerService, iNatRuleName);
-                    } catch (nitro_exception e) {
-                        if (e.getErrorCode() != NitroError.NS_RESOURCE_NOT_EXISTS) {
-                            throw e;
-                        }
-                    }
-
-                    if (iNatRule == null) {
-                        iNatRule = new inat();
-                        iNatRule.set_name(iNatRuleName);
-                        iNatRule.set_publicip(srcIp);
-                        iNatRule.set_privateip(dstIP);
-                        iNatRule.set_usnip("OFF");
-                        iNatRule.set_usip("ON");
-                        try {
-                            apiCallResult = inat.add(_netscalerService, iNatRule);
-                        } catch (nitro_exception e) {
-                            if (e.getErrorCode() != NitroError.NS_RESOURCE_EXISTS) {
-                                throw e;
-                            }
-                        }
-                        s_logger.debug("Created Inat rule on the Netscaler device " + _ip + " to enable static NAT from " + srcIp + " to " + dstIP);
-                    }
-                    try {
-                        rnat[] rnatRules = rnat.get(_netscalerService);
-                        if (rnatRules != null) {
-                            for (rnat rantrule : rnatRules) {
-                                if (rantrule.get_network().equalsIgnoreCase(rNatRuleName)) {
-                                    rnatRule = rantrule;
-                                    break;
-                                }
-                            }
-                        }
-                    } catch (nitro_exception e) {
-                        throw e;
-                    }
-
-                    if (rnatRule == null) {
-                        rnatRule = new rnat();
-                        rnatRule.set_natip(srcIp);
-                        rnatRule.set_network(dstIP);
-                        rnatRule.set_netmask("255.255.255.255");
-                        try {
-                            apiCallResult = rnat.update(_netscalerService, rnatRule);
-                        } catch (nitro_exception e) {
-                            if (e.getErrorCode() != NitroError.NS_RESOURCE_EXISTS) {
-                                throw e;
-                            }
-                        }
-                        s_logger.debug("Created Rnat rule on the Netscaler device " + _ip + " to enable revese static NAT from " + dstIP + " to " + srcIp);
-                    }
-                } else {
-                    try {
-                        inat.delete(_netscalerService, iNatRuleName);
-                        rnat[] rnatRules = rnat.get(_netscalerService);
-                        if (rnatRules != null) {
-                            for (rnat rantrule : rnatRules) {
-                                if (rantrule.get_network().equalsIgnoreCase(dstIP)) {
-                                    rnatRule = rantrule;
-                                    rnat.clear(_netscalerService, rnatRule);
-                                    break;
-                                }
-                            }
-                        }
-                    } catch (nitro_exception e) {
-                        if (e.getErrorCode() != NitroError.NS_RESOURCE_NOT_EXISTS) {
-                            throw e;
-                        }
-                    }
-                    s_logger.debug("Deleted Inat rule on the Netscaler device " + _ip + " to remove static NAT from " + srcIp + " to " + dstIP);
-                }
-
-                saveConfiguration();
-                results[i++] = "Static nat rule from " + srcIp + " to " + dstIP + " successfully " + (rule.revoked() ? " revoked." : " created.");
-            }
-        } catch (Exception e) {
-            if (shouldRetry(numRetries)) {
-                return retry(cmd, numRetries);
-            }
-            results[i++] = "Configuring static nat rule failed due to " + e.getMessage();
-            endResult = false;
-            return new SetStaticNatRulesAnswer(cmd, results, endResult);
-        }
-
-        return new SetStaticNatRulesAnswer(cmd, results, endResult);
-    }
-
-    private synchronized Answer execute(ExternalNetworkResourceUsageCommand cmd, int numRetries) {
-        try {
-            if (!_isSdx) {
-                return getPublicIpBytesSentAndReceived(cmd);
-            } else {
-                return Answer.createUnsupportedCommandAnswer(cmd);
-            }
-        } catch (ExecutionException e) {
-            if (shouldRetry(numRetries)) {
-                return retry(cmd, numRetries);
-            } else {
-                return new ExternalNetworkResourceUsageAnswer(cmd, e);
-            }
-        }
-    }
-
-    private void addSubnetIP(String snip, String netmask) throws ExecutionException {
-        try {
-            nsip selfIp = new nsip();
-            selfIp.set_ipaddress(snip);
-            selfIp.set_netmask(netmask);
-            selfIp.set_type("SNIP");
-            apiCallResult = nsip.add(_netscalerService, selfIp);
-            if (apiCallResult.errorcode != 0) {
-                throw new ExecutionException("Failed to add SNIP object on the Netscaler device due to " + apiCallResult.message);
-            }
-        } catch (nitro_exception e) {
-            throw new ExecutionException("Failed to add SNIP object on the Netscaler device due to " + e.getMessage());
-        } catch (Exception e) {
-            throw new ExecutionException("Failed to add SNIP object on the Netscaler device due to " + e.getMessage());
-        }
-    }
-
-    private void addGuestVlanAndSubnet(long vlanTag, String vlanSelfIp, String vlanNetmask, boolean guestVlan) throws ExecutionException {
-        try {
-            // add vlan object for guest VLAN
-            if (!nsVlanExists(vlanTag)) {
-                try {
-                    vlan vlanObj = new vlan();
-                    vlanObj.set_id(vlanTag);
-                    apiCallResult = vlan.add(_netscalerService, vlanObj);
-                    if (apiCallResult.errorcode != 0) {
-                        throw new ExecutionException("Failed to add new vlan with tag:" + vlanTag + "on the NetScaler device due to " + apiCallResult.message);
-                    }
-                } catch (nitro_exception e) {
-                    throw new ExecutionException("Failed to add new vlan with tag:" + vlanTag + "on the NetScaler device due to " + e.getMessage());
-                }
-            }
-
-            // add subnet IP object for this guest network
-            if (!nsSnipExists(vlanSelfIp)) {
-                try {
-                    nsip selfIp = new nsip();
-                    selfIp.set_ipaddress(vlanSelfIp);
-                    selfIp.set_netmask(vlanNetmask);
-                    selfIp.set_type("SNIP");
-                    apiCallResult = nsip.add(_netscalerService, selfIp);
-                    if (apiCallResult.errorcode != 0) {
-                        throw new ExecutionException("Failed to add SNIP object for the guest network on the Netscaler device due to " + apiCallResult.message);
-                    }
-                } catch (nitro_exception e) {
-                    throw new ExecutionException("Failed to add SNIP object for the guest network on the Netscaler device due to " + e.getMessage());
-                }
-            }
-
-            // bind the vlan object to subnet IP object
-            if (!nsVlanNsipBindingExists(vlanTag, vlanSelfIp)) {
-                try {
-                    vlan_nsip_binding ipVlanBinding = new vlan_nsip_binding();
-                    ipVlanBinding.set_id(vlanTag);
-                    ipVlanBinding.set_ipaddress(vlanSelfIp);
-                    ipVlanBinding.set_netmask(vlanNetmask);
-                    apiCallResult = vlan_nsip_binding.add(_netscalerService, ipVlanBinding);
-                    if (apiCallResult.errorcode != 0) {
-                        throw new ExecutionException("Failed to bind VLAN with tag:" + vlanTag + " to the subnet due to " + apiCallResult.message);
-                    }
-                } catch (nitro_exception e) {
-                    throw new ExecutionException("Failed to bind VLAN with tage:" + vlanTag + " to the subnet due to " + e.getMessage());
-                }
-            }
-
-            // bind vlan object to the private interface
-            try {
-                vlan_interface_binding vlanBinding = new vlan_interface_binding();
-                if (guestVlan) {
-                    vlanBinding.set_ifnum(_privateInterface);
-                } else {
-                    vlanBinding.set_ifnum(_publicInterface);
-                }
-                vlanBinding.set_tagged(true);
-                vlanBinding.set_id(vlanTag);
-                apiCallResult = vlan_interface_binding.add(_netscalerService, vlanBinding);
-                if (apiCallResult.errorcode != 0) {
-                    String vlanInterface = guestVlan ? _privateInterface : _publicInterface;
-                    throw new ExecutionException("Failed to bind vlan with tag:" + vlanTag + " with the interface " + vlanInterface + " due to " + apiCallResult.message);
-                }
-            } catch (nitro_exception e) {
-                if (!(e.getErrorCode() == NitroError.NS_INTERFACE_ALREADY_BOUND_TO_VLAN)) {
-                    throw new ExecutionException("Failed to bind VLAN " + vlanTag + " with interface on the Netscaler device due to " + e.getMessage());
-                }
-            }
-        } catch (nitro_exception e) {
-            throw new ExecutionException("Failed to implement guest network on the Netscaler device due to " + e.getMessage());
-        } catch (Exception e) {
-            throw new ExecutionException("Failed to implement guest network on the Netscaler device due to " + e.getMessage());
-        }
-    }
-
-    private void deleteGuestVlan(long vlanTag, String vlanSelfIp, String vlanNetmask) throws ExecutionException {
-        try {
-
-            // Delete all servers and associated services from this guest VLAN
-            deleteServersInGuestVlan(vlanTag, vlanSelfIp, vlanNetmask);
-
-            // unbind vlan to the private interface
-            try {
-                vlan_interface_binding vlanIfBinding = new vlan_interface_binding();
-                vlanIfBinding.set_id(vlanTag);
-                vlanIfBinding.set_ifnum(_privateInterface);
-                vlanIfBinding.set_tagged(true);
-                apiCallResult = vlan_interface_binding.delete(_netscalerService, vlanIfBinding);
-                if (apiCallResult.errorcode != 0) {
-                    throw new ExecutionException("Failed to unbind vlan:" + vlanTag + " with the private interface due to " + apiCallResult.message);
-                }
-            } catch (nitro_exception e) {
-                // if Vlan to interface binding does not exist then ignore the exception and proceed
-                if (!(e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS)) {
-                    throw new ExecutionException("Failed to unbind vlan from the interface while shutdown of guest network on the Netscaler device due to " +
-                            e.getMessage());
-                }
-            }
-
-            // unbind the vlan to subnet
-            try {
-                vlan_nsip_binding vlanSnipBinding = new vlan_nsip_binding();
-                vlanSnipBinding.set_netmask(vlanNetmask);
-                vlanSnipBinding.set_ipaddress(vlanSelfIp);
-                vlanSnipBinding.set_id(vlanTag);
-                apiCallResult = vlan_nsip_binding.delete(_netscalerService, vlanSnipBinding);
-                if (apiCallResult.errorcode != 0) {
-                    throw new ExecutionException("Failed to unbind vlan:" + vlanTag + " with the subnet due to " + apiCallResult.message);
-                }
-            } catch (nitro_exception e) {
-                // if Vlan to subnet binding does not exist then ignore the exception and proceed
-                if (!(e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS)) {
-                    throw new ExecutionException("Failed to unbind vlan:" + vlanTag + " with the subnet due to " + e.getMessage());
-                }
-            }
-
-            // remove subnet IP
-            try {
-                nsip _vlanSelfIp = new nsip();
-                _vlanSelfIp.set_ipaddress(vlanSelfIp);
-
-                nsip subnetIp = nsip.get(_netscalerService, _vlanSelfIp);
-                apiCallResult = nsip.delete(_netscalerService, subnetIp);
-                if (apiCallResult.errorcode != 0) {
-                    throw new ExecutionException("Failed to remove subnet ip:" + vlanSelfIp + " from the NetScaler device due to" + apiCallResult.message);
-                }
-            } catch (nitro_exception e) {
-                // if subnet SNIP does not exist then ignore the exception and proceed
-                if (!(e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS)) {
-                    throw new ExecutionException("Failed to remove subnet ip:" + vlanSelfIp + " from the NetScaler device due to" + e.getMessage());
-                }
-            }
-
-            // remove the vlan from the NetScaler device
-            if (nsVlanExists(vlanTag)) {
-                // remove vlan
-                apiCallResult = com.citrix.netscaler.nitro.resource.config.network.vlan.delete(_netscalerService, vlanTag);
-                if (apiCallResult.errorcode != 0) {
-                    throw new ExecutionException("Failed to remove vlan with tag:" + vlanTag + "due to" + apiCallResult.message);
-                }
-            }
-        } catch (nitro_exception e) {
-            throw new ExecutionException("Failed to delete guest vlan network on the Netscaler device due to " + e.getMessage());
-        } catch (Exception e) {
-            throw new ExecutionException("Failed to delete guest vlan network on the Netscaler device due to " + e.getMessage());
-        }
-    }
-
-    private boolean nsVlanExists(long vlanTag) throws ExecutionException {
-        try {
-            if (vlan.get(_netscalerService, new Long(vlanTag)) != null) {
-                return true;
-            } else {
-                return false;
-            }
-        } catch (nitro_exception e) {
-            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
-                return false;
-            } else {
-                throw new ExecutionException("Failed to verify  VLAN exists on the NetScaler device due to " + e.getMessage());
-            }
-        } catch (Exception e) {
-            throw new ExecutionException("Failed to verify  VLAN exists on the NetScaler device due to " + e.getMessage());
-        }
-    }
-
-    private boolean nsSnipExists(String subnetIp) throws ExecutionException {
-        try {
-            nsip _subnetIp = new nsip();
-            _subnetIp.set_ipaddress(subnetIp);
-
-            nsip snip = nsip.get(_netscalerService, _subnetIp);
-            return (snip != null);
-        } catch (nitro_exception e) {
-            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
-                return false;
-            } else {
-                throw new ExecutionException("Failed to verify if SNIP exists on the NetScaler device due to " + e.getMessage());
-            }
-        } catch (Exception e) {
-            throw new ExecutionException("Failed to verify if SNIP exists on the NetScaler device due to " + e.getMessage());
-        }
-    }
-
-    private boolean nsServerExists(String serverName) throws ExecutionException {
-        try {
-            if (com.citrix.netscaler.nitro.resource.config.basic.server.get(_netscalerService, serverName) != null) {
-                return true;
-            } else {
-                return false;
-            }
-        } catch (nitro_exception e) {
-            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
-                return false;
-            } else {
-                throw new ExecutionException("Failed to verify Server " + serverName + " exists on the NetScaler device due to " + e.getMessage());
-            }
-        } catch (Exception e) {
-            throw new ExecutionException("Failed to verify Server " + serverName + " exists on the NetScaler device due to " + e.getMessage());
-        }
-    }
-
-    private boolean nsVirtualServerExists(String vserverName) throws ExecutionException {
-        try {
-            if (com.citrix.netscaler.nitro.resource.config.lb.lbvserver.get(_netscalerService, vserverName) != null) {
-                return true;
-            } else {
-                return false;
-            }
-        } catch (nitro_exception e) {
-            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
-                return false;
-            } else {
-                throw new ExecutionException("Failed to verify VServer " + vserverName + " exists on the NetScaler device due to " + e.getMessage());
-            }
-        } catch (Exception e) {
-            throw new ExecutionException("Failed to verify VServer " + vserverName + " exists on the NetScaler device due to " + e.getMessage());
-        }
-    }
-
-    private boolean nsVlanNsipBindingExists(long vlanTag, String vlanSelfIp) throws ExecutionException {
-        try {
-            vlan_nsip_binding[] vlanNsipBindings = vlan_nsip_binding.get(_netscalerService, vlanTag);
-            if (vlanNsipBindings != null && vlanNsipBindings[0] != null && vlanNsipBindings[0].get_ipaddress().equalsIgnoreCase(vlanSelfIp)) {
-                return true;
-            } else {
-                return false;
-            }
-        } catch (nitro_exception e) {
-            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
-                return false;
-            } else {
-                throw new ExecutionException("Failed to verify Vlan " + vlanTag + " to SNIP " + vlanSelfIp + " binding exists due to " + e.getMessage());
-            }
-        } catch (Exception e) {
-            throw new ExecutionException("Failed to verify Vlan " + vlanTag + " to SNIP " + vlanSelfIp + " binding exists due to " + e.getMessage());
-        }
-    }
-
-    private lbvserver getVirtualServerIfExisits(String lbVServerName) throws ExecutionException {
-        try {
-            return lbvserver.get(_netscalerService, lbVServerName);
-        } catch (nitro_exception e) {
-            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
-                return null;
-            } else {
-                throw new ExecutionException(e.getMessage());
-            }
-        } catch (Exception e) {
-            throw new ExecutionException(e.getMessage());
-        }
-    }
-
-    private lbmonitor getMonitorIfExisits(String lbMonitorName) throws ExecutionException {
-        try {
-            return lbmonitor.get(_netscalerService, lbMonitorName);
-        } catch (nitro_exception e) {
-            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
-                return null;
-            } else {
-                throw new ExecutionException(e.getMessage());
-            }
-        } catch (Exception e) {
-            throw new ExecutionException(e.getMessage());
-        }
-    }
-
-    private boolean isServiceBoundToVirtualServer(String serviceName) throws ExecutionException {
-        try {
-            lbvserver[] lbservers = lbvserver.get(_netscalerService);
-            for (lbvserver vserver : lbservers) {
-                filtervalue[] filter = new filtervalue[1];
-                filter[0] = new filtervalue("servicename", serviceName);
-                lbvserver_service_binding[] result = lbvserver_service_binding.get_filtered(_netscalerService, vserver.get_name(), filter);
-                if (result != null && result.length > 0) {
-                    return true;
-                }
-            }
-            return false;
-        } catch (Exception e) {
-            throw new ExecutionException("Failed to verify service " + serviceName + " is bound to any virtual server due to " + e.getMessage());
-        }
-    }
-
-    private boolean isServiceBoundToMonitor(String nsServiceName, String nsMonitorName) throws ExecutionException {
-
-        filtervalue[] filter = new filtervalue[1];
-        filter[0] = new filtervalue("monitor_name", nsMonitorName);
-        service_lbmonitor_binding[] result;
-        try {
-            result = service_lbmonitor_binding.get_filtered(_netscalerService, nsServiceName, filter);
-            if (result != null && result.length > 0) {
-                return true;
-            }
-
-        } catch (Exception e) {
-            throw new ExecutionException("Failed to verify service " + nsServiceName + " is bound to any monitor due to " + e.getMessage());
-        }
-        return false;
-    }
-
-    private boolean nsMonitorExist(String nsMonitorname) throws ExecutionException {
-        if (getMonitorIfExisits(nsMonitorname) != null)
-            return true;
-        else
-            return false;
-    }
-
-    private boolean nsServiceExists(String serviceName) throws ExecutionException {
-        try {
-            if (com.citrix.netscaler.nitro.resource.config.basic.service.get(_netscalerService, serviceName) != null) {
-                return true;
-            } else {
-                return false;
-            }
-        } catch (nitro_exception e) {
-            if (e.getErrorCode() == NitroError.NS_NO_SERIVCE) {
-                return false;
-            } else {
-                throw new ExecutionException("Failed to verify service " + serviceName + " exists due to " + e.getMessage());
-            }
-        } catch (Exception e) {
-            throw new ExecutionException("Failed to verify service " + serviceName + " exists due to " + e.getMessage());
-        }
-    }
-
-    private boolean nsServiceBindingExists(String lbVirtualServer, String serviceName) throws ExecutionException {
-        try {
-            com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding[] serviceBindings =
-                    com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding.get(_netscalerService, lbVirtualServer);
-            if (serviceBindings != null) {
-                for (com.citrix.netscaler.nitro.resource.config.lb.lbvserver_service_binding binding : serviceBindings) {
-                    if (serviceName.equalsIgnoreCase(binding.get_servicename())) {
-                        return true;
-                    }
-                }
-            }
-            return false;
-        } catch (nitro_exception e) {
-            throw new ExecutionException("Failed to verify lb vserver " + lbVirtualServer + "and service " + serviceName + " binding exists due to " + e.getMessage());
-        } catch (Exception e) {
-            throw new ExecutionException("Failed to verify lb vserver " + lbVirtualServer + "and service " + serviceName + " binding exists due to " + e.getMessage());
-        }
-    }
-
-    private boolean isServiceGroupBoundToVirtualServer(String nsVirtualServerName, String serviceGroupName) throws ExecutionException {
-
-        new lbvserver_servicegroup_binding();
-
-        try {
-            lbvserver_servicegroup_binding[] result =
-                    lbvserver_servicegroup_binding.get_filtered(_netscalerService, nsVirtualServerName, "servicegroupname:" + serviceGroupName);
-            if (result != null && result.length > 0) {
-                return true;
-            }
-        } catch (Exception e) {
-            throw new ExecutionException("Failed to verify lb vserver " + nsVirtualServerName + "and servicegrop " + serviceGroupName + " binding exists due to " +
-                    e.getMessage());
-        }
-        return false;
-
-    }
-
-    private boolean nsServiceGroupExists(String lbVServerName) throws ExecutionException {
-        try {
-            return servicegroup.get(_netscalerService, lbVServerName) != null;
-        } catch (nitro_exception e) {
-            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
-                return false; // service group does not exist
-            } else {
-                throw new ExecutionException(e.getMessage());
-            }
-        } catch (Exception e) {
-            throw new ExecutionException(e.getMessage());
-        }
-    }
-
-    private void deleteServersInGuestVlan(long vlanTag, String vlanSelfIp, String vlanNetmask) throws ExecutionException {
-        try {
-            com.citrix.netscaler.nitro.resource.config.basic.server[] serverList = com.citrix.netscaler.nitro.resource.config.basic.server.get(_netscalerService);
-
-            if (serverList == null) {
-                return;
-            }
-
-            // remove the server and services associated with guest vlan
-            for (com.citrix.netscaler.nitro.resource.config.basic.server server : serverList) {
-                // check if server belong to same subnet as one associated with vlan
-                if (NetUtils.sameSubnet(vlanSelfIp, server.get_ipaddress(), vlanNetmask)) {
-                    // first remove services associated with this server
-                    com.citrix.netscaler.nitro.resource.config.basic.service serveicesList[] =
-                            com.citrix.netscaler.nitro.resource.config.basic.service.get(_netscalerService);
-                    if (serveicesList != null) {
-                        for (com.citrix.netscaler.nitro.resource.config.basic.service svc : serveicesList) {
-                            if (svc.get_servername().equals(server.get_ipaddress())) {
-                                apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.service.delete(_netscalerService, svc.get_name());
-                                if (apiCallResult.errorcode != 0) {
-                                    throw new ExecutionException("Failed to remove service:" + svc.get_name());
-                                }
-                            }
-                        }
-                    }
-                    // remove the server
-                    // don't delete server which has no ip address (these servers are created by NS for autoscale
-                    if (server.get_ipaddress() != null) {
-                        apiCallResult = com.citrix.netscaler.nitro.resource.config.basic.server.delete(_netscalerService, server.get_name());
-                        if (apiCallResult.errorcode != 0) {
-                            throw new ExecutionException("Failed to remove server:" + server.get_name());
-                        }
-                    }
-                }
-            }
-        } catch (Exception e) {
-            throw new ExecutionException("Failed to delete server and services in the guest vlan:" + vlanTag + " on the Netscaler device due to: " + e.getMessage());
-        }
-    }
-
-    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 void addLBVirtualServer(String virtualServerName, String publicIp, int publicPort, String lbAlgorithm, String protocol, StickinessPolicyTO[] stickyPolicies,
-            AutoScaleVmGroupTO vmGroupTO) throws ExecutionException {
-        try {
-            String lbMethod;
-            if ("roundrobin".equalsIgnoreCase(lbAlgorithm)) {
-                lbMethod = "ROUNDROBIN";
-            } else if ("leastconn".equalsIgnoreCase(lbAlgorithm)) {
-                lbMethod = "LEASTCONNECTION";
-            } else if ("source".equalsIgnoreCase(lbAlgorithm)) {
-                lbMethod = "SOURCEIPHASH";
-            } else {
-                throw new ExecutionException("Got invalid load balancing algorithm: " + lbAlgorithm + " in the load balancing rule");
-            }
-
-            boolean vserverExisis = false;
-            lbvserver vserver = getVirtualServerIfExisits(virtualServerName);
-            if (vserver != null) {
-                if (!vserver.get_servicetype().equalsIgnoreCase(protocol)) {
-                    throw new ExecutionException("Can not update virtual server:" + virtualServerName + " as current protocol:" + vserver.get_servicetype() +
-                            " of virtual server is different from the " + " intended protocol:" + protocol);
-                }
-                vserverExisis = true;
-            }
-            // Use new vserver always for configuration
-            vserver = new lbvserver();
-            vserver.set_name(virtualServerName);
-            vserver.set_ipv46(publicIp);
-            vserver.set_port(publicPort);
-            vserver.set_servicetype(protocol);
-            vserver.set_lbmethod(lbMethod);
-
-            // netmask can only be set for source IP load balancer algorithm
-            if (!lbMethod.equalsIgnoreCase("SOURCEIPHASH")) {
-                vserver.set_netmask(null);
-                vserver.set_v6netmasklen(null);
-            }
-
-            if ((stickyPolicies != null) && (stickyPolicies.length > 0) && (stickyPolicies[0] != null)) {
-                long timeout = 2;// netscaler default 2 min
-                String cookieName = null;
-                StickinessPolicyTO stickinessPolicy = stickyPolicies[0];
-
-                // get the session persistence parameters
-                List<Pair<String, String>> paramsList = stickinessPolicy.getParams();
-                for (Pair<String, String> param : paramsList) {
-                    if ("holdtime".equalsIgnoreCase(param.first())) {
-                        timeout = Long.parseLong(param.second());
-                    } else if ("name".equalsIgnoreCase(param.first())) {
-                        cookieName = param.second();
-                    }
-                }
-
-                // configure virtual server based on the persistence method
-                if (StickinessMethodType.LBCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) {
-                    vserver.set_persistencetype("COOKIEINSERT");
-                } else if (StickinessMethodType.SourceBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) {
-                    vserver.set_persistencetype("SOURCEIP");
-                } else if (StickinessMethodType.AppCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) {
-                    vserver.set_persistencetype("RULE");
-                    vserver.set_rule("HTTP.REQ.HEADER(\"COOKIE\").VALUE(0).typecast_nvlist_t('=',';').value(\"" + cookieName + "\")");
-                    vserver.set_resrule("HTTP.RES.HEADER(\"SET-COOKIE\").VALUE(0).typecast_nvlist_t('=',';').value(\"" + cookieName + "\")");
-                } else {
-                    throw new ExecutionException("Got invalid session persistence method: " + stickinessPolicy.getMethodName() + " in the load balancing rule");
-                }
-
-                // set session persistence timeout
-                vserver.set_timeout(timeout);
-            } else {
-                // delete the LB stickyness policy
-                vserver.set_persistencetype("NONE");
-            }
-
-            if (vserverExisis) {
-                apiCallResult = lbvserver.update(_netscalerService, vserver);
-            } else {
-                apiCallResult = lbvserver.add(_netscalerService, vserver);
-            }
-            if (apiCallResult.errorcode != 0) {
-                throw new ExecutionException("Failed to create new load balancing virtual server:" + virtualServerName + " due to " + apiCallResult.message);
-            }
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Created load balancing virtual server " + virtualServerName + " on the Netscaler device");
-            }
-        } catch (nitro_exception e) {
-            throw new ExecutionException("Failed to create new virtual server:" + virtualServerName + " due to " + e.getMessage());
-        } catch (Exception e) {
-            throw new ExecutionException("Failed to create new virtual server:" + virtualServerName + " due to " + e.getMessage());
-        }
-    }
-
-    private void removeLBVirtualServer(String virtualServerName) throws ExecutionException {
-        try {
-            lbvserver vserver = lbvserver.get(_netscalerService, virtualServerName);
-            if (vserver == null) {
-                return;
-            }
-            apiCallResult = lbvserver.delete(_netscalerService, vserver);
-            if (apiCallResult.errorcode != 0) {
-                throw new ExecutionException("Failed to delete virtual server:" + virtualServerName + " due to " + apiCallResult.message);
-            }
-        } catch (nitro_exception e) {
-            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
-                return;
-            } else {
-                throw new ExecutionException("Failed remove virtual server:" + virtualServerName + " due to " + e.getMessage());
-            }
-        } catch (Exception e) {
-            throw new ExecutionException("Failed to remove virtual server:" + virtualServerName + " due to " + e.getMessage());
-        }
-    }
-
-    // Monitor related methods
-    private void addLBMonitor(String nsMonitorName, String lbProtocol, HealthCheckPolicyTO hcp) throws ExecutionException {
-        try {
-            // check if the monitor exists
-            boolean csMonitorExisis = false;
-            lbmonitor csMonitor = getMonitorIfExisits(nsMonitorName);
-            if (csMonitor != null) {
-                if (!csMonitor.get_type().equalsIgnoreCase(lbProtocol)) {
-                    throw new ExecutionException("Can not update monitor :" + nsMonitorName + " as current protocol:" + csMonitor.get_type() +
-                            " of monitor is different from the " + " intended protocol:" + lbProtocol);
-                }
-                csMonitorExisis = true;
-            }
-            if (!csMonitorExisis) {
-                lbmonitor csMon = new lbmonitor();
-                csMon.set_monitorname(nsMonitorName);
-                csMon.set_type(lbProtocol);
-                if (lbProtocol.equalsIgnoreCase("HTTP")) {
-                    csMon.set_httprequest(hcp.getpingPath());
-                    s_logger.trace("LB Protocol is HTTP,  Applying  ping path on HealthCheck Policy");
-                } else {
-                    s_logger.debug("LB Protocol is not HTTP, Skipping to apply  ping path on HealthCheck Policy");
-                }
-
-                csMon.set_interval(hcp.getHealthcheckInterval());
-                csMon.set_retries(Math.max(hcp.getHealthcheckThresshold(), hcp.getUnhealthThresshold()) + 1);
-                csMon.set_resptimeout(hcp.getResponseTime());
-                csMon.set_failureretries(hcp.getUnhealthThresshold());
-                csMon.set_successretries(hcp.getHealthcheckThresshold());
-                s_logger.debug("Monitor properites going to get created :interval :: " + csMon.get_interval() + "respTimeOUt:: " + csMon.get_resptimeout() +
-                        "failure retires(unhealththresshold) :: " + csMon.get_failureretries() + "successtries(healththresshold) ::" + csMon.get_successretries());
-                lbmonitor.add(_netscalerService, csMon);
-            } else {
-                s_logger.debug("Monitor :" + nsMonitorName + " is already existing. Skipping to delete and create it");
-            }
-        } catch (nitro_exception e) {
-            throw new ExecutionException("Failed to create new monitor :" + nsMonitorName + " due to " + e.getMessage());
-        } catch (Exception e) {
-            throw new ExecutionException("Failed to create new monitor :" + nsMonitorName + " due to " + e.getMessage());
-        }
-    }
-
-    private void bindServiceToMonitor(String nsServiceName, String nsMonitorName) throws ExecutionException {
-
-        try {
-            com.citrix.netscaler.nitro.resource.config.basic.service serviceObject = new com.citrix.netscaler.nitro.resource.config.basic.service();
-            serviceObject = com.citrix.netscaler.nitro.resource.config.basic.service.get(_netscalerService, nsServiceName);
-            if (serviceObject != null) {
-                com.citrix.netscaler.nitro.resource.config.basic.service_lbmonitor_binding serviceMonitor =
-                        new com.citrix.netscaler.nitro.resource.config.basic.service_lbmonitor_binding();
-                serviceMonitor.set_monitor_name(nsMonitorName);
-                serviceMonitor.set_name(nsServiceName);
-                serviceMonitor.set_monstate("ENABLED");
-                s_logger.debug("Trying to bind  the monitor :" + nsMonitorName + " to the service :" + nsServiceName);
-                com.citrix.netscaler.nitro.resource.config.basic.service_lbmonitor_binding.add(_netscalerService, serviceMonitor);
-                s_logger.debug("Successfully binded the monitor :" + nsMonitorName + " to the service :" + nsServiceName);
-            }
-        } catch (nitro_exception e) {
-            throw new ExecutionException("Failed to create new monitor :" + nsMonitorName + " due to " + e.getMessage());
-        } catch (Exception e) {
-            throw new ExecutionException("Failed to create new monitor :" + nsMonitorName + " due to " + e.getMessage());
-        }
-    }
-
-    private void unBindServiceToMonitor(String nsServiceName, String nsMonitorName) throws ExecutionException {
-
-        try {
-            com.citrix.netscaler.nitro.resource.config.basic.service serviceObject = new com.citrix.netscaler.nitro.resource.config.basic.service();
-            serviceObject = com.citrix.netscaler.nitro.resource.config.basic.service.get(_netscalerService, nsServiceName);
-
-            if (serviceObject != null) {
-                com.citrix.netscaler.nitro.resource.config.basic.service_lbmonitor_binding serviceMonitor =
-                        new com.citrix.netscaler.nitro.resource.config.basic.service_lbmonitor_binding();
-                serviceMonitor.set_monitor_name(nsMonitorName);
-                serviceMonitor.set_name(nsServiceName);
-                s_logger.debug("Trying to unbind  the monitor :" + nsMonitorName + " from the service :" + nsServiceName);
-                service_lbmonitor_binding.delete(_netscalerService, serviceMonitor);
-                s_logger.debug("Successfully unbinded the monitor :" + nsMonitorName + " from the service :" + nsServiceName);
-            }
-
-        } catch (nitro_exception e) {
-            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
-                return;
-            } else {
-                throw new ExecutionException("Failed to unbind monitor :" + nsMonitorName + "from the service :" + nsServiceName + "due to " + e.getMessage());
-            }
-        } catch (Exception e) {
-            throw new ExecutionException("Failed to unbind monitor :" + nsMonitorName + "from the service :" + nsServiceName + "due to " + e.getMessage());
-        }
-
-    }
-
-    private void removeLBMonitor(String nsMonitorName) throws ExecutionException {
-
-        try {
-            if (nsMonitorExist(nsMonitorName)) {
-                lbmonitor monitorObj = lbmonitor.get(_netscalerService, nsMonitorName);
-                monitorObj.set_respcode(null);
-                lbmonitor.delete(_netscalerService, monitorObj);
-                s_logger.info("Successfully deleted monitor : " + nsMonitorName);
-            }
-        } catch (nitro_exception e) {
-            if (e.getErrorCode() == NitroError.NS_RESOURCE_NOT_EXISTS) {
-                return;
-            } else {
-                throw new ExecutionException("Failed to delete monitor :" + nsMonitorName + " due to " + e.getMessage());
-            }
-        } catch (Exception e) {
-            throw new ExecutionException("Failed to delete monitor :" + nsMonitorName + " due to " + e.getMessage());
-        }
-
-    }
-
-    public synchronized void applyAutoScaleConfig(LoadBalancerTO loadBalancer) throws Exception, ExecutionException {
-
-        AutoScaleVmGroupTO vmGroupTO = loadBalancer.getAutoScaleVmGroupTO();
-        if (!isAutoScaleSupportedInNetScaler()) {
-            throw new ExecutionException("AutoScale not supported in this version of NetScaler");
-        }
-        if (loadBalancer.isRevoked() || vmGroupTO.getState().equals("revoke")) {
-            removeAutoScaleConfig(loadBalancer);
-        } else {
-            createAutoScaleConfig(loadBalancer);
-        }
-        // AutoScale APIs are successful executed, now save the configuration.
-        saveConfiguration();
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Successfully executed resource AutoScaleConfig");
-        }
-    }
-
-    @SuppressWarnings("static-access")
-    private synchronized boolean createAutoScaleConfig(LoadBalancerTO loadBalancerTO) throws ExecutionException, Exception {
-
-        String srcIp = loadBalancerTO.getSrcIp();
-        int srcPort = loadBalancerTO.getSrcPort();
-        String lbProtocol = getNetScalerProtocol(loadBalancerTO);
-        String lbAlgorithm = loadBalancerTO.getAlgorithm();
-        generateAutoScaleVmGroupIdentifier(loadBalancerTO);
-        String nsVirtualServerName = generateNSVirtualServerName(srcIp, srcPort);
-        AutoScaleVmGroupTO vmGroupTO = loadBalancerTO.getAutoScaleVmGroupTO();
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Created load balancing virtual server " + nsVirtualServerName + " on the Netscaler device");
-        }
-        addLBVirtualServer(nsVirtualServerName, srcIp, srcPort, lbAlgorithm, lbProtocol, loadBalancerTO.getStickinessPolicies(), vmGroupTO);
-
-        String serviceGroupName = generateAutoScaleServiceGroupName(loadBalancerTO);
-        if (!nsServiceGroupExists(serviceGroupName)) {
-            // add servicegroup lb_autoscaleGroup -autoscale POLICY -memberPort 80
-            int memberPort = vmGroupTO.getMemberPort();
-            try {
-                servicegroup serviceGroup = new servicegroup();
-                serviceGroup.set_servicegroupname(serviceGroupName);
-                serviceGroup.set_servicetype(lbProtocol);
-                serviceGroup.set_autoscale("POLICY");
-                serviceGroup.set_memberport(memberPort);
-                servicegroup.add(_netscalerService, serviceGroup);
-            } catch (Exception e) {
-                throw e;
-            }
-        }
-
-        if (!isServiceGroupBoundToVirtualServer(nsVirtualServerName, serviceGroupName)) {
-            // Bind autoscale service group
-            // bind lb vserver lb lb_autoscaleGroup
-            lbvserver_servicegroup_binding vserver_servicegroup_binding = new lbvserver_servicegroup_binding();
-
-            try {
-                vserver_servicegroup_binding.set_name(nsVirtualServerName);
-                vserver_servicegroup_binding.set_servicegroupname(serviceGroupName);
-                lbvserver_servicegroup_binding.add(_netscalerService, vserver_servicegroup_binding);
-            } catch (Exception e) {
-                throw e;
-            }
-        }
-
-        // Create the autoscale config
-        if (!loadBalancerTO.getAutoScaleVmGroupTO().getState().equals("disabled")) {
-            // on restart of network, there might be vmgrps in disabled state, no need to create autoscale config for them
-            enableAutoScaleConfig(loadBalancerTO, false);
-        } else if (loadBalancerTO.getAutoScaleVmGroupTO().getState().equals("disabled")) {
-            disableAutoScaleConfig(loadBalancerTO, false);
-        }
-
-        return true;
-    }
-
-    @SuppressWarnings("static-access")
-    private synchronized boolean removeAutoScaleConfig(LoadBalancerTO loadBalancerTO) throws Exception, ExecutionException {
-        String srcIp = loadBalancerTO.getSrcIp();
-        int srcPort = loadBalancerTO.getSrcPort();
-        generateAutoScaleVmGroupIdentifier(loadBalancerTO);
-
-        String nsVirtualServerName = generateNSVirtualServerName(srcIp, srcPort);
-        String serviceGroupName = generateAutoScaleServiceGroupName(loadBalancerTO);
-
-        if (loadBalancerTO.getAutoScaleVmGroupTO().getCurrentState().equals("enabled")) {
-            disableAutoScaleConfig(loadBalancerTO, false);
-        }
-
-        if (isServiceGroupBoundToVirtualServer(nsVirtualServerName, serviceGroupName)) {
-            // UnBind autoscale service group
-            // unbind lb vserver lb lb_autoscaleGroup
-            lbvserver_servicegroup_binding vserver_servicegroup_binding = new lbvserver_servicegroup_binding();
-            try {
-                vserver_servicegroup_binding.set_name(nsVirtualServerName);
-                vserver_servicegroup_binding.set_servicegroupname(serviceGroupName);
-                lbvserver_servicegroup_binding.delete(_netscalerService, vserver_servicegroup_binding);
-            } catch (Exception e) {
-                throw e;
-            }
-        }
-
-        if (nsServiceGroupExists(serviceGroupName)) {
-            // Remove autoscale service group
-            com.citrix.netscaler.nitro.resource.config.basic.servicegroup serviceGroup = new com.citrix.netscaler.nitro.resource.config.basic.servicegroup();
-            try {
-                serviceGroup.set_servicegroupname(serviceGroupName);
-                servicegroup.delete(_netscalerService, serviceGroup);
-            } catch (Exception e) {
-                throw e;
-            }
-        }
-
-        removeLBVirtualServer(nsVirtualServerName);
-
-        return true;
-    }
-
-    @SuppressWarnings("static-access")
-    private synchronized boolean enableAutoScaleConfig(LoadBalancerTO loadBalancerTO, boolean isCleanUp) throws Exception {
-        String vmGroupIdentifier = generateAutoScaleVmGroupIdentifier(loadBalancerTO);
-        String srcIp = loadBalancerTO.getSrcIp();
-        int srcPort = loadBalancerTO.getSrcPort();
-
-        String nsVirtualServerName = generateNSVirtualServerName(srcIp, srcPort);
-        String serviceGroupName = generateAutoScaleServiceGroupName(loadBalancerTO);
-        String profileName = generateAutoScaleProfileName(vmGroupIdentifier);
-        String timerName = generateAutoScaleTimerName(vmGroupIdentifier);
-        String scaleDownActionName = generateAutoScaleScaleDownActionName(vmGroupIdentifier);
-        String scaleUpActionName = generateAutoScaleScaleUpActionName(vmGroupIdentifier);
-        String mtName = generateSnmpMetricTableName(vmGroupIdentifier);
-        String monitorName = generateSnmpMonitorName(vmGroupIdentifier);
-        AutoScaleVmGroupTO vmGroupTO = loadBalancerTO.getAutoScaleVmGroupTO();
-        AutoScaleVmProfileTO profileTO = vmGroupTO.getProfile();
-        List<AutoScalePolicyTO> policies = vmGroupTO.getPolicies();
-        int interval = vmGroupTO.getInterval();
-        profileTO.getCounterParamList();
-        String snmpCommunity = null;
-        int snmpPort = DEFAULT_SNMP_PORT;
-        long cur_prirotiy = 1;
-
-        // get the session persistence parameters
-        List<Pair<String, String>> paramsList = profileTO.getCounterParamList();
-        for (Pair<String, String> param : paramsList) {
-            if ("snmpcommunity".equalsIgnoreCase(param.first())) {
-                snmpCommunity = param.second();
-            } else if ("snmpport".equalsIgnoreCase(param.first())) {
-                snmpPort = Integer.parseInt(param.second());
-            }
-        }
-
-        try {
-            // Set min and max autoscale members;
-            // add lb vserver lb  http 10.102.31.100 80 -minAutoscaleMinMembers 3 -maxAutoscaleMembers 10
-            int minAutoScaleMembers = vmGroupTO.getMinMembers();
-            int maxAutoScaleMembers = vmGroupTO.getMaxMembers();
-            lbvserver vserver = new lbvserver();
-            try {
-                vserver.set_name(nsVirtualServerName);
-                vserver.set_minautoscalemembers(minAutoScaleMembers);
-                vserver.set_maxautoscalemembers(maxAutoScaleMembers);
-                lbvserver.update(_netscalerService, vserver);
-            } catch (Exception e) {
-                // Ignore Exception on cleanup
-                if (!isCleanUp)
-                    throw e;
-            }
-
-            /* AutoScale Config */
-            // Add AutoScale Profile
-            // add autoscale profile lb_asprofile CLOUDSTACK -url -http:// 10.102.31.34:8080/client/api- -apiKey abcdef
-            // -sharedSecret xyzabc
-            String apiKey = profileTO.getAutoScaleUserApiKey();
-            String secretKey = profileTO.getAutoScaleUserSecretKey();
-            String url = profileTO.getCloudStackApiUrl();
-
-            autoscaleprofile autoscaleProfile = new autoscaleprofile();
-            try {
-                autoscaleProfile.set_name(profileName);
-                autoscaleProfile.set_type("CLOUDSTACK");
-                autoscaleProfile.set_apikey(apiKey);
-                autoscaleProfile.set_sharedsecret(secretKey);
-                autoscaleProfile.set_url(url);
-                autoscaleprofile.add(_netscalerService, autoscaleProfile);
-            } catch (Exception e) {
-                // Ignore Exception on cleanup
-                if (!isCleanUp)
-                    throw e;
-            }
-
-            // Add Timer
-            nstimer timer = new nstimer();
-            try {
-                timer.set_name(timerName);
-                timer.set_interval(interval);
-                nstimer.add(_netscalerService, timer);
-            } catch (Exception e) {
-                // Ignore Exception on cleanup
-                if (!isCleanUp)
-                    throw e;
-            }
-
-            // AutoScale Actions
-            Integer scaleUpQuietTime = null;
-            Integer scaleDownQuietTime = null;
-            for (AutoScalePolicyTO autoScalePolicyTO : policies) {
-                if (scaleUpQuietTime == null) {
-                    if (isScaleUpPolicy(autoScalePolicyTO)) {
-                        scaleUpQuietTime = autoScalePolicyTO.getQuietTime();
-                        if (scaleDownQuietTime != null) {
-                            break;
-                        }
-                    }
-                }
-                if (scaleDownQuietTime == null) {
-                    if (isScaleDownPolicy(autoScalePolicyTO)) {
-                        scaleDownQuietTime = autoScalePolicyTO.getQuietTime();
-                        if (scaleUpQuietTime != null) {
-                            break;
-                        }
-                    }
-                }
-            }
-
-            // Add AutoScale ScaleUp action
-            // add autoscale action lb_scaleUpAction provision -vserver lb -profilename lb_asprofile -params
-            // -lbruleid=1234&command=deployvm&zoneid=10&templateid=5&serviceofferingid=3- -quiettime 300
-            com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction scaleUpAction =
-                    new com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction();
-            try {
-                scaleUpAction.set_name(scaleUpActionName);
-                scaleUpAction.set_type("SCALE_UP"); // TODO: will this be called provision?
-                scaleUpAction.set_vserver(nsVirtualServerName); // Actions Vserver, the one that is autoscaled, with CS
-                // now both are same. Not exposed in API.
-                scaleUpAction.set_profilename(profileName);
-                if(scaleUpQuietTime != null) {
-                    scaleUpAction.set_quiettime(scaleUpQuietTime);
-                }
-                String scaleUpParameters =
-                        "command=deployVirtualMachine" + "&" + ApiConstants.ZONE_ID + "=" + profileTO.getZoneId() + "&" + ApiConstants.SERVICE_OFFERING_ID + "=" +
-                                profileTO.getServiceOfferingId() + "&" + ApiConstants.TEMPLATE_ID + "=" + profileTO.getTemplateId() + "&" + ApiConstants.DISPLAY_NAME + "=" +
-                                profileTO.getVmName() + "&" + ((profileTO.getNetworkId() == null) ? "" : (ApiConstants.NETWORK_IDS + "=" + profileTO.getNetworkId() + "&")) +
-                                ((profileTO.getOtherDeployParams() == null) ? "" : (profileTO.getOtherDeployParams() + "&")) + "lbruleid=" + loadBalancerTO.getUuid();
-                scaleUpAction.set_parameters(scaleUpParameters);
-                autoscaleaction.add(_netscalerService, scaleUpAction);
-            } catch (Exception e) {
-                // Ignore Exception on cleanup
-                if (!isCleanUp)
-                    throw e;
-            }
-
-            com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction scaleDownAction =
-                    new com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction();
-            Integer destroyVmGracePeriod = profileTO.getDestroyVmGraceperiod();
-            try {
-                scaleDownAction.set_name(scaleDownActionName);
-                scaleDownAction.set_type("SCALE_DOWN"); // TODO: will this be called de-provision?
-                scaleDownAction.set_vserver(nsVirtualServerName); // TODO: no global option as of now through Nitro.
-                // Testing cannot be done.
-                scaleDownAction.set_profilename(profileName);
-                scaleDownAction.set_quiettime(scaleDownQuietTime);
-                String scaleDownParameters = "command=destroyVirtualMachine" + "&" + "lbruleid=" + loadBalancerTO.getUuid();
-                scaleDownAction.set_parameters(scaleDownParameters);
-                scaleDownAction.set_vmdestroygraceperiod(destroyVmGracePeriod);
-                autoscaleaction.add(_netscalerService, scaleDownAction);
-            } catch (Exception e) {
-                // Ignore Exception on cleanup
-                if (!isCleanUp)
-                    throw e;
-            }
-
-            /* Create min member policy */
-            String minMemberPolicyName = generateAutoScaleMinPolicyName(vmGroupIdentifier);
-            String minMemberPolicyExp =
-                    "SYS.VSERVER(\"" + nsVirtualServerName + "\").ACTIVESERVICES.LT(SYS.VSERVER(\"" + nsVirtualServerName + "\").MINAUTOSCALEMEMBERS)";
-            addAutoScalePolicy(timerName, minMemberPolicyName, cur_prirotiy++, minMemberPolicyExp, scaleUpActionName, interval, interval, isCleanUp);
-
-            /* Create max member policy */
-            String maxMemberPolicyName = generateAutoScaleMaxPolicyName(vmGroupIdentifier);
-            String maxMemberPolicyExp =
-                    "SYS.VSERVER(\"" + nsVirtualServerName + "\").ACTIVESERVICES.GT(SYS.VSERVER(\"" + nsVirtualServerName + "\").MAXAUTOSCALEMEMBERS)";
-            addAutoScalePolicy(timerName, maxMemberPolicyName, cur_prirotiy++, maxMemberPolicyExp, scaleDownActionName, interval, interval, isCleanUp);
-
-            /* Create Counters */
-            HashMap<String, Integer> snmpMetrics = new HashMap<String, Integer>();
-            for (AutoScalePolicyTO autoScalePolicyTO : policies) {
-                List<ConditionTO> conditions = autoScalePolicyTO.getConditions();
-                String policyExpression = "";
-                int snmpCounterNumber = 0;
-                for (ConditionTO conditionTO : conditions) {
-                    CounterTO counterTO = conditionTO.getCounter();
-                    String counterName = counterTO.getName();
-                    String operator = conditionTO.getRelationalOperator();
-                    long threshold = conditionTO.getThreshold();
-
-                    StringBuilder conditionExpression = new StringBuilder();
-                    Formatter formatter = new Formatter(conditionExpression, Locale.US);
-
-                    if (counterTO.getSource().equals("snmp")) {
-                        counterName = generateSnmpMetricName(counterName);
-                        if (snmpMetrics.size() == 0) {
-                            // Create Metric Table
-                            //add lb metricTable lb_metric_table
-                            lbmetrictable metricTable = new lbmetrictable();
-                            try {
-                                metricTable.set_metrictable(mtName);
-                                lbmetrictable.add(_netscalerService, metricTable);
-                            } catch (Exception e) {
-                                // Ignore Exception on cleanup
-                                if (!isCleanUp)
-                                    throw e;
-                            }
-
-                            // Create Monitor
-                            // add lb monitor lb_metric_table_mon LOAD -destPort 161 -snmpCommunity public -metricTable
-                            // lb_metric_table -interval <policy_interval == 80% >
-                            lbmonitor monitor = new lbmonitor();
-                            try {
-                                monitor.set_monitorname(monitorName);
-                                monitor.set_type("LOAD");
-                                monitor.set_destport(snmpPort);
-                                monitor.set_snmpcommunity(snmpCommunity);
-                                monitor.set_metrictable(mtName);
-                                monitor.set_interval((int)(interval * 0.8));
-                                lbmonitor.add(_netscalerService, monitor);
-                            } catch (Exception e) {
-                                // Ignore Exception on cleanup
-                                if (!isCleanUp)
-                                    throw e;
-                            }
-
-                            // Bind monitor to servicegroup.
-                            // bind lb monitor lb_metric_table_mon lb_autoscaleGroup -passive
-                            servicegroup_lbmonitor_binding servicegroup_monitor_binding = new servicegroup_lbmonitor_binding();
-                            try {
-                                servicegroup_monitor_binding.set_servicegroupname(serviceGroupName);
-                                servicegroup_monitor_binding.set_monitor_name(monitorName);
-
-                                // Use the monitor for autoscaling purpose only.
-                                // Don't mark service members down when metric breaches threshold
-                                servicegroup_monitor_binding.set_passive(true);
-
-                                servicegroup_lbmonitor_binding.add(_netscalerService, servicegroup_monitor_binding);
-                            } catch (Exception e) {
-                                // Ignore Exception on cleanup
-                                if (!isCleanUp)
-                                    throw e;
-                            }
-                        }
-
-                        boolean newMetric = !snmpMetrics.containsKey(counterName);
-                        if (newMetric) {
-                            snmpMetrics.put(counterName, snmpCounterNumber++);
-                        }
-
-                        if (newMetric) {
-                            // bind lb metricTable lb_metric_table mem 1.3.6.1.4.1.2021.11.9.0
-                            String counterOid = counterTO.getValue();
-                            lbmetrictable_metric_binding metrictable_metric_binding = new lbmetrictable_metric_binding();
-                            try {
-                                metrictable_metric_binding.set_metrictable(mtName);
-                                metrictable_metric_binding.set_metric(counterName);
-                                metrictable_metric_binding.set_Snmpoid(counterOid);
-                                lbmetrictable_metric_binding.add(_netscalerService, metrictable_metric_binding);
-                            } catch (Exception e) {
-                                // Ignore Exception on cleanup
-                                if (!isCleanUp)
-                                    throw e;
-                            }
-
-                            // bind lb monitor lb_metric_table_mon -metric cpu -metricThreshold 1
-                            lbmonitor_metric_binding monitor_metric_binding = new lbmonitor_metric_binding();
-                            ;
-                            try {
-                                monitor_metric_binding.set_monitorname(monitorName);
-                                monitor_metric_binding.set_metric(counterName);
-                                /*
-                                 * Setting it to max to make sure traffic is not affected due to 'LOAD' monitoring.
-                                 * For Ex. if CPU is tracked and CPU is greater than 80, it is still < than Integer.MAX_VALUE
-                                 * so traffic will continue to flow.
-                                 */
-                                monitor_metric_binding.set_metricthreshold(Integer.MAX_VALUE);
-                                lbmonitor_metric_binding.add(_netscalerService, monitor_metric_binding);
-                            } catch (Exception e) {
-                                // Ignore Exception on cleanup
-                                if (!isCleanUp)
-                                    throw e;
-                            }
-                        }
-                        // SYS.VSERVER("abcd").SNMP_TABLE(0).AVERAGE_VALUE.GT(80)
-                        int counterIndex = snmpMetrics.get(counterName); // TODO: temporary fix. later on counter name
-                        // will be added as a param to SNMP_TABLE.
-                        formatter.format("SYS.VSERVER(\"%s\").SNMP_TABLE(%d).AVERAGE_VALUE.%s(%d)", nsVirtualServerName, counterIndex, operator, threshold);
-                    } else if (counterTO.getSource().equals("netscaler")) {
-                        //SYS.VSERVER("abcd").RESPTIME.GT(10)
-                        formatter.format("SYS.VSERVER(\"%s\").%s.%s(%d)", nsVirtualServerName, counterTO.getValue(), operator, threshold);
-                    }
-                    if (policyExpression.length() != 0) {
-                        policyExpression += " && ";
-                    }
-                    policyExpression += conditionExpression;
-                }
-                policyExpression = "(" + policyExpression + ")";
-
-                String policyId = Long.toString(autoScalePolicyTO.getId());
-                String policyName = generateAutoScalePolicyName(vmGroupIdentifier, policyId);
-                String action = null;
-                if (isScaleUpPolicy(autoScalePolicyTO)) {
-                    action = scaleUpActionName;
-                    String scaleUpCondition =
-                            "SYS.VSERVER(\"" + nsVirtualServerName + "\").ACTIVESERVICES.LT(SYS.VSERVER(\"" + nsVirtualServerName + "\").MAXAUTOSCALEMEMBERS)";
-                    policyExpression = scaleUpCondition + " && " + policyExpression;
-                } else {
-                    action = scaleDownActionName;
-                    String scaleDownCondition =
-                            "SYS.VSERVER(\"" + nsVirtualServerName + "\").ACTIVESERVICES.GT(SYS.VSERVER(\"" + nsVirtualServerName + "\").MINAUTOSCALEMEMBERS)";
-                    policyExpression = scaleDownCondition + " && " + policyExpression;
-                }
-
-                addAutoScalePolicy(timerName, policyName, cur_prirotiy++, policyExpression, action, autoScalePolicyTO.getDuration(), interval, isCleanUp);
-
-            }
-        } catch (Exception ex) {
-            if (!isCleanUp) {
-                // Normal course, exception has occurred
-                disableAutoScaleConfig(loadBalancerTO, true);
-                throw ex;
-
-            } else {
-                // Programming error. Exception should never be thrown afterall.
-                throw ex;
-            }
-        }
-
-        return true;
-    }
-
-    @SuppressWarnings("static-access")
-    private synchronized boolean disableAutoScaleConfig(LoadBalancerTO loadBalancerTO, boolean isCleanUp) throws Exception {
-
-        String vmGroupIdentifier = generateAutoScaleVmGroupIdentifier(loadBalancerTO);
-
-        String profileName = generateAutoScaleProfileName(vmGroupIdentifier);
-        String timerName = generateAutoScaleTimerName(vmGroupIdentifier);
-        String scaleDownActionName = generateAutoScaleScaleDownActionName(vmGroupIdentifier);
-        String scaleUpActionName = generateAutoScaleScaleUpActionName(vmGroupIdentifier);
-        String mtName = generateSnmpMetricTableName(vmGroupIdentifier);
-        String monitorName = generateSnmpMonitorName(vmGroupIdentifier);
-        String serviceGroupName = generateAutoScaleServiceGroupName(loadBalancerTO);
-        AutoScaleVmGroupTO vmGroupTO = loadBalancerTO.getAutoScaleVmGroupTO();
-        List<AutoScalePolicyTO> policies = vmGroupTO.getPolicies();
-        String minMemberPolicyName = generateAutoScaleMinPolicyName(vmGroupIdentifier);
-        String maxMemberPolicyName = generateAutoScaleMaxPolicyName(vmGroupIdentifier);
-
-        try {
-
-            /* Delete min/max member policies */
-
-            removeAutoScalePolicy(timerName, minMemberPolicyName, isCleanUp);
-
-            removeAutoScalePolicy(timerName, maxMemberPolicyName, isCleanUp);
-
-            boolean isSnmp = false;
-            /* Create Counters */
-            for (AutoScalePolicyTO autoScalePolicyTO : policies) {
-                List<ConditionTO> conditions = autoScalePolicyTO.getConditions();
-                for (ConditionTO conditionTO : conditions) {
-                    CounterTO counterTO = conditionTO.getCounter();
-                    if (counterTO.getSource().equals("snmp")) {
-                        isSnmp = true;
-                        break;
-                    }
-                }
-                String policyId = Long.toString(autoScalePolicyTO.getId());
-                String policyName = generateAutoScalePolicyName(vmGroupIdentifier, policyId);
-
-                // Removing Timer policy
-                removeAutoScalePolicy(timerName, policyName, isCleanUp);
-            }
-
-            /* Delete AutoScale Config */
-            // Delete AutoScale ScaleDown action
-            com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction scaleDownAction =
-                    new com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction();
-            try {
-                scaleDownAction.set_name(scaleDownActionName);
-                autoscaleaction.delete(_netscalerService, scaleDownAction);
-            } catch (Exception e) {
-                // Ignore Exception on cleanup
-                if (!isCleanUp)
-                    throw e;
-            }
-
-            // Delete AutoScale ScaleUp action
-            com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction scaleUpAction =
-                    new com.citrix.netscaler.nitro.resource.config.autoscale.autoscaleaction();
-            try {
-                scaleUpAction.set_name(scaleUpActionName);
-                autoscaleaction.delete(_netscalerService, scaleUpAction);
-            } catch (Exception e) {
-                // Ignore Exception on cleanup
-                if (!isCleanUp)
-                    throw e;
-            }
-
-            // Delete Timer
-            nstimer timer = new nstimer();
-            try {
-                timer.set_name(timerName);
-                nstimer.delete(_netscalerService, timer);
-            } catch (Exception e) {
-                // Ignore Exception on cleanup
-                if (!isCleanUp)
-                    throw e;
-            }
-
-            // Delete AutoScale Profile
-            autoscaleprofile autoscaleProfile = new autoscaleprofile();
-            try {
-                autoscaleProfile.set_name(profileName);
-                autoscaleprofile.delete(_netscalerService, autoscaleProfile);
-            } catch (Exception e) {
-                // Ignore Exception on cleanup
-                if (!isCleanUp)
-                    throw e;
-            }
-
-            if (isSnmp) {
-                servicegroup_lbmonitor_binding servicegroup_monitor_binding = new servicegroup_lbmonitor_binding();
-                try {
-                    servicegroup_monitor_binding.set_monitor_name(monitorName);
-                    servicegroup_monitor_binding.set_servicegroupname(serviceGroupName);
-                    servicegroup_lbmonitor_binding.delete(_netscalerService, servicegroup_monitor_binding);
-                } catch (Exception e) {
-                    // Ignore Exception on cleanup
-                    if (!isCleanUp)
-                        throw e;
-                }
-
-                // Delete Monitor
-                // rm lb monitor lb_metric_table_mon
-                com.citrix.netscaler.nitro.resource.config.lb.lbmonitor monitor = new com.citrix.netscaler.nitro.resource.config.lb.lbmonitor();
-                try {
-                    monitor.set_monitorname(monitorName);
-                    monitor.set_type("LOAD");
-                    lbmonitor.delete(_netscalerService, monitor);
-                } catch (Exception e) {
-                    // Ignore Exception on cleanup
-                    if (!isCleanUp)
-                        throw e;
-                }
-
-                // Delete Metric Table
-                com.citrix.netscaler.nitro.resource.config.lb.lbmetrictable metricTable = new com.citrix.netscaler.nitro.resource.config.lb.lbmetrictable();
-                try {
-                    metricTable.set_metrictable(mtName);
-                    lbmetrictable.delete(_netscalerService, metricTable);
-                } catch (Exception e) {
-                    // Ignore Exception on cleanup
-                    if (!isCleanUp)
-                        throw e;
-                }
-            }
-        } catch (Exception ex) {
-            if (!isCleanUp) {
-                // Normal course, exception has occurred
-                enableAutoScaleConfig(loadBalancerTO, true);
-                throw ex;
-            } else {
-                // Programming error
-                throw ex;
-            }
-        }
-
-        return true;
-    }
-
-    private synchronized void addAutoScalePolicy(String timerName, String policyName, long priority, String policyExpression, String action, int duration, int interval,
-            boolean isCleanUp) throws Exception {
-        // Adding a autoscale policy
-        // add timer policy lb_policy_scaleUp_cpu_mem -rule - (SYS.CUR_VSERVER.METRIC_TABLE(cpu).AVG_VAL.GT(80)-
-        // -action lb_scaleUpAction
-        autoscalepolicy timerPolicy = new autoscalepolicy();
-        try {
-            timerPolicy.set_name(policyName);
-            timerPolicy.set_action(action);
-            timerPolicy.set_rule(policyExpression);
-            autoscalepolicy.add(_netscalerService, timerPolicy);
-        } catch (Exception e) {
-            // Ignore Exception on cleanup
-            if (!isCleanUp)
-                throw e;
-        }
-
-        // bind timer policy
-        // For now it is bound globally.
-        // bind timer trigger lb_astimer -policyName lb_policy_scaleUp -vserver lb -priority 1 -samplesize 5
-        // TODO: later bind to lbvserver. bind timer trigger lb_astimer -policyName lb_policy_scaleUp -vserver lb
-        // -priority 1 -samplesize 5
-        // -thresholdsize 5
-        nstimer_autoscalepolicy_binding timer_policy_binding = new nstimer_autoscalepolicy_binding();
-        int sampleSize = duration / interval;
-        try {
-            timer_policy_binding.set_name(timerName);
-            timer_policy_binding.set_policyname(policyName);
-            timer_policy_binding.set_samplesize(sampleSize);
-            timer_policy_binding.set_threshold(sampleSize); // We are not exposing this parameter as of now.
-            // i.e. n(m) is not exposed to CS user. So thresholdSize == sampleSize
-            timer_policy_binding.set_priority(priority);
-            nstimer_autoscalepolicy_binding.add(_netscalerService, timer_policy_binding);
-        } catch (Exception e) {
-            // Ignore Exception on cleanup
-            if (!isCleanUp)
-                throw e;
-        }
-    }
-
-    private void removeAutoScalePolicy(String timerName, String policyName, boolean isCleanUp) throws Exception {
-        // unbind timer policy
-        // unbbind timer trigger lb_astimer -policyName lb_policy_scaleUp
-        nstimer_autoscalepolicy_binding timer_policy_binding = new nstimer_autoscalepolicy_binding();
-        try {
-            timer_policy_binding.set_name(timerName);
-            timer_policy_binding.set_policyname(policyName);
-            nstimer_autoscalepolicy_binding.delete(_netscalerService, timer_policy_binding);
-        } catch (Exception e) {
-            // Ignore Exception on cleanup
-            if (!isCleanUp)
-                throw e;
-        }
-
-        // Removing Timer policy
-        // rm timer policy lb_policy_scaleUp_cpu_mem
-        autoscalepolicy timerPolicy = new autoscalepolicy();
-        try {
-            timerPolicy.set_name(policyName);
-            autoscalepolicy.delete(_netscalerService, timerPolicy);
-        } catch (Exception e) {
-            // Ignore Exception on cleanup
-            if (!isCleanUp)
-                throw e;
-        }
-
-    }
-
-    private boolean isAutoScaleSupportedInNetScaler() throws ExecutionException {
-        new autoscaleprofile();
-        try {
-            autoscaleprofile.get(_netscalerService);
-        } catch (Exception ex) {
-            // Looks like autoscale is not supported in this netscaler.
-            // TODO: Config team has introduce a new command to check
-            // the list of entities supported in a NetScaler. Can use that
-            // once it is present in AutoScale branch.
-            s_logger.warn("AutoScale is not supported in NetScaler");
-            return false;
-        }
-        return true;
-    }
-
-    private boolean isScaleUpPolicy(AutoScalePolicyTO autoScalePolicyTO) {
-        return autoScalePolicyTO.getAction().equals("scaleup");
-    }
-
-    private boolean isScaleDownPolicy(AutoScalePolicyTO autoScalePolicyTO) {
-        return autoScalePolicyTO.getAction().equals("scaledown");
-    }
-
-    private void saveConfiguration() throws ExecutionException {
-        try {
-            apiCallResult = nsconfig.save(_netscalerService);
-            if (apiCallResult.errorcode != 0) {
-                throw new ExecutionException("Error occured while saving configuration changes to Netscaler device due to " + apiCallResult.message);
-            }
-        } catch (nitro_exception e) {
-            throw new ExecutionException("Failed to save configuration changes to Netscaler device due to " + e.getMessage());
-        } catch (Exception e) {
-            throw new ExecutionException("Failed to save configuration changes to Netscaler device due to " + e.getMessage());
-        }
-    }
-
-    private ExternalNetworkResourceUsageAnswer getPublicIpBytesSentAndReceived(ExternalNetworkResourceUsageCommand cmd) throws ExecutionException {
-        ExternalNetworkResourceUsageAnswer answer = new ExternalNetworkResourceUsageAnswer(cmd);
-
-        try {
-            lbvserver_stats[] stats = lbvserver_stats.get(_netscalerService);
-
-            if (stats == null || stats.length == 0) {
-                return answer;
-            }
-
-            for (lbvserver_stats stat_entry : stats) {
-                String lbvserverName = stat_entry.get_name();
-                lbvserver vserver = lbvserver.get(_netscalerService, lbvserverName);
-                if (vserver != null) {
-                    String lbVirtualServerIp = vserver.get_ipv46();
-
-                    long[] bytesSentAndReceived = answer.ipBytes.get(lbVirtualServerIp);
-                    if (bytesSentAndReceived == null) {
-                        bytesSentAndReceived = new long[] {0, 0};
-                    }
-                    bytesSentAndReceived[0] += stat_entry.get_totalrequestbytes();
-                    bytesSentAndReceived[1] += stat_entry.get_totalresponsebytes();
-
-                    if (bytesSentAndReceived[0] >= 0 && bytesSentAndReceived[1] >= 0) {
-                        answer.ipBytes.put(lbVirtualServerIp, bytesSentAndReceived);
-                    }
-                }
-            }
-        } 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) {
-        //JSONObject jsonResponse = null;
-        try {
-            if (numRetries > 0) {
-                login();
-                /*if (response == null) {
-                    throw new ConfigurationException("No Response Received from the NetScalerControlCenter Device");
-                } else {
-                    jsonResponse = new JSONObject(response);
-                    org.json.JSONArray loginResponse = jsonResponse.getJSONArray("login");
-                    _sessionid = jsonResponse.getJSONArray("login").getJSONObject(0).getString("sessionid");
-                }*/
-                return true;
-            }
-        } catch (Exception e) {
-            s_logger.error("Failed to log in to Netscaler ControlCenter device at " + _ip + " due to " + e.getMessage());
-            return false;
-            //throw new ConfigurationException("No Response Received from the NetScalerControlCenter Device");
-        }
-        return false;
-    }
-
-    private String generateInatRuleName(String srcIp, String dstIP) {
-        return genObjectName("Cloud-Inat", srcIp);
-    }
-
-    private String generateRnatRuleName(String srcIp, String dstIP) {
-        return genObjectName("Cloud-Rnat", srcIp);
-    }
-
-    private String generateNSVirtualServerName(String srcIp, long srcPort) {
-        return genObjectName("Cloud-VirtualServer", srcIp, srcPort);
-    }
-
-    private String generateNSMonitorName(String srcIp, long srcPort) {
-        // maximum length supported by NS is 31
-        return genObjectName("Cloud-Hc", srcIp, srcPort);
-    }
-
-    private String generateNSServerName(String serverIP) {
-        return genObjectName("Cloud-Server-", serverIP);
-    }
-
-    private String generateNSServiceName(String ip, long port) {
-        return genObjectName("Cloud-Service", ip, port);
-    }
-
-    private String generateAutoScaleVmGroupIdentifier(LoadBalancerTO lbTO) {
-        return lbTO.getSrcIp() + "-" + lbTO.getSrcPort();
-    }
-
-    private String generateAutoScaleServiceGroupName(LoadBalancerTO lbTO) {
-        /*
-         *  ServiceGroup name in NetScaler wont support long names. Providing special name.
-         *  Need for introducing uuid because every vmgroup creation should be distinguished.
-         *  Ex. (1) create a vm group, delete a vmgroup, create a vmgroup on same lb ip and port
-         *  This will reuse all vms from the original vm group in step (1)
-         */
-
-        return "Cloud" + lbTO.getAutoScaleVmGroupTO().getUuid().replace("-", "");
-    }
-
-    private String generateAutoScaleTimerName(String vmGroupIdentifier) {
-        return genObjectName("Cloud-AutoScale-Timer", vmGroupIdentifier);
-    }
-
-    private String generateAutoScaleProfileName(String vmGroupIdentifier) {
-        return genObjectName("Cloud-AutoScale-Profile", vmGroupIdentifier);
-    }
-
-    private String generateAutoScaleScaleUpActionName(String vmGroupIdentifier) {
-        return genObjectName("Cloud-AutoScale-ScaleUpAction", vmGroupIdentifier);
-    }
-
-    private String generateAutoScaleScaleDownActionName(String vmGroupIdentifier) {
-        return genObjectName("Cloud-AutoScale-ScaleDownAction", vmGroupIdentifier);
-    }
-
-    private String generateAutoScalePolicyName(String vmGroupIdentifier, String poilcyId) {
-        return genObjectName("Cloud-AutoScale-Policy", vmGroupIdentifier, poilcyId);
-    }
-
-    private String generateAutoScaleMinPolicyName(String vmGroupIdentifier) {
-        return genObjectName("Cloud-AutoScale-Policy-Min", vmGroupIdentifier);
-    }
-
-    private String generateAutoScaleMaxPolicyName(String vmGroupIdentifier) {
-        return genObjectName("Cloud-AutoScale-Policy-Max", vmGroupIdentifier);
-    }
-
-    private String generateSnmpMetricTableName(String vmGroupIdentifier) {
-        return genObjectName("Cloud-MTbl", vmGroupIdentifier);
-    }
-
-    private String generateSnmpMonitorName(String vmGroupIdentifier) {
-        return genObjectName("Cloud-Mon", vmGroupIdentifier);
-    }
-
-    private String generateSnmpMetricName(String counterName) {
-        return counterName.replace(' ', '_');
-    }
-
-    private String generateSslCertName(String fingerPrint) {
-        // maximum length supported by NS is 31
-        // the first 20 characters of the SHA-1 checksum are the unique id
-        String uniqueId = fingerPrint.replace(":", "").substring(0, 20);
-
-        return genObjectName("Cloud-Cert", uniqueId);
-    }
-
-    private String generateSslKeyName(String fingerPrint) {
-        String uniqueId = fingerPrint.replace(":", "").substring(0, 20);
-        return genObjectName("Cloud-Key", uniqueId);
-    }
-
-    private String generateSslCertKeyName(String fingerPrint) {
-        String uniqueId = fingerPrint.replace(":", "").substring(0, 20);
-        return genObjectName("Cloud-Cert", uniqueId);
-    }
-
-    private String genObjectName(Object... args) {
-        StringBuffer buff = new StringBuffer();
-        for (int i = 0; i < args.length; i++) {
-            buff.append(args[i]);
-            if (i != args.length - 1) {
-                buff.append(_objectNamePathSep);
-            }
-        }
-        return buff.toString();
-    }
-
-    @Override
-    public IAgentControl getAgentControl() {
-        return null;
-    }
-
-    private boolean refreshNCCConnection() {
-        boolean ret = false;
-        try {
-            login();
-            return true;
-        } catch (ExecutionException ex) {
-            s_logger.error("Login to NCC failed", ex);
-        }
-        return ret;
-    }
-
-    @Override
-    public PingCommand getCurrentStatus(long id) {
-        /*if (!refreshNCCConnection()) {
-            return null;
-        }*/
-        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 boolean start() {
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    @Override
-    public void disconnected() {
-        return;
-    }
-
-    @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
-
-    }
-
-    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, ",");
+                List<String> stringList = new ArrayList<String>();
+                Collections.addAll(stringList, temp);
+                cleanLogString = StringUtils.join(stringList, ",");
             }
         }
         return cleanLogString;
@@ -3741,7 +807,6 @@ public class NetScalerControlCenterResource implements ServerResource {
 
         // TODO: are there timeout settings and worker thread settings to tweak?
         try {
-            //HttpPost request = new HttpPost(agentUri);
             HttpGet request = new HttpGet(agentUri);
 
             // JSON encode command
@@ -3750,7 +815,6 @@ public class NetScalerControlCenterResource implements ServerResource {
             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);
             HttpResponse response = httpClient.execute(request);
@@ -3767,7 +831,6 @@ public class NetScalerControlCenterResource implements ServerResource {
                 String errMsg = "Failed send to " + agentUri.toString() + " : HTTP error code : " + response.getStatusLine().getStatusCode();
                 s_logger.error(errMsg);
                 throw new ExecutionException("UNAUTHORIZED");
-                //return null;
             } else {
                 result = EntityUtils.toString(response.getEntity());
                 String logResult = cleanPassword(StringEscapeUtils.unescapeJava(result));
@@ -3841,31 +904,25 @@ public class NetScalerControlCenterResource implements ServerResource {
 
             // Unsupported commands will not route.
             if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_FOUND) {
-                String errMsg = "Failed to send : HTTP error code : " + response.getStatusLine().getStatusCode();
-                throw new ExecutionException("NOT_FOUND");
-                /*s_logger.error(errMsg);
-                String unsupportMsg = "Unsupported command " + agentUri.getPath() + ".  Are you sure you got the right type of" + " server?";
-                Answer ans = new UnsupportedAnswer(null, unsupportMsg);
-                s_logger.error(ans);*/
-                //result = s_gson.toJson(new Answer[] {ans});
+                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 = "Failed send to " + agentUri.toString() + " : HTTP error code : " + response.getStatusLine().getStatusCode();
+                String errMsg = "Command Not Success " + agentUri.toString() + " : HTTP error code : " + response.getStatusLine().getStatusCode();
                 s_logger.error(errMsg);
-                throw new ExecutionException("UNAUTHORIZED");
-                //return null;
+                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("UNAUTHORIZED");
+                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("Job_id").getValue();
-                //"jobid : " +
+                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);
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManager.java b/plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManager.java
new file mode 100644
index 0000000..ae1c9da
--- /dev/null
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManager.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.network.vm;
+import java.util.Map;
+
+import com.cloud.api.commands.DeployNetscalerVpxCmd;
+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.network.router.VirtualRouter;
+import com.cloud.user.Account;
+
+public interface NetScalerVMManager {
+
+ //RAM/CPU for the system offering used by Internal LB VMs
+ public static final int DEFAULT_NETSCALER_VM_RAMSIZE = 2048;            // 2048 MB
+ public static final int DEFAULT_NETSCALER_VM_CPU_MHZ = 1024;            // 1024 MHz
+
+ public Map<String, Object> deployNetscalerServiceVm(DeployNetscalerVpxCmd cmd);
+
+ public VirtualRouter stopNetscalerServiceVm(Long id, boolean forced, Account callingAccount, long callingUserId) throws ConcurrentOperationException, ResourceUnavailableException;
+ public Map<String, Object> deployNsVpx(Account owner, DeployDestination dest, DeploymentPlan plan, long svcOffId, long templateId) throws InsufficientCapacityException;
+
+ public VirtualRouter stopNetScalerVm(Long id, boolean forced, Account callingAccount, long callingUserId);
+}
\ No newline at end of file
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManagerImpl.java b/plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManagerImpl.java
new file mode 100644
index 0000000..63574ad
--- /dev/null
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManagerImpl.java
@@ -0,0 +1,448 @@
+//Licensed to the Apache Software Foundation (ASF) under one
+//or more contributor license agreements.  See the NOTICE file
+//distributed with this work for additional information
+//regarding copyright ownership.  The ASF licenses this file
+//to you under the Apache License, Version 2.0 (the
+//"License"); you may not use this file except in compliance
+//with the License.  You may obtain a copy of the License at
+//
+//http://www.apache.org/licenses/LICENSE-2.0
+//
+//Unless required by applicable law or agreed to in writing,
+//software distributed under the License is distributed on an
+//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.vm;
+
+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 javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+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.dao.ApplicationLoadBalancerRuleDao;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.manager.Commands;
+import com.cloud.api.commands.DeployNetscalerVpxCmd;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.deploy.DataCenterDeployment;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.network.IpAddressManager;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Provider;
+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.VirtualRouterProvider;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
+import com.cloud.network.dao.VirtualRouterProviderDao;
+import com.cloud.network.element.VirtualRouterProviderVO;
+import com.cloud.network.lb.LoadBalancingRulesManager;
+import com.cloud.network.router.VirtualRouter;
+import com.cloud.network.router.VirtualRouter.RedundantState;
+import com.cloud.network.router.VirtualRouter.Role;
+import com.cloud.offering.NetworkOffering;
+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.VMTemplateVO;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineGuru;
+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;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+@Local(value = {NetScalerVMManager.class})
+public class NetScalerVMManagerImpl extends ManagerBase implements NetScalerVMManager, VirtualMachineGuru {
+ private static final Logger s_logger = Logger.getLogger(NetScalerVMManagerImpl.class);
+ static final private String NetScalerLbVmNamePrefix = "NS";
+
+ @Inject
+ IpAddressManager _ipAddrMgr;
+ @Inject
+ VirtualMachineManager _itMgr;
+ @Inject
+ DomainRouterDao _internalLbVmDao;
+ @Inject
+ ConfigurationDao _configDao;
+ @Inject
+ AgentManager _agentMgr;
+ @Inject
+ DataCenterDao _dcDao;
+ @Inject
+ VirtualRouterProviderDao _vrProviderDao;
+ @Inject
+ ApplicationLoadBalancerRuleDao _lbDao;
+ @Inject
+ NetworkModel _ntwkModel;
+ @Inject
+ LoadBalancingRulesManager _lbMgr;
+ @Inject
+ NicDao _nicDao;
+ @Inject
+ AccountManager _accountMgr;
+ @Inject
+ NetworkDao _networkDao;
+ @Inject
+ NetworkOrchestrationService _networkMgr;
+ @Inject
+ ServiceOfferingDao _serviceOfferingDao;
+ @Inject
+ PhysicalNetworkServiceProviderDao _physicalProviderDao;
+ @Inject
+ NetworkOfferingDao _networkOfferingDao;
+ @Inject
+ VMTemplateDao _templateDao;
+ @Inject
+ ResourceManager _resourceMgr;
+ @Inject
+ VMInstanceDao _vmDao;
+ @Inject
+ NetworkModel _networkModel;
+ @Inject
+ PhysicalNetworkDao _physicalNetworkDao;
+ @Inject
+ VlanDao _vlanDao;
+ @Inject
+ DomainRouterDao _routerDao;
+
+ @Override
+ public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
+
+     //NetScalerLB vm starts up with 3 Nics
+     //Nic #1 - NS IP
+     //Nic #2 - locallink(guest network)
+     //Nic #3 - public nic
+
+     for (final NicProfile nic : profile.getNics()) {
+         if(nic.getTrafficType() == TrafficType.Control) {
+             nic.setTrafficType(TrafficType.Guest);
+         }
+     }
+     return true;
+ }
+
+ @Override
+ public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context)
+     throws ResourceUnavailableException {
+     return true;
+ }
+
+ @Override
+ public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) {
+     return true;
+ }
+
+ @Override
+ public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) {
+     return true;
+ }
+
+ @Override
+ public void finalizeStop(VirtualMachineProfile profile, Answer answer) {
+ }
+
+ @Override
+ public void finalizeExpunge(VirtualMachine vm) {
+ }
+
+ @Override
+ public void prepareStop(VirtualMachineProfile profile) {
+ }
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+
+     _itMgr.registerGuru(VirtualMachine.Type.NetScalerVm, this);
+     if (s_logger.isInfoEnabled()) {
+         s_logger.info(getName() + " has been configured");
+     }
+     return true;
+ }
+
+ @Override
+ public String getName() {
+     return _name;
+ }
+
+ protected VirtualRouter stopInternalLbVm(DomainRouterVO internalLbVm, boolean forced, Account caller, long callerUserId) throws ResourceUnavailableException,
+     ConcurrentOperationException {
+     s_logger.debug("Stopping internal lb vm " + internalLbVm);
+     try {
+         _itMgr.advanceStop(internalLbVm.getUuid(), forced);
+         return _internalLbVmDao.findById(internalLbVm.getId());
+     } catch (OperationTimedoutException e) {
+         throw new CloudRuntimeException("Unable to stop " + internalLbVm, e);
+     }
+ }
+
+ public VirtualRouterProvider addNetScalerLoadBalancerElement(long ntwkSvcProviderId) {
+     VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(ntwkSvcProviderId, com.cloud.network.VirtualRouterProvider.Type.NetScalerVm);
+     if (element != null) {
+         s_logger.debug("There is already an " + getName() + " with service provider id " + ntwkSvcProviderId);
+         return element;
+     }
+
+     PhysicalNetworkServiceProvider provider = _physicalProviderDao.findById(ntwkSvcProviderId);
+     if (provider == null || !provider.getProviderName().equalsIgnoreCase(getName())) {
+         throw new InvalidParameterValueException("Invalid network service provider is specified");
+     }
+
+     element = new VirtualRouterProviderVO(ntwkSvcProviderId, com.cloud.network.VirtualRouterProvider.Type.NetScalerVm);
+     element.setEnabled(true);
+     element = _vrProviderDao.persist(element);
+     return element;
+ }
+
+ protected long getNetScalerLbProviderId(long physicalNetworkId) {
+     //final long physicalNetworkId = _ntwkModel.getPhysicalNetworkId(guestNetwork);
+
+     final PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, "Netscaler");
+     if (provider == null) {
+         throw new CloudRuntimeException("Cannot find service provider " + Provider.Netscaler.toString() + " in physical network " + physicalNetworkId);
+     }
+
+     //TODO: get from type
+     VirtualRouterProvider netScalerLbProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), com.cloud.network.VirtualRouterProvider.Type.NetScalerVm);
+     if (netScalerLbProvider == null) {
+         //create the vrp for netscalerVM.
+         netScalerLbProvider = addNetScalerLoadBalancerElement(provider.getId());
+     }
+
+     return netScalerLbProvider.getId();
+ }
+ @Override
+    public Map<String, Object> deployNsVpx(Account owner, DeployDestination dest, DeploymentPlan plan, long svcOffId, long templateId) throws InsufficientCapacityException {
+
+     VMTemplateVO template = _templateDao.findById(templateId) ;
+     long id = _vmDao.getNextInSequence(Long.class, "id");
+     Account systemAcct = _accountMgr.getSystemAccount();
+
+     if (template == null) {
+         s_logger.error(" Unable to find the NS VPX template");
+         throw new CloudRuntimeException("Unable to find the Template" + templateId);
+     }
+     long dataCenterId = dest.getDataCenter().getId();
+     DataCenterVO dc = _dcDao.findById(dest.getDataCenter().getId());
+
+     String nxVpxName = VirtualMachineName.getSystemVmName(id, "Vpx", NetScalerLbVmNamePrefix);
+
+     ServiceOfferingVO vpxOffering =   _serviceOfferingDao.findById(svcOffId); //using 2GB and 2CPU  offering
+     if(vpxOffering.getRamSize() < 2048 && vpxOffering.getCpu() <2 ) {
+         throw new InvalidParameterValueException("Specified Service Offering :" + vpxOffering.getUuid() + " NS Vpx cannot be deployed. Min 2GB Ram and 2 CPU are required");
+     }
+
+     long userId = CallContext.current().getCallingUserId();
+     //TODO change the os bits from 142  103 to the actual guest of bits
+     if(template.getGuestOSId() !=  103 ) {
+         throw new InvalidParameterValueException("Specified Template " + template.getUuid()+ " not suitable for NS VPX Deployment. Please register the template with guest os type as unknow(64-bit)");
+     }
+     NetworkVO defaultNetwork = null;
+      NetworkVO defaultPublicNetwork = null;
+      if (dc.getNetworkType() == NetworkType.Advanced && dc.isSecurityGroupEnabled()) {
+          List<NetworkVO> networks = _networkDao.listByZoneSecurityGroup(dataCenterId);
+          if (networks == null || networks.size() == 0) {
+              throw new CloudRuntimeException("Can not found security enabled network in SG Zone " + dc);
+          }
+          defaultNetwork = networks.get(0);
+      } else {
+          TrafficType defaultTrafficType = TrafficType.Management;
+          List<NetworkVO> defaultNetworks = _networkDao.listByZoneAndTrafficType(dataCenterId, defaultTrafficType);
+
+          TrafficType publicTrafficType = TrafficType.Public;
+          List<NetworkVO> publicNetworks = _networkDao.listByZoneAndTrafficType(dataCenterId, publicTrafficType);
+
+          // 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");
+          }
+
+          if (publicNetworks.size() != 1) {
+              throw new CloudRuntimeException("Found " + defaultNetworks.size() + " networks of type " + defaultTrafficType + " when expect to find 1");
+          }
+          defaultPublicNetwork = publicNetworks.get(0);
+          defaultNetwork = defaultNetworks.get(0);
+      }
+
+      LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>(4);
+      NicProfile defaultNic = new NicProfile();
+      defaultNic.setDefaultNic(true);
+      defaultNic.setDeviceId(0);
+
+      networks.put(_networkMgr.setupNetwork(_accountMgr.getSystemAccount() , _networkOfferingDao.findById(defaultNetwork.getNetworkOfferingId()), plan, null, null, false).get(0),
+              new ArrayList<NicProfile>());
+
+      NicProfile defaultNic1 = new NicProfile();
+      defaultNic1.setDefaultNic(false);
+      defaultNic1.setDeviceId(1);
+
+      NicProfile defaultNic2 = new NicProfile();
+      defaultNic2.setDefaultNic(false);
+      defaultNic2.setDeviceId(2);
+      defaultNic2.setIPv4Address("");
+      defaultNic2.setIPv4Gateway("");
+      defaultNic2.setIPv4Netmask("");
+      String macAddress = _networkDao.getNextAvailableMacAddress(defaultPublicNetwork.getId());
+      defaultNic2.setMacAddress(macAddress);
+
+      networks.put(_networkMgr.setupNetwork(_accountMgr.getSystemAccount(), _networkOfferingDao.findByUniqueName(NetworkOffering.SystemPublicNetwork), plan, null, null, false).get(0),
+              new ArrayList<NicProfile>(Arrays.asList(defaultNic2)));
+
+      networks.put(_networkMgr.setupNetwork(_accountMgr.getSystemAccount(), _networkOfferingDao.findByUniqueName(NetworkOffering.SystemControlNetwork), plan, null, null, false).get(0),
+              new ArrayList<NicProfile>());
+
+      long physicalNetworkId = _networkModel.findPhysicalNetworkId(dataCenterId, _networkOfferingDao.findById(defaultPublicNetwork.getNetworkOfferingId()).getTags(), TrafficType.Public);
+      // Validate physical network
+      PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+      if (physicalNetwork == null) {
+          throw new InvalidParameterValueException("Unable to find physical network with id: " + physicalNetworkId + " and tag: "
+                  + _networkOfferingDao.findById(defaultPublicNetwork.getNetworkOfferingId()).getTags());
+      }
+      String guestvnet = physicalNetwork.getVnetString();
+
+      final List<VlanVO> vlans = _vlanDao.listByZone(dataCenterId);
+      List<String> pvlan = new ArrayList<String>();
+      for (final VlanVO vlan : vlans) {
+          pvlan.add(vlan.getVlanTag());
+      }
+
+      long netScalerProvider = getNetScalerLbProviderId(physicalNetworkId);
+      DomainRouterVO nsVpx = new DomainRouterVO(id, vpxOffering.getId(), netScalerProvider, nxVpxName,
+              template.getId(), template.getHypervisorType(),  template.getGuestOSId(), owner.getDomainId(), owner.getId(), userId, false, RedundantState.UNKNOWN, false,
+              false, VirtualMachine.Type.NetScalerVm, null);
+
+          nsVpx.setRole(Role.NETSCALER_VM);
+
+          nsVpx = _routerDao.persist(nsVpx);
+
+      VMInstanceVO vmVO= _vmDao.findVMByHostName(nxVpxName);
+     _itMgr.allocate(nxVpxName, template, vpxOffering, networks, plan, template.getHypervisorType());
+     Map<Param, Object> params = new HashMap<VirtualMachineProfile.Param, Object>(1);
+     try {
+         if (vmVO != null) {
+             startNsVpx(vmVO, params);
+         } else {
+             throw new NullPointerException();
+         }
+     } catch (StorageUnavailableException e) {
+         e.printStackTrace();
+     } catch (ConcurrentOperationException e) {
+         e.printStackTrace();
+     } catch (ResourceUnavailableException e) {
+         e.printStackTrace();
+     }
+     vmVO= _vmDao.findByUuid(nsVpx.getUuid());
+     Map<String, Object> deployResponse = new HashMap<String, Object>();
+     deployResponse.put("vm", vmVO);
+     deployResponse.put("guestvlan", guestvnet);
+     deployResponse.put("publicvlan", pvlan);
+     return deployResponse;
+ }
+
+ protected void startNsVpx(VMInstanceVO nsVpx, Map<Param, Object> params) throws StorageUnavailableException,
+ InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
+     s_logger.debug("Starting NS Vpx " + nsVpx);
+     _itMgr.start(nsVpx.getUuid(), params, null, null);
+ }
+
+ @Override
+ public Map<String,Object> deployNetscalerServiceVm(DeployNetscalerVpxCmd cmd) {
+     DataCenter zone = _dcDao.findById(cmd.getZoneId());
+     DeployDestination dest = new DeployDestination(zone, null, null, null);
+     VMInstanceVO vmvo = 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 = deployNsVpx(cmd.getAccount(), dest, plan, serviceOfferingId, templateId);
+     } catch (InsufficientCapacityException e) {
+         // TODO Auto-generated catch block
+         e.printStackTrace();
+     }
+     return resp;
+ }
+
+ protected VirtualRouter stopNetScalerVm(final long vmId, final boolean forced, final Account caller, final long callerUserId) throws ResourceUnavailableException,
+ ConcurrentOperationException {
+     final DomainRouterVO netscalerVm = _routerDao.findById(vmId);
+     s_logger.debug("Stopping NetScaler vm " + netscalerVm);
+
+     if (netscalerVm == null || netscalerVm.getRole() != Role.NETSCALER_VM) {
+         throw new InvalidParameterValueException("Can't find NetScaler vm by id specified");
+     }
+     _accountMgr.checkAccess(caller, null, true, netscalerVm);
+     try {
+         _itMgr.expunge(netscalerVm.getUuid());
+         return _routerDao.findById(netscalerVm.getId());
+     } catch (final Exception e) {
+         throw new CloudRuntimeException("Unable to stop " + netscalerVm, e);
+     }
+ }
+ @Override
+ public VirtualRouter stopNetscalerServiceVm(Long id, boolean forced, Account callingAccount, long callingUserId) throws ConcurrentOperationException,
+         ResourceUnavailableException {
+     return stopNetScalerVm(id, forced, callingAccount, callingUserId);
+ }
+
+@Override
+public VirtualRouter stopNetScalerVm(Long vmId, boolean forced, Account caller, long callingUserId) {
+    final DomainRouterVO netscalerVm = _routerDao.findById(vmId);
+    s_logger.debug("Stopping NetScaler vm " + netscalerVm);
+
+    if (netscalerVm == null || netscalerVm.getRole() != Role.NETSCALER_VM) {
+        throw new InvalidParameterValueException("Can't find NetScaler vm by id specified");
+    }
+    _accountMgr.checkAccess(caller, null, true, netscalerVm);
+    try {
+        _itMgr.expunge(netscalerVm.getUuid());
+        return _routerDao.findById(netscalerVm.getId());
+    } catch (final Exception e) {
+        throw new CloudRuntimeException("Unable to stop " + netscalerVm, e);
+    }
+}
+}
diff --git a/server/src/com/cloud/alert/AlertManagerImpl.java b/server/src/com/cloud/alert/AlertManagerImpl.java
index e18d231..93c3b77 100644
--- a/server/src/com/cloud/alert/AlertManagerImpl.java
+++ b/server/src/com/cloud/alert/AlertManagerImpl.java
@@ -90,7 +90,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
     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 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("########");
@@ -126,7 +126,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
     protected ConfigDepot _configDepot;
 
     private Timer _timer = null;
-    private long _capacityCheckPeriod = 60L * 60L * 1000L; // one hour by default
+    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;
@@ -250,7 +250,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
                 _emailAlert.sendAlert(alertType, dataCenterId, podId, null, subject, body);
             } else {
                 s_alertsLogger.warn(" alertType:: " + alertType + " // dataCenterId:: " + dataCenterId + " // podId:: " + podId +
-                    " // message:: " + subject + " // body:: " + body);
+                        " // message:: " + subject + " // body:: " + body);
             }
         } catch (Exception ex) {
             s_logger.error("Problem sending email alert", ex);
@@ -367,7 +367,8 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
             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)) {
+        } 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);
@@ -405,7 +406,8 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
             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)) {
+        } 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);
@@ -489,21 +491,21 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
                 // 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);
+                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;
@@ -513,7 +515,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
                 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);
+                            usedCapacity, capacityType);
                 }
             }
         }
@@ -549,84 +551,82 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
         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;
+        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 {
@@ -746,9 +746,9 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
 
         // 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 {
+                UnsupportedEncodingException {
             s_alertsLogger.warn(" alertType:: " + alertType + " // dataCenterId:: " + dataCenterId + " // podId:: " +
-                podId + " // clusterId:: " + clusterId + " // message:: " + subject);
+                    podId + " // clusterId:: " + clusterId + " // message:: " + subject);
             AlertVO alert = null;
             if ((alertType != AlertManager.AlertType.ALERT_TYPE_HOST) &&
                 (alertType != AlertManager.AlertType.ALERT_TYPE_USERVM) &&
@@ -771,7 +771,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
                 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.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);
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index 7d7f0fd..c03d367 100644
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -1267,13 +1267,11 @@ public class ApiResponseHelper implements ResponseGenerator {
     @Override
     public SystemVmResponse createSystemVmResponse(VirtualMachine vm) {
         SystemVmResponse vmResponse = new SystemVmResponse();
-        if (vm.getType() == Type.SecondaryStorageVm || vm.getType() == Type.ConsoleProxy || vm.getType() == Type.DomainRouter) {
-            // SystemVm vm = (SystemVm) systemVM;
+        if (vm.getType() == Type.SecondaryStorageVm || vm.getType() == Type.ConsoleProxy || vm.getType() == Type.DomainRouter || vm.getType() == Type.NetScalerVm) {
             vmResponse.setId(vm.getUuid());
-            // vmResponse.setObjectId(vm.getId());
             vmResponse.setSystemVmType(vm.getType().toString().toLowerCase());
-
             vmResponse.setName(vm.getHostName());
+
             if (vm.getPodIdToDeployIn() != null) {
                 HostPodVO pod = ApiDBUtils.findPodById(vm.getPodIdToDeployIn());
                 if (pod != null) {
diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
index f6e040f..f7a6104 100755
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -3917,7 +3917,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
         final Boolean egressDefaultPolicy = cmd.getEgressDefaultPolicy();
         Integer maxconn = null;
         boolean enableKeepAlive = false;
-
+        String servicePackageuuid = cmd.getServicePackageId();
         // Verify traffic type
         for (final TrafficType tType : TrafficType.values()) {
             if (tType.name().equalsIgnoreCase(trafficTypeString)) {
@@ -4293,6 +4293,16 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
             final boolean conserveMode, final Map<Service, Map<Capability, String>> serviceCapabilityMap, final boolean specifyIpRanges, final boolean isPersistent,
             final Map<NetworkOffering.Detail, String> details, final boolean egressDefaultPolicy, final Integer maxconn, final boolean enableKeepAlive) {
 
+        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);
@@ -4451,11 +4461,37 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
             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) {
@@ -4778,6 +4814,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
         return vpcProvider || nuageVpcProvider;
     }
 
+    @DB
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_NETWORK_OFFERING_DELETE, eventDescription = "deleting network offering")
     public boolean deleteNetworkOffering(final DeleteNetworkOfferingCmd cmd) {
diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
index c413edd..d84c104 100644
--- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
+++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
@@ -48,6 +48,7 @@ import com.cloud.vm.dao.NicDao;
 import com.cloud.vm.dao.NicSecondaryIpDao;
 import com.cloud.vm.dao.UserVmDetailsDao;
 import com.cloud.vm.dao.VMInstanceDao;
+import com.cloud.network.Networks.BroadcastDomainType;
 
 public abstract class HypervisorGuruBase extends AdapterBase implements HypervisorGuru {
     public static final Logger s_logger = Logger.getLogger(HypervisorGuruBase.class);
@@ -134,6 +135,9 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
         NicTO[] nics = new NicTO[nicProfiles.size()];
         int i = 0;
         for (NicProfile nicProfile : nicProfiles) {
+            if(vm.getType() == VirtualMachine.Type.NetScalerVm) {
+                nicProfile.setBroadcastType(BroadcastDomainType.Native);
+            }
             nics[i++] = toNicTO(nicProfile);
         }
 
diff --git a/server/src/com/cloud/network/ExternalDeviceUsageManagerImpl.java b/server/src/com/cloud/network/ExternalDeviceUsageManagerImpl.java
index 200b279..49dc785 100644
--- a/server/src/com/cloud/network/ExternalDeviceUsageManagerImpl.java
+++ b/server/src/com/cloud/network/ExternalDeviceUsageManagerImpl.java
@@ -43,6 +43,7 @@ import com.cloud.dc.dao.HostPodDao;
 import com.cloud.dc.dao.VlanDao;
 import com.cloud.host.Host;
 import com.cloud.host.HostVO;
+import com.cloud.host.Host.Type;
 import com.cloud.host.dao.HostDao;
 import com.cloud.host.dao.HostDetailsDao;
 import com.cloud.network.Networks.BroadcastDomainType;
@@ -68,6 +69,7 @@ import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
 import com.cloud.network.rules.LoadBalancerContainer.Scheme;
 import com.cloud.network.rules.PortForwardingRuleVO;
 import com.cloud.network.rules.dao.PortForwardingRulesDao;
+import com.cloud.offering.NetworkOffering;
 import com.cloud.offerings.dao.NetworkOfferingDao;
 import com.cloud.resource.ResourceManager;
 import com.cloud.user.AccountManager;
@@ -332,6 +334,21 @@ public class ExternalDeviceUsageManagerImpl extends ManagerBase implements Exter
         });
     }
 
+    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);
+    }
+
     protected class ExternalDeviceNetworkUsageTask extends ManagedContextRunnable {
 
         public ExternalDeviceNetworkUsageTask() {
@@ -400,11 +417,20 @@ public class ExternalDeviceUsageManagerImpl extends ManagerBase implements Exter
                             continue;
                         }
 
-                        ExternalFirewallDeviceVO fwDeviceVO = getExternalFirewallForNetwork(network);
                         ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network);
-                        if (lbDeviceVO == null && fwDeviceVO == null) {
+                        HostVO externalNcc = null;
+                        boolean isNccNetwork = isNccServiceProvider(network);
+                        if(isNccNetwork) {
+                            externalNcc = getNetScalerControlCenterForNetwork(network);
+                        }
+                        ExternalFirewallDeviceVO fwDeviceVO = getExternalFirewallForNetwork(network);
+
+                        if (fwDeviceVO == null) {
                             continue;
                         }
+                        if(externalNcc == null && lbDeviceVO == null) {
+                            return;
+                        }
 
                         // Get network stats from the external firewall
                         ExternalNetworkResourceUsageAnswer firewallAnswer = null;
@@ -440,13 +466,17 @@ public class ExternalDeviceUsageManagerImpl extends ManagerBase implements Exter
                         // Get network stats from the external load balancer
                         ExternalNetworkResourceUsageAnswer lbAnswer = null;
                         HostVO externalLoadBalancer = null;
-                        if (lbDeviceVO != null) {
-                            externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
+                        if (lbDeviceVO != null || externalNcc != null) {
+                            if(isNccNetwork) {
+                                externalLoadBalancer = externalNcc;
+                            } else {
+                                externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
+                            }
                             if (externalLoadBalancer != null) {
                                 Long lbDeviceId = new Long(externalLoadBalancer.getId());
                                 if (!lbDeviceUsageAnswerMap.containsKey(lbDeviceId)) {
                                     try {
-                                        ExternalNetworkResourceUsageCommand cmd = new ExternalNetworkResourceUsageCommand();
+                                        ExternalNetworkResourceUsageCommand cmd = new ExternalNetworkResourceUsageCommand(network.getId());
                                         lbAnswer = (ExternalNetworkResourceUsageAnswer)_agentMgr.easySend(externalLoadBalancer.getId(), cmd);
                                         if (lbAnswer == null || !lbAnswer.getResult()) {
                                             String details = (lbAnswer != null) ? lbAnswer.getDetails() : "details unavailable";
diff --git a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
index 85eda6b..f1b4a79 100644
--- a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
+++ b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
@@ -27,12 +27,13 @@ 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 org.apache.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
@@ -63,8 +64,8 @@ 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.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;
@@ -91,6 +92,7 @@ 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;
@@ -111,6 +113,8 @@ 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;
@@ -129,8 +133,10 @@ 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 {
 
@@ -194,6 +200,19 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
     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);
@@ -867,9 +886,9 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
         return nic;
     }
 
-    private boolean isNccServiceProvider(Network network) {
+    public boolean isNccServiceProvider(Network network) {
         NetworkOffering networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
-        if(networkOffering.getServicePackage() != null ) {
+        if(null!= networkOffering && networkOffering.getServicePackage() != null ) {
             return true;
         }
         else {
@@ -927,11 +946,14 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
             String uuid = rule.getUuid();
             String srcIp = rule.getSourceIp().addr();
             String srcIpVlan = null;
-            //IpAddress ipAddress =  _networkModel.getPublicIpAddress(rule.getSourceIp().addr(), network.getDataCenterId()).getVlanId();
+            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();
@@ -956,6 +978,8 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
                         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());
                 }
@@ -1197,13 +1221,19 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
             return 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;
-        }
+        HostVO externalLoadBalancer = null;
 
-        HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId());
+        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);
 
@@ -1253,7 +1283,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
                 LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply.toArray(new LoadBalancerTO[numLoadBalancersForCommand]);
                 // LoadBalancerConfigCommand cmd = new
                 // LoadBalancerConfigCommand(loadBalancersForCommand, null);
-                HealthCheckLBConfigCommand cmd = new HealthCheckLBConfigCommand(loadBalancersForCommand);
+                HealthCheckLBConfigCommand cmd = new HealthCheckLBConfigCommand(loadBalancersForCommand, network.getId());
                 long guestVlanTag = Integer.parseInt(BroadcastDomainType.getValue(network.getBroadcastUri()));
                 cmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, String.valueOf(guestVlanTag));
 
@@ -1280,4 +1310,5 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
         }
         return null;
     }
+
 }
diff --git a/server/src/com/cloud/network/IpAddressManagerImpl.java b/server/src/com/cloud/network/IpAddressManagerImpl.java
index d950cc4..f3584d1 100644
--- a/server/src/com/cloud/network/IpAddressManagerImpl.java
+++ b/server/src/com/cloud/network/IpAddressManagerImpl.java
@@ -52,7 +52,6 @@ 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.DomainVlanMapVO;
 import com.cloud.dc.DataCenterIpAddressVO;
 import com.cloud.dc.HostPodVO;
 import com.cloud.dc.Pod;
@@ -287,6 +286,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
     VpcDao _vpcDao;
     @Inject
     DataCenterIpAddressDao _privateIPAddressDao;
+    @Inject
     HostPodDao _hpDao;
 
     SearchBuilder<IPAddressVO> AssignIpAddressSearch;
@@ -1024,9 +1024,9 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
 
     @DB
     @Override
-    public AcquirePodIpCmdResponse allocatePodIp(Long zoneId, String cidr) throws ConcurrentOperationException, ResourceAllocationException {
+    public AcquirePodIpCmdResponse allocatePodIp(String zoneId, String podId) throws ConcurrentOperationException, ResourceAllocationException {
 
-        DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
+        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(),
@@ -1035,15 +1035,18 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
         }
 
         DataCenterIpAddressVO vo = null;
-        if (cidr != null) {
-            List<HostPodVO> pod_list = _hpDao.listAllPodsByCidr(zoneId, cidr);
-            if (pod_list.get(0) == null)
-                throw new ResourceAllocationException("No sush pod exists", ResourceType.network);
-            vo = _privateIPAddressDao.takeIpAddress(zoneId, pod_list.get(0).getId(), 0, caller.getId() + "");
-            if (vo.getIpAddress() == null)
-                throw new ResourceAllocationException("Unable to allocate IP from this Pod", ResourceType.network);
-        } else
-            vo = _privateIPAddressDao.takeDataCenterIpAddress(zoneId, caller.getId() + "");
+        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() + "");
+        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();
@@ -1956,7 +1959,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                 boolean ipv4 = false;
 
                 if (network.getGateway() != null) {
-                    if (nic.getIp4Address() == null) {
+                    if (nic.getIPv4Address() == null) {
                         ipv4 = true;
                         PublicIp ip = null;
 
@@ -1964,9 +1967,9 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                         if (requestedIpv4 != null && vm.getType() == VirtualMachine.Type.DomainRouter) {
                             Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, null);
                             if (placeholderNic != null) {
-                                IPAddressVO userIp = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), placeholderNic.getIp4Address());
+                                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.getIp4Address() + " stored in placeholder nic for the network " + network);
+                                s_logger.debug("Nic got an ip address " + placeholderNic.getIPv4Address() + " stored in placeholder nic for the network " + network);
                             }
                         }
 
@@ -1974,12 +1977,10 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                             ip = assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.DirectAttached, network.getId(), requestedIpv4, false);
                         }
 
-                        nic.setIp4Address(ip.getAddress().toString());
-                        nic.setGateway(ip.getGateway());
-                        nic.setNetmask(ip.getNetmask());
+                        nic.setIPv4Address(ip.getAddress().toString());
+                        nic.setIPv4Gateway(ip.getGateway());
+                        nic.setIPv4Netmask(ip.getNetmask());
                         nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag()));
-                        //nic.setBroadcastType(BroadcastDomainType.Vlan);
-                        //nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag()));
                         nic.setBroadcastType(network.getBroadcastDomainType());
                         if (network.getBroadcastUri() != null)
                             nic.setBroadcastUri(network.getBroadcastUri());
@@ -1989,18 +1990,18 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                         nic.setReservationId(String.valueOf(ip.getVlanTag()));
                         nic.setMacAddress(ip.getMacAddress());
                     }
-                    nic.setDns1(dc.getDns1());
-                    nic.setDns2(dc.getDns2());
+                    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.getIp6Address() == null) {
+                    if (nic.getIPv6Address() == null) {
                         UserIpv6Address ip = _ipv6Mgr.assignDirectIp6Address(dc.getId(), vm.getOwner(), network.getId(), requestedIpv6);
                         Vlan vlan = _vlanDao.findById(ip.getVlanId());
-                        nic.setIp6Address(ip.getAddress().toString());
-                        nic.setIp6Gateway(vlan.getIp6Gateway());
-                        nic.setIp6Cidr(vlan.getIp6Cidr());
+                        nic.setIPv6Address(ip.getAddress().toString());
+                        nic.setIPv6Gateway(vlan.getIp6Gateway());
+                        nic.setIPv6Cidr(vlan.getIp6Cidr());
                         if (ipv4) {
                             nic.setFormat(AddressFormat.DualStack);
                         } else {
@@ -2012,8 +2013,8 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
                             nic.setMacAddress(ip.getMacAddress());
                         }
                     }
-                    nic.setIp6Dns1(dc.getIp6Dns1());
-                    nic.setIp6Dns2(dc.getIp6Dns2());
+                    nic.setIPv6Dns1(dc.getIp6Dns1());
+                    nic.setIPv6Dns2(dc.getIp6Dns2());
                 }
             }
         });
diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java
index 26ad1db..0495606 100644
--- a/server/src/com/cloud/network/NetworkServiceImpl.java
+++ b/server/src/com/cloud/network/NetworkServiceImpl.java
@@ -42,6 +42,7 @@ 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;
@@ -50,6 +51,7 @@ 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;
@@ -4210,4 +4212,27 @@ public class NetworkServiceImpl extends ManagerBase implements  NetworkService {
         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/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
index 5e19ad7..099a274 100644
--- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
+++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
@@ -875,13 +875,10 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
                     for (LoadBalancerVO lb : rules) {
                         List<LbDestination> dstList = getExistingDestinations(lb.getId());
                         List<LbHealthCheckPolicy> hcPolicyList = getHealthCheckPolicies(lb.getId());
-                        // adding to lbrules list only if the LB rule
-                        // hashealtChecks
-                        if (hcPolicyList != null && hcPolicyList.size() > 0) {
-                            Ip sourceIp = getSourceIp(lb);
-                            LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, null, hcPolicyList, sourceIp, null, lb.getLbProtocol());
-                            lbrules.add(loadBalancing);
-                        }
+                        // 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;
@@ -2124,10 +2121,11 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
             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) {
+        if ((algorithm!= null) && (tmplbVo.getAlgorithm().compareTo(algorithm)!=0)){
             try {
                 lb.setState(FirewallRule.State.Add);
                 _lbDao.persist(lb);
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index c20039a..b14086a 100644
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -48,8 +48,10 @@ 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;
@@ -3019,6 +3021,9 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
         cmdList.add(ChangeOutOfBandManagementPasswordCmd.class);
         cmdList.add(GetUserKeysCmd.class);
 
+        cmdList.add(AcquirePodIpCmdByAdmin.class);
+        cmdList.add(ReleasePodIpCmdByAdmin.class);
+
         return cmdList;
     }
 
diff --git a/server/src/org/apache/cloudstack/network/ssl/CertServiceImpl.java b/server/src/org/apache/cloudstack/network/ssl/CertServiceImpl.java
index 9da9bdd..68e84fb 100644
--- a/server/src/org/apache/cloudstack/network/ssl/CertServiceImpl.java
+++ b/server/src/org/apache/cloudstack/network/ssl/CertServiceImpl.java
@@ -123,6 +123,7 @@ public class CertServiceImpl implements CertService {
         final String key = certCmd.getKey();
         final String password = certCmd.getPassword();
         final String chain = certCmd.getChain();
+        final String name = certCmd.getName();
 
         validate(cert, key, password, chain);
         s_logger.debug("Certificate Validation succeeded");
@@ -142,7 +143,7 @@ public class CertServiceImpl implements CertService {
         final Long accountId = owner.getId();
         final Long domainId = owner.getDomainId();
 
-        final SslCertVO certVO = new SslCertVO(cert, key, password, chain, accountId, domainId, fingerPrint);
+        final SslCertVO certVO = new SslCertVO(cert, key, password, chain, accountId, domainId, fingerPrint, name);
         _sslCertDao.persist(certVO);
 
         return createCertResponse(certVO, null);
@@ -325,10 +326,10 @@ public class CertServiceImpl implements CertService {
         response.setId(cert.getUuid());
         response.setCertificate(cert.getCertificate());
         response.setFingerprint(cert.getFingerPrint());
+        response.setName(cert.getName());
 
-        if (cert.getChain() != null) {
+        if (cert.getChain() != null)
             response.setCertchain(cert.getChain());
-        }
 
         if (lbCertMap != null && !lbCertMap.isEmpty()) {
             final List<String> lbIds = new ArrayList<String>();
diff --git a/server/test/com/cloud/network/ExternalLoadBalancerDeviceManagerImplTest.java b/server/test/com/cloud/network/ExternalLoadBalancerDeviceManagerImplTest.java
index dbc31ba..47c3250 100644
--- a/server/test/com/cloud/network/ExternalLoadBalancerDeviceManagerImplTest.java
+++ b/server/test/com/cloud/network/ExternalLoadBalancerDeviceManagerImplTest.java
@@ -61,16 +61,21 @@ 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.VirtualRouterProviderDao;
 import com.cloud.network.lb.LoadBalancingRule;
 import com.cloud.network.rules.dao.PortForwardingRulesDao;
 import com.cloud.offerings.dao.NetworkOfferingDao;
 import com.cloud.resource.ResourceManager;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.dao.VMTemplateDao;
 import com.cloud.user.AccountManager;
 import com.cloud.user.dao.AccountDao;
 import com.cloud.user.dao.UserStatisticsDao;
 import com.cloud.utils.net.Ip;
+import com.cloud.vm.VirtualMachineManager;
 import com.cloud.vm.dao.DomainRouterDao;
 import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.VMInstanceDao;
 
 @RunWith(MockitoJUnitRunner.class)
 public class ExternalLoadBalancerDeviceManagerImplTest {
@@ -135,9 +140,20 @@ public class ExternalLoadBalancerDeviceManagerImplTest {
     protected HostPodDao _podDao = null;
     @Mock
     IpAddressManager _ipAddrMgr;
-
+    @Mock
+    protected VirtualMachineManager _itMgr;
     @Mock
     Network network;
+    @Mock
+    VMInstanceDao _vmDao;
+    @Mock
+    VMTemplateDao _templateDao;
+    @Mock
+    ServiceOfferingDao _serviceOfferingDao;
+    @Mock
+    PhysicalNetworkServiceProviderDao _physicalProviderDao;
+    @Mock
+    VirtualRouterProviderDao _vrProviderDao;
 
     @Mock
     LoadBalancingRule rule;
@@ -192,6 +208,7 @@ public class ExternalLoadBalancerDeviceManagerImplTest {
 
     private void setupLBHealthChecksMocks() throws URISyntaxException {
         Mockito.when(network.getId()).thenReturn(42l);
+        Mockito.when(network.getNetworkOfferingId()).thenReturn(1l);
         Mockito.when(network.getBroadcastUri()).thenReturn(new URI("vlan://1"));
         NetworkExternalLoadBalancerVO externalLb = Mockito
                 .mock(NetworkExternalLoadBalancerVO.class);
diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
index 75c181f..495989d 100644
--- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
+++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
@@ -25,6 +25,7 @@ import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
 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;
@@ -32,6 +33,7 @@ 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 org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
@@ -72,6 +74,7 @@ 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;
@@ -907,30 +910,17 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches
     }
 
     @Override
-<<<<<<< db052a96b18391ae5f972960d1f496f5396b8684
     public List<? extends NicSecondaryIp> listVmNicSecondaryIps(ListNicsCmd listNicsCmd) {
         return null;
-=======
-    public AcquirePodIpCmdResponse allocatePodIp(Account ipOwner, long zoneId, String cidr) throws ResourceAllocationException, ConcurrentOperationException {
-
-        Account caller = CallContext.current().getCallingAccount();
-        long callerUserId = CallContext.current().getCallingUserId();
-        DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
-
-        if (zone == null)
-            throw new InvalidParameterValueException("Invalid zone Id is Null");
-        if (_accountMgr.checkAccessAndSpecifyAuthority(caller, zoneId) != zoneId)
-            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, cidr);
     }
 
     @Override
     public boolean releasePodIp(ReleasePodIpCmdByAdmin ip) throws CloudRuntimeException {
-        _ipAddrMgr.releasePodIp(ip.getId());
         return true;
->>>>>>> CLOUDSTACK-8672 : NCC Integration with CloudStack.
     }
 
+    @Override
+    public AcquirePodIpCmdResponse allocatePodIp(Account account, String zoneId, String podId) throws ResourceAllocationException, ConcurrentOperationException {
+        return null;
+    }
 }
diff --git a/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java b/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java
index 757b024..b0440f2 100644
--- a/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java
+++ b/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java
@@ -381,4 +381,10 @@ public class MockNetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implemen
     public int getNonSystemNetworkCountByVpcId(final long vpcId) {
         return 0;
     }
+
+    @Override
+    public List<NetworkVO> listNetworkVO(List<Long> idset) {
+        // TODO Auto-generated method stub
+        return null;
+    }
 }
diff --git a/tools/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py
index 0fd9775..a261037 100644
--- a/tools/apidoc/gen_toc.py
+++ b/tools/apidoc/gen_toc.py
@@ -171,6 +171,16 @@ known_categories = {
     'StratosphereSsp' : ' Stratosphere SSP',
     'Metrics' : 'Metrics',
     'Infrastructure' : 'Metrics',
+    'listNetscalerControlCenter' : 'Load Balancer',
+    'listRegisteredServicePackages': 'Load Balancer',
+    'listNsVpx' : 'Load Balancer',
+    'destroyNsVPx': 'Load Balancer',
+    'deployNetscalerVpx' : 'Load Balancer',
+    'deleteNetscalerControlCenter' : 'Load Balancer',
+    'stopNetScalerVpx' : 'Load Balancer',
+    'deleteServicePackageOffering' : 'Load Balancer',
+    'destroyNsVpx' : 'Load Balancer',
+    'startNsVpx' : 'Load Balancer'
     }
 
 
diff --git a/ui/index.html b/ui/index.html
index 41894a6..6cc7db9 100644
--- a/ui/index.html
+++ b/ui/index.html
@@ -1837,6 +1837,7 @@
         <script type="text/javascript" src="scripts/ui-custom/projects.js"></script>
         <script type="text/javascript" src="scripts/cloudStack.js"></script>
         <script type="text/javascript" src="scripts/lbStickyPolicy.js"></script>
+        <script type="text/javascript" src="scripts/lbCertificatePolicy.js"></script>
         <script type="text/javascript" src="scripts/ui-custom/autoscaler.js"></script>
         <script type="text/javascript" src="scripts/ui-custom/healthCheck.js"></script>
         <script type="text/javascript" src="scripts/autoscaler.js"></script>
diff --git a/ui/l10n/en.js b/ui/l10n/en.js
index 125e96d..bd6ac0a 100644
--- a/ui/l10n/en.js
+++ b/ui/l10n/en.js
@@ -254,6 +254,7 @@ var dictionary = {"ICMP.code":"ICMP Code",
 "label.action.reboot.systemvm.processing":"Rebooting System VM....",
 "label.action.recurring.snapshot":"Recurring Snapshots",
 "label.action.register.iso":"Register ISO",
+"label.action.register.ncc":"Register NCC",
 "label.action.register.template":"Register Template from URL",
 "label.action.release.ip":"Release IP",
 "label.action.release.ip.processing":"Releasing IP....",
@@ -318,6 +319,7 @@ var dictionary = {"ICMP.code":"ICMP Code",
 "label.add.by":"Add by",
 "label.add.by.cidr":"Add By CIDR",
 "label.add.by.group":"Add By Group",
+"label.add.certificate":"Add Certificate",
 "label.add.ciscoASA1000v":"Add CiscoASA1000v Resource",
 "label.add.cluster":"Add Cluster",
 "label.add.compute.offering":"Add compute offering",
@@ -502,6 +504,10 @@ var dictionary = {"ICMP.code":"ICMP Code",
 "label.capacity.bytes":"Capacity Bytes",
 "label.capacity.iops":"Capacity IOPS",
 "label.certificate":"Server certificate",
+"label.certificate.details":"Certificate Details",
+"label.certificate.name":"Certificate",
+"label.certificateid":"Certificate ID",
+"label.chain":"Chain",
 "label.change.affinity":"Change Affinity",
 "label.change.ipaddress":"Change IP address for NIC",
 "label.change.service.offering":"Change service offering",
@@ -617,6 +623,7 @@ var dictionary = {"ICMP.code":"ICMP Code",
 "label.delete.project":"Delete project",
 "label.delete.role":"Delete Role",
 "label.delete.secondary.staging.store":"Delete Secondary Staging Store",
+"label.delete.sslcertificate":"Delete SSL Certificate",
 "label.delete.ucs.manager":"Delete UCS Manager",
 "label.delete.vpn.user":"Delete VPN user",
 "label.deleting.failed":"Deleting Failed",
@@ -941,6 +948,10 @@ var dictionary = {"ICMP.code":"ICMP Code",
 "label.lb.algorithm.leastconn":"Least connections",
 "label.lb.algorithm.roundrobin":"Round-robin",
 "label.lb.algorithm.source":"Source",
+"label.lb.protocol.http":"HTTP",
+"label.lb.protocol.ssl":"SSL",
+"label.lb.protocol.tcp":"TCP",
+"label.lb.protocol.udp":"UDP",
 "label.ldap.configuration":"LDAP Configuration",
 "label.ldap.group.name":"LDAP Group",
 "label.ldap.link.type":"Type",
@@ -1101,9 +1112,14 @@ var dictionary = {"ICMP.code":"ICMP Code",
 "label.name.lower":"name",
 "label.name.optional":"Name (Optional)",
 "label.nat.port.range":"NAT Port Range",
+"label.ncc":"NCC",
+"label.ncc.delete":"Delete NCC",
+"label.ncc.details":"NCC Details",
 "label.netScaler":"NetScaler",
 "label.netmask":"Netmask",
 "label.netscaler.details":"NetScaler details",
+"label.netscaler.service.packages":"Netscaler Service Packages",
+"label.netscaler.service.packages.description":"Service Package Description",
 "label.network":"Network",
 "label.network.ACL":"Network ACL",
 "label.network.ACL.total":"Network ACL Total",
@@ -1263,6 +1279,8 @@ var dictionary = {"ICMP.code":"ICMP Code",
 "label.private.port":"Private Port",
 "label.private.zone":"Private Zone",
 "label.privatekey":"PKCS#8 Private Key",
+"label.privatekey.name":"Private Key",
+"label.privatekey.password":"Private Key Password",
 "label.profile":"Profile",
 "label.project":"Project",
 "label.project.dashboard":"Project dashboard",
@@ -1520,6 +1538,7 @@ var dictionary = {"ICMP.code":"ICMP Code",
 "label.ssh.key.pair":"SSH Key Pair",
 "label.ssh.key.pair.details":"SSH Key Pair Details",
 "label.ssh.key.pairs":"SSH Key Pairs",
+"label.sslcertificates":"SSL Certificates",
 "label.standard.us.keyboard":"Standard (US) keyboard",
 "label.start.IP":"Start IP",
 "label.start.lb.vm":"Start LB VM",
@@ -1667,6 +1686,7 @@ var dictionary = {"ICMP.code":"ICMP Code",
 "label.username":"Username",
 "label.username.lower":"username",
 "label.users":"Users",
+"label.uuid":"UUID",
 "label.vSwitch.type":"vSwitch Type",
 "label.value":"Value",
 "label.vcdcname":"vCenter DC name",
@@ -2020,6 +2040,7 @@ var dictionary = {"ICMP.code":"ICMP Code",
 "message.delete.affinity.group":"Please confirm that you would like to remove this affinity group.",
 "message.delete.gateway":"Please confirm you want to delete the gateway",
 "message.delete.project":"Are you sure you want to delete this project?",
+"message.delete.sslcertificate":"Please confirm that you would like to delete this certificate.",
 "message.delete.user":"Please confirm that you would like to delete this user.",
 "message.desc.add.new.lb.sticky.rule":"Add new LB sticky rule",
 "message.desc.advanced.zone":"For more sophisticated network topologies. This network model provides the most flexibility in defining guest networks and providing custom network offerings such as firewall, VPN, or load balancer support.",
@@ -2122,6 +2143,7 @@ var dictionary = {"ICMP.code":"ICMP Code",
 "message.migrate.router.confirm":"Please confirm the host you wish to migrate the router to:",
 "message.migrate.systemvm.confirm":"Please confirm the host you wish to migrate the system VM to:",
 "message.migrate.volume":"Please confirm that you want to migrate volume to another primary storage.",
+"message.ncc.delete.confirm":"Please confirm you want to delete this NCC",
 "message.network.addVM.desc":"Please specify the network that you would like to add this VM to. A new NIC will be added for this network.",
 "message.network.addVMNIC":"Please confirm that you would like to add a new VM NIC for this network.",
 "message.network.remote.access.vpn.configuration":"Remote Access VPN configuration has been generated, but it failed to apply. Please check connectivity of the network element, then re-try.",
@@ -2165,6 +2187,8 @@ var dictionary = {"ICMP.code":"ICMP Code",
 "message.read.admin.guide.scaling.up":"Please read the dynamic scaling section in the admin guide before scaling up.",
 "message.recover.vm":"Please confirm that you would like to recover this VM.",
 "message.redirecting.region":"Redirecting to region...",
+"message.register.failed":"Registration Failed",
+"message.register.succeeded":"Registration Succeeded",
 "message.reinstall.vm":"NOTE: Proceed with caution. This will cause the VM to be reinstalled from the template; data on the root disk will be lost. Extra data volumes, if any, will not be touched.",
 "message.remove.ldap":"Are you sure you want to delete the LDAP configuration?",
 "message.remove.region":"Are you sure you want to remove this region from this management server?",
diff --git a/ui/scripts/accounts.js b/ui/scripts/accounts.js
index 62cc625..439683f 100644
--- a/ui/scripts/accounts.js
+++ b/ui/scripts/accounts.js
@@ -895,6 +895,199 @@
                                 }
                             },
 
+                            sslCertificates: {
+                                title: 'label.sslcertificates',
+                                listView: {
+                                    id: 'sslCertificates',
+                                    
+                                    fields: {
+                                        name: {
+                                            label: 'label.name'
+                                        },
+                                        id: {
+                                            label: 'label.certificateid'
+                                        }
+                                    },
+                                    
+                                    dataProvider: function(args) {
+                                        var data = {};
+                                        listViewDataProvider(args, data);
+                                        if (args.context != null) {
+                                            if ("accounts" in args.context) {
+                                                $.extend(data, {
+                                                    accountid: args.context.accounts[0].id
+                                                });
+                                            }
+                                        }
+                                        $.ajax({
+                                            url: createURL('listSslCerts'),
+                                            data: data,
+                                            success: function(json) {
+                                                var items = json.listsslcertsresponse.sslcert;
+                                                args.response.success({
+                                                    data: items
+                                                });
+                                            }
+                                        });
+                                    },
+                                    
+                                    actions: {
+                                        add: {
+                                            label: 'label.add.certificate',
+
+                                            messages: {
+                                                notification: function(args) {
+                                                    return 'label.add.certificate';
+                                                }
+                                            },
+
+                                            createForm: {
+                                                title: 'label.add.certificate',
+                                                fields: {
+                                                    name: {
+                                                        label: 'label.name',
+                                                        validation: {
+                                                            required: true
+                                                        }
+                                                    },
+                                                    certificate: {
+                                                        label: 'label.certificate.name',
+                                                        isTextarea: true,
+                                                        validation: {
+                                                            required: true
+                                                        },
+                                                    },
+                                                    privatekey: {
+                                                        label: 'label.privatekey.name',
+                                                        isTextarea: true,
+                                                        validation: {
+                                                            required: true
+                                                        }
+                                                    },
+                                                    certchain: {
+                                                        label: "label.chain",
+                                                        isTextarea: true,
+                                                        validation: {
+                                                            required: false
+                                                        }
+                                                    },
+                                                    password: {
+                                                        label: "label.privatekey.password",
+                                                        isPassword: true,
+                                                        validation: {
+                                                            required: false
+                                                        }
+                                                    }
+                                                }
+                                            },
+
+                                            action: function(args) {
+                                                var data = {
+                                                    name: args.data.name,
+                                                    certificate: args.data.certificate,
+                                                    privatekey: args.data.privatekey
+                                                };
+
+                                                if (args.data.certchain != null && args.data.certchain.length > 0) {
+                                                    $.extend(data, {
+                                                        certchain: args.data.certchain
+                                                    });
+                                                }
+
+                                                if (args.data.password != null && args.data.password.length > 0) {
+                                                    $.extend(data, {
+                                                        password: args.data.password
+                                                    });
+                                                }
+
+                                                $.ajax({
+                                                    url: createURL('uploadSslCert'),
+                                                    data: data,
+                                                    success: function(json) {
+                                                        var item = json.uploadsslcertresponse.sslcert;
+                                                        args.response.success({
+                                                            data: item
+                                                        });
+                                                    },
+                                                    error: function(json) {
+                                                        args.response.error(parseXMLHttpResponse(json));
+                                                    }
+                                                });
+                                            }
+                                        }
+                                    },
+                                    
+                                    detailView: {
+                                        actions: {
+                                            remove: {
+                                                label: 'label.delete.sslcertificate',
+                                                messages: {
+                                                    confirm: function(args) {
+                                                        return 'message.delete.sslcertificate';
+                                                    },
+                                                    notification: function(args) {
+                                                        return 'label.delete.sslcertificate';
+                                                    }
+                                                },
+                                                action: function(args) {
+                                                    $.ajax({
+                                                        url: createURL('deleteSslCert'),
+                                                        data: {
+                                                            id: args.context.sslCertificates[0].id
+                                                        },
+                                                        success: function(json) {
+                                                            var items = json.deletesslcertresponse.sslcert;
+                                                            args.response.success({
+                                                                data: items
+                                                            });
+                                                        }
+                                                    });
+                                                }
+                                            }
+                                        },
+
+                                        tabs: {
+                                            details: {
+                                                title: 'label.certificate.details',
+                                                fields: {
+                                                    name: {
+                                                        label: 'label.name'
+                                                    },
+                                                    certificate: {
+                                                        label: 'label.certificate.name'
+                                                    },
+                                                    certchain: {
+                                                        label: 'label.chain'
+                                                    }
+                                                },
+
+                                                dataProvider: function(args) {
+                                                    var data = {};
+                                                
+                                                    if (args.context != null) {
+                                                        if ("sslCertificates" in args.context) {
+                                                            $.extend(data, {
+                                                                certid: args.context.sslCertificates[0].id
+                                                            });
+                                                        }
+                                                    }
+                                                    $.ajax({
+                                                        url: createURL('listSslCerts'),
+                                                        data: data,
+                                                        success: function(json) {
+                                                            var items = json.listsslcertsresponse.sslcert[0];
+                                                            args.response.success({
+                                                                data: items
+                                                            });
+                                                        }
+                                                    });
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            },
+
                             // Granular settings for account
                             settings: {
                                 title: 'label.settings',
diff --git a/ui/scripts/configuration.js b/ui/scripts/configuration.js
index 512ccf7..921735b 100644
--- a/ui/scripts/configuration.js
+++ b/ui/scripts/configuration.js
@@ -2639,11 +2639,17 @@
                                             args.$form.find('.form-item[rel=\"egressdefaultpolicy\"]').css('display', 'none');
                                         }
 
-                                        //show LB Isolation dropdown only when (1)LB Service is checked (2)Service Provider is Netscaler OR F5
-                                        if ((args.$form.find('.form-item[rel=\"service.Lb.isEnabled\"]').find('input[type=checkbox]').is(':checked') == true) && (args.$form.find('.form-item[rel=\"service.Lb.provider\"]').find('select').val() == 'Netscaler' || args.$form.find('.form-item[rel=\"service.Lb.provider\"]').find('select').val() == 'F5BigIp')) {
-                                            args.$form.find('.form-item[rel=\"service.Lb.lbIsolationDropdown\"]').css('display', 'inline-block');
+                                        //show Netscaler service packages only when (1)LB Service is checked (2)Service Provider is Netscaler
+                                        if ((args.$form.find('.form-item[rel=\"service.Lb.isEnabled\"]').find('input[type=checkbox]').is(':checked') == true) && (args.$form.find('.form-item[rel=\"service.Lb.provider\"]').find('select').val() == 'Netscaler')) {
+                                            args.$form.find('.form-item[rel=\"service.Lb.Netscaler.servicePackages\"]').css('display', 'inline-block');
+                                            args.$form.find('.form-item[rel=\"service.Lb.Netscaler.servicePackages.description\"]').css('display', 'inline-block');
+                                            args.$form.find('.form-item[rel=\"service.Lb.Netscaler.servicePackages.description\"]').find("#label_netscaler_service_packages_description").attr("disabled", "disabled");
+                                            args.$form.find('.form-item[rel=\"service.Lb.Netscaler.servicePackages.description\"]').find("#label_netscaler_service_packages_description").text(args.$form.find('.form-item[rel=\"service.Lb.Netscaler.servicePackages\"]').find('#label_netscaler_service_packages option:selected').data("json-obj").desc);
                                         } else {
-                                            args.$form.find('.form-item[rel=\"service.Lb.lbIsolationDropdown\"]').hide();
+                                            args.$form.find('.form-item[rel=\"service.Lb.Netscaler.servicePackages\"]').hide();
+                                            args.$form.find('.form-item[rel=\"service.Lb.Netscaler.servicePackages.description\"]').hide();
+                                            args.$form.find('.form-item[rel=\"service.Lb.Netscaler.servicePackages.description\"]').find("#label_netscaler_service_packages_description").attr("disabled", "disabled");
+                                            args.$form.find('.form-item[rel=\"service.Lb.Netscaler.servicePackages.description\"]').find("#label_netscaler_service_packages_description").text("");
                                         }
 
                                         //show Elastic LB checkbox only when (1)LB Service is checked (2)Service Provider is Netscaler (3)Guest IP Type is Shared
@@ -3014,22 +3020,7 @@
                                         isHidden: true,
                                         isBoolean: true
                                     },
-                                    "service.Lb.lbIsolationDropdown": {
-                                        label: 'label.LB.isolation',
-                                        docID: 'helpNetworkOfferingLBIsolation',
-                                        isHidden: true,
-                                        select: function(args) {
-                                            args.response.success({
-                                                data: [{
-                                                    id: 'dedicated',
-                                                    description: 'Dedicated'
-                                                }, {
-                                                    id: 'shared',
-                                                    description: 'Shared'
-                                                }]
-                                            })
-                                        }
-                                    },
+
                                     "service.Lb.inlineModeDropdown": {
                                         label: 'label.mode',
                                         docID: 'helpNetworkOfferingMode',
@@ -3049,6 +3040,62 @@
                                         }
                                     },
 
+                                    "service.Lb.Netscaler.servicePackages": {
+                                        label: 'label.netscaler.service.packages',
+                                        docID: 'helpNetscalerServicePackages',
+                                        isHidden: true,
+                                        select: function(args) {
+                                            $.ajax({
+                                                url: createURL('listRegisteredServicePackages'),
+                                                dataType: 'json',
+                                                async: true,
+                                                success: function(data) {
+                                                    var servicePackages = data.listregisteredservicepackage.registeredServicepackage;
+
+                                                    if (servicePackages == undefined || servicePackages == null || !servicePackages) {
+                                                        servicePackages = data.listregisteredservicepackage;
+                                                    }
+
+                                                    args.response.success({
+                                                        data:   $.map(servicePackages, function(elem) {
+                                                            return {
+                                                                id: elem.id,
+                                                                description: elem.name,
+                                                                desc: elem.description
+                                                            };
+                                                        })
+                                                    });
+                                                },
+                                                error: function(data) {
+                                                    args.response.error(parseXMLHttpResponse(data));
+                                                }
+                                            });
+                                        }
+                                    },
+
+                                    "service.Lb.Netscaler.servicePackages.description": {
+                                        label: 'label.netscaler.service.packages.description',
+                                        isHidden: true,
+                                        isTextarea: true
+                                    },
+
+                                    "service.Lb.lbIsolationDropdown": {
+                                        label: 'label.LB.isolation',
+                                        docID: 'helpNetworkOfferingLBIsolation',
+                                        isHidden: true,
+                                        select: function(args) {
+                                            args.response.success({
+                                                data: [{
+                                                    id: 'dedicated',
+                                                    description: 'Dedicated'
+                                                }, {
+                                                    id: 'shared',
+                                                    description: 'Shared'
+                                                }]
+                                            })
+                                        }
+                                    },
+
                                     "service.StaticNat.elasticIpCheckbox": {
                                         label: "label.elastic.IP",
                                         isHidden: true,
@@ -3129,6 +3176,12 @@
                                 $.each(formData, function(key, value) {
                                     var serviceData = key.split('.');
 
+                                    if (key == 'service.Lb.Netscaler.servicePackages' && value != "") {
+                                       inputData['details[' + 0 + '].servicepackageuuid'] = value;
+                                       inputData['details[' + 1 + '].servicepackagedescription'] = args.$form.find('#label_netscaler_service_packages option:selected').data().jsonObj.desc;
+                                    }
+
+
                                     if (serviceData.length > 1) {
                                         if (serviceData[0] == 'service' &&
                                             serviceData[2] == 'isEnabled' &&
diff --git a/ui/scripts/docs.js b/ui/scripts/docs.js
index 938514f..2908e8b 100755
--- a/ui/scripts/docs.js
+++ b/ui/scripts/docs.js
@@ -568,6 +568,10 @@ cloudStack.docs = {
         desc: 'Number of guest networks/accounts that will share this device',
         externalLink: ''
     },
+    helpNetscalerServicePackages: {
+        desc: 'Choose the Netscaler Service Package you want to use.',
+        externalLink: ''
+    },
     // Add network offering
     helpNetworkOfferingName: {
         desc: 'Any desired name for the network offering',
diff --git a/ui/scripts/lbCertificatePolicy.js b/ui/scripts/lbCertificatePolicy.js
new file mode 100644
index 0000000..538e33d
--- /dev/null
+++ b/ui/scripts/lbCertificatePolicy.js
@@ -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.
+
+(function($, cloudStack) {
+    cloudStack.lbCertificatePolicy = {
+        dialog: function(args) {
+            return function(args) {
+                var success = args.response.success;
+                var context = args.context;
+
+                var certid = {
+                    certificate: {
+                        label: 'label.certificate.name',
+                        select: function(args) {
+                            var data = {};
+                            var item = {};
+
+                            if (context != null) {
+                                if (context.networks != null) {
+                                    $.extend(data, {account: context.networks[0].account});
+                                    $.extend(data, {domain: context.networks[0].domain});
+                                }
+                            }
+
+                            $.ajax({
+                                url: createURL('listAccounts'),
+                                async: false,
+                                data: data,
+                                success: function(json) {
+                                    var items = json.listaccountsresponse.account;
+                                    $.extend(item, {accountid: items[0].id});
+                                }
+                            });
+
+                            $.ajax({
+                                url: createURL('listSslCerts'),
+                                async: false,
+                                data: item,
+                                success: function(json) {
+                                    var items = json.listsslcertsresponse.sslcert;
+                                    args.response.success({
+                                        data: $.map(items, function(item) {
+                                                return {
+                                                    id: item.id,
+                                                    description: item.id
+                                                };
+                                            })
+                                    });
+                                }
+                            });
+                        }
+                    }
+                };
+
+                var $item = args.$item;
+
+                cloudStack.dialog.createForm({
+                    form: {
+                        title: 'Configure Certificate',
+                        desc: 'Please complete the following fields',
+                        fields: certid
+                    },
+                    after: function(args) {
+                        // Remove fields not applicable to sticky method
+                        args.$form.find('.form-item:hidden').remove();
+
+                        var data = cloudStack.serializeForm(args.$form);
+
+                        /* $item indicates that this is an existing sticky rule;
+               re-create sticky rule with new parameters */
+                        if ($item) {
+                            var $loading = $('<div>').addClass('loading-overlay');
+
+                            $loading.prependTo($item);
+                            cloudStack.lbStickyPolicy.actions.recreate(
+                                $item.data('multi-custom-data').id,
+                                $item.data('multi-custom-data').lbRuleID,
+                                data,
+                                function() { // Complete
+                                    $(window).trigger('cloudStack.fullRefresh');
+                                },
+                                function(error) { // Error
+                                    $(window).trigger('cloudStack.fullRefresh');
+                                }
+                            );
+                        } else {
+                            success({
+                                data: data
+                            });
+                        }
+                    }
+                });
+            };
+        },
+
+        actions: {
+            add: function(lbRuleID, data, complete, error) {
+
+                $.ajax({
+                    url: createURL('assignCertToLoadBalancer'),
+                    data: {certid: data.certificate, lbruleid: lbRuleID},
+                    success: function(json) {
+                        cloudStack.ui.notifications.add({
+                                desc: 'Add new LB Certificate',
+                                section: 'Network',
+                                poll: pollAsyncJobResult,
+                                _custom: {
+                                    jobId: json.assigncerttoloadbalancerresponse.jobid
+                                }
+                            },
+                            complete, {},
+                            error, {}
+                        );
+                    },
+                    error: function(json) {
+                        complete();
+                        cloudStack.dialog.notice({
+                            message: parseXMLHttpResponse(json)
+                        });
+                    }
+                });
+            },
+            'delete': function(stickyRuleID, complete, error) {
+                $.ajax({
+                    url: createURL('deleteLBStickinessPolicy'),
+                    data: {
+                        id: stickyRuleID
+                    },
+                    success: function(json) {
+                        cloudStack.ui.notifications.add({
+                                desc: 'Remove previous LB sticky rule',
+                                section: 'Network',
+                                poll: pollAsyncJobResult,
+                                _custom: {
+                                    jobId: json.deleteLBstickinessrruleresponse.jobid
+                                }
+                            },
+                            complete, {},
+                            error, {}
+                        );
+                    },
+                    error: function(json) {
+                        complete();
+                        cloudStack.dialog.notice({
+                            message: parseXMLHttpResponse(json)
+                        });
+                    }
+                });
+            },
+            recreate: function(stickyRuleID, lbRuleID, data, complete, error) {
+                var addStickyPolicy = function() {
+                    cloudStack.lbStickyPolicy.actions.add(
+                        lbRuleID,
+                        data,
+                        complete,
+                        error
+                    );
+                };
+
+                // Delete existing rule
+                if (data.methodname !== 'None') {
+                    addStickyPolicy();
+                } else {
+                    cloudStack.lbStickyPolicy.actions['delete'](stickyRuleID, complete, error);
+                }
+            }
+        }
+    };
+}(jQuery, cloudStack));
\ No newline at end of file
diff --git a/ui/scripts/network.js b/ui/scripts/network.js
old mode 100755
new mode 100644
index 175ab4c..31f8016
--- a/ui/scripts/network.js
+++ b/ui/scripts/network.js
@@ -3025,112 +3025,6 @@
 
                                     vmDetails: cloudStack.sections.instances.listView.detailView,
 
-
-                                    //"NAT Port Range" multiEdit screen for StaticNAT is obsolete in cloudstack 3.0 because createIpForwardingRule/deleteIpForwardingRule/listIpForwardingRules API are obsolete in cloudstack 3.0.
-                                    //cloudstack 3.0 is using createFirewallRule/listFirewallRules/deleteFirewallRule API for both staticNAT and non-staticNAT .
-                                    /*
-                   staticNAT: {
-                   noSelect: true,
-                   fields: {
-                   'protocol': {
-                   label: 'label.protocol',
-                   select: function(args) {
-                   args.response.success({
-                   data: [
-                   { name: 'tcp', description: 'TCP' },
-                   { name: 'udp', description: 'UDP' }
-                   ]
-                   });
-                   }
-                   },
-                   'startport': { edit: true, label: 'label.start.port' },
-                   'endport': { edit: true, label: 'label.end.port' },
-                   'add-rule': {
-                   label: 'label.add.rule',
-                   addButton: true
-                   }
-                   },
-                   add: {
-                   label: 'label.add',
-                   action: function(args) {
-                   $.ajax({
-                   url: createURL('createIpForwardingRule'),
-                   data: $.extend(args.data, {
-                   ipaddressid: args.context.ipAddresses[0].id
-                   }),
-                   dataType: 'json',
-                   success: function(data) {
-                   args.response.success({
-                   _custom: {
-                   jobId: data.createipforwardingruleresponse.jobid
-                   },
-                   notification: {
-                   label: 'label.add.static.nat.rule',
-                   poll: pollAsyncJobResult
-                   }
-                   });
-                   },
-                   error: function(data) {
-                   args.response.error(parseXMLHttpResponse(data));
-                   }
-                   });
-                   }
-                   },
-                   actions: {
-                   destroy: {
-                   label: 'label.remove.rule',
-                   action: function(args) {
-                   $.ajax({
-                   url: createURL('deleteIpForwardingRule'),
-                   data: {
-                   id: args.context.multiRule[0].id
-                   },
-                   dataType: 'json',
-                   async: true,
-                   success: function(data) {
-                   var jobID = data.deleteipforwardingruleresponse.jobid;
-                   args.response.success({
-                   _custom: {
-                   jobId: jobID
-                   },
-                   notification: {
-                   label: 'label.remove.static.nat.rule',
-                   poll: pollAsyncJobResult
-                   }
-                   });
-                   },
-                   error: function(data) {
-                   args.response.error(parseXMLHttpResponse(data));
-                   }
-                   });
-                   }
-                   }
-                   },
-                   dataProvider: function(args) {
-                   setTimeout(function() {
-                   $.ajax({
-                   url: createURL('listIpForwardingRules'),
-                   data: {
-                   listAll: true,
-                   ipaddressid: args.context.ipAddresses[0].id
-                   },
-                   dataType: 'json',
-                   async: true,
-                   success: function(data) {
-                   args.response.success({
-                   data: data.listipforwardingrulesresponse.ipforwardingrule
-                   });
-                   },
-                   error: function(data) {
-                   args.response.error(parseXMLHttpResponse(data));
-                   }
-                   });
-                   }, 100);
-                   }
-                   },
-                   */
-
-
                                     // Load balancing rules
                                     loadBalancing: {
                                         listView: $.extend(true, {}, cloudStack.sections.instances, {
@@ -3360,6 +3254,41 @@
                                                 }
                                             },
 
+                                            'protocol': {
+                                                label: 'label.protocol',
+                                                isEditable: true,
+                                                select: function(args) {
+                                                    var data = [{
+                                                            id: 'ssl',
+                                                            name: 'ssl',
+                                                            description: _l('label.lb.protocol.ssl')
+                                                        }, {
+                                                            id: 'tcp',
+                                                            name: 'tcp',
+                                                            description: _l('label.lb.protocol.tcp')
+                                                        }, {
+                                                            id: 'udp',
+                                                            name: 'udp',
+                                                            description: _l('label.lb.protocol.udp')
+                                                        }];
+                                                    if (typeof args.context != 'undefined') {
+                                                        var lbProtocols = getLBProtocols(args.context.networks[0]);
+                                                        data = (lbProtocols.length == 0) ? data : lbProtocols;
+                                                    }
+                                                    args.response.success({
+                                                        data: data
+                                                    });
+                                                }
+                                            },
+
+                                            'sslcertificate': {
+                                                label: 'label.update.ssl',
+                                                custom: {
+                                                    buttonLabel: 'label.configure',
+                                                    action: cloudStack.lbCertificatePolicy.dialog()
+                                                }
+                                            },
+
                                             'health-check': {
                                                 label: 'label.health.check',
                                                 custom: {
@@ -3441,12 +3370,10 @@
                                                     }
                                                 }
                                             },
-
                                             'add-vm': {
                                                 label: 'label.add.vms',
                                                 addButton: true
                                             },
-
                                             'state' : {
                                                 edit: 'ignore',
                                                 label: 'label.state'
@@ -3478,11 +3405,13 @@
                                                     publicport: args.data.publicport,
                                                     openfirewall: false,
                                                     networkid: networkid,
-                                                    publicipid: args.context.ipAddresses[0].id
+                                                    publicipid: args.context.ipAddresses[0].id,
+                                                    protocol: args.data.protocol
                                                 };
 
                                                 var stickyData = $.extend(true, {}, args.data.sticky);
-
+                                                var certificateData = $.extend(true, {}, args.data.sslcertificate);
+                                                  
                                               //***** create new LB rule > Add VMs *****
                                                 $.ajax({
                                                     url: createURL('createLoadBalancerRule'),
@@ -3495,46 +3424,70 @@
                                                         var lbID = data.createloadbalancerruleresponse.id;
 
                                                         var inputData = {
-                                                            id: data.createloadbalancerruleresponse.id
-                                                        };
-
-                                                        /*
-                                                        var inputData = {
-                                                            id: data.createloadbalancerruleresponse.id,
-                                                            virtualmachineids: $.map(itemData, function(elem) {
-                                                                return elem.id;
-                                                            }).join(',')
-                                                        };
-                                                        */
-                                                        //virtualmachineids parameter has been replaced with vmidipmap parameter, so comment out the 6 lines above.
-
-
-                                                        /*
-                                                         * e.g. first VM(xxx) has two IPs(10.1.1.~), second VM(yyy) has three IPs(10.2.2.~):
-                                                         * vmidipmap[0].vmid=xxx  vmidipmap[0].vmip=10.1.1.11
-                                                         * vmidipmap[1].vmid=xxx  vmidipmap[1].vmip=10.1.1.12
-                                                         * vmidipmap[2].vmid=yyy  vmidipmap[2].vmip=10.2.2.77
-                                                         * vmidipmap[3].vmid=yyy  vmidipmap[3].vmip=10.2.2.78
-                                                         * vmidipmap[4].vmid=yyy  vmidipmap[4].vmip=10.2.2.79
-                                                         */
+                                                        	id: data.createloadbalancerruleresponse.id	
+                                                        };    
+                                                        
                                                         var selectedVMs = args.itemData;
                                                         if (selectedVMs != null) {
-                                                            var vmidipmapIndex = 0;
-                                                            for (var vmIndex = 0; vmIndex < selectedVMs.length; vmIndex++) {
-                                                                var selectedIPs = selectedVMs[vmIndex]._subselect;
-                                                                for (var ipIndex = 0; ipIndex < selectedIPs.length; ipIndex++) {
-                                                                    inputData['vmidipmap[' + vmidipmapIndex + '].vmid'] = selectedVMs[vmIndex].id;
-
-                                                                    if (args.context.ipAddresses[0].isportable) {
-                                                                        inputData['vmidipmap[' + vmidipmapIndex + '].vmip'] = selectedIPs[ipIndex].split(',')[1];
-                                                                    } else {
-                                                                        inputData['vmidipmap[' + vmidipmapIndex + '].vmip'] = selectedIPs[ipIndex];
-                                                                    }
+                                                        	var vmidipmapIndex = 0;
+                                                    		for (var vmIndex = 0; vmIndex < selectedVMs.length; vmIndex++) {      
+                                                    			var selectedIPs = selectedVMs[vmIndex]._subselect;
+                                                    			for (var ipIndex = 0; ipIndex < selectedIPs.length; ipIndex++) {
+                                                    				inputData['vmidipmap[' + vmidipmapIndex + '].vmid'] = selectedVMs[vmIndex].id;
+                                                        			
+                                                    				if (args.context.ipAddresses[0].isportable) {
+                                                        			    inputData['vmidipmap[' + vmidipmapIndex + '].vmip'] = selectedIPs[ipIndex].split(',')[1];  
+                                                        			} else {
+                                                        				inputData['vmidipmap[' + vmidipmapIndex + '].vmip'] = selectedIPs[ipIndex];
+                                                        			}
+                                                    				
+                                                    				vmidipmapIndex++;
+                                                    			}                                                			
+                                                    		}
+                                                    	}   
+                                                        
+                                                        /*$.ajax({
+                                                            url: createURL('assignCertToLoadBalancer'),
+                                                            data: {certid: certificateData.certificate, lbruleid: lbID},
+                                                            success: function(data) {
+                                                                var jobID = data.assigncerttoloadbalancerresponse.jobid;
+                                                                var lbProtocolCreated = false;
 
-                                                                    vmidipmapIndex++;
-                                                                }
+                                                                args.response.success({
+                                                                    _custom: {
+                                                                        jobId: jobID 
+                                                                    },
+                                                                    notification: {
+                                                                        label: 'label.add.certificate',
+                                                                        poll: function(args) {
+                                                                            var complete = args.complete;
+                                                                            var error = args.error;
+
+                                                                            pollAsyncJobResult({
+                                                                                _custom: {
+                                                                                    jobId: jobID
+                                                                                },
+                                                                                complete: function(args) {
+                                                                                    if (lbProtocolCreated) return;
+
+                                                                                    lbProtocolCreated = true;
+
+                                                                                    if (certificateData && certificateData.certificate) {
+                                                                                        cloudStack.lbCertificatePolicy.actions.add(lbID, certificateData, complete, error);
+                                                                                    } else {
+                                                                                        complete();
+                                                                                    }
+                                                                                },
+                                                                                error: error
+                                                                            });
+                                                                        }
+                                                                    }
+                                                                });
+                                                            },
+                                                            error: function(data) {
+                                                                args.response.error(parseXMLHttpResponse(data));
                                                             }
-                                                        }
+                                                        });*/
 
                                                         $.ajax({
                                                             url: createURL('assignToLoadBalancerRule'),
@@ -3542,6 +3495,7 @@
                                                             success: function(data) {
                                                                 var jobID = data.assigntoloadbalancerruleresponse.jobid;
                                                                 var lbStickyCreated = false;
+                                                                var lbCertificateCreated = false;
 
                                                                 args.response.success({
                                                                     _custom: {
@@ -3558,17 +3512,26 @@
                                                                                     jobId: jobID
                                                                                 },
                                                                                 complete: function(args) {
-                                                                                    if (lbStickyCreated) return;
+                                                                                    if (lbStickyCreated && lbCertificateCreated) {
+                                                                                            return;
+                                                                                    }
+
+                                                                                    if (!lbStickyCreated) {
+                                                                                        lbStickyCreated = true;
 
-                                                                                    lbStickyCreated = true;
+                                                                                        if (stickyData && stickyData.methodname && stickyData.methodname != 'None') {
+                                                                                            cloudStack.lbStickyPolicy.actions.add(lbID, stickyData, complete, error);
+                                                                                        }
+                                                                                    }
 
-                                                                                    // Create stickiness policy
-                                                                                    if (stickyData &&
-                                                                                        stickyData.methodname &&
-                                                                                        stickyData.methodname != 'None') {
-                                                                                        cloudStack.lbStickyPolicy.actions.add(lbID,
-                                                                                            stickyData,
-                                                                                            complete, error);
+                                                                                    if (!lbCertificateCreated) {
+                                                                                        lbCertificateCreated = true;
+
+                                                                                        if (certificateData && certificateData.certificate && certificateData.certificate != 'None') {
+                                                                                            cloudStack.lbCertificatePolicy.actions.add(lbID, certificateData, complete, error);
+                                                                                        } else {
+                                                                                            complete();
+                                                                                        }
                                                                                     } else {
                                                                                         complete();
                                                                                     }
@@ -3761,7 +3724,7 @@
                                                     $(loadbalancerrules).each(function() {
                                                         var lbRule = this;
                                                         var stickyData = {};
-
+                                                        var sslCertData = {};
                                                         //var lbInstances = [];
                                                         var itemData = [];
 
@@ -3822,6 +3785,21 @@
                                                             }
                                                         });
 
+                                                        // Get SSL Certificate data
+                                                        $.ajax({
+                                                            url: createURL('listSslCerts'),
+                                                            data: {
+                                                                listAll: true,
+                                                                lbruleid: lbRule.id
+                                                            },
+                                                            async: false,
+                                                            success: function(json) {
+                                                                if (json.listsslcertsresponse != null) {
+                                                                    lbRule._hideFields.push('sslcertificate');
+                                                                }
+                                                            }
+                                                        });
+
                                                         // Get instances
                                                         $.ajax({
                                                             url: createURL('listLoadBalancerRuleInstances'),
@@ -6562,4 +6540,63 @@
         }
     }
 
+    var getLBProtocols = function(networkObj) {
+        if (!networkObj || !networkObj.service) {
+            return [];
+        }
+
+        var lbService = $.grep(networkObj.service, function(service) {
+            return service.name == 'Lb';
+        })[0];
+
+        if (!lbService || !lbService.capability) {
+            return [];
+        }
+
+        var protocolCapabilities = $.grep(
+            lbService.capability,
+            function(capability) {
+                return (capability.name == 'SupportedProtocols');
+            }
+        )[0];
+
+        if (!protocolCapabilities) {
+            return [];
+        }
+
+        var protocols = protocolCapabilities.value.split(',');
+
+        if (!protocols) {
+            return [];
+        }
+
+        var data = [];
+        $(protocols).each(function() {
+            data.push({id: this.valueOf(), name: this.valueOf(), description: _l('label.lb.protocol.' + this.valueOf())});
+        });
+
+        protocolCapabilities = $.grep(
+            lbService.capability,
+            function(capability) {
+                return (capability.name == 'SslTermination' && (capability.value == 'true' || capability.value == true));
+            }
+        )[0];
+
+        if (!protocolCapabilities) {
+            return data;
+        }
+
+        var protocols = protocolCapabilities.value.split(',');
+
+        if (!protocols) {
+            return data;
+        }
+
+        $(protocols).each(function() {
+                data.push({id: 'ssl', name: 'ssl', description: _l('label.lb.protocol.ssl')});
+        });
+
+        return data;
+    }
+
 })(cloudStack, jQuery);
diff --git a/ui/scripts/regions.js b/ui/scripts/regions.js
index 16b891f..ff50bff 100644
--- a/ui/scripts/regions.js
+++ b/ui/scripts/regions.js
@@ -159,6 +159,9 @@
 
                                 return false;
                             }
+                        }, {
+                            path: 'regions.NCC',
+                            label: 'label.ncc'
                         }],
                         actions: {
                             edit: {
@@ -258,6 +261,7 @@
                     }
                 }
             },
+
             GSLB: {
                 id: 'GSLB',
                 type: 'select',
@@ -1021,6 +1025,224 @@
                         }
                     }
                 }
+            },
+
+            NCC: {
+                id: 'NCC',
+                type: 'select',
+                title: 'NCC',
+                listView: {
+                    id: 'NCC',
+                    label: 'label.ncc',
+
+                    fields: {
+                        uuid: {
+                            label: 'label.id'
+                        },
+                        ipaddress: {
+                            label: 'label.ipaddress'
+                        },
+                        numretries: {
+                            label: 'label.numretries'
+                        }
+                    },
+
+                    actions: {
+                        add: {
+                            label: 'label.action.register.ncc',
+
+                            preFilter: function(args) {
+                                var isRegisterButtonShown = false;
+
+                                $.ajax({
+                                    url: createURL('listNetscalerControlCenter'),
+                                    async: false,
+                                    success: function(json) {
+                                        isRegisterButtonShown = json.listNetscalerControlCenter.netscalercontrolcenter ? false : true;
+                                    }
+                                });
+
+                                return isRegisterButtonShown;
+                            },
+
+                            messages: {
+                                confirm: function(args) {
+                                    return 'label.action.register.ncc';
+                                },
+                                notification: function(args) {
+                                    return 'label.action.register.ncc';
+                                }
+                            },
+
+                            createForm: {
+                                title: 'label.action.register.ncc',
+                                fields: {
+                                    ipaddress: {
+                                        label: 'label.ipaddress',
+                                        validation: {
+                                            required: true
+                                        }
+                                    },
+                                    username: {
+                                        label: 'label.username',
+                                        validation : {
+                                            required: true
+                                        }
+                                    },
+                                    password: {
+                                        label: 'label.password',
+                                        isPassword: true,
+                                        validation : {
+                                            required: true,
+                                        }
+                                    },
+                                    numretries: {
+                                        label: 'label.numretries',
+                                        defaultValue: '2',
+                                        validation : {
+                                            required: true,
+                                        }
+                                    }
+                                }
+                            },
+
+                            action: function(args) {
+                                var $loading = $('<div>').addClass('loading-overlay');
+                                $('.system-dashboard-view:visible').prepend($loading);
+
+                                var data = {
+                                    ipaddress: args.data.ipaddress,
+                                    username: args.data.username,
+                                    password: args.data.password,
+                                    numretries: args.data.numretries
+                                };
+
+                                $.ajax({
+                                    url: createURL('registerNetscalerControlCenter'),
+                                    data: data,
+                                    dataType: 'json',
+                                    type: "POST",
+                                    success: function(json) {
+                                        var jid = json.registernetscalercontrolcenterresponse.jobid;
+                                        var registerNetscalerControlCenterIntervalID = setInterval(function() {
+                                            $.ajax({
+                                                url: createURL("queryAsyncJobResult&jobId=" + jid),
+                                                dataType: "json",
+                                                success: function(json) {
+                                                    var result = json.queryasyncjobresultresponse;
+                                                    if (result.jobstatus == 0) {
+                                                        return; //Job has not completed
+                                                    } else {
+                                                        clearInterval(registerNetscalerControlCenterIntervalID);
+                                                        if (result.jobstatus == 1) {
+                                                            cloudStack.dialog.notice({
+                                                                message: 'message.register.succeeded'
+                                                            });
+                                                            $loading.remove();
+                                                        } else if (result.jobstatus == 2) {
+                                                            cloudStack.dialog.notice({
+                                                                message: _l('message.register.failed') + ' ' + _s(result.jobresult.errortext)
+                                                            });
+                                                            $loading.remove();
+                                                        }
+                                                    }
+                                                },
+                                                error: function(XMLHttpResponse) {
+                                                    cloudStack.dialog.notice({
+                                                        message: _l('message.register.failed') + ' ' + parseXMLHttpResponse(XMLHttpResponse)
+                                                    });
+                                                    $loading.remove();
+                                                }
+                                            });
+                                        }, g_queryAsyncJobResultInterval);
+                                    },
+                                    error: function(XMLHttpResponse) {
+                                        cloudStack.dialog.notice({
+                                            message: _l('message.register.failed') + ' ' + parseXMLHttpResponse(XMLHttpResponse)
+                                        });
+                                        $loading.remove();
+                                    }
+                                });
+                            },
+
+                            notification: {
+                                poll: pollAsyncJobResult
+                            }
+                        }
+                    },
+
+                    dataProvider: function(args) {
+                        $.ajax({
+                            url: createURL('listNetscalerControlCenter'),
+                            success: function(json) {
+                                var item = json.listNetscalerControlCenter.netscalercontrolcenter ? json.listNetscalerControlCenter.netscalercontrolcenter : null;
+                                args.response.success({
+                                    data: item
+                                });
+                            }
+                        });
+                    },
+
+                    detailView: {
+                        name: 'label.ncc.details',
+                        actions: {
+                            remove: {
+                                label: 'label.ncc.delete',
+                                messages: {
+                                    confirm: function(args) {
+                                        return 'message.ncc.delete.confirm';
+                                    },
+                                    notification: function(args) {
+                                        return 'label.ncc.delete';
+                                    }
+                                },
+                                action: function(args) {
+                                    var data = {
+                                        id: args.context.NCC[0].uuid
+                                    };
+                                    $.ajax({
+                                        url: createURL("deleteNetscalerControlCenter"),
+                                        data: data,
+                                        success: function(json) {
+                                            var status = json.deleteNetscalerControlCenter ? json.deleteNetscalerControlCenter.success : null;
+                                            args.response.success({
+                                                data: status
+                                            });
+                                        }
+                                    });
+                                },
+                            }
+                        },
+                        tabs: {
+                            details: {
+                                title: 'label.details',
+                                fields: [{
+                                    uuid: {
+                                        label: 'label.id'
+                                    }
+                                }, {
+                                    ipaddress: {
+                                        label: 'label.ipaddress'
+                                    },
+                                    numretries: {
+                                        label: 'label.numretries',
+                                    },
+                                }],
+                                dataProvider: function(args) {
+                                    $.ajax({
+                                        url: createURL('listNetscalerControlCenter'),
+                                        success: function(json) {
+                                            var item = json.listNetscalerControlCenter.netscalercontrolcenter ? json.listNetscalerControlCenter.netscalercontrolcenter[0] : null;
+                                            args.response.success({
+                                                data: item
+                                            });
+                                        }
+                                    });
+                                }
+                            }
+                        }
+                    }
+                }
             }
         }
     };
diff --git a/ui/scripts/system.js b/ui/scripts/system.js
old mode 100644
new mode 100755
index 9cff595..6c1b89d
--- a/ui/scripts/system.js
+++ b/ui/scripts/system.js
@@ -21472,11 +21472,66 @@
             nspMap[id]: {
             };
 
+            if (id == "netscaler") {
+                var netscalerControlCenter = null;
+
+                $.ajax({
+                    url: createURL("listNetscalerControlCenter"),
+                    dataType: "json",
+                    async: false,
+                    success: function(json) {
+                        var items = json.listNetscalerControlCenter.netscalercontrolcenter;
+                        if (items != null && items.length > 0) {
+                            netscalerControlCenter = items[0];
+                        }
+                    }
+                });
+            }
+
+            if (netscalerControlCenter != null) {
+              if (jsonObj.state == undefined) {
+                        $.ajax({
+                            url: createURL("addNetworkServiceProvider&name=Netscaler&physicalnetworkid=" + selectedPhysicalNetworkObj.id),
+                            dataType: "json",
+                            async: true,
+                            success: function (json) {
+                                var jobId = json.addnetworkserviceproviderresponse.jobid;
+                                var addNetscalerProviderIntervalID = setInterval(function () {
+                                    $.ajax({
+                                        url: createURL("queryAsyncJobResult&jobId=" + jobId),
+                                        dataType: "json",
+                                        success: function (json) {
+                                            var result = json.queryasyncjobresultresponse;
+                                            if (result.jobstatus == 0) {
+                                                return; //Job has not completed
+                                            } else {
+                                                clearInterval(addNetscalerProviderIntervalID);
+                                                if (result.jobstatus == 1) {
+                                                    nspMap[ "netscaler"] = result.jobresult.networkserviceprovider;
+                                                    addExternalLoadBalancer(args, selectedPhysicalNetworkObj, "addNetscalerLoadBalancer", "addnetscalerloadbalancerresponse", "netscalerloadbalancer");
+                                                } else if (result.jobstatus == 2) {
+                                                    alert("addNetworkServiceProvider&name=Netscaler failed. Error: " + _s(result.jobresult.errortext));
+                                                }
+                                            }
+                                        },
+                                        error: function (XMLHttpResponse) {
+                                            var errorMsg = parseXMLHttpResponse(XMLHttpResponse);
+                                            alert("addNetworkServiceProvider&name=Netscaler failed. Error: " + errorMsg);
+                                        }
+                                    });
+                                },
+                                g_queryAsyncJobResultInterval);
+                            }
+                        });
+                        jsonObj.state = "Disabled";
+                    }
+            }
+
             if (jsonObj.state) {
-                if (jsonObj.state == "Enabled")
-                allowedActions.push("disable"); else if (jsonObj.state == "Disabled")
-                allowedActions.push("enable");
-                allowedActions.push("destroy");
+               if (jsonObj.state == "Enabled")
+                 allowedActions.push("disable"); else if (jsonObj.state == "Disabled")
+                 allowedActions.push("enable");
+                 allowedActions.push("destroy");
             }
 
             allowedActions.push('add');

-- 
To stop receiving notification emails like this one, please contact
"commits@cloudstack.apache.org" <co...@cloudstack.apache.org>.

[cloudstack] 05/05: CLOUDSTACK-8672 : NCC Integration with CloudStack. Improvements.

Posted by sa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sateesh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit e243a31e41ed52a78325a6d7b08351dbf236bb30
Author: Nitin Kumar Maharana <ni...@accelerite.com>
AuthorDate: Sun Jun 18 19:10:55 2017 +0530

    CLOUDSTACK-8672 : NCC Integration with CloudStack.
    Improvements.
---
 .../admin/address/AcquirePodIpCmdByAdmin.java      |   3 +-
 .../service/NetworkOrchestrationService.java       |  18 +-
 .../service/VolumeOrchestrationService.java        |   6 +-
 .../src/com/cloud/network/IpAddressManager.java    |  49 +-
 .../offerings/dao/NetworkOfferingDaoImpl.java      |   4 +-
 .../commands/DeleteNetscalerControlCenterCmd.java  |   2 -
 .../commands/DeleteServicePackageOfferingCmd.java  |   2 -
 .../api/commands/RegisterServicePackageCmd.java    |   1 -
 .../cloud/network/NetScalerControlCenterVO.java    |   1 -
 .../network/dao/NetScalerControlCenterDaoImpl.java |   5 -
 .../dao/NetScalerServicePackageDaoImpl.java        |   3 -
 .../cloud/network/element/NetscalerElement.java    |   6 -
 .../resource/NetScalerControlCenterResource.java   |  25 +-
 .../com/cloud/network/vm/NetScalerVMManager.java   |  15 +-
 .../cloud/network/vm/NetScalerVMManagerImpl.java   | 662 ++++++++++-----------
 server/src/com/cloud/alert/AlertManagerImpl.java   |  14 +-
 .../ExternalLoadBalancerDeviceManagerImpl.java     |   5 +-
 .../network/lb/LoadBalancingRulesManagerImpl.java  |   2 +-
 .../cloudstack/network/ssl/CertServiceImpl.java    |   3 +-
 .../test/com/cloud/vpc/dao/MockNetworkDaoImpl.java | 149 +----
 20 files changed, 399 insertions(+), 576 deletions(-)

diff --git a/api/src/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java
index eba41b4..fea0ca6 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java
@@ -42,7 +42,7 @@ public class AcquirePodIpCmdByAdmin extends BaseCmd {
     //////////////// API parameters /////////////////////
     /////////////////////////////////////////////////////
 
-    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.STRING, entityType = ZoneResponse.class, required = true, description = "the ID of the  zone")
+    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.STRING, entityType = ZoneResponse.class, required = true, description = "the ID of the zone")
     private String zoneId;
 
     @Parameter(name = ApiConstants.POD_ID, type = CommandType.STRING, entityType = ZoneResponse.class, required = false, description = "Pod ID")
@@ -86,7 +86,6 @@ public class AcquirePodIpCmdByAdmin extends BaseCmd {
 
     @Override
     public long getEntityOwnerId() {
-        // TODO Auto-generated method stub
         return CallContext.current().getCallingAccount().getAccountId();
     }
 
diff --git a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java b/engine/api/src/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java
index b59c9ca..13bfee6 100644
--- a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java
+++ b/engine/api/src/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java
@@ -60,19 +60,21 @@ import com.cloud.vm.VirtualMachineProfile;
  *
  */
 public interface NetworkOrchestrationService {
-    static final String NetworkLockTimeoutCK = "network.lock.timeout";
-    static final String GuestDomainSuffixCK = "guest.domain.suffix";
-    static final String NetworkThrottlingRateCK = "network.throttling.rate";
-    static final String MinVRVersionCK = "minreq.sysvmtemplate.version";
+    String NetworkLockTimeoutCK = "network.lock.timeout";
+    String GuestDomainSuffixCK = "guest.domain.suffix";
+    String NetworkThrottlingRateCK = "network.throttling.rate";
+    String MinVRVersionCK = "minreq.sysvmtemplate.version";
 
-    static final ConfigKey<String> MinVRVersion = new ConfigKey<String>(String.class, MinVRVersionCK, "Advanced", "4.10.0",
+    ConfigKey<String> MinVRVersion = new ConfigKey<String>(String.class, MinVRVersionCK, "Advanced", "4.10.0",
             "What version should the Virtual Routers report", true, ConfigKey.Scope.Zone, null);
 
-    static final ConfigKey<Integer> NetworkLockTimeout = new ConfigKey<Integer>(Integer.class, NetworkLockTimeoutCK, "Network", "600",
+    ConfigKey<Integer> NetworkLockTimeout = new ConfigKey<Integer>(Integer.class, NetworkLockTimeoutCK, "Network", "600",
         "Lock wait timeout (seconds) while implementing network", true, Scope.Global, null);
-    static final ConfigKey<String> GuestDomainSuffix = new ConfigKey<String>(String.class, GuestDomainSuffixCK, "Network", "cloud.internal",
+
+    ConfigKey<String> GuestDomainSuffix = new ConfigKey<String>(String.class, GuestDomainSuffixCK, "Network", "cloud.internal",
         "Default domain name for vms inside virtualized networks fronted by router", true, ConfigKey.Scope.Zone, null);
-    static final ConfigKey<Integer> NetworkThrottlingRate = new ConfigKey<Integer>("Network", Integer.class, NetworkThrottlingRateCK, "200",
+
+    ConfigKey<Integer> NetworkThrottlingRate = new ConfigKey<Integer>("Network", Integer.class, NetworkThrottlingRateCK, "200",
         "Default data transfer rate in megabits per second allowed in network.", true, ConfigKey.Scope.Zone);
 
     List<? extends Network> setupNetwork(Account owner, NetworkOffering offering, DeploymentPlan plan, String name, String displayText, boolean isDefault)
diff --git a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java b/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java
index 3522c1b..451995f 100644
--- a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java
+++ b/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java
@@ -57,20 +57,22 @@ import com.cloud.vm.VirtualMachineProfile;
  */
 public interface VolumeOrchestrationService {
 
-    static final ConfigKey<Long> CustomDiskOfferingMinSize = new ConfigKey<Long>("Advanced",
+    ConfigKey<Long> CustomDiskOfferingMinSize = new ConfigKey<Long>("Advanced",
         Long.class,
         "custom.diskoffering.size.min",
         "1",
         "Minimum size in GB for custom disk offering.",
         true
     );
-    static final ConfigKey<Long> CustomDiskOfferingMaxSize = new ConfigKey<Long>("Advanced",
+
+    ConfigKey<Long> CustomDiskOfferingMaxSize = new ConfigKey<Long>("Advanced",
         Long.class,
         "custom.diskoffering.size.max",
         "1024",
         "Maximum size in GB for custom disk offering.",
         true
     );
+
     VolumeInfo moveVolume(VolumeInfo volume, long destPoolDcId, Long destPoolPodId, Long destPoolClusterId, HypervisorType dataDiskHyperType)
         throws ConcurrentOperationException, StorageUnavailableException;
 
diff --git a/engine/components-api/src/com/cloud/network/IpAddressManager.java b/engine/components-api/src/com/cloud/network/IpAddressManager.java
index 30976e5..d469cba 100644
--- a/engine/components-api/src/com/cloud/network/IpAddressManager.java
+++ b/engine/components-api/src/com/cloud/network/IpAddressManager.java
@@ -40,12 +40,12 @@ import com.cloud.vm.NicProfile;
 import com.cloud.vm.VirtualMachineProfile;
 
 public interface IpAddressManager {
-    static final String UseSystemPublicIpsCK = "use.system.public.ips";
-    static final ConfigKey<Boolean> UseSystemPublicIps = new ConfigKey<Boolean>("Advanced", Boolean.class, UseSystemPublicIpsCK, "true",
+    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);
 
-    static final ConfigKey<Boolean> RulesContinueOnError = new ConfigKey<Boolean>("Advanced", Boolean.class, "network.rule.delete.ignoreerror", "true",
+    ConfigKey<Boolean> RulesContinueOnError = new ConfigKey<Boolean>("Advanced", Boolean.class, "network.rule.delete.ignoreerror", "true",
             "When true, ip address delete (ipassoc) failures are  ignored", true);
 
     /**
@@ -53,14 +53,11 @@ public interface IpAddressManager {
      *
      * @param dcId
      * @param podId
-     *            TODO
      * @param owner
      * @param type
      * @param networkId
      * @param requestedIp
-     *            TODO
-     * @param allocatedBy
-     *            TODO
+     * @param isSystem
      * @return
      * @throws InsufficientAddressCapacityException
      */
@@ -72,8 +69,7 @@ public interface IpAddressManager {
      *
      * @param userId
      * @param caller
-     *            TODO
-     * @param IpAddress
+     * @param caller
      * @return true if it did; false if it didn't
      */
     boolean disassociatePublicIpAddress(long id, long userId, Account caller);
@@ -82,17 +78,18 @@ public interface IpAddressManager {
             throws ResourceUnavailableException;
 
     /**
-     * @throws ResourceAllocationException TODO
-     * @throws InsufficientCapacityException
-     *             Associates an ip address list to an account. The list of ip addresses are all addresses associated
-     *             with the
-     *             given vlan id.
      * @param userId
      * @param accountId
      * @param zoneId
      * @param vlanId
-     * @throws InsufficientAddressCapacityException
-     * @throws
+     * @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;
@@ -104,7 +101,7 @@ public interface IpAddressManager {
 
     IPAddressVO markIpAsUnavailable(long addrId);
 
-    public String acquireGuestIpAddress(Network network, String requestedIp);
+    String acquireGuestIpAddress(Network network, String requestedIp);
 
     boolean applyStaticNats(List<? extends StaticNat> staticNats, boolean continueOnError, boolean forRevoke) throws ResourceUnavailableException;
 
@@ -125,9 +122,15 @@ public interface IpAddressManager {
     PublicIp assignSourceNatIpAddressToGuestNetwork(Account owner, Network guestNetwork) throws InsufficientAddressCapacityException, ConcurrentOperationException;
 
     /**
+     *
      * @param ipAddrId
      * @param networkId
-     * @param releaseOnFailure TODO
+     * @param releaseOnFailure
+     * @return
+     * @throws ResourceAllocationException
+     * @throws ResourceUnavailableException
+     * @throws InsufficientAddressCapacityException
+     * @throws ConcurrentOperationException
      */
     IPAddressVO associateIPToGuestNetwork(long ipAddrId, long networkId, boolean releaseOnFailure) throws ResourceAllocationException, ResourceUnavailableException,
             InsufficientAddressCapacityException, ConcurrentOperationException;
@@ -169,7 +172,6 @@ public interface IpAddressManager {
     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;
 
@@ -179,15 +181,12 @@ public interface IpAddressManager {
 
     int getRuleCountForIp(Long addressId, FirewallRule.Purpose purpose, FirewallRule.State state);
 
-    public String allocateGuestIP(Network network, String requestedIp) throws InsufficientAddressCapacityException;
+    String allocateGuestIP(Network network, String requestedIp) throws InsufficientAddressCapacityException;
 
     String allocatePublicIpForGuestNic(Network network, Long podId, Account ipOwner, String requestedIp) throws InsufficientAddressCapacityException;
 
-    public AcquirePodIpCmdResponse allocatePodIp(String zoneId, String podId) throws ConcurrentOperationException,
-            ResourceAllocationException;
-
-    public void releasePodIp(Long id) throws CloudRuntimeException;
-
+    AcquirePodIpCmdResponse allocatePodIp(String zoneId, String podId) throws ConcurrentOperationException, ResourceAllocationException;
 
+    void releasePodIp(Long id) throws CloudRuntimeException;
 }
 
diff --git a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java b/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java
index c7298f2..b0cf0fe 100644
--- a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java
+++ b/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java
@@ -23,6 +23,7 @@ import java.util.Map;
 import javax.inject.Inject;
 import javax.persistence.EntityExistsException;
 
+import org.apache.commons.collections.CollectionUtils;
 import org.springframework.stereotype.Component;
 
 import com.cloud.network.Network;
@@ -214,7 +215,8 @@ public class NetworkOfferingDaoImpl extends GenericDaoBase<NetworkOfferingVO, Lo
         sc.addAnd("state", SearchCriteria.Op.EQ, NetworkOffering.State.Enabled);
         sc.addAnd("servicePackageUuid", SearchCriteria.Op.EQ, uuid);
         List<NetworkOfferingVO> list = this.search(sc, searchFilter);
-        if(list!=null && !list.isEmpty())
+
+        if(CollectionUtils.isNotEmpty(list))
             return true;
 
         return false;
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerControlCenterCmd.java b/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerControlCenterCmd.java
index 00d4b32..f572b09 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerControlCenterCmd.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerControlCenterCmd.java
@@ -84,13 +84,11 @@ public class DeleteNetscalerControlCenterCmd extends BaseCmd {
 
     @Override
     public String getCommandName() {
-        // TODO Auto-generated method stub
         return s_name;
     }
 
     @Override
     public long getEntityOwnerId() {
-        // TODO Auto-generated method stub
         return CallContext.current().getCallingAccount().getId();
     }
 
diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteServicePackageOfferingCmd.java b/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteServicePackageOfferingCmd.java
index 96cd16e..c6fbec1 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteServicePackageOfferingCmd.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteServicePackageOfferingCmd.java
@@ -81,13 +81,11 @@ public class DeleteServicePackageOfferingCmd extends BaseCmd {
 
     @Override
     public String getCommandName() {
-        // TODO Auto-generated method stub
         return s_name;
     }
 
     @Override
     public long getEntityOwnerId() {
-        // TODO Auto-generated method stub
         return CallContext.current().getCallingAccount().getId();
     }
 
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
index 9fabe8d..fdef005 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterServicePackageCmd.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterServicePackageCmd.java
@@ -58,7 +58,6 @@ public class RegisterServicePackageCmd extends BaseCmd {
         try {
             NetScalerServicePackageResponse response = _netsclarLbService.registerNetscalerServicePackage(this);
             if (response != null) {
-                //NetScalerServicePackageResponse response = _netsclarLbService.createNetscalerServicePackageResponse(servicePackageVO);
                 response.setObjectName("netscalerservicepackage");
                 response.setResponseName(getCommandName());
                 this.setResponseObject(response);
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerControlCenterVO.java b/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerControlCenterVO.java
index 84766bc..e9d4ef5 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerControlCenterVO.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerControlCenterVO.java
@@ -121,7 +121,6 @@ public class NetScalerControlCenterVO implements InternalIdentity {
 
     @Override
     public long getId() {
-        // TODO Auto-generated method stub
         return id;
     }
 
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerControlCenterDaoImpl.java b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerControlCenterDaoImpl.java
index ec24842..1e4f63d 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerControlCenterDaoImpl.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerControlCenterDaoImpl.java
@@ -18,8 +18,6 @@ package com.cloud.network.dao;
 
 import java.util.List;
 
-import javax.ejb.Local;
-
 import org.springframework.stereotype.Component;
 
 import com.cloud.network.NetScalerControlCenterVO;
@@ -27,19 +25,16 @@ import com.cloud.utils.db.DB;
 import com.cloud.utils.db.GenericDaoBase;
 
 @Component
-@Local(value = NetScalerControlCenterDao.class)
 @DB
 public class NetScalerControlCenterDaoImpl extends GenericDaoBase<NetScalerControlCenterVO, Long> implements NetScalerControlCenterDao {
 
     @Override
     public NetScalerControlCenterVO findByPodId(long podId) {
-        // TODO Auto-generated method stub
         return null;
     }
 
     @Override
     public List<NetScalerControlCenterVO> listByNetScalerDeviceId(long netscalerDeviceId) {
-        // TODO Auto-generated method stub
         return null;
     }
 
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDaoImpl.java b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDaoImpl.java
index db3b5c0..25d0f4b 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDaoImpl.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDaoImpl.java
@@ -18,8 +18,6 @@ package com.cloud.network.dao;
 
 import java.util.List;
 
-import javax.ejb.Local;
-
 import org.springframework.stereotype.Component;
 
 import com.cloud.network.NetScalerServicePackageVO;
@@ -29,7 +27,6 @@ import com.cloud.utils.db.SearchBuilder;
 import com.cloud.utils.db.SearchCriteria;
 
 @Component
-@Local(value = NetScalerServicePackageDao.class)
 @DB
 public class NetScalerServicePackageDaoImpl extends GenericDaoBase<NetScalerServicePackageVO, Long> implements NetScalerServicePackageDao {
 
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
index 3371cf8..2041735 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java
@@ -381,7 +381,6 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl
             networkDetails.put("name", guestConfig.getName());
             networkPayload.put("network", networkDetails);
         } catch (JSONException e) {
-            // TODO Auto-generated catch block
             e.printStackTrace();
         }
 
@@ -445,7 +444,6 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl
             // multple providers available
             return false;
         } catch (ConfigurationException e) {
-            // TODO Auto-generated catch block
             e.printStackTrace();
         }
         return false;
@@ -1345,19 +1343,16 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl
 
     @Override
     public NetScalerServicePackageResponse listNetscalerServicePackage(RegisterServicePackageCmd cmd) {
-        // TODO Auto-generated method stub
         return null;
     }
 
     @Override
     public NetScalerServicePackageResponse deleteNetscalerServicePackage(RegisterServicePackageCmd cmd) {
-        // TODO Auto-generated method stub
         return null;
     }
 
     @Override
     public NetScalerServicePackageResponse createNetscalerServicePackageResponse(NetScalerServicePackageVO servicePackageVO) {
-        // TODO Auto-generated method stub
         return null;
     }
 
@@ -1515,7 +1510,6 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl
         try {
              resp =  _netScalerVMManager.deployNsVpx(cmd.getAccount(), dest, plan, serviceOfferingId, templateId);
         } catch (InsufficientCapacityException e) {
-            // TODO Auto-generated catch block
             e.printStackTrace();
         }
         return resp;
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
index 1132b6c..347186c 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetScalerControlCenterResource.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetScalerControlCenterResource.java
@@ -214,7 +214,7 @@ public class NetScalerControlCenterResource implements ServerResource {
             }
     }
 
-    private synchronized String login() throws ExecutionException{// , ConfigurationException {
+    private synchronized String login() throws ExecutionException{
         String result = null;
         JSONObject jsonResponse = null;
         try {
@@ -317,7 +317,6 @@ public class NetScalerControlCenterResource implements ServerResource {
             getHttpRequest(jsonBody.toString(), agentUri, _sessionid);
             s_logger.debug("Keeping Session Alive");
         } catch (URISyntaxException e) {
-            // TODO Auto-generated catch block
             e.printStackTrace();
         }
     }
@@ -360,7 +359,6 @@ public class NetScalerControlCenterResource implements ServerResource {
             String errMsg = "Could not generate URI for NetScaler ControlCenter";
             s_logger.error(errMsg, e);
           } catch (JSONException e) {
-            // TODO Auto-generated catch block
             e.printStackTrace();
         }
         return result;
@@ -436,7 +434,7 @@ public class NetScalerControlCenterResource implements ServerResource {
             JSONArray lbstatus = res.getJSONArray("lbhealthstatus");
             for(int i=0; i<lbstatus.length(); i++) {
                 JSONObject lbstat = lbstatus.getJSONObject(i);
-                LoadBalancerTO loadBalancer = null;// new LoadBalancerTO(lbstat.getString("lb_uuid"));
+                LoadBalancerTO loadBalancer = null;
                 JSONArray dest = lbstat.getJSONArray("destinations");
                 List<DestinationTO> listDestTo = new ArrayList<DestinationTO>();
                 for(int d=0; d<dest.length(); d++ ) {
@@ -478,7 +476,6 @@ public class NetScalerControlCenterResource implements ServerResource {
             response = getHttpRequest(jsonBody.toString(), agentUri, _sessionid);
             s_logger.debug("LBHealthcheck Response :" + response);
         } catch (URISyntaxException e) {
-            // TODO Auto-generated catch block
             e.printStackTrace();
         }
         return response;
@@ -619,10 +616,8 @@ public class NetScalerControlCenterResource implements ServerResource {
                 }
                 s_logger.debug("IPStats Response :" + response);
             } catch (URISyntaxException e) {
-                // TODO Auto-generated catch block
                 e.printStackTrace();
             } catch (ExecutionException e) {
-                // TODO Auto-generated catch block
                 s_logger.debug("Seesion Alive" + e.getMessage());
                 e.printStackTrace();
             }
@@ -696,6 +691,10 @@ public class NetScalerControlCenterResource implements ServerResource {
     }
 
     @Override
+    public void setName(String name) {
+    }
+
+    @Override
     public boolean start() {
         return true;
     }
@@ -711,33 +710,21 @@ public class NetScalerControlCenterResource implements ServerResource {
     }
 
     @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
-
     }
 
     public String getSessionID() {
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManager.java b/plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManager.java
index ae1c9da..c82d2b8 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManager.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManager.java
@@ -14,6 +14,7 @@
 //KIND, either express or implied.  See the License for the
 //specific language governing permissions and limitations
 //under the License.
+
 package com.cloud.network.vm;
 import java.util.Map;
 
@@ -27,15 +28,15 @@ import com.cloud.network.router.VirtualRouter;
 import com.cloud.user.Account;
 
 public interface NetScalerVMManager {
+    //RAM/CPU for the system offering used by Internal LB VMs
+    int DEFAULT_NETSCALER_VM_RAMSIZE = 2048; // 2048 MB
+    int DEFAULT_NETSCALER_VM_CPU_MHZ = 1024; // 1024 MHz
 
- //RAM/CPU for the system offering used by Internal LB VMs
- public static final int DEFAULT_NETSCALER_VM_RAMSIZE = 2048;            // 2048 MB
- public static final int DEFAULT_NETSCALER_VM_CPU_MHZ = 1024;            // 1024 MHz
+    Map<String, Object> deployNetscalerServiceVm(DeployNetscalerVpxCmd cmd);
 
- public Map<String, Object> deployNetscalerServiceVm(DeployNetscalerVpxCmd cmd);
+    VirtualRouter stopNetscalerServiceVm(Long id, boolean forced, Account callingAccount, long callingUserId) throws ConcurrentOperationException, ResourceUnavailableException;
 
- public VirtualRouter stopNetscalerServiceVm(Long id, boolean forced, Account callingAccount, long callingUserId) throws ConcurrentOperationException, ResourceUnavailableException;
- public Map<String, Object> deployNsVpx(Account owner, DeployDestination dest, DeploymentPlan plan, long svcOffId, long templateId) throws InsufficientCapacityException;
+    Map<String, Object> deployNsVpx(Account owner, DeployDestination dest, DeploymentPlan plan, long svcOffId, long templateId) throws InsufficientCapacityException;
 
- public VirtualRouter stopNetScalerVm(Long id, boolean forced, Account callingAccount, long callingUserId);
+    VirtualRouter stopNetScalerVm(Long id, boolean forced, Account callingAccount, long callingUserId);
 }
\ No newline at end of file
diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManagerImpl.java b/plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManagerImpl.java
index 63574ad..8d50b59 100644
--- a/plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManagerImpl.java
+++ b/plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManagerImpl.java
@@ -98,351 +98,351 @@ import com.cloud.vm.dao.VMInstanceDao;
 
 @Local(value = {NetScalerVMManager.class})
 public class NetScalerVMManagerImpl extends ManagerBase implements NetScalerVMManager, VirtualMachineGuru {
- private static final Logger s_logger = Logger.getLogger(NetScalerVMManagerImpl.class);
- static final private String NetScalerLbVmNamePrefix = "NS";
-
- @Inject
- IpAddressManager _ipAddrMgr;
- @Inject
- VirtualMachineManager _itMgr;
- @Inject
- DomainRouterDao _internalLbVmDao;
- @Inject
- ConfigurationDao _configDao;
- @Inject
- AgentManager _agentMgr;
- @Inject
- DataCenterDao _dcDao;
- @Inject
- VirtualRouterProviderDao _vrProviderDao;
- @Inject
- ApplicationLoadBalancerRuleDao _lbDao;
- @Inject
- NetworkModel _ntwkModel;
- @Inject
- LoadBalancingRulesManager _lbMgr;
- @Inject
- NicDao _nicDao;
- @Inject
- AccountManager _accountMgr;
- @Inject
- NetworkDao _networkDao;
- @Inject
- NetworkOrchestrationService _networkMgr;
- @Inject
- ServiceOfferingDao _serviceOfferingDao;
- @Inject
- PhysicalNetworkServiceProviderDao _physicalProviderDao;
- @Inject
- NetworkOfferingDao _networkOfferingDao;
- @Inject
- VMTemplateDao _templateDao;
- @Inject
- ResourceManager _resourceMgr;
- @Inject
- VMInstanceDao _vmDao;
- @Inject
- NetworkModel _networkModel;
- @Inject
- PhysicalNetworkDao _physicalNetworkDao;
- @Inject
- VlanDao _vlanDao;
- @Inject
- DomainRouterDao _routerDao;
-
- @Override
- public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
-
-     //NetScalerLB vm starts up with 3 Nics
-     //Nic #1 - NS IP
-     //Nic #2 - locallink(guest network)
-     //Nic #3 - public nic
-
-     for (final NicProfile nic : profile.getNics()) {
-         if(nic.getTrafficType() == TrafficType.Control) {
-             nic.setTrafficType(TrafficType.Guest);
-         }
-     }
-     return true;
- }
-
- @Override
- public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context)
-     throws ResourceUnavailableException {
-     return true;
- }
-
- @Override
- public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) {
-     return true;
- }
-
- @Override
- public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) {
-     return true;
- }
-
- @Override
- public void finalizeStop(VirtualMachineProfile profile, Answer answer) {
- }
-
- @Override
- public void finalizeExpunge(VirtualMachine vm) {
- }
-
- @Override
- public void prepareStop(VirtualMachineProfile profile) {
- }
-
- @Override
- public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-
-     _itMgr.registerGuru(VirtualMachine.Type.NetScalerVm, this);
-     if (s_logger.isInfoEnabled()) {
-         s_logger.info(getName() + " has been configured");
-     }
-     return true;
- }
-
- @Override
- public String getName() {
-     return _name;
- }
-
- protected VirtualRouter stopInternalLbVm(DomainRouterVO internalLbVm, boolean forced, Account caller, long callerUserId) throws ResourceUnavailableException,
-     ConcurrentOperationException {
-     s_logger.debug("Stopping internal lb vm " + internalLbVm);
-     try {
-         _itMgr.advanceStop(internalLbVm.getUuid(), forced);
-         return _internalLbVmDao.findById(internalLbVm.getId());
-     } catch (OperationTimedoutException e) {
-         throw new CloudRuntimeException("Unable to stop " + internalLbVm, e);
-     }
- }
-
- public VirtualRouterProvider addNetScalerLoadBalancerElement(long ntwkSvcProviderId) {
-     VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(ntwkSvcProviderId, com.cloud.network.VirtualRouterProvider.Type.NetScalerVm);
-     if (element != null) {
-         s_logger.debug("There is already an " + getName() + " with service provider id " + ntwkSvcProviderId);
-         return element;
-     }
-
-     PhysicalNetworkServiceProvider provider = _physicalProviderDao.findById(ntwkSvcProviderId);
-     if (provider == null || !provider.getProviderName().equalsIgnoreCase(getName())) {
-         throw new InvalidParameterValueException("Invalid network service provider is specified");
-     }
-
-     element = new VirtualRouterProviderVO(ntwkSvcProviderId, com.cloud.network.VirtualRouterProvider.Type.NetScalerVm);
-     element.setEnabled(true);
-     element = _vrProviderDao.persist(element);
-     return element;
- }
-
- protected long getNetScalerLbProviderId(long physicalNetworkId) {
-     //final long physicalNetworkId = _ntwkModel.getPhysicalNetworkId(guestNetwork);
-
-     final PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, "Netscaler");
-     if (provider == null) {
-         throw new CloudRuntimeException("Cannot find service provider " + Provider.Netscaler.toString() + " in physical network " + physicalNetworkId);
-     }
-
-     //TODO: get from type
-     VirtualRouterProvider netScalerLbProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), com.cloud.network.VirtualRouterProvider.Type.NetScalerVm);
-     if (netScalerLbProvider == null) {
-         //create the vrp for netscalerVM.
-         netScalerLbProvider = addNetScalerLoadBalancerElement(provider.getId());
-     }
-
-     return netScalerLbProvider.getId();
- }
- @Override
-    public Map<String, Object> deployNsVpx(Account owner, DeployDestination dest, DeploymentPlan plan, long svcOffId, long templateId) throws InsufficientCapacityException {
+    private static final Logger s_logger = Logger.getLogger(NetScalerVMManagerImpl.class);
+    static final private String NetScalerLbVmNamePrefix = "NS";
+
+    @Inject
+    IpAddressManager _ipAddrMgr;
+    @Inject
+    VirtualMachineManager _itMgr;
+    @Inject
+    DomainRouterDao _internalLbVmDao;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    AgentManager _agentMgr;
+    @Inject
+    DataCenterDao _dcDao;
+    @Inject
+    VirtualRouterProviderDao _vrProviderDao;
+    @Inject
+    ApplicationLoadBalancerRuleDao _lbDao;
+    @Inject
+    NetworkModel _ntwkModel;
+    @Inject
+    LoadBalancingRulesManager _lbMgr;
+    @Inject
+    NicDao _nicDao;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    NetworkDao _networkDao;
+    @Inject
+    NetworkOrchestrationService _networkMgr;
+    @Inject
+    ServiceOfferingDao _serviceOfferingDao;
+    @Inject
+    PhysicalNetworkServiceProviderDao _physicalProviderDao;
+    @Inject
+    NetworkOfferingDao _networkOfferingDao;
+    @Inject
+    VMTemplateDao _templateDao;
+    @Inject
+    ResourceManager _resourceMgr;
+    @Inject
+    VMInstanceDao _vmDao;
+    @Inject
+    NetworkModel _networkModel;
+    @Inject
+    PhysicalNetworkDao _physicalNetworkDao;
+    @Inject
+    VlanDao _vlanDao;
+    @Inject
+    DomainRouterDao _routerDao;
+
+    @Override
+    public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
+        //NetScalerLB vm starts up with 3 Nics
+        //Nic #1 - NS IP
+        //Nic #2 - locallink(guest network)
+        //Nic #3 - public nic
+
+        for (final NicProfile nic : profile.getNics()) {
+            if(nic.getTrafficType() == TrafficType.Control) {
+                nic.setTrafficType(TrafficType.Guest);
+            }
+        }
+        return true;
+    }
 
-     VMTemplateVO template = _templateDao.findById(templateId) ;
-     long id = _vmDao.getNextInSequence(Long.class, "id");
-     Account systemAcct = _accountMgr.getSystemAccount();
-
-     if (template == null) {
-         s_logger.error(" Unable to find the NS VPX template");
-         throw new CloudRuntimeException("Unable to find the Template" + templateId);
-     }
-     long dataCenterId = dest.getDataCenter().getId();
-     DataCenterVO dc = _dcDao.findById(dest.getDataCenter().getId());
-
-     String nxVpxName = VirtualMachineName.getSystemVmName(id, "Vpx", NetScalerLbVmNamePrefix);
-
-     ServiceOfferingVO vpxOffering =   _serviceOfferingDao.findById(svcOffId); //using 2GB and 2CPU  offering
-     if(vpxOffering.getRamSize() < 2048 && vpxOffering.getCpu() <2 ) {
-         throw new InvalidParameterValueException("Specified Service Offering :" + vpxOffering.getUuid() + " NS Vpx cannot be deployed. Min 2GB Ram and 2 CPU are required");
-     }
-
-     long userId = CallContext.current().getCallingUserId();
-     //TODO change the os bits from 142  103 to the actual guest of bits
-     if(template.getGuestOSId() !=  103 ) {
-         throw new InvalidParameterValueException("Specified Template " + template.getUuid()+ " not suitable for NS VPX Deployment. Please register the template with guest os type as unknow(64-bit)");
-     }
-     NetworkVO defaultNetwork = null;
-      NetworkVO defaultPublicNetwork = null;
-      if (dc.getNetworkType() == NetworkType.Advanced && dc.isSecurityGroupEnabled()) {
-          List<NetworkVO> networks = _networkDao.listByZoneSecurityGroup(dataCenterId);
-          if (networks == null || networks.size() == 0) {
-              throw new CloudRuntimeException("Can not found security enabled network in SG Zone " + dc);
-          }
-          defaultNetwork = networks.get(0);
-      } else {
-          TrafficType defaultTrafficType = TrafficType.Management;
-          List<NetworkVO> defaultNetworks = _networkDao.listByZoneAndTrafficType(dataCenterId, defaultTrafficType);
-
-          TrafficType publicTrafficType = TrafficType.Public;
-          List<NetworkVO> publicNetworks = _networkDao.listByZoneAndTrafficType(dataCenterId, publicTrafficType);
-
-          // 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");
-          }
-
-          if (publicNetworks.size() != 1) {
-              throw new CloudRuntimeException("Found " + defaultNetworks.size() + " networks of type " + defaultTrafficType + " when expect to find 1");
-          }
-          defaultPublicNetwork = publicNetworks.get(0);
-          defaultNetwork = defaultNetworks.get(0);
-      }
-
-      LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>(4);
-      NicProfile defaultNic = new NicProfile();
-      defaultNic.setDefaultNic(true);
-      defaultNic.setDeviceId(0);
-
-      networks.put(_networkMgr.setupNetwork(_accountMgr.getSystemAccount() , _networkOfferingDao.findById(defaultNetwork.getNetworkOfferingId()), plan, null, null, false).get(0),
-              new ArrayList<NicProfile>());
+    @Override
+    public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException {
+        return true;
+    }
+
+    @Override
+    public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) {
+        return true;
+    }
+
+    @Override
+    public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) {
+        return true;
+    }
+
+    @Override
+    public void finalizeStop(VirtualMachineProfile profile, Answer answer) {
+    }
+
+    @Override
+    public void finalizeExpunge(VirtualMachine vm) {
+    }
+
+    @Override
+    public void prepareStop(VirtualMachineProfile profile) {
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        _itMgr.registerGuru(VirtualMachine.Type.NetScalerVm, this);
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info(getName() + " has been configured");
+        }
+        return true;
+    }
+
+    @Override
+    public String getName() {
+        return _name;
+    }
+
+    protected VirtualRouter stopInternalLbVm(DomainRouterVO internalLbVm, boolean forced, Account caller, long callerUserId) throws ResourceUnavailableException, ConcurrentOperationException {
+        s_logger.debug("Stopping internal lb vm " + internalLbVm);
+        try {
+            _itMgr.advanceStop(internalLbVm.getUuid(), forced);
+            return _internalLbVmDao.findById(internalLbVm.getId());
+        } catch (OperationTimedoutException e) {
+            throw new CloudRuntimeException("Unable to stop " + internalLbVm, e);
+        }
+    }
 
-      NicProfile defaultNic1 = new NicProfile();
-      defaultNic1.setDefaultNic(false);
-      defaultNic1.setDeviceId(1);
+    public VirtualRouterProvider addNetScalerLoadBalancerElement(long ntwkSvcProviderId) {
+        VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(ntwkSvcProviderId, com.cloud.network.VirtualRouterProvider.Type.NetScalerVm);
+        if (element != null) {
+            s_logger.debug("There is already an " + getName() + " with service provider id " + ntwkSvcProviderId);
+            return element;
+        }
+
+        PhysicalNetworkServiceProvider provider = _physicalProviderDao.findById(ntwkSvcProviderId);
+        if (provider == null || !provider.getProviderName().equalsIgnoreCase(getName())) {
+            throw new InvalidParameterValueException("Invalid network service provider is specified");
+        }
+
+        element = new VirtualRouterProviderVO(ntwkSvcProviderId, com.cloud.network.VirtualRouterProvider.Type.NetScalerVm);
+        element.setEnabled(true);
+        element = _vrProviderDao.persist(element);
+        return element;
+    }
+
+    protected long getNetScalerLbProviderId(long physicalNetworkId) {
+        //final long physicalNetworkId = _ntwkModel.getPhysicalNetworkId(guestNetwork);
+
+        final PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, "Netscaler");
+        if (provider == null) {
+            throw new CloudRuntimeException("Cannot find service provider " + Provider.Netscaler.toString() + " in physical network " + physicalNetworkId);
+        }
+
+        //TODO: get from type
+        VirtualRouterProvider netScalerLbProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), com.cloud.network.VirtualRouterProvider.Type.NetScalerVm);
+        if (netScalerLbProvider == null) {
+            //create the vrp for netscalerVM.
+            netScalerLbProvider = addNetScalerLoadBalancerElement(provider.getId());
+        }
+
+        return netScalerLbProvider.getId();
+    }
 
-      NicProfile defaultNic2 = new NicProfile();
-      defaultNic2.setDefaultNic(false);
-      defaultNic2.setDeviceId(2);
-      defaultNic2.setIPv4Address("");
-      defaultNic2.setIPv4Gateway("");
-      defaultNic2.setIPv4Netmask("");
-      String macAddress = _networkDao.getNextAvailableMacAddress(defaultPublicNetwork.getId());
-      defaultNic2.setMacAddress(macAddress);
+    @Override
+    public Map<String, Object> deployNsVpx(Account owner, DeployDestination dest, DeploymentPlan plan, long svcOffId, long templateId) throws InsufficientCapacityException {
 
-      networks.put(_networkMgr.setupNetwork(_accountMgr.getSystemAccount(), _networkOfferingDao.findByUniqueName(NetworkOffering.SystemPublicNetwork), plan, null, null, false).get(0),
+        VMTemplateVO template = _templateDao.findById(templateId) ;
+        long id = _vmDao.getNextInSequence(Long.class, "id");
+        Account systemAcct = _accountMgr.getSystemAccount();
+
+        if (template == null) {
+            s_logger.error(" Unable to find the NS VPX template");
+            throw new CloudRuntimeException("Unable to find the Template" + templateId);
+        }
+        long dataCenterId = dest.getDataCenter().getId();
+        DataCenterVO dc = _dcDao.findById(dest.getDataCenter().getId());
+
+        String nxVpxName = VirtualMachineName.getSystemVmName(id, "Vpx", NetScalerLbVmNamePrefix);
+
+        ServiceOfferingVO vpxOffering = _serviceOfferingDao.findById(svcOffId); //using 2GB and 2CPU  offering
+        if(vpxOffering.getRamSize() < 2048 && vpxOffering.getCpu() <2 ) {
+            throw new InvalidParameterValueException("Specified Service Offering :" + vpxOffering.getUuid() + " NS Vpx cannot be deployed. Min 2GB Ram and 2 CPU are required");
+        }
+
+        long userId = CallContext.current().getCallingUserId();
+        //TODO change the os bits from 142  103 to the actual guest of bits
+        if(template.getGuestOSId() !=  103 ) {
+            throw new InvalidParameterValueException("Specified Template " + template.getUuid()+ " not suitable for NS VPX Deployment. Please register the template with guest os type as unknow(64-bit)");
+        }
+
+        NetworkVO defaultNetwork = null;
+        NetworkVO defaultPublicNetwork = null;
+        if (dc.getNetworkType() == NetworkType.Advanced && dc.isSecurityGroupEnabled()) {
+            List<NetworkVO> networks = _networkDao.listByZoneSecurityGroup(dataCenterId);
+            if (networks == null || networks.size() == 0) {
+                throw new CloudRuntimeException("Can not found security enabled network in SG Zone " + dc);
+            }
+            defaultNetwork = networks.get(0);
+        } else {
+            TrafficType defaultTrafficType = TrafficType.Management;
+            List<NetworkVO> defaultNetworks = _networkDao.listByZoneAndTrafficType(dataCenterId, defaultTrafficType);
+
+            TrafficType publicTrafficType = TrafficType.Public;
+            List<NetworkVO> publicNetworks = _networkDao.listByZoneAndTrafficType(dataCenterId, publicTrafficType);
+
+            // 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");
+            }
+
+            if (publicNetworks.size() != 1) {
+                throw new CloudRuntimeException("Found " + defaultNetworks.size() + " networks of type " + defaultTrafficType + " when expect to find 1");
+            }
+            defaultPublicNetwork = publicNetworks.get(0);
+            defaultNetwork = defaultNetworks.get(0);
+        }
+
+        LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>(4);
+        NicProfile defaultNic = new NicProfile();
+        defaultNic.setDefaultNic(true);
+        defaultNic.setDeviceId(0);
+
+        networks.put(_networkMgr.setupNetwork(_accountMgr.getSystemAccount() , _networkOfferingDao.findById(defaultNetwork.getNetworkOfferingId()), plan, null, null, false).get(0), new ArrayList<NicProfile>());
+
+        NicProfile defaultNic1 = new NicProfile();
+        defaultNic1.setDefaultNic(false);
+        defaultNic1.setDeviceId(1);
+
+        NicProfile defaultNic2 = new NicProfile();
+        defaultNic2.setDefaultNic(false);
+        defaultNic2.setDeviceId(2);
+        defaultNic2.setIPv4Address("");
+        defaultNic2.setIPv4Gateway("");
+        defaultNic2.setIPv4Netmask("");
+        String macAddress = _networkDao.getNextAvailableMacAddress(defaultPublicNetwork.getId(), null);
+        defaultNic2.setMacAddress(macAddress);
+
+        networks.put(_networkMgr.setupNetwork(_accountMgr.getSystemAccount(), _networkOfferingDao.findByUniqueName(NetworkOffering.SystemPublicNetwork), plan, null, null, false).get(0),
               new ArrayList<NicProfile>(Arrays.asList(defaultNic2)));
 
-      networks.put(_networkMgr.setupNetwork(_accountMgr.getSystemAccount(), _networkOfferingDao.findByUniqueName(NetworkOffering.SystemControlNetwork), plan, null, null, false).get(0),
+        networks.put(_networkMgr.setupNetwork(_accountMgr.getSystemAccount(), _networkOfferingDao.findByUniqueName(NetworkOffering.SystemControlNetwork), plan, null, null, false).get(0),
               new ArrayList<NicProfile>());
 
-      long physicalNetworkId = _networkModel.findPhysicalNetworkId(dataCenterId, _networkOfferingDao.findById(defaultPublicNetwork.getNetworkOfferingId()).getTags(), TrafficType.Public);
-      // Validate physical network
-      PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
-      if (physicalNetwork == null) {
-          throw new InvalidParameterValueException("Unable to find physical network with id: " + physicalNetworkId + " and tag: "
+        long physicalNetworkId = _networkModel.findPhysicalNetworkId(dataCenterId, _networkOfferingDao.findById(defaultPublicNetwork.getNetworkOfferingId()).getTags(), TrafficType.Public);
+        // Validate physical network
+        PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+        if (physicalNetwork == null) {
+            throw new InvalidParameterValueException("Unable to find physical network with id: " + physicalNetworkId + " and tag: "
                   + _networkOfferingDao.findById(defaultPublicNetwork.getNetworkOfferingId()).getTags());
-      }
-      String guestvnet = physicalNetwork.getVnetString();
+        }
+        String guestvnet = physicalNetwork.getVnetString();
 
-      final List<VlanVO> vlans = _vlanDao.listByZone(dataCenterId);
-      List<String> pvlan = new ArrayList<String>();
-      for (final VlanVO vlan : vlans) {
-          pvlan.add(vlan.getVlanTag());
-      }
+        final List<VlanVO> vlans = _vlanDao.listByZone(dataCenterId);
+        List<String> pvlan = new ArrayList<String>();
+        for (final VlanVO vlan : vlans) {
+            pvlan.add(vlan.getVlanTag());
+        }
 
-      long netScalerProvider = getNetScalerLbProviderId(physicalNetworkId);
-      DomainRouterVO nsVpx = new DomainRouterVO(id, vpxOffering.getId(), netScalerProvider, nxVpxName,
+        long netScalerProvider = getNetScalerLbProviderId(physicalNetworkId);
+        DomainRouterVO nsVpx = new DomainRouterVO(id, vpxOffering.getId(), netScalerProvider, nxVpxName,
               template.getId(), template.getHypervisorType(),  template.getGuestOSId(), owner.getDomainId(), owner.getId(), userId, false, RedundantState.UNKNOWN, false,
               false, VirtualMachine.Type.NetScalerVm, null);
 
-          nsVpx.setRole(Role.NETSCALER_VM);
-
-          nsVpx = _routerDao.persist(nsVpx);
-
-      VMInstanceVO vmVO= _vmDao.findVMByHostName(nxVpxName);
-     _itMgr.allocate(nxVpxName, template, vpxOffering, networks, plan, template.getHypervisorType());
-     Map<Param, Object> params = new HashMap<VirtualMachineProfile.Param, Object>(1);
-     try {
-         if (vmVO != null) {
-             startNsVpx(vmVO, params);
-         } else {
-             throw new NullPointerException();
-         }
-     } catch (StorageUnavailableException e) {
-         e.printStackTrace();
-     } catch (ConcurrentOperationException e) {
-         e.printStackTrace();
-     } catch (ResourceUnavailableException e) {
-         e.printStackTrace();
-     }
-     vmVO= _vmDao.findByUuid(nsVpx.getUuid());
-     Map<String, Object> deployResponse = new HashMap<String, Object>();
-     deployResponse.put("vm", vmVO);
-     deployResponse.put("guestvlan", guestvnet);
-     deployResponse.put("publicvlan", pvlan);
-     return deployResponse;
- }
-
- protected void startNsVpx(VMInstanceVO nsVpx, Map<Param, Object> params) throws StorageUnavailableException,
- InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
-     s_logger.debug("Starting NS Vpx " + nsVpx);
-     _itMgr.start(nsVpx.getUuid(), params, null, null);
- }
-
- @Override
- public Map<String,Object> deployNetscalerServiceVm(DeployNetscalerVpxCmd cmd) {
-     DataCenter zone = _dcDao.findById(cmd.getZoneId());
-     DeployDestination dest = new DeployDestination(zone, null, null, null);
-     VMInstanceVO vmvo = 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 = deployNsVpx(cmd.getAccount(), dest, plan, serviceOfferingId, templateId);
-     } catch (InsufficientCapacityException e) {
-         // TODO Auto-generated catch block
-         e.printStackTrace();
-     }
-     return resp;
- }
-
- protected VirtualRouter stopNetScalerVm(final long vmId, final boolean forced, final Account caller, final long callerUserId) throws ResourceUnavailableException,
- ConcurrentOperationException {
-     final DomainRouterVO netscalerVm = _routerDao.findById(vmId);
-     s_logger.debug("Stopping NetScaler vm " + netscalerVm);
-
-     if (netscalerVm == null || netscalerVm.getRole() != Role.NETSCALER_VM) {
-         throw new InvalidParameterValueException("Can't find NetScaler vm by id specified");
-     }
-     _accountMgr.checkAccess(caller, null, true, netscalerVm);
-     try {
-         _itMgr.expunge(netscalerVm.getUuid());
-         return _routerDao.findById(netscalerVm.getId());
-     } catch (final Exception e) {
-         throw new CloudRuntimeException("Unable to stop " + netscalerVm, e);
-     }
- }
- @Override
- public VirtualRouter stopNetscalerServiceVm(Long id, boolean forced, Account callingAccount, long callingUserId) throws ConcurrentOperationException,
-         ResourceUnavailableException {
-     return stopNetScalerVm(id, forced, callingAccount, callingUserId);
- }
-
-@Override
-public VirtualRouter stopNetScalerVm(Long vmId, boolean forced, Account caller, long callingUserId) {
-    final DomainRouterVO netscalerVm = _routerDao.findById(vmId);
-    s_logger.debug("Stopping NetScaler vm " + netscalerVm);
-
-    if (netscalerVm == null || netscalerVm.getRole() != Role.NETSCALER_VM) {
-        throw new InvalidParameterValueException("Can't find NetScaler vm by id specified");
+        nsVpx.setRole(Role.NETSCALER_VM);
+
+        nsVpx = _routerDao.persist(nsVpx);
+
+        VMInstanceVO vmVO= _vmDao.findVMByHostName(nxVpxName);
+        _itMgr.allocate(nxVpxName, template, vpxOffering, networks, plan, template.getHypervisorType());
+        Map<Param, Object> params = new HashMap<VirtualMachineProfile.Param, Object>(1);
+        try {
+            if (vmVO != null) {
+                startNsVpx(vmVO, params);
+            } else {
+                throw new NullPointerException();
+            }
+        } catch (StorageUnavailableException e) {
+            e.printStackTrace();
+        } catch (ConcurrentOperationException e) {
+            e.printStackTrace();
+        } catch (ResourceUnavailableException e) {
+            e.printStackTrace();
+        }
+        vmVO= _vmDao.findByUuid(nsVpx.getUuid());
+        Map<String, Object> deployResponse = new HashMap<String, Object>();
+        deployResponse.put("vm", vmVO);
+        deployResponse.put("guestvlan", guestvnet);
+        deployResponse.put("publicvlan", pvlan);
+
+        return deployResponse;
     }
-    _accountMgr.checkAccess(caller, null, true, netscalerVm);
-    try {
-        _itMgr.expunge(netscalerVm.getUuid());
-        return _routerDao.findById(netscalerVm.getId());
-    } catch (final Exception e) {
-        throw new CloudRuntimeException("Unable to stop " + netscalerVm, e);
+
+    protected void startNsVpx(VMInstanceVO nsVpx, Map<Param, Object> params) throws StorageUnavailableException,
+    InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
+        s_logger.debug("Starting NS Vpx " + nsVpx);
+        _itMgr.start(nsVpx.getUuid(), params, null, null);
+    }
+
+    @Override
+    public Map<String,Object> deployNetscalerServiceVm(DeployNetscalerVpxCmd cmd) {
+        DataCenter zone = _dcDao.findById(cmd.getZoneId());
+        DeployDestination dest = new DeployDestination(zone, null, null, null);
+        VMInstanceVO vmvo = 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 = deployNsVpx(cmd.getAccount(), dest, plan, serviceOfferingId, templateId);
+        } catch (InsufficientCapacityException e) {
+            e.printStackTrace();
+        }
+
+        return resp;
+    }
+
+    protected VirtualRouter stopNetScalerVm(final long vmId, final boolean forced, final Account caller, final long callerUserId) throws ResourceUnavailableException, ConcurrentOperationException {
+        final DomainRouterVO netscalerVm = _routerDao.findById(vmId);
+        s_logger.debug("Stopping NetScaler vm " + netscalerVm);
+
+        if (netscalerVm == null || netscalerVm.getRole() != Role.NETSCALER_VM) {
+            throw new InvalidParameterValueException("Can't find NetScaler vm by id specified");
+        }
+
+        _accountMgr.checkAccess(caller, null, true, netscalerVm);
+
+        try {
+            _itMgr.expunge(netscalerVm.getUuid());
+            return _routerDao.findById(netscalerVm.getId());
+        } catch (final Exception e) {
+            throw new CloudRuntimeException("Unable to stop " + netscalerVm, e);
+        }
+    }
+
+    @Override
+    public VirtualRouter stopNetscalerServiceVm(Long id, boolean forced, Account callingAccount, long callingUserId) throws ConcurrentOperationException, ResourceUnavailableException {
+        return stopNetScalerVm(id, forced, callingAccount, callingUserId);
+    }
+
+    @Override
+    public VirtualRouter stopNetScalerVm(Long vmId, boolean forced, Account caller, long callingUserId) {
+        final DomainRouterVO netscalerVm = _routerDao.findById(vmId);
+        s_logger.debug("Stopping NetScaler vm " + netscalerVm);
+
+        if (netscalerVm == null || netscalerVm.getRole() != Role.NETSCALER_VM) {
+            throw new InvalidParameterValueException("Can't find NetScaler vm by id specified");
+        }
+        _accountMgr.checkAccess(caller, null, true, netscalerVm);
+        try {
+            _itMgr.expunge(netscalerVm.getUuid());
+            return _routerDao.findById(netscalerVm.getId());
+        } catch (final Exception e) {
+            throw new CloudRuntimeException("Unable to stop " + netscalerVm, e);
+        }
     }
-}
 }
diff --git a/server/src/com/cloud/alert/AlertManagerImpl.java b/server/src/com/cloud/alert/AlertManagerImpl.java
index 93c3b77..c751c6a 100644
--- a/server/src/com/cloud/alert/AlertManagerImpl.java
+++ b/server/src/com/cloud/alert/AlertManagerImpl.java
@@ -90,7 +90,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
     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 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("########");
@@ -126,7 +126,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
     protected ConfigDepot _configDepot;
 
     private Timer _timer = null;
-    private long _capacityCheckPeriod = 60L * 60L * 1000L;// one hour by default
+    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;
@@ -249,8 +249,8 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
             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);
+                s_alertsLogger.warn("AlertType:: " + alertType + " | dataCenterId:: " + dataCenterId + " | podId:: " + podId +
+                        " | message:: " + subject + " | body:: " + body);
             }
         } catch (Exception ex) {
             s_logger.error("Problem sending email alert", ex);
@@ -747,8 +747,8 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
         // 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);
+            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) &&
@@ -771,7 +771,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi
                 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.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);
diff --git a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
index f1b4a79..1e6271d 100644
--- a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
+++ b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
@@ -1281,14 +1281,11 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
             if (loadBalancersToApply.size() > 0) {
                 int numLoadBalancersForCommand = loadBalancersToApply.size();
                 LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply.toArray(new LoadBalancerTO[numLoadBalancersForCommand]);
-                // LoadBalancerConfigCommand cmd = new
-                // LoadBalancerConfigCommand(loadBalancersForCommand, null);
                 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);
+                HealthCheckLBConfigAnswer answer = (HealthCheckLBConfigAnswer) _agentMgr.easySend(externalLoadBalancer.getId(), cmd);
                 // easySend will return null on error
                 return answer == null ? null : answer.getLoadBalancers();
             }
diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
index 099a274..9b7cf9b 100644
--- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
+++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
@@ -2125,7 +2125,7 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
         boolean success = _lbDao.update(lbRuleId, lb);
 
         // If algorithm is changed, have to reapply the lb config
-        if ((algorithm!= null) && (tmplbVo.getAlgorithm().compareTo(algorithm)!=0)){
+        if ((algorithm != null) && (tmplbVo.getAlgorithm().compareTo(algorithm) != 0)){
             try {
                 lb.setState(FirewallRule.State.Add);
                 _lbDao.persist(lb);
diff --git a/server/src/org/apache/cloudstack/network/ssl/CertServiceImpl.java b/server/src/org/apache/cloudstack/network/ssl/CertServiceImpl.java
index 68e84fb..e142ee5 100644
--- a/server/src/org/apache/cloudstack/network/ssl/CertServiceImpl.java
+++ b/server/src/org/apache/cloudstack/network/ssl/CertServiceImpl.java
@@ -328,8 +328,9 @@ public class CertServiceImpl implements CertService {
         response.setFingerprint(cert.getFingerPrint());
         response.setName(cert.getName());
 
-        if (cert.getChain() != null)
+        if (cert.getChain() != null) {
             response.setCertchain(cert.getChain());
+        }
 
         if (lbCertMap != null && !lbCertMap.isEmpty()) {
             final List<String> lbIds = new ArrayList<String>();
diff --git a/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java b/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java
index b0440f2..4c4a0a1 100644
--- a/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java
+++ b/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java
@@ -34,12 +34,8 @@ import com.cloud.utils.db.SearchBuilder;
 @DB()
 public class MockNetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements NetworkDao {
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#listByOwner(long)
-     */
     @Override
     public List<NetworkVO> listByOwner(final long ownerId) {
-        // TODO Auto-generated method stub
         return null;
     }
 
@@ -48,279 +44,151 @@ public class MockNetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implemen
         return null;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#listBy(long, long, long)
-     */
     @Override
     public List<NetworkVO> listBy(final long accountId, final long offeringId, final long dataCenterId) {
-        // TODO Auto-generated method stub
         return null;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#listBy(long, long, java.lang.String, boolean)
-     */
     @Override
     public List<NetworkVO> listBy(final long accountId, final long dataCenterId, final String cidr, final boolean skipVpc) {
-        // TODO Auto-generated method stub
         return null;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#listByZoneAndGuestType(long, long, com.cloud.network.Network.GuestType, java.lang.Boolean)
-     */
     @Override
     public List<NetworkVO> listByZoneAndGuestType(final long accountId, final long dataCenterId, final GuestType type, final Boolean isSystem) {
-        // TODO Auto-generated method stub
         return null;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#persist(com.cloud.network.NetworkVO, boolean, java.util.Map)
-     */
     @Override
     public NetworkVO persist(final NetworkVO network, final boolean gc, final Map<String, String> serviceProviderMap) {
-        // TODO Auto-generated method stub
         return null;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#createSearchBuilderForAccount()
-     */
     @Override
     public SearchBuilder<NetworkAccountVO> createSearchBuilderForAccount() {
-        // TODO Auto-generated method stub
         return null;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#getNetworksForOffering(long, long, long)
-     */
     @Override
     public List<NetworkVO> getNetworksForOffering(final long offeringId, final long dataCenterId, final long accountId) {
-        // TODO Auto-generated method stub
         return null;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#getNextAvailableMacAddress(long)
-     */
     @Override
     public String getNextAvailableMacAddress(final long networkConfigId, Integer zoneMacIdentifier) {
-        // TODO Auto-generated method stub
         return null;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#listBy(long, long)
-     */
     @Override
     public List<NetworkVO> listBy(final long accountId, final long networkId) {
-        // TODO Auto-generated method stub
         return null;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#countByZoneAndUri(long, java.lang.String)
-     */
     @Override
     public long countByZoneAndUri(final long zoneId, final String broadcastUri) {
-        // TODO Auto-generated method stub
         return 0;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#countByZoneUriAndGuestType(long, java.lang.String, com.cloud.network.Network.GuestType)
-     */
     @Override
     public long countByZoneUriAndGuestType(final long zoneId, final String broadcastUri, final GuestType guestType) {
-        // TODO Auto-generated method stub
         return 0;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#listByZone(long)
-     */
     @Override
     public List<NetworkVO> listByZone(final long zoneId) {
-        // TODO Auto-generated method stub
         return null;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#changeActiveNicsBy(long, int)
-     */
     @Override
     public void changeActiveNicsBy(final long networkId, final int nicsCount) {
-        // TODO Auto-generated method stub
-
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#getActiveNicsIn(long)
-     */
     @Override
     public int getActiveNicsIn(final long networkId) {
-        // TODO Auto-generated method stub
         return 0;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#findNetworksToGarbageCollect()
-     */
     @Override
     public List<Long> findNetworksToGarbageCollect() {
-        // TODO Auto-generated method stub
         return null;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#clearCheckForGc(long)
-     */
     @Override
     public void clearCheckForGc(final long networkId) {
-        // TODO Auto-generated method stub
-
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#listByZoneSecurityGroup(java.lang.Long)
-     */
     @Override
     public List<NetworkVO> listByZoneSecurityGroup(final Long zoneId) {
-        // TODO Auto-generated method stub
         return null;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#addDomainToNetwork(long, long, java.lang.Boolean)
-     */
     @Override
     public void addDomainToNetwork(final long networkId, final long domainId, final Boolean subdomainAccess) {
-        // TODO Auto-generated method stub
-
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#listByPhysicalNetwork(long)
-     */
     @Override
     public List<NetworkVO> listByPhysicalNetwork(final long physicalNetworkId) {
-        // TODO Auto-generated method stub
         return null;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#listSecurityGroupEnabledNetworks()
-     */
     @Override
     public List<NetworkVO> listSecurityGroupEnabledNetworks() {
-        // TODO Auto-generated method stub
         return null;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#listByPhysicalNetworkTrafficType(long, com.cloud.network.Networks.TrafficType)
-     */
     @Override
     public List<NetworkVO> listByPhysicalNetworkTrafficType(final long physicalNetworkId, final TrafficType trafficType) {
-        // TODO Auto-generated method stub
         return null;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#listBy(long, long, com.cloud.network.Network.GuestType, com.cloud.network.Networks.TrafficType)
-     */
     @Override
     public List<NetworkVO> listBy(final long accountId, final long dataCenterId, final GuestType type, final TrafficType trafficType) {
-        // TODO Auto-generated method stub
         return null;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#listByPhysicalNetworkAndProvider(long, java.lang.String)
-     */
     @Override
     public List<NetworkVO> listByPhysicalNetworkAndProvider(final long physicalNetworkId, final String providerName) {
-        // TODO Auto-generated method stub
         return null;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#persistNetworkServiceProviders(long, java.util.Map)
-     */
     @Override
     public void persistNetworkServiceProviders(final long networkId, final Map<String, String> serviceProviderMap) {
-        // TODO Auto-generated method stub
-
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#update(java.lang.Long, com.cloud.network.NetworkVO, java.util.Map)
-     */
     @Override
     public boolean update(final Long networkId, final NetworkVO network, final Map<String, String> serviceProviderMap) {
-        // TODO Auto-generated method stub
         return false;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#listByZoneAndTrafficType(long, com.cloud.network.Networks.TrafficType)
-     */
     @Override
     public List<NetworkVO> listByZoneAndTrafficType(final long zoneId, final TrafficType trafficType) {
-        // TODO Auto-generated method stub
         return null;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#setCheckForGc(long)
-     */
     @Override
     public void setCheckForGc(final long networkId) {
-        // TODO Auto-generated method stub
-
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#getNetworkCountByNetworkOffId(long)
-     */
     @Override
     public int getNetworkCountByNetworkOffId(final long networkOfferingId) {
-        // TODO Auto-generated method stub
         return 0;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#countNetworksUserCanCreate(long)
-     */
     @Override
     public long countNetworksUserCanCreate(final long ownerId) {
-        // TODO Auto-generated method stub
         return 0;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#listSourceNATEnabledNetworks(long, long, com.cloud.network.Network.GuestType)
-     */
     @Override
     public List<NetworkVO> listSourceNATEnabledNetworks(final long accountId, final long dataCenterId, final GuestType type) {
-        // TODO Auto-generated method stub
         return null;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#getNetworkCountByVpcId(long)
-     */
     @Override
     public int getNetworkCountByVpcId(final long vpcId) {
-        // TODO Auto-generated method stub
         return 0;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#listByVpc(long)
-     */
     @Override
     public List<NetworkVO> listByVpc(final long vpcId) {
         final List<NetworkVO> networks = new ArrayList<NetworkVO>();
@@ -328,21 +196,13 @@ public class MockNetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implemen
         return networks;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#getPrivateNetwork(java.lang.String, java.lang.String, long, long)
-     */
     @Override
     public NetworkVO getPrivateNetwork(final String broadcastUri, final String cidr, final long accountId, final long zoneId, final Long netofferid) {
-        // TODO Auto-generated method stub
         return null;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#countVpcNetworks(long)
-     */
     @Override
     public long countVpcNetworks(final long vpcId) {
-        // TODO Auto-generated method stub
         return 0;
     }
 
@@ -351,24 +211,18 @@ public class MockNetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implemen
         return true;
     }
 
-    /* (non-Javadoc)
-     * @see com.cloud.network.dao.NetworkDao#listNetworksByAccount(long, long, com.cloud.network.Network.GuestType, boolean)
-     */
     @Override
     public List<NetworkVO> listNetworksByAccount(final long accountId, final long zoneId, final GuestType type, final boolean isSystem) {
-        // TODO Auto-generated method stub
         return null;
     }
 
     @Override
     public List<NetworkVO> listRedundantNetworks() {
-        // TODO Auto-generated method stub
         return null;
     }
 
     @Override
     public List<NetworkVO> listVpcNetworks() {
-        // TODO Auto-generated method stub
         return null;
     }
 
@@ -384,7 +238,6 @@ public class MockNetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implemen
 
     @Override
     public List<NetworkVO> listNetworkVO(List<Long> idset) {
-        // TODO Auto-generated method stub
         return null;
     }
-}
+}
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
"commits@cloudstack.apache.org" <co...@cloudstack.apache.org>.