You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ab...@apache.org on 2013/07/01 21:13:23 UTC

[18/20] JCLOUDS-150 - Removal of async from AWS - specifically EC2

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/main/java/org/jclouds/ec2/features/InstanceApi.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/features/InstanceApi.java b/apis/ec2/src/main/java/org/jclouds/ec2/features/InstanceApi.java
new file mode 100644
index 0000000..2b56324
--- /dev/null
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/features/InstanceApi.java
@@ -0,0 +1,765 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.ec2.features;
+
+import static org.jclouds.aws.reference.FormParameters.ACTION;
+
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Named;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+
+import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
+import org.jclouds.aws.filters.FormSigner;
+import org.jclouds.ec2.binders.BindBlockDeviceMappingToIndexedFormParams;
+import org.jclouds.ec2.binders.BindInstanceIdsToIndexedFormParams;
+import org.jclouds.ec2.binders.IfNotNullBindAvailabilityZoneToFormParam;
+import org.jclouds.ec2.domain.BlockDevice;
+import org.jclouds.ec2.domain.InstanceStateChange;
+import org.jclouds.ec2.domain.Reservation;
+import org.jclouds.ec2.domain.RunningInstance;
+import org.jclouds.ec2.domain.Volume.InstanceInitiatedShutdownBehavior;
+import org.jclouds.ec2.functions.ConvertUnencodedBytesToBase64EncodedString;
+import org.jclouds.ec2.options.RunInstancesOptions;
+import org.jclouds.ec2.xml.BlockDeviceMappingHandler;
+import org.jclouds.ec2.xml.BooleanValueHandler;
+import org.jclouds.ec2.xml.DescribeInstancesResponseHandler;
+import org.jclouds.ec2.xml.GetConsoleOutputResponseHandler;
+import org.jclouds.ec2.xml.InstanceInitiatedShutdownBehaviorHandler;
+import org.jclouds.ec2.xml.InstanceStateChangeHandler;
+import org.jclouds.ec2.xml.InstanceTypeHandler;
+import org.jclouds.ec2.xml.RunInstancesResponseHandler;
+import org.jclouds.ec2.xml.StringValueHandler;
+import org.jclouds.ec2.xml.UnencodeStringValueHandler;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.EndpointParam;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.FormParams;
+import org.jclouds.rest.annotations.ParamParser;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.VirtualHost;
+import org.jclouds.rest.annotations.XMLResponseParser;
+
+/**
+ * Provides access to EC2 Instance Services via their REST API.
+ * <p/>
+ * 
+ * @author Adrian Cole
+ */
+@RequestFilters(FormSigner.class)
+@VirtualHost
+public interface InstanceApi {
+
+   /**
+    * Returns information about instances that you own.
+    * <p/>
+    * 
+    * If you specify one or more instance IDs, Amazon EC2 returns information
+    * for those instances. If you do not specify instance IDs, Amazon EC2
+    * returns information for all relevant instances. If you specify an invalid
+    * instance ID, a fault is returned. If you specify an instance that you do
+    * not own, it will not be included in the returned results.
+    * <p/>
+    * Recently terminated instances might appear in the returned results.This
+    * interval is usually less than one hour.
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * 
+    * @see #runInstancesInRegion
+    * @see #terminateInstancesInRegion
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html"
+    *      />
+    */
+   @Named("DescribeInstances")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DescribeInstances")
+   @XMLResponseParser(DescribeInstancesResponseHandler.class)
+   @Fallback(EmptySetOnNotFoundOr404.class)
+   Set<? extends Reservation<? extends RunningInstance>> describeInstancesInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
+
+   /**
+    * Launches a specified number of instances of an AMI for which you have
+    * permissions.
+    * <p/>
+    * 
+    * If Amazon EC2 cannot launch the minimum number AMIs you request, no
+    * instances will be launched. If there is insufficient capacity to launch
+    * the maximum number of AMIs you request, Amazon EC2 launches the minimum
+    * number specified for each AMI and allocate the remaining available
+    * instances using round robin.
+    * <p/>
+    * <h4>Security Groups</h4>
+    * <b>Note:</b> Every instance is launched in a security group (created using
+    * the CreateSecurityGroup operation.
+    * <h4>Key Pair</h4>
+    * You can provide an optional key pair ID for each image in the launch
+    * request (created using the CreateKeyPair operation). All instances that
+    * are created from images that use this key pair will have access to the
+    * associated public key at boot. You can use this key to provide secure
+    * access to an instance of an image on a per-instance basis. Amazon EC2
+    * public images use this feature to provide secure access without passwords.
+    * <p/>
+    * <b>Note:</b> Launching public images without a key pair ID will leave them
+    * inaccessible.
+    * <p/>
+    * The public key material is made available to the instance at boot time by
+    * placing it in the openssh_id.pub file on a logical device that is exposed
+    * to the instance as /dev/sda2 (the instance store). The format of this file
+    * is suitable for use as an entry within ~/.ssh/authorized_keys (the OpenSSH
+    * format). This can be done at boot (e.g., as part of rc.local) allowing for
+    * secure access without passwords.
+    * <h4>User Data</h4>
+    * Optional user data can be provided in the launch request. All instances
+    * that collectively comprise the launch request have access to this data.
+    * For more information, go the Amazon Elastic Compute Cloud Developer Guide.
+    * <h4>Product Codes</h4>
+    * 
+    * <b>Note:</b> If any of the AMIs have a product code attached for which the
+    * user has not subscribed, the RunInstances call will fail.
+    * <h4>Kernel</h4>
+    * 
+    * <b>Important:</b> We strongly recommend using the 2.6.18 Xen stock kernel
+    * with High-CPU and High-Memory instances. Although the default Amazon EC2
+    * kernels will work, the new kernels provide greater stability and
+    * performance for these instance types. For more information about kernels,
+    * go the Amazon Elastic Compute Cloud Developer Guide.
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * @param nullableAvailabilityZone
+    *           Specifies the placement constraints (Availability Zones) for
+    *           launching the instances. If null, Amazon will determine the best
+    *           availability zone to place the instance.
+    * @param imageId
+    *           Unique ID of a machine image, returned by a call to
+    * @param minCount
+    *           Minimum number of instances to launch. If the value is more than
+    *           Amazon EC2 can launch, no instances a re launched at all.
+    *           Constraints: Between 1 and the maximum number allowed for your
+    *           account (default: 20).
+    * @param maxCount
+    *           Maximum number of instances to launch. If the value is more than
+    *           Amazon EC2 can launch, the largest possible number above
+    *           minCount will be launched instead. Constraints: Between 1 and
+    *           the maximum number allowed for your account (default: 20).
+    * @see #describeInstancesInRegion
+    * @see #terminateInstancesInRegion
+    * @see #authorizeSecurityGroupIngressInRegion
+    * @see #revokeSecurityGroupIngressInRegion
+    * @see #describeSecurityGroupsInRegion
+    * @see #createSecurityGroupInRegion
+    * @see #createKeyPairInRegion
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-RunInstances.html"
+    *      />
+    * @see RunInstancesOptions
+    */
+   @Named("RunInstances")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "RunInstances")
+   @XMLResponseParser(RunInstancesResponseHandler.class)
+   Reservation<? extends RunningInstance> runInstancesInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @Nullable @BinderParam(IfNotNullBindAvailabilityZoneToFormParam.class) String nullableAvailabilityZone,
+         @FormParam("ImageId") String imageId, @FormParam("MinCount") int minCount,
+         @FormParam("MaxCount") int maxCount, RunInstancesOptions... options);
+
+   /**
+    * Requests a reboot of one or more instances. This operation is
+    * asynchronous; it only queues a request to reboot the specified
+    * instance(s). The operation will succeed if the instances are valid and
+    * belong to you. Requests to reboot terminated instances are ignored. <h3>
+    * Note</h3> If a Linux/UNIX instance does not cleanly shut down within four
+    * minutes, Amazon EC2 will perform a hard reboot.
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * 
+    * @param instanceIds
+    *           Instance ID to reboot.
+    * 
+    * @see #startInstancesInRegion
+    * @see #runInstancesInRegion
+    * @see #describeInstancesInRegion
+    * @see #terminateInstancesInRegion
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-StopInstances.html"
+    *      />
+    */
+   @Named("RebootInstances")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "RebootInstances")
+   void rebootInstancesInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
+
+   /**
+    * Shuts down one or more instances. This operation is idempotent; if you
+    * terminate an instance more than once, each call will succeed.
+    * <p/>
+    * Terminated instances will remain visible after termination (approximately
+    * one hour).
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * @param instanceIds
+    *           Instance ID to terminate.
+    * @see #describeInstancesInRegion
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-TerminateInstances.html"
+    *      />
+    */
+   @Named("TerminateInstances")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "TerminateInstances")
+   @XMLResponseParser(InstanceStateChangeHandler.class)
+   @Fallback(EmptySetOnNotFoundOr404.class)
+   Set<? extends InstanceStateChange> terminateInstancesInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
+
+   /**
+    * Stops an instance that uses an Amazon EBS volume as its root device.
+    * <p/>
+    * Instances that use Amazon EBS volumes as their root devices can be quickly
+    * stopped and started. When an instance is stopped, the compute resources
+    * are released and you are not billed for hourly instance usage. However,
+    * your root partition Amazon EBS volume remains, continues to persist your
+    * data, and you are charged for Amazon EBS volume usage. You can restart
+    * your instance at any time.
+    * <h3>Note</h3>
+    * Before stopping an instance, make sure it is in a state from which it can
+    * be restarted. Stopping an instance does not preserve data stored in RAM.
+    * <p/>
+    * Performing this operation on an instance that uses an instance store as
+    * its root device returns an error.
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * @param force
+    *           Forces the instance to stop. The instance will not have an
+    *           opportunity to flush file system caches nor file system meta
+    *           data. If you use this option, you must perform file system check
+    *           and repair procedures. This option is not recommended for
+    *           Windows instances.
+    * @param instanceIds
+    *           Instance ID to stop.
+    * 
+    * @see #startInstancesInRegion
+    * @see #runInstancesInRegion
+    * @see #describeInstancesInRegion
+    * @see #terminateInstancesInRegion
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-StopInstances.html"
+    *      />
+    */
+   @Named("StopInstances")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "StopInstances")
+   @XMLResponseParser(InstanceStateChangeHandler.class)
+   Set<? extends InstanceStateChange> stopInstancesInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("Force") boolean force,
+         @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
+
+   /**
+    * Starts an instance that uses an Amazon EBS volume as its root device.
+    * <p/>
+    * Instances that use Amazon EBS volumes as their root devices can be quickly
+    * stopped and started. When an instance is stopped, the compute resources
+    * are released and you are not billed for hourly instance usage. However,
+    * your root partition Amazon EBS volume remains, continues to persist your
+    * data, and you are charged for Amazon EBS volume usage. You can restart
+    * your instance at any time.
+    * <h3>Note</h3>
+    * Before stopping an instance, make sure it is in a state from which it can
+    * be restarted. Stopping an instance does not preserve data stored in RAM.
+    * <p/>
+    * Performing this operation on an instance that uses an instance store as
+    * its root device returns an error.
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * @param instanceIds
+    *           Instance ID to start.
+    * 
+    * @see #stopInstancesInRegion
+    * @see #runInstancesInRegion
+    * @see #describeInstancesInRegion
+    * @see #terminateInstancesInRegion
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-StartInstances.html"
+    *      />
+    */
+   @Named("StartInstances")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "StartInstances")
+   @XMLResponseParser(InstanceStateChangeHandler.class)
+   Set<? extends InstanceStateChange> startInstancesInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
+
+   /**
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * @param instanceId
+    *           which instance to describe the attribute of
+    * @return unencoded user data
+    */
+   @Named("DescribeInstanceAttribute")
+   @POST
+   @Path("/")
+   @FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeInstanceAttribute", "userData" })
+   @XMLResponseParser(UnencodeStringValueHandler.class)
+   String getUserDataForInstanceInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("InstanceId") String instanceId);
+
+   /**
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * @param instanceId
+    *           which instance to describe the attribute of
+    * @return The root device name (e.g., /dev/sda1).
+    */
+   @Named("DescribeInstanceAttribute")
+   @POST
+   @Path("/")
+   @FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeInstanceAttribute", "rootDeviceName" })
+   @XMLResponseParser(StringValueHandler.class)
+   String getRootDeviceNameForInstanceInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("InstanceId") String instanceId);
+
+   /**
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * @param instanceId
+    *           which instance to describe the attribute of
+    * @return the ID of the RAM disk associated with the AMI.
+    */
+   @Named("DescribeInstanceAttribute")
+   @POST
+   @Path("/")
+   @FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeInstanceAttribute", "ramdisk" })
+   @XMLResponseParser(StringValueHandler.class)
+   String getRamdiskForInstanceInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("InstanceId") String instanceId);
+
+   /**
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * @param instanceId
+    *           which instance to describe the attribute of
+    * @return the ID of the kernel associated with the AMI.
+    */
+   @Named("DescribeInstanceAttribute")
+   @POST
+   @Path("/")
+   @FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeInstanceAttribute", "kernel" })
+   @XMLResponseParser(StringValueHandler.class)
+   String getKernelForInstanceInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("InstanceId") String instanceId);
+
+   /**
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * @param instanceId
+    *           which instance to describe the attribute of
+    * @return Specifies whether the instance can be terminated using the APIs.
+    *         You must modify this attribute before you can terminate any
+    *         "locked" instances from the APIs.
+    */
+   @Named("DescribeInstanceAttribute")
+   @POST
+   @Path("/")
+   @FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeInstanceAttribute", "disableApiTermination" })
+   @XMLResponseParser(BooleanValueHandler.class)
+   boolean isApiTerminationDisabledForInstanceInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("InstanceId") String instanceId);
+
+   /**
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * @param instanceId
+    *           which instance to describe the attribute of
+    * @return The instance type of the instance.
+    */
+   @Named("DescribeInstanceAttribute")
+   @POST
+   @Path("/")
+   @FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeInstanceAttribute", "instanceType" })
+   @XMLResponseParser(InstanceTypeHandler.class)
+   String getInstanceTypeForInstanceInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("InstanceId") String instanceId);
+
+   /**
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * @param instanceId
+    *           which instance to describe the attribute of
+    * @return whether the instance's Amazon EBS volumes are stopped or
+    *         terminated when the instance is shut down.
+    */
+   @Named("DescribeInstanceAttribute")
+   @POST
+   @Path("/")
+   @FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeInstanceAttribute",
+         "instanceInitiatedShutdownBehavior" })
+   @XMLResponseParser(InstanceInitiatedShutdownBehaviorHandler.class)
+   InstanceInitiatedShutdownBehavior getInstanceInitiatedShutdownBehaviorForInstanceInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("InstanceId") String instanceId);
+
+   /**
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * @param instanceId
+    *           which instance to describe the attribute of
+    * @return Describes the mapping that defines native device names to use when
+    *         exposing virtual devices.
+    */
+   @Named("DescribeInstanceAttribute")
+   @POST
+   @Path("/")
+   @FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeInstanceAttribute", "blockDeviceMapping" })
+   @XMLResponseParser(BlockDeviceMappingHandler.class)
+   Map<String, BlockDevice> getBlockDeviceMappingForInstanceInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("InstanceId") String instanceId);
+
+   /**
+    * Resets an attribute of an instance to its default value.
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * @param instanceId
+    *           which instance to reset the attribute of
+    * @return the ID of the RAM disk associated with the AMI.
+    */
+   @Named("ResetInstanceAttribute")
+   @POST
+   @Path("/")
+   @FormParams(keys = { ACTION, "Attribute" }, values = { "ResetInstanceAttribute", "ramdisk" })
+   void resetRamdiskForInstanceInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("InstanceId") String instanceId);
+
+   /**
+    * Resets an attribute of an instance to its default value.
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * @param instanceId
+    *           which instance to reset the attribute of
+    * @return the ID of the kernel associated with the AMI.
+    */
+   @Named("ResetInstanceAttribute")
+   @POST
+   @Path("/")
+   @FormParams(keys = { ACTION, "Attribute" }, values = { "ResetInstanceAttribute", "kernel" })
+   void resetKernelForInstanceInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("InstanceId") String instanceId);
+
+   /**
+    * Sets the userData used for starting the instance.
+    * <p/>
+    * The instance needs to be in a {@link InstanceState#STOPPED} state, which
+    * implies two things:
+    * <ol>
+    * <li>The instance was launched from an EBS-backed AMI so that it can stop</li>
+    * <li>You have stopped and waited for the instance to transition from
+    * {@link InstanceState#STOPPING} to {@link InstanceState#STOPPED}</li>
+    * </ol>
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * @param instanceId
+    *           which instance to change the attribute of
+    * @param unencodedData
+    *           unencoded data to set as userData
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyInstanceAttribute.html"
+    *      />
+    */
+   @Named("ModifyInstanceAttribute")
+   @POST
+   @Path("/")
+   @FormParams(keys = { ACTION, "Attribute" }, values = { "ModifyInstanceAttribute", "userData" })
+   void setUserDataForInstanceInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("InstanceId") String instanceId,
+         @FormParam("Value") @ParamParser(ConvertUnencodedBytesToBase64EncodedString.class) byte[] unencodedData);
+
+   /**
+    * Sets the ramdisk used for starting the instance.
+    * <p/>
+    * The instance needs to be in a {@link InstanceState#STOPPED} state, which
+    * implies two things:
+    * <ol>
+    * <li>The instance was launched from an EBS-backed AMI so that it can stop</li>
+    * <li>You have stopped and waited for the instance to transition from
+    * {@link InstanceState#STOPPING} to {@link InstanceState#STOPPED}</li>
+    * </ol>
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * @param instanceId
+    *           which instance to change the attribute of
+    * @param ramdisk
+    *           ramdisk used to start the instance
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyInstanceAttribute.html"
+    *      />
+    */
+   @Named("ModifyInstanceAttribute")
+   @POST
+   @Path("/")
+   @FormParams(keys = { ACTION, "Attribute" }, values = { "ModifyInstanceAttribute", "ramdisk" })
+   void setRamdiskForInstanceInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("InstanceId") String instanceId, @FormParam("Value") String ramdisk);
+
+   /**
+    * Sets the kernelId used for starting the instance.
+    * <p/>
+    * The instance needs to be in a {@link InstanceState#STOPPED} state, which
+    * implies two things:
+    * <ol>
+    * <li>The instance was launched from an EBS-backed AMI so that it can stop</li>
+    * <li>You have stopped and waited for the instance to transition from
+    * {@link InstanceState#STOPPING} to {@link InstanceState#STOPPED}</li>
+    * </ol>
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * @param instanceId
+    *           which instance to change the attribute of
+    * @param kernel
+    *           kernelId used to start the instance
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyInstanceAttribute.html"
+    *      />
+    */
+   @Named("ModifyInstanceAttribute")
+   @POST
+   @Path("/")
+   @FormParams(keys = { ACTION, "Attribute" }, values = { "ModifyInstanceAttribute", "kernel" })
+   void setKernelForInstanceInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("InstanceId") String instanceId, @FormParam("Value") String kernel);
+
+   /**
+    * This command works while the instance is running and controls whether or
+    * not the api can be used to terminate the instance.
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * @param instanceId
+    *           which instance to reset the attribute of
+    * @param apiTerminationDisabled
+    *           true to disable api termination
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyInstanceAttribute.html"
+    *      />
+    */
+   @Named("ModifyInstanceAttribute")
+   @POST
+   @Path("/")
+   @FormParams(keys = { ACTION, "Attribute" }, values = { "ModifyInstanceAttribute", "disableApiTermination" })
+   void setApiTerminationDisabledForInstanceInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("InstanceId") String instanceId, @FormParam("Value") boolean apiTerminationDisabled);
+
+   /**
+    * Sets the instanceType used for starting the instance.
+    * <p/>
+    * The instance needs to be in a {@link InstanceState#STOPPED} state, which
+    * implies two things:
+    * <ol>
+    * <li>The instance was launched from an EBS-backed AMI so that it can stop</li>
+    * <li>You have stopped and waited for the instance to transition from
+    * {@link InstanceState#STOPPING} to {@link InstanceState#STOPPED}</li>
+    * </ol>
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * @param instanceId
+    *           which instance to change the attribute of
+    * @param instanceType
+    *           instanceType used to start the instance
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyInstanceAttribute.html"
+    *      />
+    */
+   @Named("ModifyInstanceAttribute")
+   @POST
+   @Path("/")
+   @FormParams(keys = { ACTION, "Attribute" }, values = { "ModifyInstanceAttribute", "instanceType" })
+   void setInstanceTypeForInstanceInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("InstanceId") String instanceId, @FormParam("Value") String instanceType);
+
+   /**
+    * Specifies whether the instance's Amazon EBS volumes are stopped or
+    * terminated when the instance is shut down.
+    * <p/>
+    * The instance needs to be in a {@link InstanceState#STOPPED} state, which
+    * implies two things:
+    * <ol>
+    * <li>The instance was launched from an EBS-backed AMI so that it can stop</li>
+    * <li>You have stopped and waited for the instance to transition from
+    * {@link InstanceState#STOPPING} to {@link InstanceState#STOPPED}</li>
+    * </ol>
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * @param instanceId
+    *           which instance to change the attribute of
+    * @param instanceInitiatedShutdownBehavior
+    *           whether the instance's Amazon EBS volumes are stopped or
+    *           terminated when the instance is shut down.
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyInstanceAttribute.html"
+    *      />
+    */
+   @Named("ModifyInstanceAttribute")
+   @POST
+   @Path("/")
+   @FormParams(keys = { ACTION, "Attribute" }, values = { "ModifyInstanceAttribute",
+         "instanceInitiatedShutdownBehavior" })
+   void setInstanceInitiatedShutdownBehaviorForInstanceInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("InstanceId") String instanceId,
+         @FormParam("Value") InstanceInitiatedShutdownBehavior instanceInitiatedShutdownBehavior);
+
+   /**
+    * Sets the blockDeviceMapping used for an instance.
+    * <p/>
+    * The instance needs to be in a {@link InstanceState#STOPPED} state, which
+    * implies two things:
+    * <ol>
+    * <li>The instance was launched from an EBS-backed AMI so that it can stop</li>
+    * <li>You have stopped and waited for the instance to transition from
+    * {@link InstanceState#STOPPING} to {@link InstanceState#STOPPED}</li>
+    * </ol>
+    * 
+    * To create the instances of {@link BlockDevice}, the
+    * constructor can be used with the following parameters:
+    * {@link BlockDevice#EbsBlockDevice(String, String, boolean)}
+    * , that are:
+    * <ol>
+    * <li>Volume id (required), for instance, "vol-blah"</li>
+    * <li>Device name (optional), for instance, "/dev/sda1". To find out more
+    * about device names, read the next paragraph.</li>
+    * <li>Delete on termination flag (optional), which defines whether the
+    * volume will be deleted upon instance's termination.</li>
+    * </ol>
+    * <p/>
+    * Note that the device names between Linux and Windows differ. For Linux,
+    * ensure that your device name is in the form /dev/sd[a-z] . For example,
+    * /dev/sda , /dev/sdb and /dev/sdh are all valid device names.
+    * <p/>
+    * For Windows, the root device is still referred to as /dev/sda1 . For other
+    * devices, ensure that they are in the form /xvd[c-p] . For example, /xvde ,
+    * /xvdf and /xvdp are all valid Windows device names.
+    * <p/>
+    * <b>NOTE</b>: As of now 02/20/2010, this command only works to change the
+    * DeleteOnTermination property of the device. The volume must be
+    * <i>attached</i> to a stopped instance.
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * @param instanceId
+    *           which instance to change the attribute of
+    * @param blockDeviceMapping
+    *           blockDeviceMapping used to start the instance
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyInstanceAttribute.html"
+    *      />
+    */
+   @Named("ModifyInstanceAttribute")
+   @POST
+   @Path("/")
+   @FormParams(keys = { ACTION }, values = { "ModifyInstanceAttribute" })
+   void setBlockDeviceMappingForInstanceInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("InstanceId") String instanceId,
+         @BinderParam(BindBlockDeviceMappingToIndexedFormParams.class) Map<String, BlockDevice> blockDeviceMapping);
+
+   /**
+    * Retrieves console output for the specified instance.
+    *
+    * Instance console output is buffered and posted shortly after instance boot, reboot, and termination. Amazon EC2 preserves
+    * the most recent 64 KB output which will be available for at least one hour after the most recent post.
+    *
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance
+    *           ID is tied to the Region.
+    * @param instanceId
+    *           which instance to retrieve console output for
+    * @return The console output
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-GetConsoleOutput.html">
+    *       ApiReference query GetConsoleOutput</a>
+    */
+   @Named("GetConsoleOutput")
+   @POST
+   @Path("/")
+   @FormParams(keys = { ACTION }, values = { "GetConsoleOutput" })
+   @XMLResponseParser(GetConsoleOutputResponseHandler.class)
+   String getConsoleOutputForInstanceInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("InstanceId") String instanceId);
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/main/java/org/jclouds/ec2/features/KeyPairApi.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/features/KeyPairApi.java b/apis/ec2/src/main/java/org/jclouds/ec2/features/KeyPairApi.java
new file mode 100644
index 0000000..b09406e
--- /dev/null
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/features/KeyPairApi.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.ec2.features;
+
+import static org.jclouds.aws.reference.FormParameters.ACTION;
+
+import java.util.Set;
+
+import javax.inject.Named;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+
+import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
+import org.jclouds.aws.filters.FormSigner;
+import org.jclouds.ec2.binders.BindKeyNamesToIndexedFormParams;
+import org.jclouds.ec2.domain.KeyPair;
+import org.jclouds.ec2.xml.DescribeKeyPairsResponseHandler;
+import org.jclouds.ec2.xml.KeyPairResponseHandler;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.EndpointParam;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.FormParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.VirtualHost;
+import org.jclouds.rest.annotations.XMLResponseParser;
+
+/**
+ * Provides access to EC2 via their REST API.
+ * <p/>
+ * 
+ * @author Adrian Cole
+ */
+@RequestFilters(FormSigner.class)
+@VirtualHost
+public interface KeyPairApi {
+
+   /**
+    * Creates a new 2048-bit RSA key pair with the specified name. The public key is stored by
+    * Amazon EC2 and the private key is displayed on the console. The private key is returned as an
+    * unencrypted PEM encoded PKCS#8 private key. If a key with the specified name already exists,
+    * Amazon EC2 returns an error.
+    * 
+    * @param region
+    *           Key pairs (to connect to instances) are Region-specific.
+    * @param keyName
+    *           A unique name for the key pair.
+    * 
+    * @see #runInstances
+    * @see #describeKeyPairs
+    * @see #deleteKeyPair
+    * 
+    * @see <a href=
+    *      "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateKeyPair.html"
+    *      />
+    */
+   @Named("CreateKeyPair")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "CreateKeyPair")
+   @XMLResponseParser(KeyPairResponseHandler.class)
+   KeyPair createKeyPairInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+            @FormParam("KeyName") String keyName);
+
+   /**
+    * Returns information about key pairs available to you. If you specify key pairs, information
+    * about those key pairs is returned. Otherwise, information for all registered key pairs is
+    * returned.
+    * 
+    * @param region
+    *           Key pairs (to connect to instances) are Region-specific.
+    * @param keyPairNames
+    *           Key pairs to describe.
+    * 
+    * @see #runInstances
+    * @see #describeAvailabilityZones
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeKeyPairs.html"
+    *      />
+    */
+   @Named("DescribeKeyPairs")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DescribeKeyPairs")
+   @XMLResponseParser(DescribeKeyPairsResponseHandler.class)
+   @Fallback(EmptySetOnNotFoundOr404.class)
+   Set<KeyPair> describeKeyPairsInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+            @BinderParam(BindKeyNamesToIndexedFormParams.class) String... keyPairNames);
+
+   /**
+    * Deletes the specified key pair, by removing the public key from Amazon EC2. You must own the
+    * key pair
+    * 
+    * @param region
+    *           Key pairs (to connect to instances) are Region-specific.
+    * @param keyName
+    *           Name of the key pair to delete
+    * 
+    * @see #describeKeyPairs
+    * @see #createKeyPair
+    * 
+    * @see <a href=
+    *      "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteKeyPair.html"
+    *      />
+    */
+   @Named("DeleteKeyPair")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DeleteKeyPair")
+   void deleteKeyPairInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+            @FormParam("KeyName") String keyName);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/main/java/org/jclouds/ec2/features/SecurityGroupApi.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/features/SecurityGroupApi.java b/apis/ec2/src/main/java/org/jclouds/ec2/features/SecurityGroupApi.java
new file mode 100644
index 0000000..70cbdac
--- /dev/null
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/features/SecurityGroupApi.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.ec2.features;
+
+import static org.jclouds.aws.reference.FormParameters.ACTION;
+
+import java.util.Set;
+
+import javax.inject.Named;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+
+import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
+import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
+import org.jclouds.aws.filters.FormSigner;
+import org.jclouds.ec2.binders.BindGroupNamesToIndexedFormParams;
+import org.jclouds.ec2.binders.BindUserIdGroupPairToSourceSecurityGroupFormParams;
+import org.jclouds.ec2.domain.SecurityGroup;
+import org.jclouds.ec2.domain.UserIdGroupPair;
+import org.jclouds.ec2.xml.DescribeSecurityGroupsResponseHandler;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
+import org.jclouds.net.domain.IpProtocol;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.EndpointParam;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.FormParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.VirtualHost;
+import org.jclouds.rest.annotations.XMLResponseParser;
+
+/**
+ * Provides access to EC2 via their REST API.
+ * <p/>
+ * 
+ * @author Adrian Cole
+ */
+@RequestFilters(FormSigner.class)
+@VirtualHost
+public interface SecurityGroupApi {
+
+   /**
+    * Creates a new security group. Group names must be unique per identity.
+    * 
+    * @param region
+    *           Security groups are not copied across Regions. Instances within the Region cannot
+    *           communicate with instances outside the Region using group-based firewall rules.
+    *           Traffic from instances in another Region is seen as WAN bandwidth.
+    * @param name
+    *           Name of the security group. Accepts alphanumeric characters, spaces, dashes, and
+    *           underscores.
+    * @param description
+    *           Description of the group. This is informational only. If the description contains
+    *           spaces, you must enc lose it in single quotes (') or URL-encode it. Accepts
+    *           alphanumeric characters, spaces, dashes, and underscores.
+    * @see #runInstances
+    * @see #describeSecurityGroups
+    * @see #authorizeSecurityGroupIngress
+    * @see #revokeSecurityGroupIngress
+    * @see #deleteSecurityGroup
+    * 
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateSecurityGroup.html"
+    *      />
+    */
+   @Named("CreateSecurityGroup")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "CreateSecurityGroup")
+   void createSecurityGroupInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+            @FormParam("GroupName") String name, @FormParam("GroupDescription") String description);
+
+   /**
+    * Deletes a security group that you own.
+    * 
+    * @param region
+    *           Security groups are not copied across Regions. Instances within the Region cannot
+    *           communicate with instances outside the Region using group-based firewall rules.
+    *           Traffic from instances in another Region is seen as WAN bandwidth.
+    * @param name
+    *           Name of the security group to delete.
+    * 
+    * @see #describeSecurityGroups
+    * @see #authorizeSecurityGroupIngress
+    * @see #revokeSecurityGroupIngress
+    * @see #createSecurityGroup
+    * 
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteSecurityGroup.html"
+    *      />
+    */
+   @Named("DeleteSecurityGroup")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DeleteSecurityGroup")
+   @Fallback(VoidOnNotFoundOr404.class)
+   void deleteSecurityGroupInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @FormParam("GroupName") String name);
+
+   /**
+    * Returns information about security groups that you own.
+    * 
+    * @param region
+    *           Security groups are not copied across Regions. Instances within the Region cannot
+    *           communicate with instances outside the Region using group-based firewall rules.
+    *           Traffic from instances in another Region is seen as WAN bandwidth.
+    * @param securityGroupNames
+    *           Name of the security groups
+    * 
+    * @see #createSecurityGroup
+    * @see #authorizeSecurityGroupIngress
+    * @see #revokeSecurityGroupIngress
+    * @see #deleteSecurityGroup
+    * 
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSecurityGroups.html"
+    *      />
+    */
+   @Named("DescribeSecurityGroups")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DescribeSecurityGroups")
+   @XMLResponseParser(DescribeSecurityGroupsResponseHandler.class)
+   @Fallback(EmptySetOnNotFoundOr404.class)
+   Set<SecurityGroup> describeSecurityGroupsInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+            @BinderParam(BindGroupNamesToIndexedFormParams.class) String... securityGroupNames);
+
+   /**
+    * 
+    * Adds permissions to a security group based on another group.
+    * 
+    * @param region
+    *           Security groups are not copied across Regions. Instances within the Region cannot
+    *           communicate with instances outside the Region using group-based firewall rules.
+    *           Traffic from instances in another Region is seen as WAN bandwidth.
+    * @param groupName
+    *           Name of the group to modify. The name must be valid and belong to the identity
+    * @param sourceSecurityGroup
+    *           group to associate with this group.
+    * 
+    * @see #createSecurityGroup
+    * @see #describeSecurityGroups
+    * @see #revokeSecurityGroupIngress
+    * @see #deleteSecurityGroup
+    * 
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-AuthorizeSecurityGroupIngress.html"
+    * 
+    */
+   @Named("AuthorizeSecurityGroupIngress")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "AuthorizeSecurityGroupIngress")
+   void authorizeSecurityGroupIngressInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+            @FormParam("GroupName") String groupName,
+            @BinderParam(BindUserIdGroupPairToSourceSecurityGroupFormParams.class) UserIdGroupPair sourceSecurityGroup);
+
+   /**
+    * 
+    * Adds permissions to a security group.
+    * <p/>
+    * Permissions are specified by the IP protocol (TCP, UDP or ICMP), the source of the request (by
+    * IP range or an Amazon EC2 user-group pair), the source and destination port ranges (for TCP
+    * and UDP), and the ICMP codes and types (for ICMP). When authorizing ICMP, -1 can be used as a
+    * wildcard in the type and code fields. Permission changes are propagated to instances within
+    * the security group as quickly as possible. However, depending on the number of instances, a
+    * small delay might occur.
+    * 
+    * @param region
+    *           Security groups are not copied across Regions. Instances within the Region cannot
+    *           communicate with instances outside the Region using group-based firewall rules.
+    *           Traffic from instances in another Region is seen as WAN bandwidth.
+    * @param groupName
+    *           Name of the group to modify. The name must be valid and belong to the identity
+    * @param ipProtocol
+    *           IP protocol.
+    * @param fromPort
+    *           Start of port range for the TCP and UDP protocols, or an ICMP type number. An ICMP
+    *           type number of -1 indicates a wildcard (i.e., any ICMP type number).
+    * @param toPort
+    *           End of port range for the TCP and UDP protocols, or an ICMP code. An ICMP code of -1
+    *           indicates a wildcard (i.e., any ICMP code).
+    * @param cidrIp
+    *           CIDR range.
+    * 
+    * @see #createSecurityGroup
+    * @see #describeSecurityGroups
+    * @see #revokeSecurityGroupIngress
+    * @see #deleteSecurityGroup
+    * 
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-AuthorizeSecurityGroupIngress.html"
+    * 
+    */
+   @Named("AuthorizeSecurityGroupIngress")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "AuthorizeSecurityGroupIngress")
+   void authorizeSecurityGroupIngressInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+            @FormParam("GroupName") String groupName, @FormParam("IpProtocol") IpProtocol ipProtocol,
+            @FormParam("FromPort") int fromPort, @FormParam("ToPort") int toPort, @FormParam("CidrIp") String cidrIp);
+
+   /**
+    * 
+    * Revokes permissions from a security group. The permissions used to revoke must be specified
+    * using the same values used to grant the permissions.
+    * 
+    * @param region
+    *           Security groups are not copied across Regions. Instances within the Region cannot
+    *           communicate with instances outside the Region using group-based firewall rules.
+    *           Traffic from instances in another Region is seen as WAN bandwidth.
+    * @param groupName
+    *           Name of the group to modify. The name must be valid and belong to the identity
+    * @param sourceSecurityGroup
+    *           group to associate with this group.
+    * 
+    * @see #createSecurityGroup
+    * @see #describeSecurityGroups
+    * @see #authorizeSecurityGroupIngress
+    * @see #deleteSecurityGroup
+    * 
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-RevokeSecurityGroupIngress.html"
+    * 
+    */
+   @Named("RevokeSecurityGroupIngress")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "RevokeSecurityGroupIngress")
+   void revokeSecurityGroupIngressInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+            @FormParam("GroupName") String groupName,
+            @BinderParam(BindUserIdGroupPairToSourceSecurityGroupFormParams.class) UserIdGroupPair sourceSecurityGroup);
+
+   /**
+    * 
+    * Revokes permissions from a security group. The permissions used to revoke must be specified
+    * using the same values used to grant the permissions.
+    * <p/>
+    * Permissions are specified by IP protocol (TCP, UDP, or ICMP), the source of the request (by IP
+    * range or an Amazon EC2 user-group pair), the source and destination port ranges (for TCP and
+    * UDP), and the ICMP codes and types (for ICMP).
+    * 
+    * Permission changes are quickly propagated to instances within the security group. However,
+    * depending on the number of instances in the group, a small delay is might occur.
+    * 
+    * @param region
+    *           Security groups are not copied across Regions. Instances within the Region cannot
+    *           communicate with instances outside the Region using group-based firewall rules.
+    *           Traffic from instances in another Region is seen as WAN bandwidth.
+    * @param groupName
+    *           Name of the group to modify. The name must be valid and belong to the identity
+    * @param ipProtocol
+    *           IP protocol.
+    * @param fromPort
+    *           Start of port range for the TCP and UDP protocols, or an ICMP type number. An ICMP
+    *           type number of -1 indicates a wildcard (i.e., any ICMP type number).
+    * @param toPort
+    *           End of port range for the TCP and UDP protocols, or an ICMP code. An ICMP code of -1
+    *           indicates a wildcard (i.e., any ICMP code).
+    * @param cidrIp
+    *           CIDR range.
+    * 
+    * @see #createSecurityGroup
+    * @see #describeSecurityGroups
+    * @see #authorizeSecurityGroupIngress
+    * @see #deleteSecurityGroup
+    * 
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-RevokeSecurityGroupIngress.html"
+    * 
+    */
+   @Named("RevokeSecurityGroupIngress")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "RevokeSecurityGroupIngress")
+   void revokeSecurityGroupIngressInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+            @FormParam("GroupName") String groupName, @FormParam("IpProtocol") IpProtocol ipProtocol,
+            @FormParam("FromPort") int fromPort, @FormParam("ToPort") int toPort, @FormParam("CidrIp") String cidrIp);
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/main/java/org/jclouds/ec2/features/SubnetApi.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/features/SubnetApi.java b/apis/ec2/src/main/java/org/jclouds/ec2/features/SubnetApi.java
index 1d3e338..c9aa1c4 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/features/SubnetApi.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/features/SubnetApi.java
@@ -16,25 +16,40 @@
  */
 package org.jclouds.ec2.features;
 
