JCLOUDS-1431 - Support AU geo for Live Tests.
diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApi.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApi.java
index ce8c1a6..9824357 100644
--- a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApi.java
+++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApi.java
@@ -17,6 +17,7 @@
 package org.jclouds.dimensiondata.cloudcontrol;
 
 import org.jclouds.dimensiondata.cloudcontrol.features.AccountApi;
+import org.jclouds.dimensiondata.cloudcontrol.features.CustomerImageApi;
 import org.jclouds.dimensiondata.cloudcontrol.features.InfrastructureApi;
 import org.jclouds.dimensiondata.cloudcontrol.features.NetworkApi;
 import org.jclouds.dimensiondata.cloudcontrol.features.ServerApi;
@@ -45,4 +46,7 @@
 
    @Delegate
    TagApi getTagApi();
+
+   @Delegate
+   CustomerImageApi getCustomerImageApi();
 }
diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApiMetadata.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApiMetadata.java
index a352129..3a39c16 100644
--- a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApiMetadata.java
+++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApiMetadata.java
@@ -54,7 +54,7 @@
          id("dimensiondata-cloudcontrol").name("DimensionData CloudControl API").identityName("user name")
                .credentialName("user password")
                .documentation(URI.create("http://www.dimensiondata.com/en-US/Solutions/Cloud"))
-               .defaultEndpoint("https://api-REGION.dimensiondata.com/caas").version("2.4")
+               .defaultEndpoint("https://api-REGION.dimensiondata.com").version("2.4")
                .defaultProperties(defaultProperties).view(typeToken(ComputeServiceContext.class)).defaultModules(
                ImmutableSet.<Class<? extends Module>>builder().add(DimensionDataCloudControlHttpApiModule.class)
                      .add(DimensionDataCloudControlParserModule.class)
diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlProviderMetadata.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlProviderMetadata.java
index f25cd15..db4303d 100644
--- a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlProviderMetadata.java
+++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlProviderMetadata.java
@@ -81,8 +81,7 @@
          id("dimensiondata-cloudcontrol").name("DimensionData Cloud Control")
                .apiMetadata(new DimensionDataCloudControlApiMetadata())
                .homepage(URI.create("https://na-cloud.dimensiondata.com/"))
-               .console(URI.create("https://na-cloud.dimensiondata.com/"))
-               .endpoint("https://api-na.dimensiondata.com/caas")
+               .console(URI.create("https://na-cloud.dimensiondata.com/")).endpoint("https://api-na.dimensiondata.com")
                .defaultProperties(DimensionDataCloudControlProviderMetadata.defaultProperties());
       }
 
diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/config/DimensionDataCloudControlComputeServiceContextModule.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/config/DimensionDataCloudControlComputeServiceContextModule.java
index dca9512..c85128a 100644
--- a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/config/DimensionDataCloudControlComputeServiceContextModule.java
+++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/config/DimensionDataCloudControlComputeServiceContextModule.java
@@ -22,6 +22,7 @@
 import com.google.inject.Provides;
 import org.jclouds.compute.reference.ComputeServiceConstants;
 import org.jclouds.dimensiondata.cloudcontrol.DimensionDataCloudControlApi;
+import org.jclouds.dimensiondata.cloudcontrol.domain.CustomerImage;
 import org.jclouds.dimensiondata.cloudcontrol.domain.NetworkDomain;
 import org.jclouds.dimensiondata.cloudcontrol.domain.Server;
 import org.jclouds.dimensiondata.cloudcontrol.domain.State;
@@ -29,6 +30,7 @@
 import org.jclouds.dimensiondata.cloudcontrol.domain.VmTools;
 import org.jclouds.dimensiondata.cloudcontrol.features.NetworkApi;
 import org.jclouds.dimensiondata.cloudcontrol.features.ServerApi;
+import org.jclouds.dimensiondata.cloudcontrol.features.ServerImageApi;
 import org.jclouds.logging.Logger;
 
 import javax.annotation.Resource;
@@ -52,6 +54,7 @@
    public static final String SERVER_DELETED_PREDICATE = "SERVER_DELETED_PREDICATE";
    public static final String SERVER_NORMAL_PREDICATE = "SERVER_NORMAL_PREDICATE";
    public static final String VM_TOOLS_RUNNING_PREDICATE = "VM_TOOLS_RUNNING_PREDICATE";
+   public static final String CUSTOMER_IMAGE_DELETED_PREDICATE = "CUSTOMER_IMAGE_DELETED_PREDICATE";
 
    @Override
    protected void configure() {
@@ -132,6 +135,14 @@
             pollPeriod.pollMaxPeriod);
    }
 
+   @Provides
+   @Named(CUSTOMER_IMAGE_DELETED_PREDICATE)
+   protected Predicate<String> provideCustomerImageDeletedPredicate(final DimensionDataCloudControlApi api,
+         @Named(OPERATION_TIMEOUT) final Long operationTimeout, final ComputeServiceConstants.PollPeriod pollPeriod) {
+      return retry(new CustomerImageState(api.getServerImageApi(), State.DELETED), operationTimeout,
+            pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
+   }
+
    private class VlanState implements Predicate<String> {
 
       private final State state;
@@ -249,4 +260,24 @@
          return vmTools != null && vmTools.runningStatus() == VmTools.RunningStatus.RUNNING;
       }
    }
+
+   private class CustomerImageState implements Predicate<String> {
+
+      private final State state;
+      private final ServerImageApi serverImageApi;
+
+      private CustomerImageState(final ServerImageApi serverImageApi, final State state) {
+         this.serverImageApi = serverImageApi;
+         this.state = state;
+      }
+
+      @Override
+      public boolean apply(final String customerImageId) {
+         checkNotNull(customerImageId, "customerImageId");
+         logger.trace("looking for state on customer image %s", customerImageId);
+         final CustomerImage customerImage = serverImageApi.getCustomerImage(customerImageId);
+         final boolean isDeleted = customerImage == null && state == State.DELETED;
+         return isDeleted || (customerImage != null && customerImage.state() == state);
+      }
+   }
 }
diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/CustomerImage.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/CustomerImage.java
index a549ef7..e167851 100644
--- a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/CustomerImage.java
+++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/CustomerImage.java
@@ -41,7 +41,7 @@
          "softwareLabel", "createTime", "state", "tag", "progress", "virtualHardware", "source" })
    public static CustomerImage create(String id, String name, String description, Cluster cluster, Guest guest,
          String datacenterId, CPU cpu, int memoryGb, List<ImageNic> nics, List<Disk> disk, List<String> softwareLabel,
-         Date createTime, String state, List<TagWithIdAndName> tags, Progress progress, VirtualHardware virtualHardware,
+         Date createTime, State state, List<TagWithIdAndName> tags, Progress progress, VirtualHardware virtualHardware,
          Source source) {
       return builder().id(id).datacenterId(datacenterId).name(name).description(description).cluster(cluster)
             .guest(guest).cpu(cpu).memoryGb(memoryGb).nics(nics).disks(disk).softwareLabels(softwareLabel)
@@ -49,7 +49,7 @@
             .source(source).build();
    }
 
-   public abstract String state();
+   public abstract State state();
 
    @Nullable
    public abstract List<TagWithIdAndName> tags();
@@ -96,7 +96,7 @@
 
       public abstract Builder createTime(Date createTime);
 
-      public abstract Builder state(String state);
+      public abstract Builder state(State state);
 
       public abstract Builder progress(Progress progress);
 
diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/OsImage.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/OsImage.java
index 7b179e5..a64c7a5 100644
--- a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/OsImage.java
+++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/OsImage.java
@@ -18,6 +18,7 @@
 
 import com.google.auto.value.AutoValue;
 import com.google.common.collect.ImmutableList;
+import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.json.SerializedNames;
 
 import java.util.Date;
@@ -31,6 +32,7 @@
       type = TYPE;
    }
 
