http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/domain/EC2HardwareBuilder.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/domain/EC2HardwareBuilder.java
 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/domain/EC2HardwareBuilder.java
new file mode 100644
index 0000000..38c48d1
--- /dev/null
+++ 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/domain/EC2HardwareBuilder.java
@@ -0,0 +1,608 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.compute.domain;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Predicates.not;
+import static org.jclouds.compute.domain.Volume.Type.LOCAL;
+import static org.jclouds.compute.predicates.ImagePredicates.any;
+import static org.jclouds.compute.predicates.ImagePredicates.idIn;
+
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.HardwareBuilder;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.compute.domain.Processor;
+import org.jclouds.compute.domain.Volume;
+import org.jclouds.compute.domain.VolumeBuilder;
+import org.jclouds.compute.predicates.ImagePredicates;
+import org.jclouds.domain.Location;
+import org.jclouds.ec2.domain.InstanceType;
+import org.jclouds.ec2.domain.RootDeviceType;
+import org.jclouds.ec2.domain.VirtualizationType;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * 
+ * @see <a href=
+ *      
"http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/index.html?instance-types.html";
+ *      />
+ */
+public class EC2HardwareBuilder extends HardwareBuilder {
+   private Predicate<Image> rootDeviceType = any();
+   private Predicate<Image> virtualizationType = Predicates.or(new 
IsWindows(), new RequiresVirtualizationType(
+         VirtualizationType.PARAVIRTUAL));
+   private Predicate<Image> imageIds = any();
+   private Predicate<Image> is64Bit = any();
+
+   public EC2HardwareBuilder() {
+      this.supportsImage = null;
+   }
+
+   /**
+    * evaluates true if the Image has the following rootDeviceType
+    * 
+    * @param type
+    *           rootDeviceType of the image
+    * @return predicate
+    */
+   public static class RequiresRootDeviceType implements Predicate<Image> {
+      final RootDeviceType type;
+
+      public RequiresRootDeviceType(final RootDeviceType type) {
+         this.type = checkNotNull(type, "type must be defined");
+      }
+
+      @Override
+      public boolean apply(Image image) {
+         return image.getUserMetadata().containsKey("rootDeviceType")
+               && type == 
RootDeviceType.fromValue(image.getUserMetadata().get("rootDeviceType"));
+      }
+
+      @Override
+      public String toString() {
+         return "requiresRootDeviceType(" + type + ")";
+      }
+
+   }
+
+   public static class IsWindows implements Predicate<Image> {
+
+      @Override
+      public boolean apply(Image image) {
+         return image.getOperatingSystem() != null && OsFamily.WINDOWS == 
image.getOperatingSystem().getFamily();
+      }
+
+      @Override
+      public String toString() {
+         return "isWindows()";
+      }
+
+   }
+
+   /**
+    * evaluates true if the Image requires the following virtualizationType
+    * 
+    * @param type
+    *           virtualizationType of the image
+    * @return predicate
+    */
+   public static class RequiresVirtualizationType implements Predicate<Image> {
+      final VirtualizationType type;
+
+      public RequiresVirtualizationType(final VirtualizationType type) {
+         this.type = checkNotNull(type, "type must be defined");
+      }
+
+      @Override
+      public boolean apply(Image image) {
+         return image.getOperatingSystem() != null && 
image.getOperatingSystem().getArch() != null
+               && type == 
VirtualizationType.fromValue(image.getOperatingSystem().getArch());
+      }
+
+      @Override
+      public String toString() {
+         return "requiresVirtualizationType(" + type + ")";
+      }
+
+   }
+
+   public EC2HardwareBuilder(String instanceType) {
+      ids(instanceType);
+   }
+
+   public EC2HardwareBuilder virtualizationType(VirtualizationType 
virtualizationType) {
+      this.virtualizationType = new 
RequiresVirtualizationType(virtualizationType);
+      return this;
+   }
+
+   public EC2HardwareBuilder rootDeviceType(RootDeviceType rootDeviceType) {
+      this.rootDeviceType = new RequiresRootDeviceType(rootDeviceType);
+      return this;
+   }
+
+   public EC2HardwareBuilder supportsImageIds(Iterable<String> ids) {
+      this.imageIds = idIn(ids);
+      return this;
+   }
+
+   public EC2HardwareBuilder ids(String id) {
+      return EC2HardwareBuilder.class.cast(super.ids(id));
+   }
+
+   public EC2HardwareBuilder ram(int ram) {
+      return EC2HardwareBuilder.class.cast(super.ram(ram));
+   }
+
+   public EC2HardwareBuilder processors(List<Processor> processors) {
+      return EC2HardwareBuilder.class.cast(super.processors(processors));
+   }
+
+   public EC2HardwareBuilder volumes(List<Volume> volumes) {
+      return EC2HardwareBuilder.class.cast(super.volumes(volumes));
+   }
+
+   public EC2HardwareBuilder supportsImage(Predicate<Image> supportsImage) {
+      return EC2HardwareBuilder.class.cast(super.supportsImage(supportsImage));
+   }
+
+   public EC2HardwareBuilder is64Bit(boolean is64Bit) {
+      this.is64Bit = is64Bit ? ImagePredicates.is64Bit() : 
not(ImagePredicates.is64Bit());
+      return this;
+   }
+
+   public EC2HardwareBuilder id(String id) {
+      return EC2HardwareBuilder.class.cast(super.id(id));
+   }
+
+   @Override
+   public EC2HardwareBuilder providerId(String providerId) {
+      return EC2HardwareBuilder.class.cast(super.providerId(providerId));
+   }
+
+   @Override
+   public EC2HardwareBuilder name(String name) {
+      return EC2HardwareBuilder.class.cast(super.name(name));
+   }
+
+   @Override
+   public EC2HardwareBuilder location(Location location) {
+      return EC2HardwareBuilder.class.cast(super.location(location));
+   }
+
+   @Override
+   public EC2HardwareBuilder uri(URI uri) {
+      return EC2HardwareBuilder.class.cast(super.uri(uri));
+   }
+
+   @Override
+   public EC2HardwareBuilder userMetadata(Map<String, String> userMetadata) {
+      return EC2HardwareBuilder.class.cast(super.userMetadata(userMetadata));
+   }
+
+   /**
+    * @see InstanceType#M1_SMALL
+    */
+   public static EC2HardwareBuilder m1_small() {
+      return new EC2HardwareBuilder(InstanceType.M1_SMALL)
+            .ram(1740)
+            .processors(ImmutableList.of(new Processor(1.0, 1.0)))
+            .volumes(ImmutableList.<Volume> of(
+                  new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(150.0f).device("/dev/sda2").bootDevice(false).durable(false).build()));
+   }
+
+   /**
+    * @see InstanceType#M1_MEDIUM
+    */
+   public static EC2HardwareBuilder m1_medium() {
+      return new EC2HardwareBuilder(InstanceType.M1_MEDIUM)
+            .ram(3750)
+            .processors(ImmutableList.of(new Processor(1.0, 2.0)))
+            .volumes(ImmutableList.<Volume> of(
+                  new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(420.0f).device("/dev/sdb").bootDevice(false).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(420.0f).device("/dev/sdc").bootDevice(false).durable(false).build()));
+   }
+
+
+   /**
+    * @see InstanceType#T1_MICRO
+    */
+   public static EC2HardwareBuilder t1_micro() {
+      return new EC2HardwareBuilder(InstanceType.T1_MICRO).ram(630)
+            .processors(ImmutableList.of(new Processor(1.0, 
1.0))).rootDeviceType(RootDeviceType.EBS);
+   }
+
+   /**
+    * @see InstanceType#M1_LARGE
+    */
+   public static EC2HardwareBuilder m1_large() {
+      return new EC2HardwareBuilder(InstanceType.M1_LARGE)
+            .ram(7680)
+            .processors(ImmutableList.of(new Processor(2.0, 2.0)))
+            .volumes(ImmutableList.<Volume> of(
+                  new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(420.0f).device("/dev/sdb").bootDevice(false).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(420.0f).device("/dev/sdc").bootDevice(false).durable(false).build()))
+            .is64Bit(true);
+   }
+
+   /**
+    * @see InstanceType#M1_XLARGE
+    */
+   public static EC2HardwareBuilder m1_xlarge() {
+      return new EC2HardwareBuilder(InstanceType.M1_XLARGE)
+            .ram(15360)
+            .processors(ImmutableList.of(new Processor(4.0, 2.0)))
+            .volumes(ImmutableList.<Volume> of(
+                  new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(420.0f).device("/dev/sdb").bootDevice(false).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(420.0f).device("/dev/sdc").bootDevice(false).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(420.0f).device("/dev/sdd").bootDevice(false).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(420.0f).device("/dev/sde").bootDevice(false).durable(false).build()))
+            .is64Bit(true);
+   }
+
+   /**
+    * @see InstanceType#M2_XLARGE
+    */
+   public static EC2HardwareBuilder m2_xlarge() {
+      return new EC2HardwareBuilder(InstanceType.M2_XLARGE).ram(17510)
+            .processors(ImmutableList.of(new Processor(2.0, 3.25)))
+            .volumes(ImmutableList.<Volume> of(
+                  new 
VolumeBuilder().type(LOCAL).size(420.0f).device("/dev/sda1").bootDevice(true).durable(false).build()))
+            .is64Bit(true);
+   }
+
+   /**
+    * @see InstanceType#M2_2XLARGE
+    */
+   public static EC2HardwareBuilder m2_2xlarge() {
+      return new EC2HardwareBuilder(InstanceType.M2_2XLARGE)
+            .ram(35020)
+            .processors(ImmutableList.of(new Processor(4.0, 3.25)))
+            .volumes(ImmutableList.<Volume> of(
+                  new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(840.0f).device("/dev/sdb").bootDevice(false).durable(false).build()))
+            .is64Bit(true);
+   }
+
+   /**
+    * @see InstanceType#M2_4XLARGE
+    */
+   public static EC2HardwareBuilder m2_4xlarge() {
+      return new EC2HardwareBuilder(InstanceType.M2_4XLARGE)
+            .ram(70041)
+            .processors(ImmutableList.of(new Processor(8.0, 3.25)))
+            .volumes(ImmutableList.<Volume> of(
+                  new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(840.0f).device("/dev/sdb").bootDevice(false).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(840.0f).device("/dev/sdc").bootDevice(false).durable(false).build()))
+            .is64Bit(true);
+   }
+   
+   /**
+    * @see InstanceType#M3_MEDIUM
+    */
+   public static EC2HardwareBuilder m3_medium() {
+      return new EC2HardwareBuilder(InstanceType.M3_MEDIUM)
+            .ram(3840)
+            .processors(ImmutableList.of(new Processor(1.0, 3.0)))
+            .volumes(ImmutableList.<Volume> of(
+                  new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(4.0f).device("/dev/sdb").bootDevice(false).durable(false).build()));
+   }
+
+   /**
+    * @see InstanceType#M3_LARGE
+    */
+   public static EC2HardwareBuilder m3_large() {
+      return new EC2HardwareBuilder(InstanceType.M3_LARGE)
+            .ram(7680)
+            .processors(ImmutableList.of(new Processor(2.0, 3.25)))
+            .volumes(ImmutableList.<Volume> of(
+                  new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(32.0f).device("/dev/sdb").bootDevice(false).durable(false).build()));
+   }
+
+   /**
+    * @see InstanceType#M3_XLARGE
+    */
+   public static EC2HardwareBuilder m3_xlarge() {
+      return new EC2HardwareBuilder(InstanceType.M3_XLARGE).ram(15360)
+              .processors(ImmutableList.of(new Processor(4.0, 3.25)))
+              .is64Bit(true)
+              .volumes(ImmutableList.<Volume> of(
+                      new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                      new 
VolumeBuilder().type(LOCAL).size(40.0f).device("/dev/sdb").bootDevice(false).durable(false).build(),
+                      new 
VolumeBuilder().type(LOCAL).size(40.0f).device("/dev/sdc").bootDevice(false).durable(false).build()));
+   }
+
+   /**
+    * @see InstanceType#M3_2XLARGE
+    */
+   public static EC2HardwareBuilder m3_2xlarge() {
+      return new EC2HardwareBuilder(InstanceType.M3_2XLARGE).ram(30720)
+              .processors(ImmutableList.of(new Processor(8.0, 3.25)))
+              .is64Bit(true)
+              .volumes(ImmutableList.<Volume> of(
+                      new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                      new 
VolumeBuilder().type(LOCAL).size(80.0f).device("/dev/sdb").bootDevice(false).durable(false).build(),
+                      new 
VolumeBuilder().type(LOCAL).size(80.0f).device("/dev/sdc").bootDevice(false).durable(false).build()));
+   }
+   
+   /**
+    * @see InstanceType#C1_MEDIUM
+    */
+   public static EC2HardwareBuilder c1_medium() {
+      return new EC2HardwareBuilder(InstanceType.C1_MEDIUM)
+            .ram(1740)
+            .processors(ImmutableList.of(new Processor(2.0, 2.5)))
+            .volumes(ImmutableList.<Volume> of(
+                  new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(340.0f).device("/dev/sda2").bootDevice(false).durable(false).build()));
+   }
+
+   /**
+    * @see InstanceType#C1_XLARGE
+    */
+   public static EC2HardwareBuilder c1_xlarge() {
+      return new EC2HardwareBuilder(InstanceType.C1_XLARGE)
+            .ram(7168)
+            .processors(ImmutableList.of(new Processor(8.0, 2.5)))
+            .volumes(ImmutableList.<Volume> of(
+                  new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(420.0f).device("/dev/sdb").bootDevice(false).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(420.0f).device("/dev/sdc").bootDevice(false).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(420.0f).device("/dev/sdd").bootDevice(false).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(420.0f).device("/dev/sde").bootDevice(false).durable(false).build()))
+            .is64Bit(true);
+   }
+
+   /**
+    * @see InstanceType#C3_LARGE
+    */
+   public static EC2HardwareBuilder c3_large() {
+      return new EC2HardwareBuilder(InstanceType.C3_LARGE)
+              .ram(3750)
+              .processors(ImmutableList.of(new Processor(2.0, 3.5)))
+              .volumes(ImmutableList.<Volume> of(
+                    new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(16.0f).device("/dev/sdb").bootDevice(false).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(16.0f).device("/dev/sdc").bootDevice(false).durable(false).build()))
+              .is64Bit(true);
+   }
+
+   /**
+    * @see InstanceType#C3_XLARGE
+    */
+   public static EC2HardwareBuilder c3_xlarge() {
+      return new EC2HardwareBuilder(InstanceType.C3_XLARGE)
+              .ram(7168)
+              .processors(ImmutableList.of(new Processor(4.0, 3.5)))
+              .volumes(ImmutableList.<Volume> of(
+                    new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(40.0f).device("/dev/sdb").bootDevice(false).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(40.0f).device("/dev/sdc").bootDevice(false).durable(false).build()))
+              .is64Bit(true);
+   }
+
+   /**
+    * @see InstanceType#C3_2XLARGE
+    */
+   public static EC2HardwareBuilder c3_2xlarge() {
+      return new EC2HardwareBuilder(InstanceType.C3_2XLARGE)
+              .ram(15360)
+              .processors(ImmutableList.of(new Processor(8.0, 3.5)))
+              .volumes(ImmutableList.<Volume> of(
+                    new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(80.0f).device("/dev/sdb").bootDevice(false).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(80.0f).device("/dev/sdc").bootDevice(false).durable(false).build()))
+              .is64Bit(true);
+   }
+
+   /**
+    * @see InstanceType#C3_4XLARGE
+    */
+   public static EC2HardwareBuilder c3_4xlarge() {
+      return new EC2HardwareBuilder(InstanceType.C3_4XLARGE)
+              .ram(30720)
+              .processors(ImmutableList.of(new Processor(16.0, 3.4375)))
+              .volumes(ImmutableList.<Volume> of(
+                    new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(160.0f).device("/dev/sdb").bootDevice(false).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(160.0f).device("/dev/sdc").bootDevice(false).durable(false).build()))
+              .is64Bit(true);
+   }
+
+   /**
+    * @see InstanceType#C3_8XLARGE
+    */
+   public static EC2HardwareBuilder c3_8xlarge() {
+      return new EC2HardwareBuilder(InstanceType.C3_8XLARGE)
+              .ram(61440)
+              .processors(ImmutableList.of(new Processor(32.0, 3.375)))
+              .volumes(ImmutableList.<Volume> of(
+                    new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(320.0f).device("/dev/sdb").bootDevice(false).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(320.0f).device("/dev/sdc").bootDevice(false).durable(false).build()))
+              .is64Bit(true);
+   }
+
+   public static EC2HardwareBuilder cg1_4xlarge() {
+      return new EC2HardwareBuilder(InstanceType.CG1_4XLARGE)
+            .ram(22 * 1024)
+            .processors(ImmutableList.of(new Processor(4.0, 4.0), new 
Processor(4.0, 4.0)))
+            .volumes(ImmutableList.<Volume> of(
+                  new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(840.0f).device("/dev/sdb").bootDevice(false).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(840.0f).device("/dev/sdc").bootDevice(false).durable(false).build()))
+            .virtualizationType(VirtualizationType.HVM);
+   }
+
+   public static EC2HardwareBuilder cc1_4xlarge() {
+      return new EC2HardwareBuilder(InstanceType.CC1_4XLARGE)
+            .ram(23 * 1024)
+            .processors(ImmutableList.of(new Processor(4.0, 4.0), new 
Processor(4.0, 4.0)))
+            .volumes(ImmutableList.<Volume> of(
+                  new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(840.0f).device("/dev/sdb").bootDevice(false).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(840.0f).device("/dev/sdc").bootDevice(false).durable(false).build()))
+            .virtualizationType(VirtualizationType.HVM);
+   }
+
+   public static EC2HardwareBuilder cc2_8xlarge() {
+      return new EC2HardwareBuilder(InstanceType.CC2_8XLARGE)
+            .ram(60 * 1024 + 512)
+            .processors(ImmutableList.of(new Processor(8.0, 5.5), new 
Processor(8.0, 5.5)))
+            .volumes(ImmutableList.<Volume> of(
+                  new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(840.0f).device("/dev/sdb").bootDevice(false).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(840.0f).device("/dev/sdc").bootDevice(false).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(840.0f).device("/dev/sdd").bootDevice(false).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(840.0f).device("/dev/sde").bootDevice(false).durable(false).build()))
+            .virtualizationType(VirtualizationType.HVM);
+   }
+
+   /**
+    * @see InstanceType#G2_2XLARGE
+    */
+   public static EC2HardwareBuilder g2_2xlarge() {
+      return new EC2HardwareBuilder(InstanceType.G2_2XLARGE)
+           .ram(15 * 1024)
+            .processors(ImmutableList.of(new Processor(8.0, 3.25)))
+            .volumes(ImmutableList.<Volume> of(
+                  new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(60.0f).device("/dev/sdb").bootDevice(false).durable(false).build()))
+            .virtualizationType(VirtualizationType.HVM);
+   }
+
+   /**
+    * @see InstanceType#I2_XLARGE
+    */
+   public static EC2HardwareBuilder i2_xlarge() {
+      return new EC2HardwareBuilder(InstanceType.I2_XLARGE)
+              .ram(30 * 1024 + 512)
+              .processors(ImmutableList.of(new Processor(4.0, 3.5)))
+              .volumes(ImmutableList.<Volume> of(
+                    new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(800.0f).device("/dev/sdb").bootDevice(false).durable(false).build()))
+              .virtualizationType(VirtualizationType.HVM);
+   }
+
+   /**
+    * @see InstanceType#I2_2XLARGE
+    */
+   public static EC2HardwareBuilder i2_2xlarge() {
+      return new EC2HardwareBuilder(InstanceType.I2_2XLARGE)
+              .ram(61 * 1024)
+              .processors(ImmutableList.of(new Processor(8.0, 3.375)))
+              .volumes(ImmutableList.<Volume> of(
+                    new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(800.0f).device("/dev/sdb").bootDevice(false).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(800.0f).device("/dev/sdc").bootDevice(false).durable(false).build()))
+              .virtualizationType(VirtualizationType.HVM);
+   }
+
+   /**
+    * @see InstanceType#I2_4XLARGE
+    */
+   public static EC2HardwareBuilder i2_4xlarge() {
+      return new EC2HardwareBuilder(InstanceType.I2_4XLARGE)
+              .ram(122 * 1024)
+              .processors(ImmutableList.of(new Processor(16.0, 3.3125)))
+              .volumes(ImmutableList.<Volume> of(
+                    new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(800.0f).device("/dev/sdb").bootDevice(false).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(800.0f).device("/dev/sdc").bootDevice(false).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(800.0f).device("/dev/sdd").bootDevice(false).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(800.0f).device("/dev/sde").bootDevice(false).durable(false).build()))
+              .virtualizationType(VirtualizationType.HVM);
+   }
+
+   /**
+    * @see InstanceType#I2_8XLARGE
+    */
+   public static EC2HardwareBuilder i2_8xlarge() {
+      return new EC2HardwareBuilder(InstanceType.I2_8XLARGE)
+              .ram(244 * 1024)
+              .processors(ImmutableList.of(new Processor(32.0, 3.25)))
+              .volumes(ImmutableList.<Volume> of(
+                    new 
VolumeBuilder().type(LOCAL).size(10.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(800.0f).device("/dev/sdb").bootDevice(false).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(800.0f).device("/dev/sdc").bootDevice(false).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(800.0f).device("/dev/sdd").bootDevice(false).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(800.0f).device("/dev/sde").bootDevice(false).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(800.0f).device("/dev/sdf").bootDevice(false).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(800.0f).device("/dev/sdg").bootDevice(false).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(800.0f).device("/dev/sdh").bootDevice(false).durable(false).build(),
+                    new 
VolumeBuilder().type(LOCAL).size(800.0f).device("/dev/sdi").bootDevice(false).durable(false).build()))
+              .virtualizationType(VirtualizationType.HVM);
+   }
+
+   public static EC2HardwareBuilder hi1_4xlarge() {
+      return new EC2HardwareBuilder(InstanceType.HI1_4XLARGE)
+            .ram(60 * 1024 + 512)
+            .processors(ImmutableList.of(new Processor(16.0, 2.1875)))
+            .volumes(ImmutableList.<Volume> of(
+                  new 
VolumeBuilder().type(LOCAL).size(1024.0f).device("/dev/sda1").bootDevice(true).durable(false).build(),
+                  new 
VolumeBuilder().type(LOCAL).size(1024.0f).device("/dev/sdb").bootDevice(false).durable(false).build()))
+            .virtualizationType(VirtualizationType.HVM);
+   }
+   
+   public static EC2HardwareBuilder hs1_8xlarge() {
+      float twoTB = 2048.0f * 1024.0f;
+      Builder<Volume> all24Volumes = ImmutableList.<Volume>builder();
+      all24Volumes.add(new 
VolumeBuilder().type(LOCAL).size(twoTB).device("/dev/sda1").bootDevice(true).durable(false).build());
+      for (char letter : ImmutableSet.of('b', 'c', 'd', 'e', 'f', 'g', 'h', 
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
+            'q', 'r', 's', 't', 'u', 'v', 'w', 'x')) {
+         all24Volumes.add(new 
VolumeBuilder().type(LOCAL).size(twoTB).device("/dev/sd" + 
letter).bootDevice(false).durable(false).build());
+      }
+      return new EC2HardwareBuilder(InstanceType.HS1_8XLARGE)
+            .ram(117 * 1024)
+            .processors(ImmutableList.of(new Processor(16.0, 2.1875)))
+            .volumes(all24Volumes.build())
+            .virtualizationType(VirtualizationType.HVM);
+   }
+   
+   @SuppressWarnings("unchecked")
+   @Override
+   public Hardware build() {
+      boolean reset = false;
+      if (this.supportsImage == null)
+         reset = true;
+      try {
+         supportsImage = Predicates.<Image> and(rootDeviceType, 
virtualizationType, imageIds, is64Bit);
+         return super.build();
+      } finally {
+         if (reset)
+            this.supportsImage = null;
+      }
+
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/domain/PasswordDataAndPrivateKey.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/domain/PasswordDataAndPrivateKey.java
 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/domain/PasswordDataAndPrivateKey.java
new file mode 100644
index 0000000..b3d9100
--- /dev/null
+++ 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/domain/PasswordDataAndPrivateKey.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.ec2.compute.domain;
+
+import org.jclouds.ec2.domain.PasswordData;
+
+import com.google.common.base.Objects;
+
+/**
+ * An encrypted Windows Administrator password, and the private key that can 
decrypt it.
+ */
+public class PasswordDataAndPrivateKey {
+
+   private final PasswordData passwordData;
+   private final String privateKey;
+
+   public PasswordDataAndPrivateKey(PasswordData passwordData, String 
privateKey) {
+      this.passwordData = passwordData;
+      this.privateKey = privateKey;
+   }
+
+   public PasswordData getPasswordData() {
+      return passwordData;
+   }
+
+   public String getPrivateKey() {
+      return privateKey;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(passwordData, privateKey);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj)
+         return true;
+      if (obj == null)
+         return false;
+      if (getClass() != obj.getClass())
+         return false;
+      PasswordDataAndPrivateKey other = 
PasswordDataAndPrivateKey.class.cast(obj);
+      return Objects.equal(this.passwordData, other.passwordData) && 
Objects.equal(this.privateKey, other.privateKey);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String toString() {
+      return Objects.toStringHelper(this).omitNullValues().add("passwordData", 
passwordData).toString();
+   }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/domain/RegionAndName.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/domain/RegionAndName.java
 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/domain/RegionAndName.java
new file mode 100644
index 0000000..cf38056
--- /dev/null
+++ 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/domain/RegionAndName.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.ec2.compute.domain;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.base.Objects.ToStringHelper;
+
+public class RegionAndName {
+
+   protected final String region;
+   protected final String name;
+
+   public String slashEncode() {
+      return new StringBuilder(region).append('/').append(name).toString();
+   }
+
+   public RegionAndName(String region, String name) {
+      this.region = checkNotNull(region, "region");
+      this.name = checkNotNull(name, "name");
+   }
+   
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(region, name);
+   }
+
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj)
+         return true;
+      if (obj == null)
+         return false;
+      if (!(obj instanceof RegionAndName))
+         return false;
+      RegionAndName other = RegionAndName.class.cast(obj);
+      return Objects.equal(region, other.region) && Objects.equal(name, 
other.name);
+   }
+
+   public String getRegion() {
+      return region;
+   }
+
+   public String getName() {
+      return name;
+   }
+
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+
+   protected ToStringHelper string() {
+      return Objects.toStringHelper("").add("region", region).add("name", 
name);
+   }
+
+   private static enum RegionFunction implements Function<RegionAndName, 
String> {
+      INSTANCE;
+      @Override
+      public String apply(RegionAndName input) {
+         return input.getRegion();
+      }
+
+      @Override
+      public String toString() {
+         return "getRegion()";
+      }
+   };
+
+   public static Function<RegionAndName, String> regionFunction() {
+      return RegionFunction.INSTANCE;
+   }
+
+   private static enum NameFunction implements Function<RegionAndName, String> 
{
+      INSTANCE;
+      @Override
+      public String apply(RegionAndName input) {
+         return input.getName();
+      }
+
+      @Override
+      public String toString() {
+         return "getName()";
+      }
+   };
+
+   public static Function<RegionAndName, String> nameFunction() {
+      return NameFunction.INSTANCE;
+   }
+   
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/domain/RegionNameAndIngressRules.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/domain/RegionNameAndIngressRules.java
 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/domain/RegionNameAndIngressRules.java
new file mode 100644
index 0000000..081d075
--- /dev/null
+++ 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/domain/RegionNameAndIngressRules.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.ec2.compute.domain;
+
+public class RegionNameAndIngressRules extends RegionAndName {
+   private final int[] ports;
+   private final boolean authorizeSelf;
+
+   public RegionNameAndIngressRules(String region, String tag, int[] ports, 
boolean authorizeSelf) {
+      super(region, tag);
+      this.ports = ports;
+      this.authorizeSelf = authorizeSelf;
+   }
+
+   // intentionally not overriding equals or hash-code so that we can search 
only by region/tag in a
+   // map
+
+   public int[] getPorts() {
+      return ports;
+   }
+
+   public boolean shouldAuthorizeSelf() {
+      return authorizeSelf;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/extensions/EC2ImageExtension.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/extensions/EC2ImageExtension.java
 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/extensions/EC2ImageExtension.java
new file mode 100644
index 0000000..03c18d7
--- /dev/null
+++ 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/extensions/EC2ImageExtension.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.compute.extensions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.collect.Iterables.find;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static 
org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_AVAILABLE;
+import static org.jclouds.location.predicates.LocationPredicates.idEquals;
+
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jclouds.Constants;
+import org.jclouds.aws.util.AWSUtils;
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.domain.CloneImageTemplate;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.ImageBuilder;
+import org.jclouds.compute.domain.ImageTemplate;
+import org.jclouds.compute.domain.ImageTemplateBuilder;
+import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.domain.Location;
+import org.jclouds.ec2.EC2Api;
+import org.jclouds.ec2.domain.Reservation;
+import org.jclouds.ec2.domain.RunningInstance;
+import org.jclouds.ec2.options.CreateImageOptions;
+import org.jclouds.logging.Logger;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.util.concurrent.Atomics;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.UncheckedTimeoutException;
+
+/**
+ * EC2 implementation of {@link ImageExtension} please note that {@link 
#createImage(ImageTemplate)}
+ * only works by cloning EBS backed instances for the moment.
+ */
+public class EC2ImageExtension implements ImageExtension {
+
+   @Resource
+   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+   protected Logger logger = Logger.NULL;
+   private final EC2Api ec2Api;
+   private final ListeningExecutorService userExecutor;
+   private final Supplier<Set<? extends Location>> locations;
+   private final Predicate<AtomicReference<Image>> imageAvailablePredicate;
+   
+   @Inject
+   public EC2ImageExtension(EC2Api ec2Api, 
@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
+         @Memoized Supplier<Set<? extends Location>> locations,
+         @Named(TIMEOUT_IMAGE_AVAILABLE) Predicate<AtomicReference<Image>> 
imageAvailablePredicate) {
+      this.ec2Api = checkNotNull(ec2Api, "ec2Api");
+      this.userExecutor = checkNotNull(userExecutor, "userExecutor");
+      this.locations = checkNotNull(locations, "locations");
+      this.imageAvailablePredicate = checkNotNull(imageAvailablePredicate, 
"imageAvailablePredicate");
+   }
+
+   @Override
+   public ImageTemplate buildImageTemplateFromNode(String name, String id) {
+      String[] parts = AWSUtils.parseHandle(id);
+      String region = parts[0];
+      String instanceId = parts[1];
+      Reservation<? extends RunningInstance> instance = 
getOnlyElement(ec2Api.getInstanceApi().get()
+            .describeInstancesInRegion(region, instanceId));
+      if (instance == null)
+         throw new NoSuchElementException("Cannot find server with id: " + id);
+      CloneImageTemplate template = new 
ImageTemplateBuilder.CloneImageTemplateBuilder().nodeId(id).name(name).build();
+      return template;
+   }
+
+   @Override
+   public ListenableFuture<Image> createImage(ImageTemplate template) {
+      checkState(template instanceof CloneImageTemplate, " ec2 only supports 
creating images through cloning.");
+      CloneImageTemplate cloneTemplate = (CloneImageTemplate) template;
+      String[] parts = AWSUtils.parseHandle(cloneTemplate.getSourceNodeId());
+      String region = parts[0];
+      String instanceId = parts[1];
+
+      String imageId = ec2Api.getAMIApi().get().createImageInRegion(region, 
cloneTemplate.getName(), instanceId,
+            CreateImageOptions.NONE);
+
+      final AtomicReference<Image> image = Atomics.newReference(new 
ImageBuilder()
+            .location(find(locations.get(), idEquals(region)))
+            .id(region + "/" + imageId)
+            .providerId(imageId)
+            .description(cloneTemplate.getName())
+            
.operatingSystem(OperatingSystem.builder().description(cloneTemplate.getName()).build())
+            .status(Image.Status.PENDING).build());
+      
+      return userExecutor.submit(new Callable<Image>() {
+         @Override
+         public Image call() throws Exception {
+            if (imageAvailablePredicate.apply(image))
+               return image.get();
+            // TODO: get rid of the expectation that the image will be 
available, as it is very brittle
+            throw new UncheckedTimeoutException("Image was not created within 
the time limit: " + image.get());
+         }
+      });
+   }
+
+   @Override
+   public boolean deleteImage(String id) {
+      String[] parts = AWSUtils.parseHandle(id);
+      String region = parts[0];
+      String instanceId = parts[1];
+      try {
+         ec2Api.getAMIApi().get().deregisterImageInRegion(region, instanceId);
+         return true;
+      } catch (Exception e) {
+         return false;
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/extensions/EC2SecurityGroupExtension.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/extensions/EC2SecurityGroupExtension.java
 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/extensions/EC2SecurityGroupExtension.java
new file mode 100644
index 0000000..789a7b6
--- /dev/null
+++ 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/extensions/EC2SecurityGroupExtension.java
@@ -0,0 +1,378 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.compute.extensions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Predicates.notNull;
+import static com.google.common.collect.Iterables.concat;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.collect.Iterables.transform;
+
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jclouds.Constants;
+import org.jclouds.aws.util.AWSUtils;
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
+import org.jclouds.compute.functions.GroupNamingConvention;
+import org.jclouds.compute.functions.GroupNamingConvention.Factory;
+import org.jclouds.domain.Location;
+import org.jclouds.ec2.EC2Api;
+import org.jclouds.ec2.compute.domain.RegionAndName;
+import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
+import org.jclouds.ec2.domain.RunningInstance;
+import org.jclouds.ec2.domain.UserIdGroupPair;
+import org.jclouds.location.Region;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Multimap;
+import com.google.common.util.concurrent.ListeningExecutorService;
+
+/**
+ * An extension to compute service to allow for the manipulation of {@link 
SecurityGroup}s. Implementation
+ * is optional by providers.
+ */
+public class EC2SecurityGroupExtension implements SecurityGroupExtension {
+
+   protected final EC2Api client;
+   protected final ListeningExecutorService userExecutor;
+   protected final Supplier<Set<String>> regions;
+   protected final Function<org.jclouds.ec2.domain.SecurityGroup, 
SecurityGroup> groupConverter;
+   protected final Supplier<Set<? extends Location>> locations;
+   protected final LoadingCache<RegionAndName, String> groupCreator;
+   protected final Factory namingConvention;
+
+   @Inject
+   public EC2SecurityGroupExtension(EC2Api client,
+                                    @Named(Constants.PROPERTY_USER_THREADS) 
ListeningExecutorService userExecutor,
+                                    @Region Supplier<Set<String>> regions,
+                                    
Function<org.jclouds.ec2.domain.SecurityGroup, SecurityGroup> groupConverter,
+                                    @Memoized Supplier<Set<? extends 
Location>> locations,
+                                    @Named("SECURITY") 
LoadingCache<RegionAndName, String> groupCreator,
+                                    GroupNamingConvention.Factory 
namingConvention) {
+                                    
+      this.client = checkNotNull(client, "client");
+      this.userExecutor = checkNotNull(userExecutor, "userExecutor");
+      this.regions = checkNotNull(regions, "regions");
+      this.groupConverter = checkNotNull(groupConverter, "groupConverter");
+      this.locations = checkNotNull(locations, "locations");
+      this.groupCreator = checkNotNull(groupCreator, "groupCreator");
+      this.namingConvention = checkNotNull(namingConvention, 
"namingConvention");
+   }
+
+   @Override
+   public Set<SecurityGroup> listSecurityGroups() {
+      Iterable<? extends org.jclouds.ec2.domain.SecurityGroup> rawGroups = 
pollSecurityGroups();
+      Iterable<SecurityGroup> groups = transform(filter(rawGroups, notNull()),
+                                                 groupConverter);
+      return ImmutableSet.copyOf(groups);
+   }
+
+
+   @Override
+   public Set<SecurityGroup> listSecurityGroupsInLocation(final Location 
location) {
+      String region = AWSUtils.getRegionFromLocationOrNull(location);
+      if (region == null) {
+         return ImmutableSet.of();
+      }
+      return listSecurityGroupsInLocation(region);
+   }
+
+   public Set<SecurityGroup> listSecurityGroupsInLocation(String region) {
+      Iterable<? extends org.jclouds.ec2.domain.SecurityGroup> rawGroups = 
pollSecurityGroupsByRegion(region);
+      Iterable<SecurityGroup> groups = transform(filter(rawGroups, notNull()),
+                                                 groupConverter);
+      return ImmutableSet.copyOf(groups);
+   }
+   
+   @Override
+   public Set<SecurityGroup> listSecurityGroupsForNode(String id) {
+      checkNotNull(id, "id");
+      String[] parts = AWSUtils.parseHandle(id);
+      String region = parts[0];
+      String instanceId = parts[1];
+      
+      RunningInstance instance = 
getOnlyElement(Iterables.concat(client.getInstanceApi().get().describeInstancesInRegion(region,
 instanceId)));
+
+      if (instance == null) {
+         return ImmutableSet.of();
+      }
+      
+      Set<String> groupNames = instance.getGroupNames();
+      Set<? extends org.jclouds.ec2.domain.SecurityGroup> rawGroups =
+         
client.getSecurityGroupApi().get().describeSecurityGroupsInRegion(region, 
Iterables.toArray(groupNames, String.class));
+      
+      return ImmutableSet.copyOf(transform(filter(rawGroups, notNull()), 
groupConverter));
+   }
+
+   @Override
+   public SecurityGroup getSecurityGroupById(String id) {
+      checkNotNull(id, "id");
+      String[] parts = AWSUtils.parseHandle(id);
+      String region = parts[0];
+      String groupId = parts[1];
+
+      Set<? extends org.jclouds.ec2.domain.SecurityGroup> rawGroups =
+         
client.getSecurityGroupApi().get().describeSecurityGroupsInRegion(region, 
groupId);
+      
+      return getOnlyElement(transform(filter(rawGroups, notNull()), 
groupConverter));
+   }
+
+   @Override
+   public SecurityGroup createSecurityGroup(String name, Location location) {
+      String region = AWSUtils.getRegionFromLocationOrNull(location);
+      if (region != null) {
+         return createSecurityGroup(name, region);
+      } else {
+         return null;
+      }
+   }
+   
+   public SecurityGroup createSecurityGroup(String name, String region) {
+      String markerGroup = namingConvention.create().sharedNameForGroup(name);
+      RegionNameAndIngressRules regionAndName = new 
RegionNameAndIngressRules(region, markerGroup, new int[] {},
+                                                                              
false);
+
+      groupCreator.getUnchecked(regionAndName);
+
+      return getSecurityGroupById(regionAndName.slashEncode());
+   }
+
+   @Override
+   public boolean removeSecurityGroup(String id) {
+      checkNotNull(id, "id");
+      String[] parts = AWSUtils.parseHandle(id);
+      String region = parts[0];
+      String groupName = parts[1];
+      
+      if 
(client.getSecurityGroupApi().get().describeSecurityGroupsInRegion(region, 
groupName).size() > 0) {
+         
client.getSecurityGroupApi().get().deleteSecurityGroupInRegion(region, 
groupName);
+         // TODO: test this clear happens
+         groupCreator.invalidate(new RegionNameAndIngressRules(region, 
groupName, null, false));
+         return true;
+      }
+
+      return false;
+   }
+
+
+   @Override
+   public SecurityGroup addIpPermission(IpPermission ipPermission, 
SecurityGroup group) {
+      String region = 
AWSUtils.getRegionFromLocationOrNull(group.getLocation());
+      String name = group.getName();
+
+      if (ipPermission.getCidrBlocks().size() > 0) {
+         for (String cidr : ipPermission.getCidrBlocks()) {
+            client.getSecurityGroupApi().get().
+               authorizeSecurityGroupIngressInRegion(region,
+                                                     name,
+                                                     
ipPermission.getIpProtocol(),
+                                                     
ipPermission.getFromPort(),
+                                                     ipPermission.getToPort(),
+                                                     cidr);
+         }
+      }
+
+      if (ipPermission.getTenantIdGroupNamePairs().size() > 0) {
+         for (String userId : 
ipPermission.getTenantIdGroupNamePairs().keySet()) {
+            for (String groupName : 
ipPermission.getTenantIdGroupNamePairs().get(userId)) {
+               client.getSecurityGroupApi().get().
+                  authorizeSecurityGroupIngressInRegion(region,
+                                                        name,
+                                                        new 
UserIdGroupPair(userId, groupName));
+            }
+         }
+      }
+
+      return getSecurityGroupById(new RegionAndName(region, 
group.getName()).slashEncode());
+   }
+
+   @Override
+   public SecurityGroup addIpPermission(IpProtocol protocol, int startPort, 
int endPort,
+                                        Multimap<String, String> 
tenantIdGroupNamePairs,
+                                        Iterable<String> ipRanges,
+                                        Iterable<String> groupIds, 
SecurityGroup group) {
+      String region = 
AWSUtils.getRegionFromLocationOrNull(group.getLocation());
+      String name = group.getName();
+
+      if (Iterables.size(ipRanges) > 0) {
+         for (String cidr : ipRanges) {
+            client.getSecurityGroupApi().get().
+               authorizeSecurityGroupIngressInRegion(region,
+                                                     name,
+                                                     protocol,
+                                                     startPort,
+                                                     endPort,
+                                                     cidr);
+         }
+      }
+
+      if (tenantIdGroupNamePairs.size() > 0) {
+         for (String userId : tenantIdGroupNamePairs.keySet()) {
+            for (String groupName : tenantIdGroupNamePairs.get(userId)) {
+               client.getSecurityGroupApi().get().
+                  authorizeSecurityGroupIngressInRegion(region,
+                                                        name,
+                                                        new 
UserIdGroupPair(userId, groupName));
+            }
+         }
+      }
+      
+      return getSecurityGroupById(new RegionAndName(region, 
group.getName()).slashEncode());
+   }
+      
+   @Override
+   public SecurityGroup removeIpPermission(IpPermission ipPermission, 
SecurityGroup group) {
+      String region = 
AWSUtils.getRegionFromLocationOrNull(group.getLocation());
+      String name = group.getName();
+
+      if (ipPermission.getCidrBlocks().size() > 0) {
+         for (String cidr : ipPermission.getCidrBlocks()) {
+            client.getSecurityGroupApi().get().
+               revokeSecurityGroupIngressInRegion(region,
+                                                  name,
+                                                  ipPermission.getIpProtocol(),
+                                                  ipPermission.getFromPort(),
+                                                  ipPermission.getToPort(),
+                                                  cidr);
+         }
+      }
+
+      if (ipPermission.getTenantIdGroupNamePairs().size() > 0) {
+         for (String userId : 
ipPermission.getTenantIdGroupNamePairs().keySet()) {
+            for (String groupName : 
ipPermission.getTenantIdGroupNamePairs().get(userId)) {
+               client.getSecurityGroupApi().get().
+                  revokeSecurityGroupIngressInRegion(region,
+                                                     name,
+                                                     new 
UserIdGroupPair(userId, groupName));
+            }
+         }
+      }
+
+      return getSecurityGroupById(new RegionAndName(region, 
group.getName()).slashEncode());
+   }
+
+   @Override
+   public SecurityGroup removeIpPermission(IpProtocol protocol, int startPort, 
int endPort,
+                                           Multimap<String, String> 
tenantIdGroupNamePairs,
+                                           Iterable<String> ipRanges,
+                                           Iterable<String> groupIds, 
SecurityGroup group) {
+      String region = 
AWSUtils.getRegionFromLocationOrNull(group.getLocation());
+      String name = group.getName();
+
+      if (Iterables.size(ipRanges) > 0) {
+         for (String cidr : ipRanges) {
+            client.getSecurityGroupApi().get().
+               revokeSecurityGroupIngressInRegion(region,
+                                                  name,
+                                                  protocol,
+                                                  startPort,
+                                                  endPort,
+                                                  cidr);
+         }
+      }
+
+      if (tenantIdGroupNamePairs.size() > 0) {
+         for (String userId : tenantIdGroupNamePairs.keySet()) {
+            for (String groupName : tenantIdGroupNamePairs.get(userId)) {
+               client.getSecurityGroupApi().get().
+                  revokeSecurityGroupIngressInRegion(region,
+                                                     name,
+                                                     new 
UserIdGroupPair(userId, groupName));
+            }
+         }
+      }
+      
+      return getSecurityGroupById(new RegionAndName(region, 
group.getName()).slashEncode());
+   }
+
+   @Override
+   public boolean supportsTenantIdGroupNamePairs() {
+      return true;
+   }
+
+   @Override
+   public boolean supportsTenantIdGroupIdPairs() {
+      return false;
+   }
+
+   @Override
+   public boolean supportsGroupIds() {
+      return false;
+   }
+
+   @Override
+   public boolean supportsPortRangesForGroups() {
+      return false;
+   }
+
+   protected Iterable<? extends org.jclouds.ec2.domain.SecurityGroup> 
pollSecurityGroups() {
+      Iterable<? extends Set<? extends org.jclouds.ec2.domain.SecurityGroup>> 
groups
+         = transform(regions.get(), allSecurityGroupsInRegion());
+      
+      return concat(groups);
+   }
+
+   
+   protected Iterable<? extends org.jclouds.ec2.domain.SecurityGroup> 
pollSecurityGroupsByRegion(String region) {
+      return allSecurityGroupsInRegion().apply(region);
+   }
+
+   protected Function<String, Set<? extends 
org.jclouds.ec2.domain.SecurityGroup>> allSecurityGroupsInRegion() {
+      return new Function<String, Set<? extends 
org.jclouds.ec2.domain.SecurityGroup>>() {
+         
+         @Override
+         public Set<? extends org.jclouds.ec2.domain.SecurityGroup> 
apply(String from) {
+            return 
client.getSecurityGroupApi().get().describeSecurityGroupsInRegion(from);
+         }
+         
+      };
+   }
+
+   protected Location findLocationWithId(final String locationId) {
+      if (locationId == null)
+         return null;
+      try {
+         Location location = Iterables.find(locations.get(), new 
Predicate<Location>() {
+
+            @Override
+            public boolean apply(Location input) {
+               return input.getId().equals(locationId);
+            }
+
+         });
+         return location;
+
+      } catch (NoSuchElementException e) {
+         return null;
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/AddElasticIpsToNodemetadata.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/AddElasticIpsToNodemetadata.java
 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/AddElasticIpsToNodemetadata.java
new file mode 100644
index 0000000..72528a1
--- /dev/null
+++ 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/AddElasticIpsToNodemetadata.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.ec2.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.concurrent.ExecutionException;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.aws.util.AWSUtils;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.NodeMetadataBuilder;
+import org.jclouds.ec2.compute.domain.RegionAndName;
+
+import com.google.common.base.Function;
+import com.google.common.base.Throwables;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This class searches for elastic ip addresses that are associated with the 
node, and adds them to
+ * the publicIpAddress collection if present.
+ */
+@Singleton
+public class AddElasticIpsToNodemetadata implements Function<NodeMetadata, 
NodeMetadata> {
+
+   private final LoadingCache<RegionAndName, String> cache;
+
+   @Inject
+   protected AddElasticIpsToNodemetadata(@Named("ELASTICIP") 
LoadingCache<RegionAndName, String> cache) {
+      this.cache = checkNotNull(cache, "cache");
+   }
+
+   // Note: Instances only have one Internet routable IP address. When an 
Elastic IP is associated to an
+   // instance, the instance's existing Public IP address mapping is removed 
and is no longer valid for this instance
+   // http://aws.amazon.com/articles/1346
+
+   // TODO can there be multiple elastic ips on one instance?
+   @Override
+   public NodeMetadata apply(NodeMetadata arg0) {
+      String[] parts = AWSUtils.parseHandle(arg0.getId());
+      String region = parts[0];
+      String instanceId = parts[1];
+      try {
+         String publicIp = cache.get(new RegionAndName(region, instanceId));
+         // Replace existing public addresses with elastic IP (see note above)
+         return NodeMetadataBuilder.fromNodeMetadata(arg0)
+                 .publicAddresses(ImmutableSet.<String> 
builder().add(publicIp).build()).build();
+      } catch (CacheLoader.InvalidCacheLoadException e) {
+         // no ip was found
+         return arg0;
+      } catch (ExecutionException e) {
+         throw Throwables.propagate(e);
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/CreateUniqueKeyPair.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/CreateUniqueKeyPair.java
 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/CreateUniqueKeyPair.java
new file mode 100644
index 0000000..37f4c15
--- /dev/null
+++ 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/CreateUniqueKeyPair.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.ec2.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.functions.GroupNamingConvention;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.ec2.EC2Api;
+import org.jclouds.ec2.compute.domain.RegionAndName;
+import org.jclouds.ec2.domain.KeyPair;
+import org.jclouds.logging.Logger;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.inject.Inject;
+
+@Singleton
+public class CreateUniqueKeyPair implements Function<RegionAndName, KeyPair> {
+   @Resource
+   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+   protected Logger logger = Logger.NULL;
+   protected final EC2Api ec2Api;
+   protected final GroupNamingConvention.Factory namingConvention;
+
+   @Inject
+   public CreateUniqueKeyPair(EC2Api ec2Api, GroupNamingConvention.Factory 
namingConvention) {
+      this.ec2Api = ec2Api;
+      this.namingConvention = checkNotNull(namingConvention, 
"namingConvention");
+   }
+
+   @Override
+   public KeyPair apply(RegionAndName from) {
+      return createNewKeyPairInRegion(from.getRegion(), from.getName());
+   }
+
+   @VisibleForTesting
+   KeyPair createNewKeyPairInRegion(String region, String group) {
+      checkNotNull(region, "region");
+      checkNotNull(group, "group");
+      logger.debug(">> creating keyPair region(%s) group(%s)", region, group);
+      KeyPair keyPair = null;
+      String prefix = group;
+      
+      while (keyPair == null) {
+         String keyName = namingConvention.create().uniqueNameForGroup(prefix);
+         try {
+            keyPair = 
ec2Api.getKeyPairApi().get().createKeyPairInRegion(region, keyName);
+         } catch (IllegalStateException e) {
+            logger.trace("   invalid keyname (%s in %s); retrying", keyName, 
region);
+         }
+      }
+      
+      logger.debug("<< created keyPair(%s)", keyPair);
+      return keyPair;
+   }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/CredentialsForInstance.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/CredentialsForInstance.java
 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/CredentialsForInstance.java
new file mode 100644
index 0000000..f9ee0a7
--- /dev/null
+++ 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/CredentialsForInstance.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.ec2.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.domain.Image;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.ec2.compute.domain.RegionAndName;
+import org.jclouds.ec2.domain.KeyPair;
+import org.jclouds.ec2.domain.RunningInstance;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Supplier;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+
+@Singleton
+public class CredentialsForInstance extends CacheLoader<RunningInstance, 
Optional<LoginCredentials>> {
+
+   private final ConcurrentMap<RegionAndName, KeyPair> credentialsMap;
+   private final Supplier<LoadingCache<RegionAndName, ? extends Image>> 
imageMap;
+   private final Function<RunningInstance, LoginCredentials> 
passwordCredentialsFromWindowsInstance;
+
+   @Inject
+   CredentialsForInstance(ConcurrentMap<RegionAndName, KeyPair> credentialsMap,
+            Supplier<LoadingCache<RegionAndName, ? extends Image>> imageMap, 
Function<RunningInstance, LoginCredentials> 
passwordCredentialsFromWindowsInstance) {
+      this.credentialsMap = checkNotNull(credentialsMap, "credentialsMap");
+      this.imageMap = checkNotNull(imageMap, "imageMap");
+      this.passwordCredentialsFromWindowsInstance = 
checkNotNull(passwordCredentialsFromWindowsInstance, 
"passwordCredentialsFromWindowsInstance");
+   }
+
+   @Override
+   public Optional<LoginCredentials> load(final RunningInstance instance) 
throws ExecutionException {
+      if ("windows".equals(instance.getPlatform())) {
+         return 
Optional.of(passwordCredentialsFromWindowsInstance.apply(instance));
+      } else  if (instance.getKeyName() != null) {
+         return 
Optional.of(LoginCredentials.builder().user(getLoginAccountFor(instance)).privateKey(getPrivateKeyOrNull(instance)).build());
+      }
+      return Optional.absent();
+   }
+
+   @VisibleForTesting
+   String getPrivateKeyOrNull(RunningInstance instance) {
+      KeyPair keyPair = credentialsMap.get(new 
RegionAndName(instance.getRegion(), instance.getKeyName()));
+      return keyPair != null ? keyPair.getKeyMaterial() : null;
+   }
+
+   @VisibleForTesting
+   String getLoginAccountFor(RunningInstance from) throws ExecutionException {
+      return imageMap.get().get(new RegionAndName(from.getRegion(), 
from.getImageId())).getDefaultCredentials().identity;
+   }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/EC2ImageParser.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/EC2ImageParser.java
 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/EC2ImageParser.java
new file mode 100644
index 0000000..fc8b184
--- /dev/null
+++ 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/EC2ImageParser.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.ec2.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static 
org.jclouds.compute.util.ComputeServiceUtils.parseOsFamilyOrUnrecognized;
+
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.Image.Status;
+import org.jclouds.compute.domain.ImageBuilder;
+import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import 
org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
+import org.jclouds.compute.util.ComputeServiceUtils;
+import org.jclouds.domain.Location;
+import org.jclouds.domain.LocationBuilder;
+import org.jclouds.domain.LocationScope;
+import org.jclouds.ec2.compute.strategy.ReviseParsedImage;
+import org.jclouds.ec2.domain.Image.Architecture;
+import org.jclouds.ec2.domain.Image.ImageState;
+import org.jclouds.ec2.domain.Image.ImageType;
+import org.jclouds.logging.Logger;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+
+@Singleton
+public class EC2ImageParser implements Function<org.jclouds.ec2.domain.Image, 
Image> {
+   @Resource
+   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+   protected Logger logger = Logger.NULL;
+   
+   private final Map<ImageState, Status> toPortableImageStatus;
+   private final PopulateDefaultLoginCredentialsForImageStrategy 
credentialProvider;
+   private final Supplier<Set<? extends Location>> locations;
+   private final Supplier<Location> defaultLocation;
+   private final Map<OsFamily, Map<String, String>> osVersionMap;
+   private final ReviseParsedImage reviseParsedImage;
+
+
+   @Inject
+   public EC2ImageParser(Map<ImageState, Image.Status> toPortableImageStatus,
+            PopulateDefaultLoginCredentialsForImageStrategy credentialProvider,
+            Map<OsFamily, Map<String, String>> osVersionMap, @Memoized 
Supplier<Set<? extends Location>> locations,
+            Supplier<Location> defaultLocation, ReviseParsedImage 
reviseParsedImage) {
+      this.toPortableImageStatus = checkNotNull(toPortableImageStatus, 
"toPortableImageStatus");
+      this.credentialProvider = checkNotNull(credentialProvider, 
"credentialProvider");
+      this.locations = checkNotNull(locations, "locations");
+      this.defaultLocation = checkNotNull(defaultLocation, "defaultLocation");
+      this.osVersionMap = checkNotNull(osVersionMap, "osVersionMap");
+      this.reviseParsedImage = checkNotNull(reviseParsedImage, 
"reviseParsedImage");
+   }
+
+   @Override
+   public Image apply(final org.jclouds.ec2.domain.Image from) {
+      if (from.getImageType() != ImageType.MACHINE) {
+         return null;
+      }
+      ImageBuilder builder = new ImageBuilder();
+      builder.providerId(from.getId());
+      builder.id(from.getRegion() + "/" + from.getId());
+      builder.name(from.getName());
+      builder.description(from.getDescription() != null ? 
from.getDescription() : from.getImageLocation());
+      builder.userMetadata(ImmutableMap.<String, String> 
builder().put("owner", from.getImageOwnerId()).put(
+               "rootDeviceType", 
from.getRootDeviceType().value()).put("virtualizationType",
+               from.getVirtualizationType().value()).put("hypervisor", 
from.getHypervisor().value()).build());
+
+      OperatingSystem.Builder osBuilder = OperatingSystem.builder();
+      osBuilder.is64Bit(from.getArchitecture() == Architecture.X86_64);
+      OsFamily family = parseOsFamily(from);
+      osBuilder.family(family);
+      
osBuilder.version(ComputeServiceUtils.parseVersionOrReturnEmptyString(family, 
from.getImageLocation(),
+               osVersionMap));
+      osBuilder.description(from.getImageLocation());
+      osBuilder.arch(from.getVirtualizationType().value());
+
+      reviseParsedImage.reviseParsedImage(from, builder, family, osBuilder);
+
+      builder.defaultCredentials(credentialProvider.apply(from));
+
+      try {
+         builder.location(Iterables.find(locations.get(), new 
Predicate<Location>() {
+
+            @Override
+            public boolean apply(Location input) {
+               return input.getId().equals(from.getRegion());
+            }
+
+         }));
+      } catch (NoSuchElementException e) {
+         logger.error("unknown region %s for image %s; not in %s", 
from.getRegion(), from.getId(), locations);
+         builder.location(new 
LocationBuilder().scope(LocationScope.REGION).id(from.getRegion()).description(
+                  from.getRegion()).parent(defaultLocation.get()).build());
+      }
+      builder.operatingSystem(osBuilder.build());
+      builder.status(toPortableImageStatus.get(from.getImageState()));
+      builder.backendStatus(from.getRawState());
+      return builder.build();
+   }
+
+   /** 
+    * First treats windows as a special case: check if platform==windows.
+    * Then tries matching based on the image name.
+    * And then falls back to checking other types of platform.
+    */
+   private OsFamily parseOsFamily(org.jclouds.ec2.domain.Image from) {
+      if (from.getPlatform() != null && 
from.getPlatform().equalsIgnoreCase("windows")) {
+         return OsFamily.WINDOWS;
+      }
+      
+      OsFamily family = parseOsFamilyOrUnrecognized(from.getImageLocation());
+      if (family == OsFamily.UNRECOGNIZED && from.getPlatform() != null) {
+         family = parseOsFamilyOrUnrecognized(from.getPlatform());
+      }
+      return family;
+   }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/EC2SecurityGroupIdFromName.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/EC2SecurityGroupIdFromName.java
 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/EC2SecurityGroupIdFromName.java
new file mode 100644
index 0000000..640a967
--- /dev/null
+++ 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/EC2SecurityGroupIdFromName.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.ec2.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.aws.util.AWSUtils;
+import org.jclouds.ec2.EC2Api;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
+
+@Singleton
+public class EC2SecurityGroupIdFromName implements Function<String, String> {
+   protected EC2Api api;
+
+   @Inject
+   public EC2SecurityGroupIdFromName(EC2Api api) {
+      this.api = checkNotNull(api, "api");
+   }
+
+   @Override
+   public String apply(String input) {
+      checkNotNull(input, "input");
+      String[] parts = AWSUtils.parseHandle(input);
+      String region = parts[0];
+      String name = parts[1];
+
+      return  
Iterables.getOnlyElement(api.getSecurityGroupApi().get().describeSecurityGroupsInRegion(region,
 name), null).getId();
+   }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/EC2SecurityGroupToSecurityGroup.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/EC2SecurityGroupToSecurityGroup.java
 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/EC2SecurityGroupToSecurityGroup.java
new file mode 100644
index 0000000..ae3b5b5
--- /dev/null
+++ 
b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/functions/EC2SecurityGroupToSecurityGroup.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.ec2.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.domain.SecurityGroupBuilder;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.domain.Location;
+import org.jclouds.logging.Logger;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.collect.Iterables;
+import com.google.inject.Inject;
+
+
+/**
+ * A function for transforming an EC2-specific SecurityGroup into a generic
+ * SecurityGroup object.
+ */
+@Singleton
+public class EC2SecurityGroupToSecurityGroup implements 
Function<org.jclouds.ec2.domain.SecurityGroup, SecurityGroup> {
+   @Resource
+   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+   protected Logger logger = Logger.NULL;
+   
+   protected final Supplier<Set<? extends Location>> locations;
+
+   @Inject
+   public EC2SecurityGroupToSecurityGroup(@Memoized Supplier<Set<? extends 
Location>> locations) {
+      this.locations = checkNotNull(locations, "locations");
+   }
+
+   @Override
+   public SecurityGroup apply(org.jclouds.ec2.domain.SecurityGroup group) {
+      SecurityGroupBuilder builder = new SecurityGroupBuilder();
+      Location location = findLocationWithId(group.getRegion());
+      builder.location(location);
+      builder.id(group.getRegion() + "/" + idOrName(group));
+      builder.providerId(group.getId());
+      builder.name(group.getName());
+      builder.ipPermissions(group);
+      builder.ownerId(group.getOwnerId());
+      
+      return builder.build();
+   }
+
+   protected String idOrName(org.jclouds.ec2.domain.SecurityGroup group) {
+      return group.getName();
+   }
+
+   private Location findLocationWithId(final String locationId) {
+      if (locationId == null)
+         return null;
+      try {
+         Location location = Iterables.find(locations.get(), new 
Predicate<Location>() {
+
+            @Override
+            public boolean apply(Location input) {
+               return input.getId().equals(locationId);
+            }
+
+         });
+         return location;
+
+      } catch (NoSuchElementException e) {
+         logger.debug("couldn't match instance location %s in: %s", 
locationId, locations.get());
+         return null;
+      }
+   }
+}

Reply via email to