+import static org.jclouds.aws.reference.FormParameters.ACTION;
+
+import javax.inject.Named;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+
+import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
+import org.jclouds.aws.filters.FormSigner;
+import org.jclouds.ec2.binders.BindFiltersToIndexedFormParams;
 import org.jclouds.ec2.domain.Subnet;
-import org.jclouds.ec2.util.SubnetFilterBuilder;
+import org.jclouds.ec2.xml.DescribeSubnetsResponseHandler;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.FormParams;
+import org.jclouds.rest.annotations.RequestFilters;
 import org.jclouds.rest.annotations.SinceApiVersion;
+import org.jclouds.rest.annotations.VirtualHost;
+import org.jclouds.rest.annotations.XMLResponseParser;
 
 import com.google.common.collect.FluentIterable;
 import com.google.common.collect.Multimap;
-
 /**
- * To help you manage your Amazon EC2 instances, images, and other Amazon EC2 resources, you can assign your own
- * metadata to each resource in the form of tags.
+ * Provides access to Amazon EC2 via the Query API
+ * <p/>
  * 
- * @see <a href="http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Subnets.html" >doc</a>
- * @see SubnetAsyncApi
+ * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSubnets.html"
+ *      >doc</a>
  * @author Adrian Cole
  * @author Andrew Bayer
  */
 @SinceApiVersion("2011-01-01")