+   @Nullable
    public abstract String osImageKey();
 
    @SerializedNames({ "id", "name", "description", "cluster", "guest", "datacenterId", "cpu", "memoryGb", "nic", "disk",
diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/AccountApi.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/AccountApi.java
index 7a2740c..d3f782e 100644
--- a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/AccountApi.java
+++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/AccountApi.java
@@ -30,7 +30,7 @@
 
 @RequestFilters({ BasicAuthentication.class })
 @Consumes("application/json")
-@Path("/{jclouds.api-version}/user")
+@Path("/caas/{jclouds.api-version}/user")
 public interface AccountApi extends Closeable {
    @Named("myuser:get")
    @Path("/myUser")
diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/CustomerImageApi.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/CustomerImageApi.java
new file mode 100644
index 0000000..df2dce4
--- /dev/null
+++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/CustomerImageApi.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.dimensiondata.cloudcontrol.features;
+
+import org.jclouds.Fallbacks;
+import org.jclouds.dimensiondata.cloudcontrol.filters.OrganisationIdFilter;
+import org.jclouds.http.filters.BasicAuthentication;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.MapBinder;
+import org.jclouds.rest.annotations.PayloadParam;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.binders.BindToJsonPayload;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+@RequestFilters({ BasicAuthentication.class, OrganisationIdFilter.class })
+@Consumes(MediaType.APPLICATION_JSON)
+@Path("/caas/2.7/image")
+public interface CustomerImageApi {
+
+   @Named("image:deleteCustomerImage")
+   @POST
+   @Path("/deleteCustomerImage")
+   @Produces(MediaType.APPLICATION_JSON)
+   @MapBinder(BindToJsonPayload.class)
+   @Fallback(Fallbacks.FalseOnNotFoundOr404.class)
+   boolean deleteCustomerImage(@PayloadParam("id") String id);
+}
diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/InfrastructureApi.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/InfrastructureApi.java
index 2d76048..4961a28 100644
--- a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/InfrastructureApi.java
+++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/InfrastructureApi.java
@@ -50,7 +50,7 @@
 
 @RequestFilters({ BasicAuthentication.class, OrganisationIdFilter.class })
 @Consumes(MediaType.APPLICATION_JSON)
-@Path("/{jclouds.api-version}/infrastructure")
+@Path("/caas/{jclouds.api-version}/infrastructure")
 public interface InfrastructureApi {
 
    @Named("infrastructure:datacenter")
diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApi.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApi.java
index 2a4629b..c46ae38 100644
--- a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApi.java
+++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApi.java
@@ -68,7 +68,7 @@
 
 @RequestFilters({ BasicAuthentication.class, OrganisationIdFilter.class })
 @Consumes(MediaType.APPLICATION_JSON)
-@Path("/{jclouds.api-version}/network")
+@Path("/caas/{jclouds.api-version}/network")
 public interface NetworkApi {
 
    @Named("network:deployNetworkDomain")
diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApi.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApi.java
index 1e05293..0753141 100644
--- a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApi.java
+++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApi.java
@@ -61,7 +61,7 @@
 
 @RequestFilters({ BasicAuthentication.class, OrganisationIdFilter.class })
 @Consumes(MediaType.APPLICATION_JSON)
-@Path("/{jclouds.api-version}/server")
+@Path("/caas/{jclouds.api-version}/server")
 public interface ServerApi {
 
    @Named("server:list")
diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApi.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApi.java
index 57c560c..8a4f249 100644
--- a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApi.java
+++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApi.java
@@ -50,7 +50,7 @@
 
 @RequestFilters({ BasicAuthentication.class, OrganisationIdFilter.class })
 @Consumes(MediaType.APPLICATION_JSON)
-@Path("/{jclouds.api-version}/image")
+@Path("/caas/{jclouds.api-version}/image")
 public interface ServerImageApi {
 
    @Named("image:listOsImages")
diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApi.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApi.java
index 9b717ec..daebc31 100644
--- a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApi.java
+++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApi.java
@@ -58,7 +58,7 @@
 
 @RequestFilters({ BasicAuthentication.class, OrganisationIdFilter.class })
 @Consumes(MediaType.APPLICATION_JSON)
-@Path("/{jclouds.api-version}/tag")
+@Path("/caas/{jclouds.api-version}/tag")
 public interface TagApi {
 
    @Named("tag:createTagKey")
diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/filters/OrganisationIdFilter.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/filters/OrganisationIdFilter.java
index cf1ec1b..daf5951 100644
--- a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/filters/OrganisationIdFilter.java
+++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/filters/OrganisationIdFilter.java
@@ -32,7 +32,6 @@
 
 /**
  * Accepts requests and modifies the endpoint path so that it is injected with the organisation id.
- * Handles both oec and caas based URLs.
  */
 @Singleton
 public class OrganisationIdFilter implements HttpRequestFilter {
diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/compute/functions/BaseImageToHardwareTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/compute/functions/BaseImageToHardwareTest.java
index ca90da2..77531d8 100644
--- a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/compute/functions/BaseImageToHardwareTest.java
+++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/compute/functions/BaseImageToHardwareTest.java
@@ -31,6 +31,7 @@
 import org.jclouds.dimensiondata.cloudcontrol.domain.ImageNic;
 import org.jclouds.dimensiondata.cloudcontrol.domain.OperatingSystem;
 import org.jclouds.dimensiondata.cloudcontrol.domain.OsImage;
+import org.jclouds.dimensiondata.cloudcontrol.domain.State;
 import org.jclouds.dimensiondata.cloudcontrol.domain.VirtualHardware;
 import org.jclouds.dimensiondata.cloudcontrol.domain.VmTools;
 import org.testng.annotations.BeforeMethod;
@@ -91,7 +92,7 @@
                   .of(Disk.builder().id("1bddd4ed-67dc-4e5e-a0d5-b5a6c012ec14").scsiId(0).sizeGb(50)
                         .speed("HIGHPERFORMANCE").build()))
             .createTime(new SimpleDateFormatDateService().iso8601DateParse("2016-07-17T23:53:48.000Z"))
-            .datacenterId("QA1_N2_VMWARE_1").state("FAILED_ADD").guest(Guest.builder().operatingSystem(
+            .datacenterId("QA1_N2_VMWARE_1").state(State.FAILED_ADD).guest(Guest.builder().operatingSystem(
                   OperatingSystem.builder().id("WIN2012DC64").displayName("WIN2012DC/64").family("WINDOWS").build())
                   .vmTools(VmTools.builder().versionStatus(VmTools.VersionStatus.CURRENT)
                         .runningStatus(VmTools.RunningStatus.NOT_RUNNING).apiVersion(9354)
diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/CustomerImageApiMockTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/CustomerImageApiMockTest.java
new file mode 100644
index 0000000..40e71eb
--- /dev/null
+++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/CustomerImageApiMockTest.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.dimensiondata.cloudcontrol.features;
+
+import com.squareup.okhttp.mockwebserver.MockResponse;
+import org.jclouds.dimensiondata.cloudcontrol.internal.BaseAccountAwareCloudControlMockTest;
+import org.testng.annotations.Test;
+
+import static javax.ws.rs.HttpMethod.POST;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertTrue;
+
+@Test(groups = "unit", testName = "CustomerImageApiMockTest", singleThreaded = true)
+public class CustomerImageApiMockTest extends BaseAccountAwareCloudControlMockTest {
+
+   public void testDeleteCustomerImage() throws Exception {
+      server.enqueue(new MockResponse().setResponseCode(200).setBody(
+            "{\n" + "\"operation\": \"DELETE_CUSTOMER_IMAGE\",\n" + "\"responseCode\": \"IN_PROGRESS\",\n"
+                  + "\"message\": \"Request to Delete Customer Image has been accepted. Please use appropriate Get or List API for status.\"\n"
+                  + "\"requestId\": \"NA9/2015-03-05T13:46:34.848-05:00/f8fdef24-8a12-45ea-a831-\n"
+                  + "d5463212ef6a\" }"));
+      boolean deleted = api.getCustomerImageApi().deleteCustomerImage("id");
+      assertSent(POST, "/caas/2.7/6ac1e746-b1ea-4da5-a24e-caf1a978789d/image/deleteCustomerImage");
+      assertTrue(deleted);
+   }
+
+   public void testDeleteCustomerImage_404() throws Exception {
+      server.enqueue(response404());
+      boolean deleted = api.getCustomerImageApi().deleteCustomerImage("networkDomainId");
+      assertSent(POST, "/caas/2.7/6ac1e746-b1ea-4da5-a24e-caf1a978789d/image/deleteCustomerImage");
+      assertFalse(deleted);
+   }
+}
diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApiLiveTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApiLiveTest.java
index 020c0b2..6cfdafe 100644
--- a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApiLiveTest.java
+++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApiLiveTest.java
@@ -22,9 +22,7 @@
 import org.jclouds.dimensiondata.cloudcontrol.domain.FirewallRule;
 import org.jclouds.dimensiondata.cloudcontrol.domain.FirewallRuleTarget;
 import org.jclouds.dimensiondata.cloudcontrol.domain.IpRange;
-import org.jclouds.dimensiondata.cloudcontrol.domain.NatRule;
 import org.jclouds.dimensiondata.cloudcontrol.domain.Placement;
-import org.jclouds.dimensiondata.cloudcontrol.domain.PublicIpBlock;
 import org.jclouds.dimensiondata.cloudcontrol.internal.BaseDimensionDataCloudControlApiLiveTest;
 import org.jclouds.rest.ResourceAlreadyExistsException;
 import org.testng.annotations.AfterClass;
@@ -46,18 +44,11 @@
 @Test(groups = "live", testName = "NetworkApiLiveTest", singleThreaded = true)
 public class NetworkApiLiveTest extends BaseDimensionDataCloudControlApiLiveTest {
 
-   private static final String DEFAULT_PRIVATE_IPV4_BASE_ADDRESS = "10.0.0.0";
-   private static final Integer DEFAULT_PRIVATE_IPV4_PREFIX_SIZE = 24;
-   private static final String DEFAULT_PROTOCOL = "TCP";
-
    private String networkDomainId;
    private String networkDomainName;
    private String vlanId;
    private String portListId;
    private String firewallRuleId;
-   private String publicIpv4BlockId;
-   private PublicIpBlock publicIpBlock;
-   private String natRuleId;
 
    private List<String> firewallRuleIds;
 
@@ -114,63 +105,6 @@
    }
 
    @Test
-   public void testAddPublicIPv4Block() {
-      publicIpv4BlockId = api().addPublicIpBlock(PREPARED_NETWORK_DOMAIN_ID);
-      assertNotNull(publicIpv4BlockId);
-   }
-
-   @Test(dependsOnMethods = "testAddPublicIPv4Block")
-   public void testListPublicIPv4AddressBlocks() {
-      PagedIterable<PublicIpBlock> ipBlockList = api().listPublicIPv4AddressBlocks(PREPARED_NETWORK_DOMAIN_ID);
-      assertTrue(!ipBlockList.isEmpty());
-      assertEquals(ipBlockList.last().get().first().get().size(), 2);
-      assertEquals(ipBlockList.last().get().first().get().networkDomainId(), PREPARED_NETWORK_DOMAIN_ID);
-   }
-
-   @Test(dependsOnMethods = "testAddPublicIPv4Block")
-   public void testGetPublicIPv4AddressBlocks() {
-      publicIpBlock = api().getPublicIPv4AddressBlock(publicIpv4BlockId);
-      assertNotNull(publicIpBlock);
-      assertEquals(publicIpBlock.size(), 2);
-      assertEquals(publicIpBlock.networkDomainId(), PREPARED_NETWORK_DOMAIN_ID);
-   }
-
-   @Test(dependsOnMethods = "testGetPublicIPv4AddressBlocks")
-   public void testCreateNatRule() {
-      natRuleId = api()
-            .createNatRule(PREPARED_NETWORK_DOMAIN_ID, PREPARED_PRIVATE_IPV4_ADDRESS, publicIpBlock.baseIp());
-      assertNotNull(natRuleId);
-   }
-
-   @Test(dependsOnMethods = "testCreateNatRule")
-   public void testListNatRules() {
-      PagedIterable<NatRule> natRulesList = api().listNatRules(PREPARED_NETWORK_DOMAIN_ID);
-      assertTrue(!natRulesList.isEmpty());
-      assertEquals(natRulesList.last().get().first().get().networkDomainId(), PREPARED_NETWORK_DOMAIN_ID);
-   }
-
-   @Test(dependsOnMethods = { "testCreateNatRule", "testListNatRules" })
-   public void testGetNatRule() {
-      NatRule natRule = api().getNatRule(natRuleId);
-      assertNotNull(natRule);
-      assertEquals(natRule.networkDomainId(), PREPARED_NETWORK_DOMAIN_ID);
-   }
-
-   @Test(dependsOnMethods = "testGetNatRule", alwaysRun = true)
-   public void testDeleteNatRule() {
-      api().deleteNatRule(natRuleId);
-      NatRule natRule = api().getNatRule(natRuleId);
-      assertNull(natRule);
-   }
-
-   @Test(dependsOnMethods = "testDeleteNatRule")
-   public void testRemovePublicIpBlock() {
-      api().removePublicIpBlock(publicIpv4BlockId);
-      publicIpBlock = api().getPublicIPv4AddressBlock(publicIpv4BlockId);
-      assertNull(publicIpBlock);
-   }
-
-   @Test
    public void testDeployNetworkDomain() {
       networkDomainName = NetworkApiLiveTest.class.getSimpleName() + new Date().getTime();
       networkDomainId = api().deployNetworkDomain(datacenters.iterator().next(), networkDomainName,
@@ -204,9 +138,6 @@
          assertTrue(networkDomainDeletedPredicate.apply(networkDomainId),
                "network domain is not in a DELETED state after timeout");
       }
-      if (publicIpBlock != null) {
-         api().removePublicIpBlock(publicIpBlock.id());
-      }
    }
 
    private NetworkApi api() {
diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApiLiveTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApiLiveTest.java
index e30f92c..9fd3e91 100644
--- a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApiLiveTest.java
+++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApiLiveTest.java
@@ -16,21 +16,38 @@
  */
 package org.jclouds.dimensiondata.cloudcontrol.features;
 
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
+import org.jclouds.collect.PagedIterable;
 import org.jclouds.dimensiondata.cloudcontrol.domain.CpuSpeed;
+import org.jclouds.dimensiondata.cloudcontrol.domain.CustomerImage;
 import org.jclouds.dimensiondata.cloudcontrol.domain.Disk;
 import org.jclouds.dimensiondata.cloudcontrol.domain.NIC;
+import org.jclouds.dimensiondata.cloudcontrol.domain.NatRule;
 import org.jclouds.dimensiondata.cloudcontrol.domain.NetworkInfo;
+import org.jclouds.dimensiondata.cloudcontrol.domain.OsImage;
+import org.jclouds.dimensiondata.cloudcontrol.domain.PublicIpBlock;
 import org.jclouds.dimensiondata.cloudcontrol.domain.Server;
+import org.jclouds.dimensiondata.cloudcontrol.domain.Tag;
+import org.jclouds.dimensiondata.cloudcontrol.domain.TagInfo;
 import org.jclouds.dimensiondata.cloudcontrol.domain.options.CloneServerOptions;
 import org.jclouds.dimensiondata.cloudcontrol.internal.BaseDimensionDataCloudControlApiLiveTest;
+import org.jclouds.dimensiondata.cloudcontrol.options.DatacenterIdListFilters;
 import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
+import java.util.Collections;
+import java.util.Date;
 import java.util.List;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertTrue;
 
 @Test(groups = "live", testName = "ServerApiLiveTest", singleThreaded = true)
@@ -39,10 +56,25 @@
    private String serverId;
    private String cloneImageId;
    private final String deployedServerName = ServerApiLiveTest.class.getSimpleName() + System.currentTimeMillis();
+   private String vlanId;
+   private String networkDomainId;
+   private String imageId;
+   private String tagKeyId;
+   private String publicIpv4BlockId;
+   private PublicIpBlock publicIpBlock;
+   private String natRuleId;
+
+   @BeforeClass
+   public void init() {
+      final String datacenterId = deployNetworkDomain();
+      deployVlan();
+      findOsImage(datacenterId);
+      tagKeyId = createTagKey();
+   }
 
    @Test(dependsOnMethods = "testDeployAndStartServer")
    public void testListServers() {
-      List<Server> servers = api().listServers().concat().toList();
+      List<Server> servers = api.getServerApi().listServers().concat().toList();
       assertNotNull(servers);
       boolean foundDeployedServer = false;
       for (Server s : servers) {
@@ -58,9 +90,10 @@
    public void testDeployAndStartServer() {
       Boolean started = Boolean.TRUE;
       NetworkInfo networkInfo = NetworkInfo
-            .create(NETWORK_DOMAIN_ID, NIC.builder().vlanId(VLAN_ID).build(), Lists.<NIC>newArrayList());
+            .create(networkDomainId, NIC.builder().vlanId(vlanId).build(), Lists.<NIC>newArrayList());
       List<Disk> disks = ImmutableList.of(Disk.builder().scsiId(0).speed("STANDARD").build());
-      serverId = api().deployServer(deployedServerName, IMAGE_ID, started, networkInfo, "P$$ssWwrrdGoDd!", disks, null);
+      serverId = api.getServerApi()
+            .deployServer(deployedServerName, imageId, started, networkInfo, "P$$ssWwrrdGoDd!", disks, null);
       assertNotNull(serverId);
       assertTrue(serverStartedPredicate.apply(serverId), "server did not start after timeout");
       assertTrue(serverNormalPredicate.apply(serverId), "server was not NORMAL after timeout");
@@ -68,55 +101,212 @@
 
    @Test(dependsOnMethods = "testDeployAndStartServer")
    public void testReconfigureServer() {
-      api().reconfigureServer(serverId, 4, CpuSpeed.HIGHPERFORMANCE.name(), 1);
+      api.getServerApi().reconfigureServer(serverId, 4, CpuSpeed.HIGHPERFORMANCE.name(), 1);
       assertTrue(serverNormalPredicate.apply(serverId), "server was not NORMAL after timeout");
    }
 
    @Test(dependsOnMethods = "testDeployAndStartServer")
+   public void testApplyTagToServer() {
+      api.getTagApi()
+            .applyTags(serverId, "SERVER", Collections.singletonList(TagInfo.create(tagKeyId, "jcloudsValue")));
+   }
+
+   @Test(dependsOnMethods = "testApplyTagToServer")
+   public void testListTags() {
+      PagedIterable<Tag> response = api.getTagApi().listTags();
+      assertTrue(FluentIterable.from(response.concat().toList()).anyMatch(new Predicate<Tag>() {
+         @Override
+         public boolean apply(Tag input) {
+            return input.tagKeyId().equals(tagKeyId);
+         }
+      }), String.format("Couldn't find tagKeyId %s in listTags response", tagKeyId));
+   }
+
+   @Test(dependsOnMethods = "testListTags")
+   public void testRemoveTagFromServer() {
+      api.getTagApi().removeTags(serverId, "SERVER", Collections.singletonList(tagKeyId));
+      assertFalse(FluentIterable.from(api.getTagApi().listTags().concat().toList()).anyMatch(new Predicate<Tag>() {
+         @Override
+         public boolean apply(Tag input) {
+            return input.tagKeyId().equals(tagKeyId);
+         }
+      }));
+   }
+
+   @Test(dependsOnMethods = "testDeployAndStartServer")
    public void testRebootServer() {
-      api().rebootServer(serverId);
+      api.getServerApi().rebootServer(serverId);
       assertTrue(serverNormalPredicate.apply(serverId), "server was not NORMAL after timeout");
       assertTrue(vmtoolsRunningPredicate.apply(serverId), "server vm tools not running after timeout");
    }
 
+   @Test(dependsOnMethods = "testDeployAndStartServer")
+   public void testAddPublicIPv4Block() {
+      publicIpv4BlockId = api.getNetworkApi().addPublicIpBlock(networkDomainId);
+      assertNotNull(publicIpv4BlockId);
+   }
+
+   @Test(dependsOnMethods = "testAddPublicIPv4Block")
+   public void testListPublicIPv4AddressBlocks() {
+      PagedIterable<PublicIpBlock> ipBlockList = api.getNetworkApi().listPublicIPv4AddressBlocks(networkDomainId);
+      assertTrue(!ipBlockList.isEmpty());
+      assertEquals(ipBlockList.last().get().first().get().size(), 2);
+      assertEquals(ipBlockList.last().get().first().get().networkDomainId(), networkDomainId);
+   }
+
+   @Test(dependsOnMethods = "testAddPublicIPv4Block")
+   public void testGetPublicIPv4AddressBlocks() {
+      publicIpBlock = api.getNetworkApi().getPublicIPv4AddressBlock(publicIpv4BlockId);
+      assertNotNull(publicIpBlock);
+      assertEquals(publicIpBlock.size(), 2);
+      assertEquals(publicIpBlock.networkDomainId(), networkDomainId);
+   }
+
+   @Test(dependsOnMethods = "testGetPublicIPv4AddressBlocks")
+   public void testCreateNatRule() {
+      natRuleId = api.getNetworkApi()
+            .createNatRule(networkDomainId, PREPARED_PRIVATE_IPV4_ADDRESS, publicIpBlock.baseIp());
+      assertNotNull(natRuleId);
+   }
+
+   @Test(dependsOnMethods = "testCreateNatRule")
+   public void testListNatRules() {
+      PagedIterable<NatRule> natRulesList = api.getNetworkApi().listNatRules(networkDomainId);
+      assertTrue(!natRulesList.isEmpty());
+      assertEquals(natRulesList.last().get().first().get().networkDomainId(), networkDomainId);
+   }
+
+   @Test(dependsOnMethods = { "testCreateNatRule", "testListNatRules" })
+   public void testGetNatRule() {
+      NatRule natRule = api.getNetworkApi().getNatRule(natRuleId);
+      assertNotNull(natRule);
+      assertEquals(natRule.networkDomainId(), networkDomainId);
+   }
+
+   @Test(dependsOnMethods = "testGetNatRule", alwaysRun = true)
+   public void testDeleteNatRule() {
+      api.getNetworkApi().deleteNatRule(natRuleId);
+      NatRule natRule = api.getNetworkApi().getNatRule(natRuleId);
+      assertNull(natRule);
+   }
+
+   @Test(dependsOnMethods = { "testDeleteNatRule" })
+   public void testRemovePublicIpBlock() {
+      api.getNetworkApi().removePublicIpBlock(publicIpv4BlockId);
+      publicIpBlock = api.getNetworkApi().getPublicIPv4AddressBlock(publicIpv4BlockId);
+      assertNull(publicIpBlock);
+   }
+
    @Test(dependsOnMethods = "testRebootServer")
    public void testPowerOffServer() {
-      api().powerOffServer(serverId);
+      api.getServerApi().powerOffServer(serverId);
       assertTrue(serverStoppedPredicate.apply(serverId), "server did not power off after timeout");
    }
 
    @Test(dependsOnMethods = "testPowerOffServer")
    public void testStartServer() {
-      api().startServer(serverId);
+      api.getServerApi().startServer(serverId);
       assertTrue(serverStartedPredicate.apply(serverId), "server did not start after timeout");
       assertTrue(vmtoolsRunningPredicate.apply(serverId), "server vm tools not running after timeout");
    }
 
    @Test(dependsOnMethods = "testStartServer")
    public void testShutdownServer() {
-      api().shutdownServer(serverId);
+      api.getServerApi().shutdownServer(serverId);
       assertTrue(serverStoppedPredicate.apply(serverId), "server did not shutdown after timeout");
    }
 
    @Test(dependsOnMethods = "testShutdownServer")
-   public void testCloneServer() {
+   public void testCloneServerToMakeCustomerImage() {
       CloneServerOptions options = CloneServerOptions.builder().clusterId("").description("")
             .guestOsCustomization(false).build();
-      cloneImageId = api().cloneServer(serverId, "ServerApiLiveTest-" + System.currentTimeMillis(), options);
+      cloneImageId = api.getServerApi()
+            .cloneServer(serverId, "ServerApiLiveTest-" + System.currentTimeMillis(), options);
       assertNotNull(cloneImageId);
       assertTrue(serverNormalPredicate.apply(serverId), "server was not NORMAL after timeout");
    }
 
+   @Test(dependsOnMethods = "testCloneServerToMakeCustomerImage")
+   public void testListCustomerImages() {
+      FluentIterable<CustomerImage> customerImages = api.getServerImageApi().listCustomerImages().concat();
+      assertNotNull(customerImages);
+      assertTrue(customerImages.anyMatch(new Predicate<CustomerImage>() {
+         @Override
+         public boolean apply(CustomerImage input) {
+            return input.id().equals(cloneImageId);
+         }
+      }));
+   }
+
+   @Test(dependsOnMethods = "testCloneServerToMakeCustomerImage")
+   public void testGetCustomerImage() {
+      CustomerImage customerImage = api.getServerImageApi().getCustomerImage(cloneImageId);
+      assertNotNull(customerImage);
+   }
+
+   @Test(dependsOnMethods = "testGetCustomerImage")
+   public void testDeleteCustomerImage() {
+      boolean deleted = api.getCustomerImageApi().deleteCustomerImage(cloneImageId);
+      assertTrue(deleted);
+      assertTrue(customerImageDeletedPredicate.apply(cloneImageId), "customer image was not DELETED after timeout");
+   }
+
    @AfterClass(alwaysRun = true)
-   public void testDeleteServer() {
+   public void testDeleteServerAndNetworking() {
+      if (publicIpBlock != null) {
+         api.getNetworkApi().removePublicIpBlock(publicIpBlock.id());
+      }
       if (serverId != null) {
-         api().deleteServer(serverId);
+         api.getServerApi().deleteServer(serverId);
          assertTrue(serverDeletedPredicate.apply(serverId), "server was not DELETED after timeout");
       }
+      if (vlanId != null) {
+         api.getNetworkApi().deleteVlan(vlanId);
+         assertTrue(vlanDeletedPredicate.apply(vlanId), "vlan is not in a DELETED state after timeout");
+      }
+      if (networkDomainId != null) {
+         api.getNetworkApi().deleteNetworkDomain(networkDomainId);
+         assertTrue(networkDomainDeletedPredicate.apply(networkDomainId),
+               "network domain is not in a DELETED state after timeout");
+      }
+      if (tagKeyId != null && !tagKeyId.isEmpty()) {
+         api.getTagApi().deleteTagKey(tagKeyId);
+      }
    }
 
-   private ServerApi api() {
-      return api.getServerApi();
+   private void findOsImage(final String datacenterId) {
+      Optional<OsImage> osImageOptional = api.getServerImageApi()
+            .listOsImages(DatacenterIdListFilters.Builder.datacenterId(datacenterId)).first();
+      assertTrue(osImageOptional.isPresent(), "unable to find compatible image for datacenter");
+      imageId = osImageOptional.get().id();
+   }
+
+   private void deployVlan() {
+      vlanId = api.getNetworkApi()
+            .deployVlan(networkDomainId, ServerApiLiveTest.class.getSimpleName() + new Date().getTime(),
+                  ServerApiLiveTest.class.getSimpleName() + new Date().getTime(), DEFAULT_PRIVATE_IPV4_BASE_ADDRESS,
+                  DEFAULT_PRIVATE_IPV4_PREFIX_SIZE);
+      assertNotNull(vlanId);
+      assertTrue(vlanNormalPredicate.apply(vlanId), "vlan is not in a NORMAL state after timeout");
+   }
+
+   private String deployNetworkDomain() {
+      String networkDomainName = ServerApiLiveTest.class.getSimpleName() + new Date().getTime();
+      final String datacenterId = datacenters.iterator().next();
+      networkDomainId = api.getNetworkApi().deployNetworkDomain(datacenterId, networkDomainName,
+            ServerApiLiveTest.class.getSimpleName() + new Date().getTime() + "description", "ESSENTIALS");
+      assertNotNull(networkDomainId);
+      assertTrue(networkDomainNormalPredicate.apply(networkDomainId),
+            "network domain is not in a NORMAL state after timeout");
+      return datacenterId;
+   }
+
+   private String createTagKey() {
+      String tagKeyName = "jcloudsTagKeyName" + System.currentTimeMillis();
+      String tagKeyId = api.getTagApi()
+            .createTagKey(tagKeyName, "jcloudsTagKeyDescription", Boolean.TRUE, Boolean.FALSE);
+      assertNotNull(tagKeyId);
+      return tagKeyId;
    }
 
 }
diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApiLiveTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApiLiveTest.java
index 4d004e9..02ab7ce 100644
--- a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApiLiveTest.java
+++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApiLiveTest.java
@@ -18,7 +18,6 @@
 
 import com.google.common.collect.FluentIterable;
 import org.jclouds.collect.PagedIterable;
-import org.jclouds.dimensiondata.cloudcontrol.domain.CustomerImage;
 import org.jclouds.dimensiondata.cloudcontrol.domain.OsImage;
 import org.jclouds.dimensiondata.cloudcontrol.internal.BaseDimensionDataCloudControlApiLiveTest;
 import org.testng.annotations.Test;
@@ -51,28 +50,6 @@
       assertNotNull(osImage);
    }
 
-   @Test
-   public void testListCustomerImages() {
-      FluentIterable<CustomerImage> customerImages = getCustomerImages();
-      assertNotNull(customerImages);
-      for (CustomerImage customerImage : customerImages) {
-         assertNotNull(customerImage);
-      }
-   }
-
-   @Test
-   public void testGetCustomerImage() {
-      CustomerImage customerImage = api().getCustomerImage(PREPARED_CUSTOMER_IMAGE_ID);
-      assertNotNull(customerImage);
-      assertTrue(customerImage.datacenterId().equals("NA9"));
-   }
-
-   private FluentIterable<CustomerImage> getCustomerImages() {
-      FluentIterable<CustomerImage> customerImages = api().listCustomerImages().concat();
-      assertNotNull(customerImages);
-      return customerImages;
-   }
-
    private ServerImageApi api() {
       return api.getServerImageApi();
    }
diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApiLiveTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApiLiveTest.java
index e8c5052..f7387cd 100644
--- a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApiLiveTest.java
+++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApiLiveTest.java
@@ -19,17 +19,12 @@
 import com.google.common.base.Predicate;
 import com.google.common.collect.FluentIterable;
 import org.jclouds.collect.PagedIterable;
-import org.jclouds.dimensiondata.cloudcontrol.domain.Tag;
-import org.jclouds.dimensiondata.cloudcontrol.domain.TagInfo;
 import org.jclouds.dimensiondata.cloudcontrol.domain.TagKey;
 import org.jclouds.dimensiondata.cloudcontrol.internal.BaseDimensionDataCloudControlApiLiveTest;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import java.util.Collections;
-
-import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 import static org.testng.AssertJUnit.assertEquals;
@@ -39,27 +34,18 @@
 
    private String tagKeyId;
    private String tagKeyName;
-   private String assetType = "SERVER";
 
    @BeforeClass
    public void setup() {
       super.setup();
       createTagKeyIfNotExist();
-      applyTagToAsset();
    }
 
-   private void applyTagToAsset() {
-      if (tagKeyId != null) {
-         api().applyTags(SERVER_ID, assetType, Collections.singletonList(TagInfo.create(tagKeyId, "jcloudsValue")));
-      }
-   }
-
-   private String createTagKey() {
+   private void createTagKey() {
       tagKeyName = "jcloudsTagKeyName" + System.currentTimeMillis();
       tagKeyId = api().createTagKey(tagKeyName, "jcloudsTagKeyDescription", Boolean.TRUE, Boolean.FALSE);
       assertNotNull(tagKeyId);
       assertTagKeyExistsAndIsValid(tagKeyId, tagKeyName, "jcloudsTagKeyDescription", Boolean.TRUE, Boolean.FALSE);
-      return tagKeyId;
    }
 
    @Test
@@ -87,33 +73,6 @@
       }
    }
 
-   @Test
-   public void testApplyTags() {
-      api().applyTags(SERVER_ID, assetType, Collections.singletonList(TagInfo.create(tagKeyId, "jcloudsValue")));
-   }
-
-   @Test
-   public void testListTags() {
-      PagedIterable<Tag> response = api().listTags();
-      assertTrue(FluentIterable.from(response.concat().toList()).anyMatch(new Predicate<Tag>() {
-         @Override
-         public boolean apply(Tag input) {
-            return input.tagKeyId().equals(tagKeyId);
-         }
-      }), String.format("Couldn't find tagKeyId %s in listTags response", tagKeyId));
-   }
-
-   @Test(dependsOnMethods = { "testListTags", "testListTagKeys" })
-   public void testRemoveTags() {
-      api().removeTags(SERVER_ID, assetType, Collections.singletonList(tagKeyId));
-      assertFalse(FluentIterable.from(api().listTags().concat().toList()).anyMatch(new Predicate<Tag>() {
-         @Override
-         public boolean apply(Tag input) {
-            return input.tagKeyId().equals(tagKeyId);
-         }
-      }));
-   }
-
    private void assertTagKeyExistsAndIsValid(String tagKeyId, String tagKeyName, String description,
          boolean valueRequired, boolean displayOnReport) {
       TagKey tagKey = api().tagKeyById(tagKeyId);
diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlApiLiveTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlApiLiveTest.java
index e682f34..e040d41 100644
--- a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlApiLiveTest.java
+++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlApiLiveTest.java
@@ -17,6 +17,7 @@
 package org.jclouds.dimensiondata.cloudcontrol.internal;
 
 import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.Injector;
 import com.google.inject.Key;
@@ -30,17 +31,20 @@
 import org.jclouds.dimensiondata.cloudcontrol.DimensionDataCloudControlApi;
 import org.jclouds.dimensiondata.cloudcontrol.DimensionDataCloudControlApiMetadata;
 import org.jclouds.dimensiondata.cloudcontrol.DimensionDataCloudControlProviderMetadata;
-import org.jclouds.location.suppliers.ZoneIdsSupplier;
+import org.jclouds.location.suppliers.ImplicitRegionIdSupplier;
+import org.jclouds.location.suppliers.RegionIdToZoneIdsSupplier;
 import org.jclouds.logging.config.LoggingModule;
 import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
 import org.jclouds.rest.ApiContext;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
+import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
 
 import static com.google.common.util.concurrent.MoreExecutors.newDirectExecutorService;
+import static org.jclouds.dimensiondata.cloudcontrol.config.DimensionDataCloudControlComputeServiceContextModule.CUSTOMER_IMAGE_DELETED_PREDICATE;
 import static org.jclouds.dimensiondata.cloudcontrol.config.DimensionDataCloudControlComputeServiceContextModule.NETWORK_DOMAIN_DELETED_PREDICATE;
 import static org.jclouds.dimensiondata.cloudcontrol.config.DimensionDataCloudControlComputeServiceContextModule.NETWORK_DOMAIN_NORMAL_PREDICATE;
 import static org.jclouds.dimensiondata.cloudcontrol.config.DimensionDataCloudControlComputeServiceContextModule.SERVER_DELETED_PREDICATE;
@@ -58,15 +62,10 @@
    private final Set<Module> modules = ImmutableSet.<Module>of(new ExecutorServiceModule(newDirectExecutorService()));
    protected Set<String> datacenters;
 
-   protected static final String PREPARED_CUSTOMER_IMAGE_ID = "fb438e00-10f8-47ac-a434-f3f9461c3a76";
-   protected static final String NETWORK_DOMAIN_ID = System
-         .getProperty("networkDomainId", "690de302-bb80-49c6-b401-8c02bbefb945");
-   protected static final String VLAN_ID = System.getProperty("vlanId", "6b25b02e-d3a2-4e69-8ca7-9bab605deebd");
-   protected static final String IMAGE_ID = System.getProperty("imageId", "4c02126c-32fc-4b4c-9466-9824c1b5aa0f");
-   protected static final String PREPARED_NETWORK_DOMAIN_ID = System
-         .getProperty("networkDomainId", "d122949b-8990-46d6-98f0-91c8676fc720");
    protected static final String PREPARED_PRIVATE_IPV4_ADDRESS = "10.0.0.6";
-   protected static final String SERVER_ID = System.getProperty("serverId", "b1c537bb-018c-49ba-beef-e0600e948149");
+   protected static final String DEFAULT_PRIVATE_IPV4_BASE_ADDRESS = "10.0.0.0";
+   protected static final Integer DEFAULT_PRIVATE_IPV4_PREFIX_SIZE = 24;
+   protected static final String DEFAULT_PROTOCOL = "TCP";
 
    protected Predicate<String> vlanDeletedPredicate;
    protected Predicate<String> vlanNormalPredicate;
@@ -77,6 +76,7 @@
    protected Predicate<String> serverDeletedPredicate;
    protected Predicate<String> serverNormalPredicate;
    protected Predicate<String> vmtoolsRunningPredicate;
+   protected Predicate<String> customerImageDeletedPredicate;
 
    public BaseDimensionDataCloudControlApiLiveTest() {
       provider = "dimensiondata-cloudcontrol";
@@ -89,8 +89,17 @@
       datacenters = getZones();
    }
 
+   //   private Set<String> getZones() {
+   //      return ctx.utils().injector().getInstance(ZoneIdsSupplier.class).get();
+   //   }
+
+   // TODO this leads to a warning - WARNING: failed to find key for value https://api-na.dimensiondata.com in {au=https://api-au.dimensiondata.com}; choosing first: au
+   // would like to improve this.  Currently I override the location config using -  -Djclouds.regions=au -Djclouds.region.au.zones=AU9
    private Set<String> getZones() {
-      return ctx.utils().injector().getInstance(ZoneIdsSupplier.class).get();
+      final String region = ctx.utils().injector().getInstance(ImplicitRegionIdSupplier.class).get();
+      final Map<String, Supplier<Set<String>>> regionToZoneMap = ctx.utils().injector()
+            .getInstance(RegionIdToZoneIdsSupplier.class).get();
+      return regionToZoneMap.get(region).get();
    }
 
    @Override
@@ -124,6 +133,8 @@
       }, Names.named(SERVER_NORMAL_PREDICATE)));
       vmtoolsRunningPredicate = injector.getInstance(Key.get(new TypeLiteral<Predicate<String>>() {
       }, Names.named(VM_TOOLS_RUNNING_PREDICATE)));
+      customerImageDeletedPredicate = injector.getInstance(Key.get(new TypeLiteral<Predicate<String>>() {
+      }, Names.named(CUSTOMER_IMAGE_DELETED_PREDICATE)));
 
       return injector.getInstance(DimensionDataCloudControlApi.class);
    }
diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlMockTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlMockTest.java
index 7ddba51..00fddf8 100644
--- a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlMockTest.java
+++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlMockTest.java
@@ -81,7 +81,7 @@
       server = new MockWebServer();
       server.play();
       ctx = ContextBuilder.newBuilder(DimensionDataCloudControlProviderMetadata.builder().build()).credentials("", "")
-            .endpoint(url("/caas/")).modules(modules).overrides(new Properties()).build();
+            .endpoint(url("")).modules(modules).overrides(new Properties()).build();
       json = ctx.utils().injector().getInstance(Json.class);
       api = ctx.getApi();
       applyAdditionalServerConfig();
diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/CustomerImagesParseTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/CustomerImagesParseTest.java
index 7b8e0ae..e9f1f8d 100644
--- a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/CustomerImagesParseTest.java
+++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/CustomerImagesParseTest.java
@@ -26,6 +26,7 @@
 import org.jclouds.dimensiondata.cloudcontrol.domain.Guest;
 import org.jclouds.dimensiondata.cloudcontrol.domain.ImageNic;
 import org.jclouds.dimensiondata.cloudcontrol.domain.OperatingSystem;
+import org.jclouds.dimensiondata.cloudcontrol.domain.State;
 import org.jclouds.dimensiondata.cloudcontrol.domain.VirtualHardware;
 import org.jclouds.dimensiondata.cloudcontrol.domain.VmTools;
 import org.jclouds.dimensiondata.cloudcontrol.internal.BaseDimensionDataCloudControlParseTest;
@@ -52,7 +53,7 @@
                   .of(Disk.builder().id("1bddd4ed-67dc-4e5e-a0d5-b5a6c012ec14").scsiId(0).sizeGb(50)
                         .speed("HIGHPERFORMANCE").build()))
             .createTime(new SimpleDateFormatDateService().iso8601DateParse("2016-07-17T23:53:48.000Z"))
-            .datacenterId("QA1_N2_VMWARE_1").state("FAILED_ADD").guest(Guest.builder().operatingSystem(
+            .datacenterId("QA1_N2_VMWARE_1").state(State.FAILED_ADD).guest(Guest.builder().operatingSystem(
                   OperatingSystem.builder().id("WIN2012DC64").displayName("WIN2012DC/64").family("WINDOWS").build())
                   .vmTools(VmTools.builder().versionStatus(VmTools.VersionStatus.CURRENT)
                         .runningStatus(VmTools.RunningStatus.NOT_RUNNING).apiVersion(9354)