http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/ResourceDefinitionToCustomImage.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/ResourceDefinitionToCustomImage.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/ResourceDefinitionToCustomImage.java
new file mode 100644
index 0000000..cce6b50
--- /dev/null
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/ResourceDefinitionToCustomImage.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.azurecompute.arm.compute.functions;
+
+import static 
org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension.CUSTOM_IMAGE_OFFER;
+
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.jclouds.azurecompute.arm.AzureComputeApi;
+import 
org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.AzureComputeConstants;
+import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
+import org.jclouds.azurecompute.arm.domain.VMImage;
+import org.jclouds.azurecompute.arm.domain.VirtualMachine;
+import 
org.jclouds.azurecompute.arm.functions.StorageProfileToStorageAccountName;
+import org.jclouds.compute.domain.Image;
+
+import com.google.common.base.Function;
+import com.google.inject.assistedinject.Assisted;
+
+public class ResourceDefinitionToCustomImage implements 
Function<ResourceDefinition, Image> {
+
+   public interface Factory {
+      ResourceDefinitionToCustomImage create(@Assisted("nodeId") String 
nodeId, @Assisted("imageName") String imageName);
+   }
+
+   private final String resourceGroup;
+   private final Function<VMImage, Image> vmImageToImage;
+   private final String imageName;
+   private final String storageAccountName;
+   private final VirtualMachine vm;
+
+   @Inject
+   ResourceDefinitionToCustomImage(AzureComputeApi api, AzureComputeConstants 
azureComputeConstants,
+         StorageProfileToStorageAccountName storageProfileToStorageAccountName,
+         Function<VMImage, Image> vmImageToImage, @Assisted("nodeId") String 
nodeId,
+         @Assisted("imageName") String imageName) {
+      this.vmImageToImage = vmImageToImage;
+      this.resourceGroup = azureComputeConstants.azureResourceGroup();
+      this.imageName = imageName;
+      this.vm = api.getVirtualMachineApi(resourceGroup).get(nodeId);
+      this.storageAccountName = 
storageProfileToStorageAccountName.apply(vm.properties().storageProfile());
+   }
+
+   @SuppressWarnings("unchecked")
+   @Override
+   public Image apply(ResourceDefinition input) {
+      VMImage.Builder builder = 
VMImage.customImage().group(resourceGroup).storage(storageAccountName).name(imageName)
+            .offer(CUSTOM_IMAGE_OFFER).location(vm.location());
+
+      Map<String, String> properties = (Map<String, String>) 
input.properties();
+
+      Object storageObject = properties.get("storageProfile");
+      Map<String, String> storageProperties = (Map<String, String>) 
storageObject;
+
+      Object osDiskObject = storageProperties.get("osDisk");
+      Map<String, String> osProperties = (Map<String, String>) osDiskObject;
+      builder.vhd1(osProperties.get("name"));
+
+      return vmImageToImage.apply(builder.build());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java
index f784842..9d9eceb 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java
@@ -16,58 +16,50 @@
  */
 package org.jclouds.azurecompute.arm.compute.functions;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-import static 
org.jclouds.azurecompute.arm.compute.functions.DeploymentToNodeMetadata.AZURE_LOGIN_PASSWORD;
-import static 
org.jclouds.azurecompute.arm.compute.functions.DeploymentToNodeMetadata.AZURE_LOGIN_USERNAME;
+import java.util.Set;
 
-import com.google.common.base.Supplier;
-import com.google.common.collect.FluentIterable;
+import org.jclouds.azurecompute.arm.domain.ImageReference;
 import org.jclouds.azurecompute.arm.domain.VMImage;
 import org.jclouds.collect.Memoized;
 import org.jclouds.compute.domain.Image;
 import org.jclouds.compute.domain.ImageBuilder;
 import org.jclouds.compute.domain.OperatingSystem;
 import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.domain.Location;
+import org.jclouds.location.predicates.LocationPredicates;
 
 import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.common.collect.FluentIterable;
 import com.google.inject.Inject;
-import org.jclouds.domain.Credentials;
-import org.jclouds.domain.Location;
-import org.jclouds.domain.LoginCredentials;
-import org.jclouds.location.predicates.LocationPredicates;
 
-import java.util.Set;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 public class VMImageToImage implements Function<VMImage, Image> {
 
-   private static final String UNRECOGNIZED = "UNRECOGNIZED";
-
    private static final String UBUNTU = "Ubuntu";
-
    private static final String WINDOWS = "Windows";
-
    private static final String OPENLOGIC = "openLogic";
-
    private static final String CENTOS = "CentOS";
-
    private static final String COREOS = "CoreOS";
-
    private static final String OPENSUSE = "openSUSE";
-
    private static final String SUSE = "SUSE";
-
-   private static final String SQL_SERVER = "SQL Server";
-
-   private static final String ORACLE_lINUX = "Oracle Linux";
+   private static final String SLES = "SLES";
+   private static final String ORACLE_lINUX = "Oracle-Linux";
+   private static final String RHEL = "RHEL";
 
    private final Supplier<Set<? extends org.jclouds.domain.Location>> 
locations;
 
+   public static String encodeFieldsToUniqueId(boolean globallyAvailable, 
String locatioName, ImageReference imageReference){
+      return (globallyAvailable ? "global" : locatioName) + "/" + 
imageReference.publisher() + "/" + imageReference.offer() + "/" + 
imageReference.sku();
+   }
+   
    public static String encodeFieldsToUniqueId(VMImage imageReference){
       return (imageReference.globallyAvailable() ? "global" : 
imageReference.location()) + "/" + imageReference.publisher() + "/" + 
imageReference.offer() + "/" + imageReference.sku();
    }
 
    public static String encodeFieldsToUniqueIdCustom(VMImage imageReference){
-      return (imageReference.globallyAvailable() ? "global" : 
imageReference.location()) + "/" + imageReference.group() + "/" + 
imageReference.storage() + "/" + imageReference.vhd1() + "/" + 
imageReference.offer();
+      return (imageReference.globallyAvailable() ? "global" : 
imageReference.location()) + "/" + imageReference.group() + "/" + 
imageReference.storage() + "/" + imageReference.offer() + "/" + 
imageReference.name();
    }
 
    public static VMImage decodeFieldsFromUniqueId(final String id) {
@@ -79,10 +71,10 @@ public class VMImageToImage implements Function<VMImage, 
Image> {
          0: imageReference.location) + "/" +
          1: imageReference.group + "/" +
          2: imageReference.storage + "/" +
-         3: imageReference.vhd1 + "/" +
-         4: imageReference.offer
+         3: imageReference.offer + "/" +
+         4: imageReference.name
          */
-         vmImage = VMImage.create(fields[1], fields[2], fields[3], null, null, 
fields[4], fields[0]);
+         vmImage = 
VMImage.customImage().location(fields[0]).group(fields[1]).storage(fields[2]).vhd1(fields[3]).offer(fields[4]).build();
       } else {
          /* id fields indexes
          0: imageReference.location) + "/" +
@@ -90,7 +82,7 @@ public class VMImageToImage implements Function<VMImage, 
Image> {
          2: imageReference.offer + "/" +
          3: imageReference.sku + "/" +
          */
-         vmImage = VMImage.create(fields[1], fields[2], fields[3], null, 
fields[0]);
+         vmImage = 
VMImage.azureImage().location(fields[0]).publisher(fields[1]).offer(fields[2]).sku(fields[3]).build();
       }
       return vmImage;
    }
@@ -102,26 +94,21 @@ public class VMImageToImage implements Function<VMImage, 
Image> {
 
    @Override
    public Image apply(final VMImage image) {
-
-      Credentials credentials = new Credentials(AZURE_LOGIN_USERNAME, 
AZURE_LOGIN_PASSWORD);
       if (image.custom()) {
-
          final ImageBuilder builder = new ImageBuilder()
                .location(FluentIterable.from(locations.get())
                      .firstMatch(LocationPredicates.idEquals(image.location()))
                      .get())
                .name(image.name())
-               .description("#" + image.group())
+               .description(image.group())
                .status(Image.Status.AVAILABLE)
-               .version(image.storage())
+               .version("latest")
                .providerId(image.vhd1())
-               .id(encodeFieldsToUniqueIdCustom(image))
-               
.defaultCredentials(LoginCredentials.fromCredentials(credentials));
+               .id(encodeFieldsToUniqueIdCustom(image));
 
          final OperatingSystem.Builder osBuilder = osFamily().apply(image);
          Image retimage = builder.operatingSystem(osBuilder.build()).build();
          return retimage;
-
       }
       else {
          final ImageBuilder builder = new ImageBuilder()
@@ -130,7 +117,6 @@ public class VMImageToImage implements Function<VMImage, 
Image> {
                .status(Image.Status.AVAILABLE)
                .version(image.sku())
                .id(encodeFieldsToUniqueId(image))
-               
.defaultCredentials(LoginCredentials.fromCredentials(credentials))
                .providerId(image.publisher())
                .location(image.globallyAvailable() ? null : 
FluentIterable.from(locations.get())
                      .firstMatch(LocationPredicates.idEquals(image.location()))
@@ -149,11 +135,11 @@ public class VMImageToImage implements Function<VMImage, 
Image> {
             final String label = image.offer();
 
             OsFamily family = OsFamily.UNRECOGNIZED;
-            if (label.contains(CENTOS)) {
-               family = OsFamily.CENTOS;
-            } else if (label.contains(OPENLOGIC)) {
+            if (label.contains(CENTOS) || label.contains(OPENLOGIC)) {
                family = OsFamily.CENTOS;
-            } else if (label.contains(SUSE)) {
+            } else if (label.contains(COREOS)) {
+               family = OsFamily.COREOS;
+            } else if (label.contains(SUSE) || label.contains(SLES) || 
label.contains(OPENSUSE)) {
                family = OsFamily.SUSE;
             } else if (label.contains(UBUNTU)) {
                family = OsFamily.UBUNTU;
@@ -161,18 +147,16 @@ public class VMImageToImage implements Function<VMImage, 
Image> {
                family = OsFamily.WINDOWS;
             } else if (label.contains(ORACLE_lINUX)) {
                family = OsFamily.OEL;
+            } else if (label.contains(RHEL)) {
+               family = OsFamily.RHEL;
             }
 
-            String sku = image.sku();
-            if (image.custom())
-               sku = image.vhd1();
-
             // only 64bit OS images are supported by Azure ARM
             return OperatingSystem.builder().
                   family(family).
                   is64Bit(true).
-                  description(sku).
-                  version(sku);
+                  description(image.custom() ? image.vhd1() : image.sku()).
+                  version(image.custom() ? "latest" : image.sku());
          }
       };
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToNodeMetadata.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToNodeMetadata.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToNodeMetadata.java
new file mode 100644
index 0000000..e151a4a
--- /dev/null
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToNodeMetadata.java
@@ -0,0 +1,279 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.azurecompute.arm.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Iterables.find;
+import static com.google.common.collect.Iterables.transform;
+import static com.google.common.collect.Iterables.tryFind;
+import static 
org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension.CONTAINER_NAME;
+import static 
org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension.CUSTOM_IMAGE_OFFER;
+import static 
org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.encodeFieldsToUniqueId;
+import static org.jclouds.util.Closeables2.closeQuietly;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jclouds.azurecompute.arm.AzureComputeApi;
+import 
org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.AzureComputeConstants;
+import org.jclouds.azurecompute.arm.domain.IdReference;
+import org.jclouds.azurecompute.arm.domain.IpConfiguration;
+import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
+import org.jclouds.azurecompute.arm.domain.StorageProfile;
+import org.jclouds.azurecompute.arm.domain.StorageServiceKeys;
+import org.jclouds.azurecompute.arm.domain.VMImage;
+import org.jclouds.azurecompute.arm.domain.VirtualMachine;
+import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance;
+import 
org.jclouds.azurecompute.arm.domain.VirtualMachineInstance.VirtualMachineStatus;
+import 
org.jclouds.azurecompute.arm.domain.VirtualMachineInstance.VirtualMachineStatus.PowerState;
+import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties;
+import 
org.jclouds.azurecompute.arm.domain.VirtualMachineProperties.ProvisioningState;
+import 
org.jclouds.azurecompute.arm.functions.StorageProfileToStorageAccountName;
+import org.jclouds.azurecompute.arm.util.BlobHelper;
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.NodeMetadataBuilder;
+import org.jclouds.compute.functions.GroupNamingConvention;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.domain.Credentials;
+import org.jclouds.domain.Location;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.logging.Logger;
+
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Splitter;
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, 
NodeMetadata> {
+
+   @Resource
+   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+   protected Logger logger = Logger.NULL;
+
+   // When using the Deployment API to deploy an ARM template, the deployment
+   // goes through
+   // stages. Accepted -> Running -> Succeeded. Only when the deployment has
+   // SUCCEEDED is
+   // the resource deployed using the template actually ready.
+   //
+   // To get details about the resource(s) deployed via template, one needs to
+   // query the
+   // various resources after the deployment has "SUCCEEDED".
+   private static final Function<VirtualMachineProperties.ProvisioningState, 
NodeMetadata.Status> PROVISIONINGSTATE_TO_NODESTATUS = Functions
+         .forMap(
+               ImmutableMap.<VirtualMachineProperties.ProvisioningState, 
NodeMetadata.Status> builder()
+                     .put(VirtualMachineProperties.ProvisioningState.ACCEPTED, 
NodeMetadata.Status.PENDING)
+                     .put(VirtualMachineProperties.ProvisioningState.READY, 
NodeMetadata.Status.PENDING)
+                     .put(VirtualMachineProperties.ProvisioningState.CREATING, 
NodeMetadata.Status.PENDING)
+                     .put(VirtualMachineProperties.ProvisioningState.RUNNING, 
NodeMetadata.Status.PENDING)
+                     .put(VirtualMachineProperties.ProvisioningState.UPDATING, 
NodeMetadata.Status.PENDING)
+                     
.put(VirtualMachineProperties.ProvisioningState.SUCCEEDED, 
NodeMetadata.Status.RUNNING)
+                     .put(VirtualMachineProperties.ProvisioningState.DELETED, 
NodeMetadata.Status.TERMINATED)
+                     .put(VirtualMachineProperties.ProvisioningState.CANCELED, 
NodeMetadata.Status.TERMINATED)
+                     .put(VirtualMachineProperties.ProvisioningState.FAILED, 
NodeMetadata.Status.ERROR)
+                     
.put(VirtualMachineProperties.ProvisioningState.UNRECOGNIZED, 
NodeMetadata.Status.UNRECOGNIZED)
+                     .build(), NodeMetadata.Status.UNRECOGNIZED);
+
+   private static final Function<VirtualMachineStatus.PowerState, 
NodeMetadata.Status> POWERSTATE_TO_NODESTATUS = Functions
+         .forMap(
+               ImmutableMap.<PowerState, NodeMetadata.Status> builder()
+                     .put(PowerState.RUNNING, NodeMetadata.Status.RUNNING)
+                     .put(PowerState.STOPPED, NodeMetadata.Status.SUSPENDED)
+                     .put(PowerState.UNRECOGNIZED, 
NodeMetadata.Status.UNRECOGNIZED).build(),
+               NodeMetadata.Status.UNRECOGNIZED);
+
+   private final String azureGroup;
+   private final AzureComputeApi api;
+   private final GroupNamingConvention nodeNamingConvention;
+   private final Supplier<Map<String, ? extends Image>> images;
+   private final Supplier<Set<? extends Location>> locations;
+   private final Supplier<Map<String, ? extends Hardware>> hardwares;
+   private final Map<String, Credentials> credentialStore;
+   private final Function<VMImage, Image> vmImageToImge;
+   private final StorageProfileToStorageAccountName 
storageProfileToStorageAccountName;
+
+   @Inject
+   VirtualMachineToNodeMetadata(AzureComputeApi api, 
GroupNamingConvention.Factory namingConvention,
+         Supplier<Map<String, ? extends Image>> images, Supplier<Map<String, ? 
extends Hardware>> hardwares,
+         @Memoized Supplier<Set<? extends Location>> locations, Map<String, 
Credentials> credentialStore,
+         final AzureComputeConstants azureComputeConstants, Function<VMImage, 
Image> vmImageToImge,
+         StorageProfileToStorageAccountName 
storageProfileToStorageAccountName) {
+      this.api = api;
+      this.nodeNamingConvention = namingConvention.createWithoutPrefix();
+      this.images = checkNotNull(images, "images cannot be null");
+      this.locations = checkNotNull(locations, "locations cannot be null");
+      this.hardwares = checkNotNull(hardwares, "hardwares cannot be null");
+      this.credentialStore = credentialStore;
+      this.azureGroup = azureComputeConstants.azureResourceGroup();
+      this.vmImageToImge = vmImageToImge;
+      this.storageProfileToStorageAccountName = 
storageProfileToStorageAccountName;
+   }
+
+   @Override
+   public NodeMetadata apply(VirtualMachine virtualMachine) {
+      NodeMetadataBuilder builder = new NodeMetadataBuilder();
+      builder.id(virtualMachine.name());
+      builder.providerId(virtualMachine.id());
+      builder.name(virtualMachine.name());
+      builder.hostname(virtualMachine.name());
+      String group = 
this.nodeNamingConvention.extractGroup(virtualMachine.name());
+      builder.group(group);
+
+      ProvisioningState provisioningState = 
virtualMachine.properties().provisioningState();
+      if (ProvisioningState.SUCCEEDED.equals(provisioningState)) {
+         // If the provisioning succeeded, we need to query the *real* status 
of
+         // the VM
+         VirtualMachineInstance instanceDetails = 
api.getVirtualMachineApi(azureGroup).getInstanceDetails(
+               virtualMachine.name());
+         
builder.status(POWERSTATE_TO_NODESTATUS.apply(instanceDetails.powerState()));
+         builder.backendStatus(Joiner.on(',').join(
+               transform(instanceDetails.statuses(), new 
Function<VirtualMachineStatus, String>() {
+                  @Override
+                  public String apply(VirtualMachineStatus input) {
+                     return input.code();
+                  }
+               })));
+      } else {
+         
builder.status(PROVISIONINGSTATE_TO_NODESTATUS.apply(provisioningState));
+         builder.backendStatus(provisioningState.name());
+      }
+
+      Credentials credentials = credentialStore.get("node#" + 
virtualMachine.name());
+      builder.credentials(LoginCredentials.fromCredentials(credentials));
+
+      
builder.publicAddresses(getPublicIpAddresses(virtualMachine.properties().networkProfile().networkInterfaces()));
+      
builder.privateAddresses(getPrivateIpAddresses(virtualMachine.properties().networkProfile().networkInterfaces()));
+
+      if (virtualMachine.tags() != null) {
+         Map<String, String> userMetaData = virtualMachine.tags();
+         builder.userMetadata(userMetaData);
+         builder.tags(Splitter.on(",").split(userMetaData.get("tags")));
+      }
+      String locationName = virtualMachine.location();
+      builder.location(getLocation(locationName));
+
+      Optional<? extends Image> image = 
findImage(virtualMachine.properties().storageProfile(), locationName);
+      if (image.isPresent()) {
+         builder.imageId(image.get().getId());
+         builder.operatingSystem(image.get().getOperatingSystem());
+      } else {
+         logger.info(">> image with id %s for virtualmachine %s was not found. 
"
+               + "This might be because the image that was used to create the 
virtualmachine has a new id.",
+               virtualMachine.id(), virtualMachine.id());
+      }
+
+      
builder.hardware(getHardware(virtualMachine.properties().hardwareProfile().vmSize()));
+
+      return builder.build();
+   }
+
+   private Iterable<String> getPrivateIpAddresses(List<IdReference> 
idReferences) {
+      List<String> privateIpAddresses = Lists.newArrayList();
+      for (IdReference networkInterfaceCardIdReference : idReferences) {
+         NetworkInterfaceCard networkInterfaceCard = 
getNetworkInterfaceCard(networkInterfaceCardIdReference);
+         for (IpConfiguration ipConfiguration : 
networkInterfaceCard.properties().ipConfigurations()) {
+            
privateIpAddresses.add(ipConfiguration.properties().privateIPAddress());
+         }
+      }
+      return privateIpAddresses;
+   }
+
+   private NetworkInterfaceCard getNetworkInterfaceCard(IdReference 
networkInterfaceCardIdReference) {
+      
Iterables.get(Splitter.on("/").split(networkInterfaceCardIdReference.id()), 2);
+      String resourceGroup = 
Iterables.get(Splitter.on("/").split(networkInterfaceCardIdReference.id()), 4);
+      String nicName = 
Iterables.getLast(Splitter.on("/").split(networkInterfaceCardIdReference.id()));
+      return api.getNetworkInterfaceCardApi(resourceGroup).get(nicName);
+
+   }
+
+   private Iterable<String> getPublicIpAddresses(List<IdReference> 
idReferences) {
+      List<String> publicIpAddresses = Lists.newArrayList();
+      for (IdReference networkInterfaceCardIdReference : idReferences) {
+         NetworkInterfaceCard networkInterfaceCard = 
getNetworkInterfaceCard(networkInterfaceCardIdReference);
+         String resourceGroup = 
Iterables.get(Splitter.on("/").split(networkInterfaceCardIdReference.id()), 4);
+         for (IpConfiguration ipConfiguration : 
networkInterfaceCard.properties().ipConfigurations()) {
+            if (ipConfiguration.properties().publicIPAddress() != null) {
+               String publicIpId = 
ipConfiguration.properties().publicIPAddress().id();
+               publicIpAddresses.add(api.getPublicIPAddressApi(resourceGroup)
+                     
.get(Iterables.getLast(Splitter.on("/").split(publicIpId))).properties().ipAddress());
+            }
+         }
+      }
+      return publicIpAddresses;
+   }
+
+   protected Location getLocation(final String locationName) {
+      return find(locations.get(), new Predicate<Location>() {
+         @Override
+         public boolean apply(Location location) {
+            return locationName != null && 
locationName.equals(location.getId());
+         }
+      }, null);
+   }
+
+   protected Optional<? extends Image> findImage(final StorageProfile 
storageProfile, String locatioName) {
+      if (storageProfile.imageReference() != null) {
+         return Optional.fromNullable(images.get().get(
+               encodeFieldsToUniqueId(false, locatioName, 
storageProfile.imageReference())));
+      } else {
+         String storageAccountName = 
storageProfileToStorageAccountName.apply(storageProfile);
+         StorageServiceKeys keys = 
api.getStorageAccountApi(azureGroup).getKeys(storageAccountName);
+         BlobHelper blobHelper = new BlobHelper(storageAccountName, 
keys.key1());
+
+         try {
+            // Custom image. Let's find it by uri
+            List<VMImage> customImagesInStorage = 
blobHelper.getImages(CONTAINER_NAME, azureGroup, CUSTOM_IMAGE_OFFER,
+                  locatioName);
+            Optional<VMImage> customImage = tryFind(customImagesInStorage, new 
Predicate<VMImage>() {
+               @Override
+               public boolean apply(VMImage input) {
+                  return 
input.vhd1().equals(storageProfile.osDisk().image().uri());
+               }
+            });
+
+            return customImage.isPresent() ? 
Optional.of(vmImageToImge.apply(customImage.get())) : Optional
+                  .<Image> absent();
+         } finally {
+            closeQuietly(blobHelper);
+         }
+      }
+   }
+
+   protected Hardware getHardware(final String vmSize) {
+      return Iterables.find(hardwares.get().values(), new 
Predicate<Hardware>() {
+         @Override
+         public boolean apply(Hardware input) {
+            return input.getId().equals(vmSize);
+         }
+      });
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/options/AzureTemplateOptions.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/options/AzureTemplateOptions.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/options/AzureTemplateOptions.java
index c5267b1..c71a7da 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/options/AzureTemplateOptions.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/options/AzureTemplateOptions.java
@@ -16,10 +16,12 @@
  */
 package org.jclouds.azurecompute.arm.compute.options;
 
-import static com.google.common.base.Objects.equal;
 import org.jclouds.compute.options.TemplateOptions;
+
 import com.google.common.base.Objects;
 
+import static com.google.common.base.Objects.equal;
+
 /**
  * Azure ARM custom options
  */
@@ -31,7 +33,9 @@ public class AzureTemplateOptions extends TemplateOptions 
implements Cloneable {
    private String subnetAddressPrefix;
    private String DNSLabelPrefix;
    private String keyVaultIdAndSecret;
-
+   private String virtualNetworkName;
+   private String subnetId;
+   private String blob;
 
    /**
     * Custom options for the Azure ARM API
@@ -40,9 +44,7 @@ public class AzureTemplateOptions extends TemplateOptions 
implements Cloneable {
       this.customData = customData;
       return this;
    }
-   private String virtualNetworkName;
-   private String subnetId;
-
+   
    /**
     * Sets the CIDR block for virtual network
     */
@@ -75,15 +77,6 @@ public class AzureTemplateOptions extends TemplateOptions 
implements Cloneable {
       return this;
    }
 
-   public String getCustomData() { return customData; }
-   public String getVirtualNetworkAddressPrefix() { return 
virtualNetworkAddressPrefix; }
-   public String getSubnetAddressPrefix() { return subnetAddressPrefix; }
-   public String getDNSLabelPrefix() { return DNSLabelPrefix; }
-   public String getKeyVaultIdAndSecret() { return keyVaultIdAndSecret; }
-   public String getVirtualNetworkName() { return virtualNetworkName; }
-   public String getSubnetId() { return subnetId; }
-
-
    /**
     * Sets the virtual network name
     */
@@ -100,6 +93,24 @@ public class AzureTemplateOptions extends TemplateOptions 
implements Cloneable {
       return this;
    }
 
+   /**
+    * Sets the blob name
+    */
+   public  AzureTemplateOptions blob(String blob) {
+      this.blob = blob;
+      return this;
+   }
+
+   public String getCustomData() { return customData; }
+   public String getVirtualNetworkAddressPrefix() { return 
virtualNetworkAddressPrefix; }
+   public String getSubnetAddressPrefix() { return subnetAddressPrefix; }
+   public String getDNSLabelPrefix() { return DNSLabelPrefix; }
+   public String getKeyVaultIdAndSecret() { return keyVaultIdAndSecret; }
+   public String getVirtualNetworkName() { return virtualNetworkName; }
+   public String getSubnetId() { return subnetId; }
+   public String getBlob() { return blob; }
+
+
    @Override
    public AzureTemplateOptions clone() {
       AzureTemplateOptions options = new AzureTemplateOptions();
@@ -119,12 +130,13 @@ public class AzureTemplateOptions extends TemplateOptions 
implements Cloneable {
          eTo.keyVaultIdAndSecret(keyVaultIdAndSecret);
          eTo.virtualNetworkName(virtualNetworkName);
          eTo.subnetId(subnetId);
+         eTo.blob(blob);
       }
    }
 
    @Override
    public int hashCode() {
-      return Objects.hashCode(super.hashCode(), virtualNetworkAddressPrefix, 
subnetAddressPrefix, DNSLabelPrefix, customData, keyVaultIdAndSecret, 
virtualNetworkName, subnetId);
+      return Objects.hashCode(super.hashCode(), virtualNetworkAddressPrefix, 
subnetAddressPrefix, DNSLabelPrefix, customData, keyVaultIdAndSecret, 
virtualNetworkName, subnetId, blob);
    }
 
    @Override
@@ -146,7 +158,8 @@ public class AzureTemplateOptions extends TemplateOptions 
implements Cloneable {
             && equal(this.DNSLabelPrefix, other.DNSLabelPrefix)
             && equal(this.keyVaultIdAndSecret, other.keyVaultIdAndSecret)
             && equal(this.virtualNetworkName, other.virtualNetworkName)
-            && equal(this.subnetId, other.subnetId);
+            && equal(this.subnetId, other.subnetId)
+            && equal(this.blob, other.blob);
    }
 
    @Override
@@ -159,6 +172,7 @@ public class AzureTemplateOptions extends TemplateOptions 
implements Cloneable {
       toString.add("keyVaultIdAndSecret", keyVaultIdAndSecret);
       toString.add("virtualNetworkName", virtualNetworkName);
       toString.add("subnetId", subnetId);
+      toString.add("blob", blob);
       return toString;
    }
 
@@ -219,5 +233,13 @@ public class AzureTemplateOptions extends TemplateOptions 
implements Cloneable {
          AzureTemplateOptions options = new AzureTemplateOptions();
          return options.subnetId(subnetId);
       }
+
+      /**
+       * @see AzureTemplateOptions#blob
+       */
+      public static AzureTemplateOptions blob(String blob) {
+         AzureTemplateOptions options = new AzureTemplateOptions();
+         return options.blob(blob);
+      }
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/predicates/IsDeploymentInRegions.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/predicates/IsDeploymentInRegions.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/predicates/IsDeploymentInRegions.java
index 57a0678..66590e1 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/predicates/IsDeploymentInRegions.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/predicates/IsDeploymentInRegions.java
@@ -40,6 +40,7 @@ public class IsDeploymentInRegions implements 
Predicate<Deployment> {
 
    @Override
    public boolean apply(Deployment deployment) {
+      if (deployment.properties() == null || 
deployment.properties().parameters() == null || 
deployment.properties().parameters().get("location") == null) return false;
       Value locationValue = 
deployment.properties().parameters().get("location");
       return regionIds.get().contains(locationValue.value());
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/AzurePopulateDefaultLoginCredentialsForImageStrategy.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/AzurePopulateDefaultLoginCredentialsForImageStrategy.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/AzurePopulateDefaultLoginCredentialsForImageStrategy.java
deleted file mode 100644
index 55d1a3c..0000000
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/AzurePopulateDefaultLoginCredentialsForImageStrategy.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR 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.azurecompute.arm.compute.strategy;
-
-import org.jclouds.compute.domain.internal.ImageImpl;
-import 
org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
-import org.jclouds.domain.Credentials;
-import org.jclouds.domain.LoginCredentials;
-
-import static 
org.jclouds.azurecompute.arm.compute.functions.DeploymentToNodeMetadata.AZURE_LOGIN_PASSWORD;
-import static 
org.jclouds.azurecompute.arm.compute.functions.DeploymentToNodeMetadata.AZURE_LOGIN_USERNAME;
-
-public class AzurePopulateDefaultLoginCredentialsForImageStrategy implements 
PopulateDefaultLoginCredentialsForImageStrategy {
-   @Override
-   public LoginCredentials apply(Object o) {
-      ImageImpl node = (ImageImpl)o;
-      String username = AZURE_LOGIN_USERNAME;
-      String password = AZURE_LOGIN_PASSWORD;
-      if (username == null) {
-         username = "jclouds";
-      }
-      if (password == null) {
-         password = "Password1!";
-      }
-      Credentials creds = new Credentials(username, password);
-      LoginCredentials credentials = LoginCredentials.fromCredentials(creds);
-      return credentials;
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CreateResourceGroupThenCreateNodes.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CreateResourceGroupThenCreateNodes.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CreateResourceGroupThenCreateNodes.java
index 468b87c..99528fd 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CreateResourceGroupThenCreateNodes.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CreateResourceGroupThenCreateNodes.java
@@ -17,26 +17,36 @@
 package org.jclouds.azurecompute.arm.compute.strategy;
 
 import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static 
org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.decodeFieldsFromUniqueId;
+import static org.jclouds.util.Predicates2.retry;
 
+import java.net.URI;
 import java.util.Arrays;
 import java.util.Map;
 import java.util.Set;
+import java.util.UUID;
 
 import javax.annotation.Resource;
 import javax.inject.Inject;
 import javax.inject.Named;
 import javax.inject.Singleton;
 
-import com.google.common.collect.ImmutableMap;
 import org.jclouds.Constants;
+import org.jclouds.azurecompute.arm.AzureComputeApi;
 import 
org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule;
 import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
 import org.jclouds.azurecompute.arm.domain.ResourceGroup;
+import org.jclouds.azurecompute.arm.domain.StorageService;
 import org.jclouds.azurecompute.arm.domain.Subnet;
+import org.jclouds.azurecompute.arm.domain.VMImage;
+import org.jclouds.azurecompute.arm.domain.VirtualNetwork;
 import org.jclouds.azurecompute.arm.features.ResourceGroupApi;
 import org.jclouds.azurecompute.arm.features.SubnetApi;
 import org.jclouds.azurecompute.arm.features.VirtualNetworkApi;
+import org.jclouds.azurecompute.arm.functions.ParseJobStatus;
 import org.jclouds.compute.config.CustomizationResponse;
+import org.jclouds.compute.domain.Image;
 import org.jclouds.compute.domain.NodeMetadata;
 import org.jclouds.compute.domain.Template;
 import org.jclouds.compute.functions.GroupNamingConvention;
@@ -45,9 +55,11 @@ import 
org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
 import 
org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
 import org.jclouds.compute.strategy.ListNodesStrategy;
 import 
org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet;
-import org.jclouds.azurecompute.arm.AzureComputeApi;
-import org.jclouds.azurecompute.arm.domain.VirtualNetwork;
 import org.jclouds.logging.Logger;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Multimap;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
@@ -81,7 +93,13 @@ public class CreateResourceGroupThenCreateNodes extends 
CreateNodesWithGroupEnco
    public Map<?, ListenableFuture<Void>> execute(String group, int count, 
Template template,
                                                  Set<NodeMetadata> goodNodes, 
Map<NodeMetadata, Exception> badNodes,
                                                  Multimap<NodeMetadata, 
CustomizationResponse> customizationResponses) {
-
+      // If there is a script to be run on the node and public key
+      // authentication has been configured, warn users if the private key
+      // is not present
+      if (hasRunScriptWithKeyAuthAndNoPrivateKey(template)) {
+         logger.warn(">> a runScript was configured but no SSH key has been 
provided. " +
+                 "Authentication will delegate to the ssh-agent");
+      }
       String azureGroupName = this.azureComputeConstants.azureResourceGroup();
 
       AzureTemplateOptions options = 
template.getOptions().as(AzureTemplateOptions.class);
@@ -91,7 +109,7 @@ public class CreateResourceGroupThenCreateNodes extends 
CreateNodesWithGroupEnco
       final String location = template.getLocation().getId();
 
       if (resourceGroup == null){
-         final Map<String, String> tags = ImmutableMap.of("description", 
"jClouds managed VMs");
+         final Map<String, String> tags = ImmutableMap.of("description", 
"jclouds managed VMs");
          resourceGroupApi.create(azureGroupName, location, tags).name();
       }
 
@@ -104,7 +122,10 @@ public class CreateResourceGroupThenCreateNodes extends 
CreateNodesWithGroupEnco
 
       this.getOrCreateVirtualNetworkWithSubnet(vnetName, subnetName, location, 
options, azureGroupName);
 
-
+      StorageService storageService = getOrCreateStorageService(group, 
azureGroupName, location, template.getImage());
+      String blob = 
storageService.storageServiceProperties().primaryEndpoints().get("blob");
+      options.blob(blob);
+      
       Map<?, ListenableFuture<Void>> responses = super.execute(group, count, 
template, goodNodes, badNodes,
               customizationResponses);
 
@@ -135,6 +156,70 @@ public class CreateResourceGroupThenCreateNodes extends 
CreateNodesWithGroupEnco
 
       options.virtualNetworkName(virtualNetworkName);
       options.subnetId(subnet.id());
+   }
+
+   private static boolean hasRunScriptWithKeyAuthAndNoPrivateKey(Template 
template) {
+      return template.getOptions().getRunScript() != null && 
template.getOptions().getPublicKey() != null
+              && !template.getOptions().hasLoginPrivateKeyOption();
+   }
+
+   public StorageService getOrCreateStorageService(String name, String 
resourceGroupName, String locationName, Image image) {
+      String storageAccountName = null;
+      VMImage imageRef = decodeFieldsFromUniqueId(image.getId());
+      if (imageRef.custom()) {
+         storageAccountName = imageRef.storage();
+      }
+
+      if (Strings.isNullOrEmpty(storageAccountName)) {
+         storageAccountName = generateStorageAccountName(name);
+      }
+
+      StorageService storageService = 
api.getStorageAccountApi(resourceGroupName).get(storageAccountName);
+      if (storageService != null) return storageService;
+
+      URI uri = 
api.getStorageAccountApi(resourceGroupName).create(storageAccountName, 
locationName, ImmutableMap.of("jclouds",
+              name), ImmutableMap.of("accountType", 
StorageService.AccountType.Standard_LRS.toString()));
+      boolean starageAccountCreated = retry(new Predicate<URI>() {
+         @Override
+         public boolean apply(URI uri) {
+            return ParseJobStatus.JobStatus.DONE == 
api.getJobApi().jobStatus(uri);
+         }
+      }, 60 * 2 * 1000 /* 2 minutes timeout */).apply(uri);
+      // TODO check provisioning state of the primary
+      checkState(starageAccountCreated, "Storage account %s was not created in 
the configured timeout",
+            storageAccountName);
+      return 
api.getStorageAccountApi(resourceGroupName).get(storageAccountName);
+   }
+
+   /**
+    * Generates a valid storage account
+    *
+    * Storage account names must be between 3 and 24 characters in length and 
may contain numbers and lowercase letters only.
+    *
+    * @param name the node name
+    * @return the storage account name starting from a sanitized name (with 
only numbers and lowercase letters only ).
+    * If sanitized name is between 3 and 24 characters, storage account name 
is equals to sanitized name.
+    * If sanitized name is less than 3 characters, storage account is 
sanitized name plus 4 random chars.
+    * If sanitized name is more than 24 characters, storage account is first 
10 chars of sanitized name plus 4 random chars plus last 10 chars of sanitized 
name.
+    */
+   public static String generateStorageAccountName(String name) {
+      String random = UUID.randomUUID().toString().substring(0, 4);
+      String storageAccountName = new 
StringBuilder().append(name).append(random).toString();
+      String sanitizedStorageAccountName = 
storageAccountName.replaceAll("[^a-z0-9]", "");
+      int nameLength = sanitizedStorageAccountName.length();
+      if (nameLength >= 3 && nameLength <= 24) {
+         return sanitizedStorageAccountName;
+      }
+
+      if (nameLength > 24) {
+         sanitizedStorageAccountName = shorten(storageAccountName, random);
+      }
+      return sanitizedStorageAccountName;
+   }
 
+   private static String shorten(String storageAccountName, String random) {
+      String prefix = storageAccountName.substring(0, 10);
+      String suffix = storageAccountName.substring(storageAccountName.length() 
- 10, storageAccountName.length());
+      return String.format("%s%s%s", prefix, random, suffix);
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeHttpApiModule.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeHttpApiModule.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeHttpApiModule.java
index bd1750f..991c738 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeHttpApiModule.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeHttpApiModule.java
@@ -18,7 +18,6 @@ package org.jclouds.azurecompute.arm.config;
 
 import org.jclouds.azurecompute.arm.AzureComputeApi;
 import org.jclouds.azurecompute.arm.handlers.AzureComputeErrorHandler;
-import org.jclouds.azurecompute.arm.util.DeploymentTemplateBuilder;
 import org.jclouds.http.HttpErrorHandler;
 import org.jclouds.http.annotation.ClientError;
 import org.jclouds.http.annotation.Redirection;
@@ -30,7 +29,6 @@ import org.jclouds.rest.ConfiguresHttpApi;
 import org.jclouds.rest.config.HttpApiModule;
 
 import com.google.inject.Scopes;
-import com.google.inject.assistedinject.FactoryModuleBuilder;
 
 @ConfiguresHttpApi
 public class AzureComputeHttpApiModule extends HttpApiModule<AzureComputeApi> {
@@ -51,7 +49,6 @@ public class AzureComputeHttpApiModule extends 
HttpApiModule<AzureComputeApi> {
 
    @Override
    protected void configure() {
-      install(new 
FactoryModuleBuilder().build(DeploymentTemplateBuilder.Factory.class));
       super.configure();
       bind(OAuthScopes.class).toInstance(OAuthScopes.NoScopes.create());
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java
index e5ef5cd..8f945d9 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java
@@ -17,10 +17,13 @@
 package org.jclouds.azurecompute.arm.config;
 
 /**
- * Configuration properties and constants used in Azure Resource Manager 
connections.
+ * Configuration properties and constants used in Azure Resource Manager
+ * connections.
  */
 public class AzureComputeProperties {
 
+   public static final String STORAGE_API_VERSION = "2015-06-15";
+
    public static final String OPERATION_TIMEOUT = 
"jclouds.azurecompute.arm.operation.timeout";
 
    public static final String OPERATION_POLL_INITIAL_PERIOD = 
"jclouds.azurecompute.arm.operation.poll.initial.period";
@@ -31,8 +34,6 @@ public class AzureComputeProperties {
 
    public static final String TCP_RULE_REGEXP = 
"jclouds.azurecompute.arm.tcp.rule.regexp";
 
-   public static final String STORAGE_API_VERSION = "2015-06-15";
-
    public static final String RESOURCE_GROUP_NAME = 
"jclouds.azurecompute.arm.operation.resourcegroup";
 
    public static final String IMAGE_PUBLISHERS = 
"jclouds.azurecompute.arm.publishers";
@@ -47,4 +48,6 @@ public class AzureComputeProperties {
 
    public static final String DEFAULT_DATADISKSIZE = 
"jclouds.azurecompute.arm.datadisksize";
 
+   public static final String API_VERSION_PREFIX = 
"jclouds.azurecompute.arm.apiversion.";
+
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMDeployment.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMDeployment.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMDeployment.java
index 948e69b..99edc5c 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMDeployment.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMDeployment.java
@@ -16,43 +16,29 @@
  */
 package org.jclouds.azurecompute.arm.domain;
 
-import com.google.auto.value.AutoValue;
+import java.util.List;
+
 import org.jclouds.javax.annotation.Nullable;
 
-import java.util.List;
-import java.util.Map;
+import com.google.auto.value.AutoValue;
 
 @AutoValue
 public abstract class VMDeployment {
 
-   public abstract Deployment deployment();
-
-   @Nullable
-   public abstract List<PublicIPAddress> ipAddressList();
-
-   @Nullable
-   public abstract VirtualMachineInstance vm();
-
+   public abstract String deploymentId();
+   
    @Nullable
    public abstract VirtualMachine virtualMachine();
-
-   @Nullable
-   public abstract List<NetworkInterfaceCard> networkInterfaceCards();
-
+   
    @Nullable
-   public abstract Map<String, String> userMetaData();
+   public abstract List<PublicIPAddress> ipAddressList();
 
    @Nullable
-   public abstract Iterable<String> tags();
-
-   public static VMDeployment create(Deployment deployment) {
-      return create(deployment, null, null, null, null, null, null);
-   }
+   public abstract List<NetworkInterfaceCard> networkInterfaceCards();
 
-   public static VMDeployment create(Deployment deployment, 
List<PublicIPAddress> ipAddressList,
-                                     VirtualMachineInstance vm, VirtualMachine 
virtualMachine,
-                                     List<NetworkInterfaceCard> 
networkInterfaceCards, Map<String, String> userMetaData,
-                                     Iterable<String> tags) {
-      return new AutoValue_VMDeployment(deployment, ipAddressList, vm, 
virtualMachine, networkInterfaceCards, userMetaData, tags);
+   public static VMDeployment create(String deploymentId, VirtualMachine 
virtualMachine,
+                                     List<PublicIPAddress> ipAddressList,
+                                     List<NetworkInterfaceCard> 
networkInterfaceCards) {
+      return new AutoValue_VMDeployment(deploymentId, virtualMachine, 
ipAddressList, networkInterfaceCards);
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMImage.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMImage.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMImage.java
index c83eafe..e4f2301 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMImage.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMImage.java
@@ -16,9 +16,9 @@
  */
 package org.jclouds.azurecompute.arm.domain;
 
-import com.google.auto.value.AutoValue;
 import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.json.SerializedNames;
+
+import com.google.auto.value.AutoValue;
 
 @AutoValue
 public abstract class VMImage {
@@ -91,16 +91,35 @@ public abstract class VMImage {
     * True if custom image
     */
    public abstract boolean custom();
-
-   @SerializedNames({ "publisher", "offer", "sku", "version", "location"})
-   public static VMImage create(String publisher, String offer, String sku, 
String version, String location) {
-
-      return new AutoValue_VMImage(publisher, offer, sku, version, location, 
false, null, null, null, null, null, false);
+   
+   public static Builder builder() {
+      return new AutoValue_VMImage.Builder();
    }
-
-   @SerializedNames({ "group", "storage", "vhd1", "vhd2", "name", "offer", 
"location"})
-   public static VMImage create(String group, String storage, String vhd1, 
String vhd2, String name, String offer, String location) {
-
-      return new AutoValue_VMImage(null, offer, null, null, location, false, 
group, storage, vhd1, vhd2, name, true);
+   
+   public static Builder azureImage() {
+      return new 
AutoValue_VMImage.Builder().globallyAvailable(false).custom(false);
+   }
+   
+   public static Builder customImage() {
+      return new 
AutoValue_VMImage.Builder().globallyAvailable(false).custom(true);
+   }
+   
+   @AutoValue.Builder
+   public abstract static class Builder {
+      
+      public abstract Builder publisher(String published);
+      public abstract Builder offer(String offer);
+      public abstract Builder sku(String sku);
+      public abstract Builder version(String version);
+      public abstract Builder location(String location);
+      public abstract Builder globallyAvailable(boolean globallyAvailable);
+      public abstract Builder group(String group);
+      public abstract Builder storage(String storage);
+      public abstract Builder vhd1(String vhd1);
+      public abstract Builder vhd2(String vhd2);
+      public abstract Builder name(String name);
+      public abstract Builder custom(boolean custom);
+      
+      public abstract VMImage build();
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VirtualMachine.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VirtualMachine.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VirtualMachine.java
index 3013543..10fa231 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VirtualMachine.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VirtualMachine.java
@@ -16,12 +16,13 @@
  */
 package org.jclouds.azurecompute.arm.domain;
 
-import com.google.auto.value.AutoValue;
-import com.google.common.collect.ImmutableMap;
+import java.util.Map;
+
 import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.json.SerializedNames;
 
-import java.util.Map;
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableMap;
 
 /**
  * A virtual machine  that is valid for your subscription.

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VirtualMachineInstance.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VirtualMachineInstance.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VirtualMachineInstance.java
index b0ed6d5..1c11e4d 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VirtualMachineInstance.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VirtualMachineInstance.java
@@ -16,13 +16,23 @@
  */
 package org.jclouds.azurecompute.arm.domain;
 
-import com.google.auto.value.AutoValue;
-import com.google.common.collect.ImmutableList;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.getFirst;
+import static com.google.common.collect.Iterables.transform;
+import static org.jclouds.util.Predicates2.startsWith;
+
+import java.util.Date;
 import java.util.List;
+
+import 
org.jclouds.azurecompute.arm.domain.VirtualMachineInstance.VirtualMachineStatus.PowerState;
+import 
org.jclouds.azurecompute.arm.domain.VirtualMachineProperties.ProvisioningState;
+import org.jclouds.azurecompute.arm.util.GetEnumValue;
 import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.json.SerializedNames;
 
-import java.util.Date;
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
 
 /**
  * A virtual machine instance view that is valid for your subscription.
@@ -30,8 +40,21 @@ import java.util.Date;
 @AutoValue
 public abstract class VirtualMachineInstance {
 
-   @AutoValue
+   @com.google.auto.value.AutoValue
    public abstract static class VirtualMachineStatus {
+      
+      public static final String PROVISIONING_STATE_PREFIX = 
"ProvisioningState/";
+      public static final String POWER_STATE_PREFIX = "PowerState/";
+      
+      public enum PowerState {
+         RUNNING,
+         STOPPED,
+         UNRECOGNIZED;
+
+         public static PowerState fromValue(final String text) {
+            return (PowerState) GetEnumValue.fromValueOrDefault(text, 
PowerState.UNRECOGNIZED);
+         }
+      }
 
       @Nullable
       public abstract String code();
@@ -61,6 +84,26 @@ public abstract class VirtualMachineInstance {
 
    @Nullable
    public abstract List<VirtualMachineStatus> statuses();
+   
+   public ProvisioningState provisioningState() {
+      return 
ProvisioningState.fromValue(firstStatus(VirtualMachineStatus.PROVISIONING_STATE_PREFIX));
+   }
+   
+   public PowerState powerState() {
+      return 
PowerState.fromValue(firstStatus(VirtualMachineStatus.POWER_STATE_PREFIX));
+   }
+   
+   private String firstStatus(final String type) {
+      return getFirst(transform(filter(transform(statuses(), new 
Function<VirtualMachineStatus, String>() {
+         @Override public String apply(VirtualMachineStatus input) {
+            return input.code();
+         }
+      }), startsWith(type)), new Function<String, String>() {
+         @Override public String apply(String input) {
+            return input.substring(type.length());
+         }
+      }), null);
+   }
 
 
    @SerializedNames({"platformUpdateDomain", "platformFaultDomain", 
"statuses"})

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VirtualMachineProperties.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VirtualMachineProperties.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VirtualMachineProperties.java
index 73afd14..eb9520a 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VirtualMachineProperties.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VirtualMachineProperties.java
@@ -16,16 +16,35 @@
  */
 package org.jclouds.azurecompute.arm.domain;
 
-import com.google.auto.value.AutoValue;
+import org.jclouds.azurecompute.arm.util.GetEnumValue;
 import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.json.SerializedNames;
 
+import com.google.auto.value.AutoValue;
+
 /**
  * A virtual machine properties for the virtual machine.
  */
 @AutoValue
 public abstract class VirtualMachineProperties {
 
+   public enum ProvisioningState {
+      ACCEPTED,
+      CREATING,
+      READY,
+      CANCELED,
+      FAILED,
+      DELETED,
+      SUCCEEDED,
+      RUNNING,
+      UPDATING,
+      UNRECOGNIZED;
+
+      public static ProvisioningState fromValue(final String text) {
+         return (ProvisioningState) GetEnumValue.fromValueOrDefault(text, 
ProvisioningState.UNRECOGNIZED);
+      }
+   }
+
    /**
     * The id of the virtual machine.
     */
@@ -78,7 +97,7 @@ public abstract class VirtualMachineProperties {
     * The provisioning state of the VM
     */
    @Nullable
-   public abstract String provisioningState();
+   public abstract ProvisioningState provisioningState();
 
    @SerializedNames({"vmId", "licenseType", "availabilitySet", 
"hardwareProfile", "storageProfile", "osProfile",
            "networkProfile", "diagnosticsProfile", "provisioningState"})
@@ -90,7 +109,7 @@ public abstract class VirtualMachineProperties {
                                                  final OSProfile osProfile,
                                                  final NetworkProfile 
networkProfile,
                                                  final DiagnosticsProfile 
diagnosticsProfile,
-                                                 final String 
provisioningState) {
+                                                 final ProvisioningState 
provisioningState) {
       return builder()
               .vmId(vmId)
               .licenseType(licenseType)
@@ -126,7 +145,7 @@ public abstract class VirtualMachineProperties {
 
       public abstract Builder diagnosticsProfile(DiagnosticsProfile 
diagnosticsProfile);
 
-      public abstract Builder provisioningState(String provisioningState);
+      public abstract Builder provisioningState(ProvisioningState 
provisioningState);
 
       public abstract VirtualMachineProperties build();
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/DeploymentApi.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/DeploymentApi.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/DeploymentApi.java
index 33c929a..8d446a5 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/DeploymentApi.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/DeploymentApi.java
@@ -34,12 +34,12 @@ import org.jclouds.Fallbacks;
 import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.azurecompute.arm.domain.Deployment;
+import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
 import org.jclouds.azurecompute.arm.functions.URIParser;
 import org.jclouds.oauth.v2.filters.OAuthFilter;
 import org.jclouds.rest.annotations.Fallback;
 import org.jclouds.rest.annotations.Payload;
 import org.jclouds.rest.annotations.PayloadParam;
-import org.jclouds.rest.annotations.QueryParams;
 import org.jclouds.rest.annotations.RequestFilters;
 import org.jclouds.rest.annotations.ResponseParser;
 import org.jclouds.rest.annotations.SelectJson;
@@ -50,8 +50,7 @@ import org.jclouds.rest.annotations.SelectJson;
  * - get information about deployment
  */
 
@Path("/resourcegroups/{resourcegroup}/providers/microsoft.resources/deployments")
-@QueryParams(keys = "api-version", values = "2016-02-01")
-@RequestFilters(OAuthFilter.class)
+@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
 @Consumes(MediaType.APPLICATION_JSON)
 public interface DeploymentApi {
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/JobApi.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/JobApi.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/JobApi.java
index f2858d9..3c3bab9 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/JobApi.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/JobApi.java
@@ -18,19 +18,20 @@ package org.jclouds.azurecompute.arm.features;
 import java.io.Closeable;
 import java.net.URI;
 import java.util.List;
+
 import javax.ws.rs.Consumes;
-import javax.ws.rs.core.MediaType;
 import javax.ws.rs.GET;
+import javax.ws.rs.core.MediaType;
 
 import org.jclouds.Fallbacks;
 import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
+import org.jclouds.azurecompute.arm.functions.ParseJobStatus;
+import org.jclouds.azurecompute.arm.functions.ParseJobStatus.JobStatus;
 import org.jclouds.oauth.v2.filters.OAuthFilter;
 import org.jclouds.rest.annotations.EndpointParam;
 import org.jclouds.rest.annotations.Fallback;
 import org.jclouds.rest.annotations.RequestFilters;
 import org.jclouds.rest.annotations.ResponseParser;
-import org.jclouds.azurecompute.arm.functions.ParseJobStatus;
-import org.jclouds.azurecompute.arm.functions.ParseJobStatus.JobStatus;
 import org.jclouds.rest.annotations.SelectJson;
 
 /**

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/LocationApi.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/LocationApi.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/LocationApi.java
index 8f31d31..257293c 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/LocationApi.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/LocationApi.java
@@ -27,11 +27,11 @@ import javax.ws.rs.core.MediaType;
 
 import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
 import org.jclouds.azurecompute.arm.domain.Location;
+import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
 import org.jclouds.oauth.v2.filters.OAuthFilter;
-import org.jclouds.rest.annotations.QueryParams;
+import org.jclouds.rest.annotations.Fallback;
 import org.jclouds.rest.annotations.RequestFilters;
 import org.jclouds.rest.annotations.SelectJson;
-import org.jclouds.rest.annotations.Fallback;
 
 /**
  * This Azure Resource Manager API provides all of the locations that are 
available for resource providers
@@ -40,8 +40,7 @@ import org.jclouds.rest.annotations.Fallback;
  * @see <a 
href="https://msdn.microsoft.com/en-US/library/azure/dn790540.aspx";>docs</a>
  */
 @Path("/locations")
-@RequestFilters(OAuthFilter.class)
-@QueryParams(keys = "api-version", values = "2015-11-01")
+@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
 @Produces(MediaType.APPLICATION_JSON)
 @Consumes(MediaType.APPLICATION_JSON)
 public interface LocationApi {

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkInterfaceCardApi.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkInterfaceCardApi.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkInterfaceCardApi.java
index 2f19996..c135e9e 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkInterfaceCardApi.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkInterfaceCardApi.java
@@ -16,38 +16,37 @@
  */
 package org.jclouds.azurecompute.arm.features;
 
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.MediaType;
+
 import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
 import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCardProperties;
+import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
 import org.jclouds.azurecompute.arm.functions.URIParser;
 import org.jclouds.oauth.v2.filters.OAuthFilter;
 import org.jclouds.rest.annotations.Fallback;
 import org.jclouds.rest.annotations.MapBinder;
 import org.jclouds.rest.annotations.PayloadParam;
-import org.jclouds.rest.annotations.QueryParams;
 import org.jclouds.rest.annotations.RequestFilters;
 import org.jclouds.rest.annotations.ResponseParser;
 import org.jclouds.rest.annotations.SelectJson;
 import org.jclouds.rest.binders.BindToJsonPayload;
 
-import javax.inject.Named;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.core.MediaType;
-import java.util.List;
-import java.util.Map;
-import java.net.URI;
-
 
@Path("/resourcegroups/{resourcegroup}/providers/Microsoft.Network/networkInterfaces")
-@QueryParams(keys = "api-version", values = "2015-06-15")
-@RequestFilters(OAuthFilter.class)
+@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
 @Consumes(MediaType.APPLICATION_JSON)
-
 public interface NetworkInterfaceCardApi {
 
    @Named("networkinterfacecard:list")

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkSecurityGroupApi.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkSecurityGroupApi.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkSecurityGroupApi.java
index e6b310d..ba4c2cd 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkSecurityGroupApi.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkSecurityGroupApi.java
@@ -16,40 +16,38 @@
  */
 package org.jclouds.azurecompute.arm.features;
 
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
 import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup;
 import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroupProperties;
+import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
 import org.jclouds.azurecompute.arm.functions.URIParser;
 import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.oauth.v2.filters.OAuthFilter;
-
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.QueryParams;
-import org.jclouds.rest.annotations.SelectJson;
 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.annotations.ResponseParser;
-import org.jclouds.rest.annotations.MapBinder;
+import org.jclouds.rest.annotations.SelectJson;
 import org.jclouds.rest.binders.BindToJsonPayload;
 
-import javax.inject.Named;
-import javax.ws.rs.Produces;
-import javax.ws.rs.Path;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.PUT;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.core.MediaType;
-import java.net.URI;
-import java.util.List;
-import java.util.Map;
-
 
@Path("/resourcegroups/{resourcegroup}/providers/Microsoft.Network/networkSecurityGroups")
-
-@QueryParams(keys = "api-version", values = "2016-03-30")
-@RequestFilters(OAuthFilter.class)
+@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
 @Consumes(MediaType.APPLICATION_JSON)
 public interface NetworkSecurityGroupApi {
 
@@ -72,9 +70,8 @@ public interface NetworkSecurityGroupApi {
    @MapBinder(BindToJsonPayload.class)
    @Produces(MediaType.APPLICATION_JSON)
    NetworkSecurityGroup createOrUpdate(@PathParam("networksecuritygroupname") 
String nsgName,
-                                       @PayloadParam("location") String 
location,
-                                       @Nullable @PayloadParam("tags") 
Map<String, String> tags,
-                                       
@PayloadParam("properties")NetworkSecurityGroupProperties properties);
+         @PayloadParam("location") String location, @Nullable 
@PayloadParam("tags") Map<String, String> tags,
+         @PayloadParam("properties") NetworkSecurityGroupProperties 
properties);
 
    @Named("networksecuritygroup:get")
    @Path("/{networksecuritygroupname}")
@@ -82,4 +79,3 @@ public interface NetworkSecurityGroupApi {
    @Fallback(NullOnNotFoundOr404.class)
    NetworkSecurityGroup get(@PathParam("networksecuritygroupname") String 
nsgName);
 }
-

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkSecurityRuleApi.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkSecurityRuleApi.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkSecurityRuleApi.java
index 2edd3df..8def4e3 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkSecurityRuleApi.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkSecurityRuleApi.java
@@ -16,38 +16,36 @@
  */
 package org.jclouds.azurecompute.arm.features;
 
+import java.net.URI;
+import java.util.List;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
 import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.azurecompute.arm.domain.NetworkSecurityRule;
 import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties;
+import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
 import org.jclouds.azurecompute.arm.functions.URIParser;
 import org.jclouds.oauth.v2.filters.OAuthFilter;
-
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.QueryParams;
-import org.jclouds.rest.annotations.SelectJson;
 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.annotations.ResponseParser;
-import org.jclouds.rest.annotations.MapBinder;
+import org.jclouds.rest.annotations.SelectJson;
 import org.jclouds.rest.binders.BindToJsonPayload;
 
-import javax.inject.Named;
-import javax.ws.rs.Produces;
-import javax.ws.rs.Path;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.PUT;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.core.MediaType;
-import java.util.List;
-import java.net.URI;
-
 
@Path("/resourcegroups/{resourcegroup}/providers/Microsoft.Network/networkSecurityGroups/{networksecuritygroup}")
-
-@QueryParams(keys = "api-version", values = "2016-03-30")
-@RequestFilters(OAuthFilter.class)
+@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
 @Consumes(MediaType.APPLICATION_JSON)
 public interface NetworkSecurityRuleApi {
    @Named("networksecurityrule:createOrUpdate")

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/OSImageApi.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/OSImageApi.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/OSImageApi.java
index 96dce6b..c8fb3f3 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/OSImageApi.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/OSImageApi.java
@@ -31,17 +31,16 @@ import org.jclouds.azurecompute.arm.domain.Offer;
 import org.jclouds.azurecompute.arm.domain.Publisher;
 import org.jclouds.azurecompute.arm.domain.SKU;
 import org.jclouds.azurecompute.arm.domain.Version;
+import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
 import org.jclouds.oauth.v2.filters.OAuthFilter;
 import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.annotations.QueryParams;
 import org.jclouds.rest.annotations.RequestFilters;
 
 /**
  * The Azure Resource Management API includes operations for managing the OS 
images in your subscription.
  */
 @Path("/providers/Microsoft.Compute/locations/{location}")
-@RequestFilters(OAuthFilter.class)
-@QueryParams(keys = "api-version", values = "2015-06-15")
+@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
 @Consumes(APPLICATION_JSON)
 public interface OSImageApi {
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/PublicIPAddressApi.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/PublicIPAddressApi.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/PublicIPAddressApi.java
index 2e19fe2..2693753 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/PublicIPAddressApi.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/PublicIPAddressApi.java
@@ -16,37 +16,36 @@
  */
 package org.jclouds.azurecompute.arm.features;
 
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.MediaType;
+
 import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
 import org.jclouds.azurecompute.arm.domain.PublicIPAddressProperties;
+import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
 import org.jclouds.azurecompute.arm.functions.FalseOn204;
 import org.jclouds.oauth.v2.filters.OAuthFilter;
 import org.jclouds.rest.annotations.Fallback;
 import org.jclouds.rest.annotations.MapBinder;
 import org.jclouds.rest.annotations.PayloadParam;
-import org.jclouds.rest.annotations.QueryParams;
 import org.jclouds.rest.annotations.RequestFilters;
 import org.jclouds.rest.annotations.ResponseParser;
 import org.jclouds.rest.annotations.SelectJson;
 import org.jclouds.rest.binders.BindToJsonPayload;
 
-import javax.inject.Named;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.core.MediaType;
-import java.util.List;
-import java.util.Map;
-
 
@Path("/resourcegroups/{resourcegroup}/providers/Microsoft.Network/publicIPAddresses")
-@QueryParams(keys = "api-version", values = "2015-06-15")
-@RequestFilters(OAuthFilter.class)
+@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
 @Consumes(MediaType.APPLICATION_JSON)
-
 public interface PublicIPAddressApi {
 
    @Named("publicipaddress:list")

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/ResourceGroupApi.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/ResourceGroupApi.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/ResourceGroupApi.java
index 1ad47d9..6f718a5 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/ResourceGroupApi.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/ResourceGroupApi.java
@@ -19,32 +19,31 @@ import java.io.Closeable;
 import java.net.URI;
 import java.util.List;
 import java.util.Map;
+
 import javax.inject.Named;
 import javax.ws.rs.Consumes;
-import javax.ws.rs.core.MediaType;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
 
 import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.azurecompute.arm.domain.ResourceGroup;
+import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
+import org.jclouds.azurecompute.arm.functions.URIParser;
 import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.oauth.v2.filters.OAuthFilter;
-import org.jclouds.rest.annotations.QueryParams;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.SelectJson;
 import org.jclouds.rest.annotations.Fallback;
 import org.jclouds.rest.annotations.MapBinder;
-import org.jclouds.rest.annotations.PayloadParam;
 import org.jclouds.rest.annotations.PATCH;
+import org.jclouds.rest.annotations.PayloadParam;
+import org.jclouds.rest.annotations.RequestFilters;
 import org.jclouds.rest.annotations.ResponseParser;
-import org.jclouds.azurecompute.arm.functions.URIParser;
-
-
+import org.jclouds.rest.annotations.SelectJson;
 import org.jclouds.rest.binders.BindToJsonPayload;
 
 /**
@@ -53,9 +52,7 @@ import org.jclouds.rest.binders.BindToJsonPayload;
  * @see <a 
href="https://msdn.microsoft.com/en-us/library/azure/dn790546.aspx";>docs</a>
  */
 @Path("/resourcegroups")
-
-@QueryParams(keys = "api-version", values = "2015-01-01")
-@RequestFilters(OAuthFilter.class)
+@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
 @Consumes(MediaType.APPLICATION_JSON)
 public interface ResourceGroupApi extends Closeable{
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/ResourceProviderApi.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/ResourceProviderApi.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/ResourceProviderApi.java
index e3d38b8..a25e2a5 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/ResourceProviderApi.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/ResourceProviderApi.java
@@ -17,14 +17,8 @@
 package org.jclouds.azurecompute.arm.features;
 
 
-import org.jclouds.Fallbacks.NullOnNotFoundOr404;
-import org.jclouds.azurecompute.arm.domain.ResourceProviderMetaData;
-import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.oauth.v2.filters.OAuthFilter;
-import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.annotations.QueryParams;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.SelectJson;
+import java.io.Closeable;
+import java.util.List;
 
 import javax.inject.Named;
 import javax.ws.rs.Consumes;
@@ -32,8 +26,15 @@ import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.core.MediaType;
-import java.io.Closeable;
-import java.util.List;
+
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.azurecompute.arm.domain.ResourceProviderMetaData;
+import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.oauth.v2.filters.OAuthFilter;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.SelectJson;
 
 /**
  * The Azure Resource Provider API provides information about a resource 
provider and its supported resource types.
@@ -42,8 +43,7 @@ import java.util.List;
  */
 @Path("/providers")
 
-@QueryParams(keys = "api-version", values = "2015-01-01")
-@RequestFilters(OAuthFilter.class)
+@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
 @Consumes(MediaType.APPLICATION_JSON)
 public interface ResourceProviderApi extends Closeable {
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2f110387/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/StorageAccountApi.java
----------------------------------------------------------------------
diff --git 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/StorageAccountApi.java
 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/StorageAccountApi.java
index fd75fca..5d2e06c 100644
--- 
a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/StorageAccountApi.java
+++ 
b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/StorageAccountApi.java
@@ -16,15 +16,19 @@
  */
 package org.jclouds.azurecompute.arm.features;
 
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
 import javax.inject.Named;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
 import javax.ws.rs.Consumes;
-import javax.ws.rs.PUT;
-import javax.ws.rs.POST;
 import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
 
 import org.jclouds.Fallbacks;
@@ -32,35 +36,28 @@ import org.jclouds.azurecompute.arm.domain.Availability;
 import org.jclouds.azurecompute.arm.domain.StorageService;
 import org.jclouds.azurecompute.arm.domain.StorageServiceKeys;
 import org.jclouds.azurecompute.arm.domain.StorageServiceUpdateParams;
+import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
 import org.jclouds.azurecompute.arm.functions.FalseOn204;
 import org.jclouds.azurecompute.arm.functions.URIParser;
 import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.oauth.v2.filters.OAuthFilter;
 import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.annotations.QueryParams;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.SelectJson;
-import org.jclouds.rest.annotations.Payload;
+import org.jclouds.rest.annotations.MapBinder;
 import org.jclouds.rest.annotations.PATCH;
-import org.jclouds.rest.annotations.ResponseParser;
+import org.jclouds.rest.annotations.Payload;
 import org.jclouds.rest.annotations.PayloadParam;
-import org.jclouds.rest.annotations.MapBinder;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.ResponseParser;
+import org.jclouds.rest.annotations.SelectJson;
 import org.jclouds.rest.binders.BindToJsonPayload;
 
-import java.util.List;
-import java.util.Map;
-import java.net.URI;
-
-import static 
org.jclouds.azurecompute.arm.config.AzureComputeProperties.STORAGE_API_VERSION;
-
 /**
  * The Azure Resource Management API includes operations for managing the 
storage accounts in your subscription.
  *
  * @see <a 
href="https://msdn.microsoft.com/en-us/library/mt163683.aspx";>docs</a>
  */
 @Path("/")
-@RequestFilters(OAuthFilter.class)
-@QueryParams(keys = "api-version", values = STORAGE_API_VERSION)
+@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
 @Consumes(MediaType.APPLICATION_JSON)
 public interface StorageAccountApi {
 

Reply via email to