+@RequestFilters(FormSigner.class)
+@VirtualHost
 public interface SubnetApi {
-
    /**
     * Describes all of your subnets for your EC2 resources.
     * 
@@ -43,6 +58,12 @@ public interface SubnetApi {
     *      "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSubnets.html"
     *      >docs</href>
     */
+   @Named("DescribeSubnets")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DescribeSubnets")
+   @XMLResponseParser(DescribeSubnetsResponseHandler.class)
+   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
    FluentIterable<Subnet> list();
 
    /**
@@ -61,6 +82,13 @@ public interface SubnetApi {
     *      "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSubnets.html"
     *      >docs</href>
     */
-   FluentIterable<Subnet> filter(Multimap<String, String> filter);
+   @Named("DescribeSubnets")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DescribeSubnets")
+   @XMLResponseParser(DescribeSubnetsResponseHandler.class)
+   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
+   FluentIterable<Subnet> filter(
+         @BinderParam(BindFiltersToIndexedFormParams.class) Multimap<String, String> filter);
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/main/java/org/jclouds/ec2/features/SubnetAsyncApi.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/features/SubnetAsyncApi.java b/apis/ec2/src/main/java/org/jclouds/ec2/features/SubnetAsyncApi.java
deleted file mode 100644
index 25454a2..0000000
--- a/apis/ec2/src/main/java/org/jclouds/ec2/features/SubnetAsyncApi.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.ec2.features;
-
-import static org.jclouds.aws.reference.FormParameters.ACTION;
-
-import javax.inject.Named;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-
-import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
-import org.jclouds.aws.filters.FormSigner;
-import org.jclouds.ec2.binders.BindFiltersToIndexedFormParams;
-import org.jclouds.ec2.domain.Subnet;
-import org.jclouds.ec2.xml.DescribeSubnetsResponseHandler;
-import org.jclouds.rest.annotations.BinderParam;
-import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.annotations.FormParams;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.SinceApiVersion;
-import org.jclouds.rest.annotations.VirtualHost;
-import org.jclouds.rest.annotations.XMLResponseParser;
-
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.Multimap;
-import com.google.common.util.concurrent.ListenableFuture;
-
-/**
- * Provides access to Amazon EC2 via the Query API
- * <p/>
- * 
- * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSubnets.html"
- *      >doc</a>
- * @see SubnetApi
- * @author Adrian Cole
- * @author Andrew Bayer
- */
-@SinceApiVersion("2011-01-01")
-@RequestFilters(FormSigner.class)
-@VirtualHost
-public interface SubnetAsyncApi {
-   /**
-    * @see SubnetApi#list()
-    * @see <a
-    *      href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSubnets.html">docs</a>
-    */
-   @Named("DescribeSubnets")
-   @POST
-   @Path("/")
-   @FormParams(keys = ACTION, values = "DescribeSubnets")
-   @XMLResponseParser(DescribeSubnetsResponseHandler.class)
-   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
-   ListenableFuture<FluentIterable<Subnet>> list();
-
-   /**
-    * @see SubnetApi#filter
-    * @see <a
-    *      href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSubnets.html">docs</a>
-    */
-   @Named("DescribeSubnets")
-   @POST
-   @Path("/")
-   @FormParams(keys = ACTION, values = "DescribeSubnets")
-   @XMLResponseParser(DescribeSubnetsResponseHandler.class)
-   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
-   ListenableFuture<FluentIterable<Subnet>> filter(
-         @BinderParam(BindFiltersToIndexedFormParams.class) Multimap<String, String> filter);
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/main/java/org/jclouds/ec2/features/TagApi.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/features/TagApi.java b/apis/ec2/src/main/java/org/jclouds/ec2/features/TagApi.java
index 42ac632..cdc6623 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/features/TagApi.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/features/TagApi.java
@@ -16,28 +16,45 @@
  */
 package org.jclouds.ec2.features;
 
+import static org.jclouds.aws.reference.FormParameters.ACTION;
+
 import java.util.Map;
+
+import javax.inject.Named;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+
+import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
+import org.jclouds.aws.filters.FormSigner;
+import org.jclouds.ec2.binders.BindFiltersToIndexedFormParams;
+import org.jclouds.ec2.binders.BindResourceIdsToIndexedFormParams;
+import org.jclouds.ec2.binders.BindTagKeysToIndexedFormParams;
+import org.jclouds.ec2.binders.BindTagsToIndexedFormParams;
 import org.jclouds.ec2.domain.Tag;
-import org.jclouds.ec2.util.TagFilterBuilder;
+import org.jclouds.ec2.xml.DescribeTagsResponseHandler;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.FormParams;
+import org.jclouds.rest.annotations.RequestFilters;
 import org.jclouds.rest.annotations.SinceApiVersion;
+import org.jclouds.rest.annotations.VirtualHost;
+import org.jclouds.rest.annotations.XMLResponseParser;
 
 import com.google.common.collect.FluentIterable;
 import com.google.common.collect.Multimap;
-
 /**
- * To help you manage your Amazon EC2 instances, images, and other Amazon EC2
- * resources, you can assign your own metadata to each resource in the form of
- * tags.
+ * Provides access to Amazon EC2 via the Query API
+ * <p/>
  * 
  * @see <a
- *      href="http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/Using_Tags.html"
+ *      href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeTags.html"
  *      >doc</a>
- * @see TagAsyncApi
  * @author Adrian Cole
  */
 @SinceApiVersion("2010-08-31")
+@RequestFilters(FormSigner.class)
+@VirtualHost
 public interface TagApi {
-
    /**
     * Adds or overwrites one or more tags for the specified resource or
     * resources. Each resource can have a maximum of 10 tags. Each tag consists
@@ -58,7 +75,12 @@ public interface TagApi {
     *      "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateTags.html"
     *      >docs</href>
     */
-   void applyToResources(Map<String, String> tags, Iterable<String> resourceIds);
+   @Named("CreateTags")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "CreateTags")
+   void applyToResources(@BinderParam(BindTagsToIndexedFormParams.class) Iterable<String> tags,
+         @BinderParam(BindResourceIdsToIndexedFormParams.class) Iterable<String> resourceIds);
 
    /**
     * like {@link #applyToResources(Map, Iterable)} except that the tags have no
@@ -72,7 +94,12 @@ public interface TagApi {
     * 
     * @see #applyToResources(Map, Iterable)
     */
-   void applyToResources(Iterable<String> tags, Iterable<String> resourceIds);
+   @Named("CreateTags")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "CreateTags")
+   void applyToResources(@BinderParam(BindTagsToIndexedFormParams.class) Map<String, String> tags,
+         @BinderParam(BindResourceIdsToIndexedFormParams.class) Iterable<String> resourceIds);
 
    /**
     * Describes all of your tags for your EC2 resources.
@@ -82,6 +109,12 @@ public interface TagApi {
     *      "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeTags.html"
     *      >docs</href>
     */
+   @Named("DescribeTags")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DescribeTags")
+   @XMLResponseParser(DescribeTagsResponseHandler.class)
+   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
    FluentIterable<Tag> list();
 
    /**
@@ -100,7 +133,14 @@ public interface TagApi {
     *      "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeTags.html"
     *      >docs</href>
     */
-   FluentIterable<Tag> filter(Multimap<String, String> filter);
+   @Named("DescribeTags")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DescribeTags")
+   @XMLResponseParser(DescribeTagsResponseHandler.class)
+   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
+   FluentIterable<Tag> filter(
+         @BinderParam(BindFiltersToIndexedFormParams.class) Multimap<String, String> filter);
 
    /**
     * Deletes a specific set of tags from a specific set of resources. This call
@@ -124,7 +164,13 @@ public interface TagApi {
     *      "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteTags.html"
     *      >docs</href>
     */
-   void deleteFromResources(Iterable<String> tags, Iterable<String> resourceIds);
+   @Named("DeleteTags")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DeleteTags")
+   void deleteFromResources(
+         @BinderParam(BindTagKeysToIndexedFormParams.class) Iterable<String> tags,
+         @BinderParam(BindResourceIdsToIndexedFormParams.class) Iterable<String> resourceIds);
 
    /**
     * like {@link #deleteFromResources(Iterable, Iterable)}, except that the
@@ -144,6 +190,12 @@ public interface TagApi {
     *           {@code ami-1a2b3c4d}
     * @see #deleteFromResources(Iterable, Iterable)
     */
-   void conditionallyDeleteFromResources(Map<String, String> conditionalTagValues, Iterable<String> resourceIds);
+   @Named("DeleteTags")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DeleteTags")
+   void conditionallyDeleteFromResources(
+         @BinderParam(BindTagsToIndexedFormParams.class) Map<String, String> conditionalTagValues,
+         @BinderParam(BindResourceIdsToIndexedFormParams.class) Iterable<String> resourceIds);
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/main/java/org/jclouds/ec2/features/TagAsyncApi.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/features/TagAsyncApi.java b/apis/ec2/src/main/java/org/jclouds/ec2/features/TagAsyncApi.java
deleted file mode 100644
index 013df70..0000000
--- a/apis/ec2/src/main/java/org/jclouds/ec2/features/TagAsyncApi.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.ec2.features;
-
-import static org.jclouds.aws.reference.FormParameters.ACTION;
-
-import java.util.Map;
-
-import javax.inject.Named;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-
-import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
-import org.jclouds.aws.filters.FormSigner;
-import org.jclouds.ec2.binders.BindFiltersToIndexedFormParams;
-import org.jclouds.ec2.binders.BindResourceIdsToIndexedFormParams;
-import org.jclouds.ec2.binders.BindTagKeysToIndexedFormParams;
-import org.jclouds.ec2.binders.BindTagsToIndexedFormParams;
-import org.jclouds.ec2.domain.Tag;
-import org.jclouds.ec2.xml.DescribeTagsResponseHandler;
-import org.jclouds.rest.annotations.BinderParam;
-import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.annotations.FormParams;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.SinceApiVersion;
-import org.jclouds.rest.annotations.VirtualHost;
-import org.jclouds.rest.annotations.XMLResponseParser;
-
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.Multimap;
-import com.google.common.util.concurrent.ListenableFuture;
-
-/**
- * Provides access to Amazon EC2 via the Query API
- * <p/>
- * 
- * @see <a
- *      href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeTags.html"
- *      >doc</a>
- * @see TagApi
- * @author Adrian Cole
- */
-@SinceApiVersion("2010-08-31")
-@RequestFilters(FormSigner.class)
-@VirtualHost
-public interface TagAsyncApi {
-   /**
-    * @see TagApi#applyToResources(Iterable, Iterable)
-    * @see <a
-    *      href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateTags.html">docs</a>
-    */
-   @Named("CreateTags")
-   @POST
-   @Path("/")
-   @FormParams(keys = ACTION, values = "CreateTags")
-   ListenableFuture<Void> applyToResources(@BinderParam(BindTagsToIndexedFormParams.class) Iterable<String> tags,
-         @BinderParam(BindResourceIdsToIndexedFormParams.class) Iterable<String> resourceIds);
-
-   /**
-    * @see TagApi#applyToResources(Map, Iterable)
-    * @see <a
-    *      href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateTags.html">docs</a>
-    */
-   @Named("CreateTags")
-   @POST
-   @Path("/")
-   @FormParams(keys = ACTION, values = "CreateTags")
-   ListenableFuture<Void> applyToResources(@BinderParam(BindTagsToIndexedFormParams.class) Map<String, String> tags,
-         @BinderParam(BindResourceIdsToIndexedFormParams.class) Iterable<String> resourceIds);
-
-   /**
-    * @see TagApi#list()
-    * @see <a
-    *      href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeTags.html">docs</a>
-    */
-   @Named("DescribeTags")
-   @POST
-   @Path("/")
-   @FormParams(keys = ACTION, values = "DescribeTags")
-   @XMLResponseParser(DescribeTagsResponseHandler.class)
-   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
-   ListenableFuture<FluentIterable<Tag>> list();
-
-   /**
-    * @see TagApi#filter
-    * @see <a
-    *      href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeTags.html">docs</a>
-    */
-   @Named("DescribeTags")
-   @POST
-   @Path("/")
-   @FormParams(keys = ACTION, values = "DescribeTags")
-   @XMLResponseParser(DescribeTagsResponseHandler.class)
-   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
-   ListenableFuture<FluentIterable<Tag>> filter(
-         @BinderParam(BindFiltersToIndexedFormParams.class) Multimap<String, String> filter);
-
-   /**
-    * @see TagApi#deleteFromResources
-    * @see <a
-    *      href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteTags.html">docs</a>
-    */
-   @Named("DeleteTags")
-   @POST
-   @Path("/")
-   @FormParams(keys = ACTION, values = "DeleteTags")
-   ListenableFuture<Void> deleteFromResources(
-         @BinderParam(BindTagKeysToIndexedFormParams.class) Iterable<String> tags,
-         @BinderParam(BindResourceIdsToIndexedFormParams.class) Iterable<String> resourceIds);
-
-   /**
-    * @see TagApi#conditionallyDeleteFromResources
-    * @see <a
-    *      href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteTags.html">docs</a>
-    */
-   @Named("DeleteTags")
-   @POST
-   @Path("/")
-   @FormParams(keys = ACTION, values = "DeleteTags")
-   ListenableFuture<Void> conditionallyDeleteFromResources(
-         @BinderParam(BindTagsToIndexedFormParams.class) Map<String, String> conditionalTagValues,
-         @BinderParam(BindResourceIdsToIndexedFormParams.class) Iterable<String> resourceIds);
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/main/java/org/jclouds/ec2/features/WindowsApi.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/features/WindowsApi.java b/apis/ec2/src/main/java/org/jclouds/ec2/features/WindowsApi.java
index c74fc20..b895d0b 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/features/WindowsApi.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/features/WindowsApi.java
@@ -16,24 +16,166 @@
  */
 package org.jclouds.ec2.features;
 
+import static org.jclouds.aws.reference.FormParameters.ACTION;
+
+import java.util.Set;
+
+import javax.inject.Named;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+
+import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.aws.filters.FormSigner;
+import org.jclouds.ec2.binders.BindBundleIdsToIndexedFormParams;
+import org.jclouds.ec2.binders.BindS3UploadPolicyAndSignature;
+import org.jclouds.ec2.domain.BundleTask;
 import org.jclouds.ec2.domain.PasswordData;
+import org.jclouds.ec2.options.BundleInstanceS3StorageOptions;
+import org.jclouds.ec2.xml.BundleTaskHandler;
+import org.jclouds.ec2.xml.DescribeBundleTasksResponseHandler;
+import org.jclouds.ec2.xml.GetPasswordDataResponseHandler;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.EndpointParam;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.FormParams;
+import org.jclouds.rest.annotations.RequestFilters;
 import org.jclouds.rest.annotations.SinceApiVersion;
-
-import com.google.common.annotations.Beta;
+import org.jclouds.rest.annotations.VirtualHost;
+import org.jclouds.rest.annotations.XMLResponseParser;
 
 /**
  * Provides access to EC2 Windows Features via the Query API
  * <p/>
  * 
  * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference" >doc</a>
- * @see WindowsAsyncApi
  * @author Adrian Cole
  */
-@Beta
+@RequestFilters(FormSigner.class)
+@VirtualHost
 @SinceApiVersion("2008-08-08")
 public interface WindowsApi {
 
    /**
+    * Bundles the Windows instance. This procedure is not applicable for Linux
+    * and UNIX instances. For more information, go to the Amazon Elastic Compute
+    * Cloud Developer Guide or Amazon Elastic Compute Cloud Getting Started
+    * Guide.
+    * 
+    * @param region
+    *           Bundles are tied to the Region where its files are located
+    *           within Amazon S3.
+    * 
+    * @param instanceId
+    *           The ID of the instance to bundle.
+    * @param prefix
+    *           Specifies the beginning of the file name of the AMI.
+    * @param bucket
+    *           The bucket in which to store the AMI. You can specify a bucket
+    *           that you already own or a new bucket that Amazon EC2 creates on
+    *           your behalf. If you specify a bucket that belongs to someone
+    *           else, Amazon EC2 returns an error.
+    * @param uploadPolicy
+    *           An Amazon S3 upload policy that gives Amazon EC2 permission to
+    *           upload items into Amazon S3 on the user's behalf.
+    *           <p/>
+    *           ex.
+    * 
+    *           <pre>
+    * {"expiration": "2008-08-30T08:49:09Z","conditions": ["bucket": "my-bucket"},["starts-with", "$key", "my-new-image"]]}
+    * </pre>
+    * 
+    * @param options
+    *           if the bucket isn't owned by you, use this to set the bucket's
+    *           accesskeyid
+    * @return status of the work
+    * 
+    * @see #cancelBundleTaskInRegion
+    * @see #describeBundleTasksInRegion
+    * 
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-BundleInstance.html"
+    *      />
+    */
+   @Named("BundleInstance")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "BundleInstance")
+   @XMLResponseParser(BundleTaskHandler.class)
+   BundleTask bundleInstanceInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+            @FormParam("InstanceId") String instanceId, @FormParam("Storage.S3.Prefix") String prefix,
+            @FormParam("Storage.S3.Bucket") String bucket,
+            @BinderParam(BindS3UploadPolicyAndSignature.class) String uploadPolicy,
+            BundleInstanceS3StorageOptions... options);
+
+   /**
+    * Cancels an Amazon EC2 bundling operation.
+    * 
+    * @param region
+    *           The bundleTask ID is tied to the Region.
+    * @param bundleId
+    *           The ID of the bundle task to cancel.
+    * @return task for the cancel.
+    * 
+    * @see #bundleInstanceInRegion
+    * @see #describeBundleTasksInRegion
+    * 
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CancelBundleTask.html"
+    *      />
+    */
+   @Named("CancelBundleTask")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "CancelBundleTask")
+   @XMLResponseParser(BundleTaskHandler.class)
+   BundleTask cancelBundleTaskInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+            @FormParam("BundleId") String bundleId);
+
+   /**
+    * 
+    * Describes current bundling tasks.
+    * 
+    * @param region
+    *           The bundleTask ID is tied to the Region.
+    * 
+    * @see #cancelBundleTaskInRegion
+    * @see #bundleInstanceInRegion
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeBundleTasks.html"
+    *      />
+    */
+   @Named("DescribeBundleTasks")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DescribeBundleTasks")
+   @XMLResponseParser(DescribeBundleTasksResponseHandler.class)
+   @Fallback(EmptySetOnNotFoundOr404.class)
+   Set<BundleTask> describeBundleTasksInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+            @BinderParam(BindBundleIdsToIndexedFormParams.class) String... bundleTaskIds);
+
+   /**
+    *
+    * Retrieves the encrypted administrator password for the instances running Windows.
+    *
+    * @param region The region where the instance is based
+    * @param instanceId The ID of the instance to query
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-GetPasswordData.html" />
+    */
+   @Named("GetPasswordData")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "GetPasswordData")
+   @XMLResponseParser(GetPasswordDataResponseHandler.class)
+   PasswordData getPasswordDataInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("InstanceId") String instanceId);
+
+
+   /**
     * 
     * Retrieves the encrypted administrator password for the instances running Windows. <h4>Note</h4>
     * 
@@ -49,5 +191,12 @@ public interface WindowsApi {
     *      "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-GetPasswordData.html"
     *      />
     */
-   PasswordData getPasswordDataForInstance(String instanceId);
+   @Named("GetPasswordData")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "GetPasswordData")
+   @XMLResponseParser(GetPasswordDataResponseHandler.class)
+   @Fallback(NullOnNotFoundOr404.class)
+   PasswordData getPasswordDataForInstance(@FormParam("InstanceId") String instanceId);
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/main/java/org/jclouds/ec2/features/WindowsAsyncApi.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/features/WindowsAsyncApi.java b/apis/ec2/src/main/java/org/jclouds/ec2/features/WindowsAsyncApi.java
deleted file mode 100644
index 3f8f02d..0000000
--- a/apis/ec2/src/main/java/org/jclouds/ec2/features/WindowsAsyncApi.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR 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.ec2.features;
-
-import static org.jclouds.aws.reference.FormParameters.ACTION;
-
-import javax.inject.Named;
-import javax.ws.rs.FormParam;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-
-import org.jclouds.Fallbacks.NullOnNotFoundOr404;
-import org.jclouds.aws.filters.FormSigner;
-import org.jclouds.ec2.domain.PasswordData;
-import org.jclouds.ec2.xml.GetPasswordDataResponseHandler;
-import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.annotations.FormParams;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.SinceApiVersion;
-import org.jclouds.rest.annotations.VirtualHost;
-import org.jclouds.rest.annotations.XMLResponseParser;
-
-import com.google.common.annotations.Beta;
-import com.google.common.util.concurrent.ListenableFuture;
-
-/**
- * Provides access to EC2 Windows Features via the Query API
- * <p/>
- * 
- * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference" >doc</a>
- * @see WindowsAsyncApi
- * @author Adrian Cole
- */
-@RequestFilters(FormSigner.class)
-@VirtualHost
-@Beta
-@SinceApiVersion("2008-08-08")
-public interface WindowsAsyncApi {
-
-   /**
-    * @see WindowsApi#getPasswordDataForInstance
-    */
-   @Named("GetPasswordData")
-   @POST
-   @Path("/")
-   @FormParams(keys = ACTION, values = "GetPasswordData")
-   @XMLResponseParser(GetPasswordDataResponseHandler.class)
-   @Fallback(NullOnNotFoundOr404.class)
-   ListenableFuture<PasswordData> getPasswordDataForInstance(@FormParam("InstanceId") String instanceId);
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/main/java/org/jclouds/ec2/options/BundleInstanceS3StorageOptions.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/options/BundleInstanceS3StorageOptions.java b/apis/ec2/src/main/java/org/jclouds/ec2/options/BundleInstanceS3StorageOptions.java
index 91e6618..ec655ae 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/options/BundleInstanceS3StorageOptions.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/options/BundleInstanceS3StorageOptions.java
@@ -39,7 +39,7 @@ import com.google.inject.Inject;
  * <code>
  * import static org.jclouds.ec2.options.BundleInstanceS3StorageOptions.Builder.*
  * <p/>
- * EC2Client connection = // get connection
+ * EC2Api connection = // get connection
  * String imageId = connection.getWindowsServices().bundleInstanceInRegion(...bucketOwnedBy(anotherAccessKey));
  * <code>
  * 

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/main/java/org/jclouds/ec2/options/CreateImageOptions.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/options/CreateImageOptions.java b/apis/ec2/src/main/java/org/jclouds/ec2/options/CreateImageOptions.java
index e6665cc..8c604d5 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/options/CreateImageOptions.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/options/CreateImageOptions.java
@@ -29,8 +29,8 @@ import org.jclouds.ec2.options.internal.BaseEC2RequestOptions;
  * <code>
  * import static org.jclouds.ec2.options.CreateImageOptions.Builder.*
  * <p/>
- * EC2Client connection = // get connection
- * Future<Set<ImageMetadata>> images = connection.getAMIServices().createImage(withDescription("123125").noReboot());
+ * EC2Api connection = // get connection
+ * Future<Set<ImageMetadata>> images = connection.getAMIApi().get().createImage(withDescription("123125").noReboot());
  * <code>
  * 
  * @author Adrian Cole

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/main/java/org/jclouds/ec2/options/CreateSnapshotOptions.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/options/CreateSnapshotOptions.java b/apis/ec2/src/main/java/org/jclouds/ec2/options/CreateSnapshotOptions.java
index 83dcd19..2c05a27 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/options/CreateSnapshotOptions.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/options/CreateSnapshotOptions.java
@@ -29,8 +29,8 @@ import org.jclouds.ec2.options.internal.BaseEC2RequestOptions;
  * <code>
  * import static org.jclouds.ec2.options.CreateSnapshotOptions.Builder.*
  * <p/>
- * EC2Client connection = // get connection
- * Snapshot snapshot = connection.getElasticBlockStoreServices().createSnapshotInRegion(volumeId, withDescription("123125"));
+ * EC2Api connection = // get connection
+ * Snapshot snapshot = connection.getElasticBlockStoreApi().get().createSnapshotInRegion(volumeId, withDescription("123125"));
  * <code>
  * 
  * @author Adrian Cole