http://git-wip-us.apache.org/repos/asf/stratos/blob/4203d59b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java
 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java
new file mode 100644
index 0000000..3a26d34
--- /dev/null
+++ 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java
@@ -0,0 +1,439 @@
+/*
+ * 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.googlecomputeengine.compute;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.collect.Iterables.contains;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.tryFind;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.CENTOS_PROJECT;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.DEBIAN_PROJECT;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GCE_BOOT_DISK_SUFFIX;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GCE_DELETE_BOOT_DISK_METADATA_KEY;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GCE_IMAGE_METADATA_KEY;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_INTERVAL;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_TIMEOUT;
+import static 
org.jclouds.googlecomputeengine.domain.Instance.NetworkInterface.AccessConfig.Type;
+import static 
org.jclouds.googlecomputeengine.predicates.InstancePredicates.isBootDisk;
+import static org.jclouds.util.Predicates2.retry;
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.ComputeServiceAdapter;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.domain.Location;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import 
org.jclouds.googlecomputeengine.compute.functions.FirewallTagNamingConvention;
+import 
org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
+import org.jclouds.googlecomputeengine.config.UserProject;
+import org.jclouds.googlecomputeengine.domain.Disk;
+import org.jclouds.googlecomputeengine.domain.Image;
+import org.jclouds.googlecomputeengine.domain.Instance;
+import org.jclouds.googlecomputeengine.domain.Instance.AttachedDisk;
+import org.jclouds.googlecomputeengine.domain.Instance.PersistentAttachedDisk;
+import org.jclouds.googlecomputeengine.domain.InstanceInZone;
+import org.jclouds.googlecomputeengine.domain.InstanceTemplate;
+import org.jclouds.googlecomputeengine.domain.InstanceTemplate.PersistentDisk;
+import 
org.jclouds.googlecomputeengine.domain.InstanceTemplate.PersistentDisk.Mode;
+import org.jclouds.googlecomputeengine.domain.MachineType;
+import org.jclouds.googlecomputeengine.domain.MachineTypeInZone;
+import org.jclouds.googlecomputeengine.domain.Operation;
+import org.jclouds.googlecomputeengine.domain.SlashEncodedIds;
+import org.jclouds.googlecomputeengine.domain.Zone;
+import org.jclouds.googlecomputeengine.features.InstanceApi;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.logging.Logger;
+
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.primitives.Ints;
+import com.google.common.util.concurrent.Atomics;
+import com.google.common.util.concurrent.UncheckedTimeoutException;
+import com.google.inject.Inject;
+
+public class GoogleComputeEngineServiceAdapter implements 
ComputeServiceAdapter<InstanceInZone, MachineTypeInZone, Image, Zone> {
+
+   @Resource
+   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+   protected Logger logger = Logger.NULL;
+
+   private final GoogleComputeEngineApi api;
+   private final Supplier<String> userProject;
+   private final Supplier<Map<URI, ? extends Location>> zones;
+   private final Function<TemplateOptions, ImmutableMap.Builder<String, 
String>> metatadaFromTemplateOptions;
+   private final Predicate<AtomicReference<Operation>> 
retryOperationDonePredicate;
+   private final long operationCompleteCheckInterval;
+   private final long operationCompleteCheckTimeout;
+   private final FirewallTagNamingConvention.Factory 
firewallTagNamingConvention;
+
+   @Inject
+   public GoogleComputeEngineServiceAdapter(GoogleComputeEngineApi api,
+                                            @UserProject Supplier<String> 
userProject,
+                                            Function<TemplateOptions,
+                                                    
ImmutableMap.Builder<String, String>> metatadaFromTemplateOptions,
+                                            @Named("zone") 
Predicate<AtomicReference<Operation>> operationDonePredicate,
+                                            
@Named(OPERATION_COMPLETE_INTERVAL) Long operationCompleteCheckInterval,
+                                            @Named(OPERATION_COMPLETE_TIMEOUT) 
Long operationCompleteCheckTimeout,
+                                            @Memoized Supplier<Map<URI, ? 
extends Location>> zones,
+                                            
FirewallTagNamingConvention.Factory firewallTagNamingConvention) {
+      this.api = checkNotNull(api, "google compute api");
+      this.userProject = checkNotNull(userProject, "user project name");
+      this.metatadaFromTemplateOptions = 
checkNotNull(metatadaFromTemplateOptions,
+              "metadata from template options function");
+      this.operationCompleteCheckInterval = 
checkNotNull(operationCompleteCheckInterval,
+              "operation completed check interval");
+      this.operationCompleteCheckTimeout = 
checkNotNull(operationCompleteCheckTimeout,
+                                                        "operation completed 
check timeout");
+      this.retryOperationDonePredicate = retry(operationDonePredicate, 
operationCompleteCheckTimeout,
+                                               operationCompleteCheckInterval, 
TimeUnit.MILLISECONDS);
+      this.zones = checkNotNull(zones, "zones");
+      this.firewallTagNamingConvention = 
checkNotNull(firewallTagNamingConvention, "firewallTagNamingConvention");
+   }
+
+   @Override
+   public NodeAndInitialCredentials<InstanceInZone> 
createNodeWithGroupEncodedIntoName(
+           final String group, final String name, final Template template) {
+
+      checkNotNull(template, "template");
+
+      GoogleComputeEngineTemplateOptions options = 
GoogleComputeEngineTemplateOptions.class.cast(template.getOptions()).clone();
+      checkState(options.getNetwork().isPresent(), "network was not present in 
template options");
+      Hardware hardware = checkNotNull(template.getHardware(), "hardware must 
be set");
+
+      checkNotNull(hardware.getUri(), "hardware must have a URI");
+      checkNotNull(template.getImage().getUri(), "image URI is null");
+
+      // Note that the ordering is significant here - the first disk must be 
the boot disk.
+      List<PersistentDisk> disks = Lists.newArrayList();
+
+      if (!tryFind(options.getDisks(), isBootDisk()).isPresent()) {
+         Disk bootDisk = createBootDisk(template, name);
+
+         disks.add(new PersistentDisk(Mode.READ_WRITE,
+                                      bootDisk.getSelfLink(),
+                                      null,
+                                      true,
+                                      true));
+      }
+
+      disks.addAll(options.getDisks());
+
+      InstanceTemplate instanceTemplate = InstanceTemplate.builder()
+              .forMachineType(hardware.getUri());
+
+      if (options.isEnableNat()) {
+         instanceTemplate.addNetworkInterface(options.getNetwork().get(), 
Type.ONE_TO_ONE_NAT);
+      } else {
+         instanceTemplate.addNetworkInterface(options.getNetwork().get());
+      }
+
+      instanceTemplate.disks(disks);
+
+      LoginCredentials credentials = 
getFromImageAndOverrideIfRequired(template.getImage(), options);
+
+      ImmutableMap.Builder<String, String> metadataBuilder = 
metatadaFromTemplateOptions.apply(options);
+
+      metadataBuilder.put(GCE_IMAGE_METADATA_KEY, 
template.getImage().getUri().toString());
+
+      if (!options.shouldKeepBootDisk()) {
+         metadataBuilder.put(GCE_DELETE_BOOT_DISK_METADATA_KEY, 
Boolean.TRUE.toString());
+      }
+
+      instanceTemplate.metadata(metadataBuilder.build());
+      instanceTemplate.serviceAccounts(options.getServiceAccounts());
+
+      final InstanceApi instanceApi = 
api.getInstanceApiForProject(userProject.get());
+      final String zone = template.getLocation().getId();
+      Operation operation = instanceApi.createInZone(name, zone, 
instanceTemplate);
+
+      if (options.shouldBlockUntilRunning()) {
+         waitOperationDone(operation);
+      }
+
+      // some times the newly created instances are not immediately returned
+      AtomicReference<Instance> instance = Atomics.newReference();
+
+      retry(new Predicate<AtomicReference<Instance>>() {
+         @Override
+         public boolean apply(AtomicReference<Instance> input) {
+            input.set(instanceApi.getInZone(zone, name));
+            return input.get() != null;
+         }
+      }, operationCompleteCheckTimeout, operationCompleteCheckInterval, 
MILLISECONDS).apply(instance);
+
+      if (!options.getTags().isEmpty()) {
+         Operation tagsOperation = instanceApi.setTagsInZone(zone,
+                 name, options.getTags(), 
instance.get().getTags().getFingerprint());
+
+         waitOperationDone(tagsOperation);
+
+         retry(new Predicate<AtomicReference<Instance>>() {
+            @Override
+            public boolean apply(AtomicReference<Instance> input) {
+               input.set(instanceApi.getInZone(zone, name));
+               return input.get() != null;
+            }
+         }, operationCompleteCheckTimeout, operationCompleteCheckInterval, 
MILLISECONDS).apply(instance);
+      }
+
+      // Add tags for security groups
+      final FirewallTagNamingConvention naming = 
firewallTagNamingConvention.get(group);
+      Set<String> tags = 
FluentIterable.from(Ints.asList(options.getInboundPorts()))
+              .transform(new Function<Integer, String>(){
+                       @Override
+                       public String apply(Integer input) {
+                          return input != null
+                                  ? naming.name(input)
+                                  : null;
+                       }
+                    })
+              .toSet();
+      instanceApi.setTagsInZone(zone, instance.get().getName(), tags, 
instance.get().getTags().getFingerprint());
+
+      InstanceInZone instanceInZone = new InstanceInZone(instance.get(), zone);
+
+      return new NodeAndInitialCredentials<InstanceInZone>(instanceInZone, 
instanceInZone.slashEncode(), credentials);
+   }
+
+   private Disk createBootDisk(Template template, String instanceName) {
+      URI imageUri = template.getImage().getUri();
+
+      GoogleComputeEngineTemplateOptions options = 
GoogleComputeEngineTemplateOptions.class.cast(template.getOptions()).clone();
+
+      int diskSize = options.getBootDiskSize().or(10l).intValue();
+
+      String diskName = instanceName + "-" + GCE_BOOT_DISK_SUFFIX;
+
+      Operation diskOperation = api.getDiskApiForProject(userProject.get())
+                                   
.createFromImageWithSizeInZone(imageUri.toString(),
+                                                                  diskName,
+                                                                  diskSize,
+                                                                  
template.getLocation().getId());
+
+      waitOperationDone(diskOperation);
+
+      return 
api.getDiskApiForProject(userProject.get()).getInZone(template.getLocation().getId(),
+                                                                   diskName);
+   }
+
+   @Override
+   public Iterable<MachineTypeInZone> listHardwareProfiles() {
+      ImmutableSet.Builder<MachineTypeInZone> builder = ImmutableSet.builder();
+
+      for (final Location zone : zones.get().values()) {
+         builder.addAll(api.getMachineTypeApiForProject(userProject.get())
+                 .listInZone(zone.getId())
+                 .concat()
+                 .filter(new Predicate<MachineType>() {
+                    @Override
+                    public boolean apply(MachineType input) {
+                       return !input.getDeprecated().isPresent();
+                    }
+                 })
+                 .transform(new Function<MachineType, MachineTypeInZone>() {
+
+                    @Override
+                    public MachineTypeInZone apply(MachineType arg0) {
+                       return new MachineTypeInZone(arg0, arg0.getZone());
+                    }
+                 }));
+      }
+
+      return builder.build();
+   }
+
+   @Override
+   public Iterable<Image> listImages() {
+      return ImmutableSet.<Image>builder()
+              
.addAll(api.getImageApiForProject(userProject.get()).list().concat())
+              
.addAll(api.getImageApiForProject(DEBIAN_PROJECT).list().concat())
+              
.addAll(api.getImageApiForProject(CENTOS_PROJECT).list().concat())
+              .build();
+   }
+
+   @Override
+   public Image getImage(String id) {
+      return 
Objects.firstNonNull(api.getImageApiForProject(userProject.get()).get(id),
+                                  
Objects.firstNonNull(api.getImageApiForProject(DEBIAN_PROJECT).get(id),
+                                          
api.getImageApiForProject(CENTOS_PROJECT).get(id)));
+
+   }
+
+   @Override
+   public Iterable<Zone> listLocations() {
+      return api.getZoneApiForProject(userProject.get()).list().concat();
+   }
+
+   @Override
+   public InstanceInZone getNode(String name) {
+      SlashEncodedIds slashEncodedIds = SlashEncodedIds.fromSlashEncoded(name);
+
+      Instance instance = 
api.getInstanceApiForProject(userProject.get()).getInZone(slashEncodedIds.getFirstId(),
+              slashEncodedIds.getSecondId());
+
+      return instance == null ?  null : new InstanceInZone(instance, 
slashEncodedIds.getFirstId());
+   }
+
+   @Override
+   public Iterable<InstanceInZone> listNodes() {
+      return FluentIterable.from(zones.get().values()).transformAndConcat(new 
Function<Location, ImmutableSet<InstanceInZone>>() {
+         @Override
+         public ImmutableSet<InstanceInZone> apply(final Location input) {
+            return 
api.getInstanceApiForProject(userProject.get()).listInZone(input.getId()).concat()
+                    .transform(new Function<Instance, InstanceInZone>() {
+
+                       @Override
+                       public InstanceInZone apply(Instance arg0) {
+                          return new InstanceInZone(arg0, input.getId());
+                       }
+                    }).toSet();
+         }
+      }).toSet();
+   }
+
+   @Override
+   public Iterable<InstanceInZone> listNodesByIds(final Iterable<String> ids) {
+      return filter(listNodes(), new Predicate<InstanceInZone>() {
+
+         @Override
+         public boolean apply(InstanceInZone instanceInZone) {
+            return contains(ids, instanceInZone.getInstance().getName());
+         }
+      });
+   }
+
+   @Override
+   public void destroyNode(final String name) {
+      SlashEncodedIds slashEncodedIds = SlashEncodedIds.fromSlashEncoded(name);
+      String diskName = null;
+      try {
+         Instance instance = 
api.getInstanceApiForProject(userProject.get()).getInZone(slashEncodedIds.getFirstId(),
+                                                                              
slashEncodedIds.getSecondId());
+         if 
(instance.getMetadata().getItems().get(GCE_DELETE_BOOT_DISK_METADATA_KEY).equals("true"))
 {
+            Optional<AttachedDisk> disk = tryFind(instance.getDisks(), new 
Predicate<AttachedDisk>() {
+               @Override
+               public boolean apply(AttachedDisk input) {
+                  return PersistentAttachedDisk.class.isInstance(input) &&
+                         PersistentAttachedDisk.class.cast(input).isBoot();
+               }
+            });
+            if (disk.isPresent()) {
+               diskName = 
PersistentAttachedDisk.class.cast(disk.get()).getSourceDiskName();
+            }
+         }
+      } catch (Exception e) {
+         // TODO: what exception actually gets thrown here if the instance 
doesn't really exist?
+      }
+      
waitOperationDone(api.getInstanceApiForProject(userProject.get()).deleteInZone(slashEncodedIds.getFirstId(),
+              slashEncodedIds.getSecondId()));
+
+      if (diskName != null) {
+         
waitOperationDone(api.getDiskApiForProject(userProject.get()).deleteInZone(slashEncodedIds.getFirstId(),
+                                                                               
     diskName));
+      }
+
+   }
+
+   @Override
+   public void rebootNode(final String name) {
+      SlashEncodedIds slashEncodedIds = SlashEncodedIds.fromSlashEncoded(name);
+
+      
waitOperationDone(api.getInstanceApiForProject(userProject.get()).resetInZone(slashEncodedIds.getFirstId(),
+              slashEncodedIds.getSecondId()));
+   }
+
+   @Override
+   public void resumeNode(String name) {
+      throw new UnsupportedOperationException("resume is not supported by 
GCE");
+   }
+
+   @Override
+   public void suspendNode(String name) {
+      throw new UnsupportedOperationException("suspend is not supported by 
GCE");
+   }
+
+   private LoginCredentials 
getFromImageAndOverrideIfRequired(org.jclouds.compute.domain.Image image,
+                                                              
GoogleComputeEngineTemplateOptions options) {
+      LoginCredentials defaultCredentials = image.getDefaultCredentials();
+      String[] keys = defaultCredentials.getPrivateKey().split(":");
+      String publicKey = keys[0];
+      String privateKey = keys[1];
+
+      LoginCredentials.Builder credentialsBuilder = 
defaultCredentials.toBuilder();
+      credentialsBuilder.privateKey(privateKey);
+
+      // LoginCredentials from image stores the public key along with the 
private key in the privateKey field
+      // @see GoogleComputePopulateDefaultLoginCredentialsForImageStrategy
+      // so if options doesn't have a public key set we set it from the default
+      if (options.getPublicKey() == null) {
+         options.authorizePublicKey(publicKey);
+      }
+      if (options.hasLoginPrivateKeyOption()) {
+         credentialsBuilder.privateKey(options.getPrivateKey());
+      }
+      if (options.getLoginUser() != null) {
+         credentialsBuilder.identity(options.getLoginUser());
+      }
+      if (options.hasLoginPasswordOption()) {
+         credentialsBuilder.password(options.getLoginPassword());
+      }
+      if (options.shouldAuthenticateSudo() != null) {
+         credentialsBuilder.authenticateSudo(options.shouldAuthenticateSudo());
+      }
+      LoginCredentials credentials = credentialsBuilder.build();
+      options.overrideLoginCredentials(credentials);
+      return credentials;
+   }
+
+   private void waitOperationDone(Operation operation) {
+      AtomicReference<Operation> operationRef = 
Atomics.newReference(operation);
+
+      // wait for the operation to complete
+      if (!retryOperationDonePredicate.apply(operationRef)) {
+         throw new UncheckedTimeoutException("operation did not reach DONE 
state" + operationRef.get());
+      }
+
+      // check if the operation failed
+      if (operationRef.get().getHttpError().isPresent()) {
+         HttpResponse response = operationRef.get().getHttpError().get();
+         throw new IllegalStateException("operation failed. Http Error Code: " 
+ response.getStatusCode() +
+                 " HttpError: " + response.getMessage());
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/4203d59b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/config/GoogleComputeEngineServiceContextModule.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/config/GoogleComputeEngineServiceContextModule.java
 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/config/GoogleComputeEngineServiceContextModule.java
new file mode 100644
index 0000000..730c515
--- /dev/null
+++ 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/config/GoogleComputeEngineServiceContextModule.java
@@ -0,0 +1,283 @@
+/*
+ * 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.googlecomputeengine.compute.config;
+
+import static com.google.common.collect.Iterables.transform;
+import static com.google.common.collect.Maps.uniqueIndex;
+import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import com.google.inject.Scopes;
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.ComputeServiceAdapter;
+import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate;
+import org.jclouds.domain.Location;
+import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import org.jclouds.googlecomputeengine.compute.GoogleComputeEngineService;
+import 
org.jclouds.googlecomputeengine.compute.GoogleComputeEngineServiceAdapter;
+import 
org.jclouds.googlecomputeengine.compute.extensions.GoogleComputeEngineSecurityGroupExtension;
+import org.jclouds.googlecomputeengine.compute.functions.BuildInstanceMetadata;
+import 
org.jclouds.googlecomputeengine.compute.functions.FirewallTagNamingConvention;
+import 
org.jclouds.googlecomputeengine.compute.functions.FirewallToIpPermission;
+import 
org.jclouds.googlecomputeengine.compute.functions.GoogleComputeEngineImageToImage;
+import 
org.jclouds.googlecomputeengine.compute.functions.InstanceInZoneToNodeMetadata;
+import 
org.jclouds.googlecomputeengine.compute.functions.MachineTypeInZoneToHardware;
+import 
org.jclouds.googlecomputeengine.compute.functions.NetworkToSecurityGroup;
+import 
org.jclouds.googlecomputeengine.compute.functions.OrphanedGroupsFromDeadNodes;
+import org.jclouds.googlecomputeengine.compute.functions.RegionToLocation;
+import org.jclouds.googlecomputeengine.compute.functions.ZoneToLocation;
+import org.jclouds.googlecomputeengine.compute.loaders.FindNetworkOrCreate;
+import 
org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
+import 
org.jclouds.googlecomputeengine.compute.predicates.AllNodesInGroupTerminated;
+import 
org.jclouds.googlecomputeengine.compute.strategy.CreateNodesWithGroupEncodedIntoNameThenAddToSet;
+import 
org.jclouds.googlecomputeengine.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
+import 
org.jclouds.googlecomputeengine.compute.strategy.UseNodeCredentialsButOverrideFromTemplate;
+import org.jclouds.googlecomputeengine.config.UserProject;
+import org.jclouds.googlecomputeengine.domain.Firewall;
+import org.jclouds.googlecomputeengine.domain.Image;
+import org.jclouds.googlecomputeengine.domain.Instance;
+import org.jclouds.googlecomputeengine.domain.InstanceInZone;
+import org.jclouds.googlecomputeengine.domain.MachineTypeInZone;
+import org.jclouds.googlecomputeengine.domain.Network;
+import org.jclouds.googlecomputeengine.domain.Region;
+import org.jclouds.googlecomputeengine.domain.Zone;
+import org.jclouds.googlecomputeengine.domain.internal.NetworkAndAddressRange;
+import org.jclouds.googlecomputeengine.functions.CreateNetworkIfNeeded;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.rest.AuthorizationException;
+import 
org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableMap;
+import com.google.inject.Injector;
+import com.google.inject.Provides;
+import com.google.inject.TypeLiteral;
+
+public class GoogleComputeEngineServiceContextModule
+        extends ComputeServiceAdapterContextModule<InstanceInZone, 
MachineTypeInZone, Image, Zone> {
+
+   @Override
+   protected void configure() {
+      super.configure();
+
+      bind(ComputeService.class).to(GoogleComputeEngineService.class);
+
+      bind(new TypeLiteral<ComputeServiceAdapter<InstanceInZone, 
MachineTypeInZone, Image, Zone>>() {})
+              .to(GoogleComputeEngineServiceAdapter.class);
+
+      bind(new TypeLiteral<Function<InstanceInZone, NodeMetadata>>() {})
+              .to(InstanceInZoneToNodeMetadata.class);
+
+      bind(new TypeLiteral<Function<MachineTypeInZone, Hardware>>() {})
+              .to(MachineTypeInZoneToHardware.class);
+
+      bind(new TypeLiteral<Function<Image, 
org.jclouds.compute.domain.Image>>() {})
+              .to(GoogleComputeEngineImageToImage.class);
+
+      bind(new TypeLiteral<Function<Region, Location>>() {
+      })
+              .to(RegionToLocation.class);
+
+      bind(new TypeLiteral<Function<Zone, Location>>() {})
+              .to(ZoneToLocation.class);
+
+      bind(new TypeLiteral<Function<Firewall, Iterable<IpPermission>>>() {})
+              .to(FirewallToIpPermission.class);
+
+      bind(new TypeLiteral<Function<Network, SecurityGroup>>() {})
+              .to(NetworkToSecurityGroup.class);
+
+      bind(new TypeLiteral<Function<TemplateOptions, 
ImmutableMap.Builder<String, String>>>() {})
+              .to(BuildInstanceMetadata.class);
+
+      
bind(org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy.class)
+              .to(PopulateDefaultLoginCredentialsForImageStrategy.class);
+
+      
bind(org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet.class).to(
+              CreateNodesWithGroupEncodedIntoNameThenAddToSet.class);
+
+      bind(TemplateOptions.class).to(GoogleComputeEngineTemplateOptions.class);
+
+      bind(new TypeLiteral<Function<Set<? extends NodeMetadata>, 
Set<String>>>() {})
+              .to(OrphanedGroupsFromDeadNodes.class);
+
+      bind(new TypeLiteral<Predicate<String>>() 
{}).to(AllNodesInGroupTerminated.class);
+
+      bind(new TypeLiteral<Function<NetworkAndAddressRange, Network>>() {})
+              .to(CreateNetworkIfNeeded.class);
+
+      bind(new TypeLiteral<CacheLoader<NetworkAndAddressRange, Network>>() {})
+              .to(FindNetworkOrCreate.class);
+
+      bind(new TypeLiteral<SecurityGroupExtension>() {})
+              .to(GoogleComputeEngineSecurityGroupExtension.class);
+
+      
bind(PrioritizeCredentialsFromTemplate.class).to(UseNodeCredentialsButOverrideFromTemplate.class);
+
+      install(new LocationsFromComputeServiceAdapterModule<InstanceInZone, 
MachineTypeInZone, Image, Zone>() {});
+
+      bind(FirewallTagNamingConvention.Factory.class).in(Scopes.SINGLETON);
+   }
+
+   @Provides
+   @Singleton
+   @Memoized
+   public Supplier<Map<URI, ? extends org.jclouds.compute.domain.Image>> 
provideImagesMap(
+           AtomicReference<AuthorizationException> authException,
+           final Supplier<Set<? extends org.jclouds.compute.domain.Image>> 
images,
+           @Named(PROPERTY_SESSION_INTERVAL) long seconds) {
+      return 
MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException,
+              new Supplier<Map<URI, ? extends 
org.jclouds.compute.domain.Image>>() {
+                 @Override
+                 public Map<URI, ? extends org.jclouds.compute.domain.Image> 
get() {
+                    return uniqueIndex(images.get(), new 
Function<org.jclouds.compute.domain.Image, URI>() {
+                       @Override
+                       public URI apply(org.jclouds.compute.domain.Image 
input) {
+                          return input.getUri();
+                       }
+                    });
+                 }
+              },
+              seconds, TimeUnit.SECONDS);
+   }
+
+   @Provides
+   @Singleton
+   @Memoized
+   public Supplier<Map<URI, ? extends Hardware>> provideHardwaresMap(
+           AtomicReference<AuthorizationException> authException,
+           final Supplier<Set<? extends Hardware>> hardwares,
+           @Named(PROPERTY_SESSION_INTERVAL) long seconds) {
+      return 
MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException,
+              new Supplier<Map<URI, ? extends Hardware>>() {
+                 @Override
+                 public Map<URI, ? extends Hardware> get() {
+                    return uniqueIndex(hardwares.get(), new Function<Hardware, 
URI>() {
+                       @Override
+                       public URI apply(Hardware input) {
+                          return input.getUri();
+                       }
+                    });
+                 }
+              },
+              seconds, TimeUnit.SECONDS);
+   }
+
+   @Provides
+   @Singleton
+   @Memoized
+   public Supplier<Map<URI, ? extends Location>> provideZones(
+           AtomicReference<AuthorizationException> authException,
+           final GoogleComputeEngineApi api, final Function<Zone, Location> 
zoneToLocation,
+           @UserProject final Supplier<String> userProject,
+           @Named(PROPERTY_SESSION_INTERVAL) long seconds) {
+      return 
MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException,
+              new Supplier<Map<URI, ? extends Location>>() {
+                 @Override
+                 public Map<URI, ? extends Location> get() {
+                    return 
uniqueIndex(transform(api.getZoneApiForProject(userProject.get()).list().concat(),
 zoneToLocation),
+                            new Function<Location, URI>() {
+                               @Override
+                               public URI apply(Location input) {
+                                  return (URI) 
input.getMetadata().get("selfLink");
+                               }
+                            });
+                 }
+              },
+              seconds, TimeUnit.SECONDS);
+   }
+
+   @Provides
+   @Singleton
+   @Memoized
+   public Supplier<Map<URI, Region>> provideRegions(
+           AtomicReference<AuthorizationException> authException,
+           final GoogleComputeEngineApi api,
+           @UserProject final Supplier<String> userProject,
+           @Named(PROPERTY_SESSION_INTERVAL) long seconds) {
+      return 
MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException,
+              new Supplier<Map<URI, Region>>() {
+                 @Override
+                 public Map<URI, Region> get() {
+                    return 
uniqueIndex(api.getRegionApiForProject(userProject.get()).list().concat(),
+                            new Function<Region, URI>() {
+                               @Override
+                               public URI apply(Region input) {
+                                  return input.getSelfLink();
+                               }
+                            });
+                 }
+              },
+              seconds, TimeUnit.SECONDS);
+   }
+
+   @Provides
+   @Singleton
+   protected LoadingCache<NetworkAndAddressRange, Network> networkMap(
+           CacheLoader<NetworkAndAddressRange, Network> in) {
+      return CacheBuilder.newBuilder().build(in);
+   }
+
+   @Override
+   protected Optional<ImageExtension> provideImageExtension(Injector i) {
+      return Optional.absent();
+   }
+
+   @Override
+   protected Optional<SecurityGroupExtension> 
provideSecurityGroupExtension(Injector i) {
+      return Optional.of(i.getInstance(SecurityGroupExtension.class));
+   }
+
+   @VisibleForTesting
+   public static final Map<Instance.Status, NodeMetadata.Status> 
toPortableNodeStatus =
+           ImmutableMap.<Instance.Status, NodeMetadata.Status>builder()
+                   .put(Instance.Status.PROVISIONING, 
NodeMetadata.Status.PENDING)
+                   .put(Instance.Status.STAGING, NodeMetadata.Status.PENDING)
+                   .put(Instance.Status.RUNNING, NodeMetadata.Status.RUNNING)
+                   .put(Instance.Status.STOPPING, NodeMetadata.Status.PENDING)
+                   .put(Instance.Status.STOPPED, NodeMetadata.Status.SUSPENDED)
+                   .put(Instance.Status.TERMINATED, 
NodeMetadata.Status.TERMINATED).build();
+
+   @Singleton
+   @Provides
+   protected Map<Instance.Status, NodeMetadata.Status> toPortableNodeStatus() {
+      return toPortableNodeStatus;
+   }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/4203d59b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/extensions/GoogleComputeEngineSecurityGroupExtension.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/extensions/GoogleComputeEngineSecurityGroupExtension.java
 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/extensions/GoogleComputeEngineSecurityGroupExtension.java
new file mode 100644
index 0000000..f1113e0
--- /dev/null
+++ 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/extensions/GoogleComputeEngineSecurityGroupExtension.java
@@ -0,0 +1,338 @@
+/*
+ * 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.googlecomputeengine.compute.extensions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_INTERVAL;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_TIMEOUT;
+import static 
org.jclouds.googlecomputeengine.compute.strategy.CreateNodesWithGroupEncodedIntoNameThenAddToSet.DEFAULT_INTERNAL_NETWORK_RANGE;
+import static 
org.jclouds.googlecomputeengine.predicates.NetworkFirewallPredicates.equalsIpPermission;
+import static 
org.jclouds.googlecomputeengine.predicates.NetworkFirewallPredicates.providesIpPermission;
+import static org.jclouds.util.Predicates2.retry;
+
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
+import org.jclouds.compute.functions.GroupNamingConvention;
+import org.jclouds.domain.Location;
+import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import org.jclouds.googlecomputeengine.config.UserProject;
+import org.jclouds.googlecomputeengine.domain.Firewall;
+import org.jclouds.googlecomputeengine.domain.Instance;
+import org.jclouds.googlecomputeengine.domain.Instance.NetworkInterface;
+import org.jclouds.googlecomputeengine.domain.Network;
+import org.jclouds.googlecomputeengine.domain.Operation;
+import org.jclouds.googlecomputeengine.domain.SlashEncodedIds;
+import org.jclouds.googlecomputeengine.domain.internal.NetworkAndAddressRange;
+import org.jclouds.googlecomputeengine.options.FirewallOptions;
+import org.jclouds.googlecomputeengine.options.ListOptions;
+import org.jclouds.googlecomputeengine.options.ListOptions.Builder;
+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.Predicates;
+import com.google.common.base.Supplier;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Multimap;
+import com.google.common.util.concurrent.Atomics;
+
+/**
+ * An extension to compute service to allow for the manipulation of {@link 
org.jclouds.compute.domain.SecurityGroup}s. Implementation
+ * is optional by providers.
+ */
+public class GoogleComputeEngineSecurityGroupExtension implements 
SecurityGroupExtension {
+
+   protected final Supplier<String> userProject;
+   protected final GroupNamingConvention.Factory namingConvention;
+   protected final LoadingCache<NetworkAndAddressRange, Network> 
networkCreator;
+   protected final Function<Network, SecurityGroup> groupConverter;
+   protected final GoogleComputeEngineApi api;
+   protected final Predicate<AtomicReference<Operation>> 
operationDonePredicate;
+   protected final long operationCompleteCheckInterval;
+   protected final long operationCompleteCheckTimeout;
+
+   @Inject
+   public GoogleComputeEngineSecurityGroupExtension(GoogleComputeEngineApi api,
+                                                    @UserProject 
Supplier<String> userProject,
+                                                    
GroupNamingConvention.Factory namingConvention,
+                                                    
LoadingCache<NetworkAndAddressRange, Network> networkCreator,
+                                                    Function<Network, 
SecurityGroup> groupConverter,
+                                                    @Named("global") 
Predicate<AtomicReference<Operation>> operationDonePredicate,
+                                                    
@Named(OPERATION_COMPLETE_INTERVAL) Long operationCompleteCheckInterval,
+                                                    
@Named(OPERATION_COMPLETE_TIMEOUT) Long operationCompleteCheckTimeout) {
+      this.api = checkNotNull(api, "api");
+      this.userProject = checkNotNull(userProject, "userProject");
+      this.namingConvention = checkNotNull(namingConvention, 
"namingConvention");
+      this.networkCreator = checkNotNull(networkCreator, "networkCreator");
+      this.groupConverter = checkNotNull(groupConverter, "groupConverter");
+      this.operationCompleteCheckInterval = 
checkNotNull(operationCompleteCheckInterval,
+              "operation completed check interval");
+      this.operationCompleteCheckTimeout = 
checkNotNull(operationCompleteCheckTimeout,
+              "operation completed check timeout");
+      this.operationDonePredicate = checkNotNull(operationDonePredicate, 
"operationDonePredicate");
+   }
+
+   @Override
+   public Set<SecurityGroup> listSecurityGroups() {
+      return 
api.getNetworkApiForProject(userProject.get()).list().concat().transform(groupConverter).toSet();
+   }
+
+   @Override
+   public Set<SecurityGroup> listSecurityGroupsInLocation(final Location 
location) {
+      return listSecurityGroups();
+   }
+
+   @Override
+   public Set<SecurityGroup> listSecurityGroupsForNode(String id) {
+      SlashEncodedIds slashEncodedIds = SlashEncodedIds.fromSlashEncoded(id);
+
+      Instance instance = 
api.getInstanceApiForProject(userProject.get()).getInZone(slashEncodedIds.getFirstId(),
+              slashEncodedIds.getSecondId());
+
+      if (instance == null) {
+         return ImmutableSet.of();
+      }
+
+      ImmutableSet.Builder builder = ImmutableSet.builder();
+
+
+      for (NetworkInterface nwInterface : instance.getNetworkInterfaces()) {
+         String networkUrl = nwInterface.getNetwork().getPath();
+         Network nw = 
api.getNetworkApiForProject(userProject.get()).get(networkUrl.substring(networkUrl.lastIndexOf('/')
 + 1));
+
+         SecurityGroup grp = groupForTagsInNetwork(nw, 
instance.getTags().getItems());
+         if (grp != null) {
+            builder.add(grp);
+         }
+      }
+
+      return builder.build();
+   }
+
+   @Override
+   public SecurityGroup getSecurityGroupById(String id) {
+      checkNotNull(id, "id");
+      Network network = api.getNetworkApiForProject(userProject.get()).get(id);
+
+      if (network == null) {
+         return null;
+      }
+
+      return groupConverter.apply(network);
+   }
+
+   @Override
+   public SecurityGroup createSecurityGroup(String name, Location location) {
+      return createSecurityGroup(name);
+   }
+
+   public SecurityGroup createSecurityGroup(String name) {
+      checkNotNull(name, "name");
+
+      NetworkAndAddressRange nAr = new NetworkAndAddressRange(name, 
DEFAULT_INTERNAL_NETWORK_RANGE, null);
+
+      Network nw = networkCreator.apply(nAr);
+
+      return groupConverter.apply(nw);
+   }
+
+   @Override
+   public boolean removeSecurityGroup(String id) {
+      checkNotNull(id, "id");
+      if (api.getNetworkApiForProject(userProject.get()).get(id) == null) {
+         return false;
+      }
+
+      ListOptions options = new ListOptions.Builder().filter("network eq .*/" 
+ id);
+
+      FluentIterable<Firewall> fws = 
api.getFirewallApiForProject(userProject.get()).list(options).concat();
+
+      for (Firewall fw : fws) {
+         AtomicReference<Operation> operation = 
Atomics.newReference(api.getFirewallApiForProject(userProject.get())
+                 .delete(fw.getName()));
+
+         retry(operationDonePredicate, operationCompleteCheckTimeout, 
operationCompleteCheckInterval,
+                 MILLISECONDS).apply(operation);
+
+         checkState(!operation.get().getHttpError().isPresent(), "Could not 
delete firewall, operation failed" + operation);
+      }
+
+      AtomicReference<Operation> operation = Atomics.newReference(
+              api.getNetworkApiForProject(userProject.get()).delete(id));
+
+      retry(operationDonePredicate, operationCompleteCheckTimeout, 
operationCompleteCheckInterval,
+                 MILLISECONDS).apply(operation);
+
+      checkState(!operation.get().getHttpError().isPresent(), "Could not 
create network, operation failed" + operation);
+
+      return true;
+   }
+
+   @Override
+   public SecurityGroup addIpPermission(IpPermission ipPermission, 
SecurityGroup group) {
+      checkNotNull(group, "group");
+      checkNotNull(ipPermission, "ipPermission");
+
+      
checkNotNull(api.getNetworkApiForProject(userProject.get()).get(group.getId()) 
== null, "network for group is null");
+
+      ListOptions options = new ListOptions.Builder().filter("network eq .*/" 
+ group.getName());
+
+      if 
(api.getFirewallApiForProject(userProject.get()).list(options).concat().anyMatch(providesIpPermission(ipPermission)))
 {
+         // Permission already exists.
+         return group;
+      }
+
+      FirewallOptions fwOptions = new FirewallOptions();
+      String uniqueFwName = 
namingConvention.createWithoutPrefix().uniqueNameForGroup(group.getName());
+      fwOptions.name(uniqueFwName);
+      fwOptions.network(group.getUri());
+      if (!ipPermission.getGroupIds().isEmpty()) {
+         fwOptions.sourceTags(ipPermission.getGroupIds());
+      }
+      if (!ipPermission.getCidrBlocks().isEmpty()) {
+         fwOptions.sourceRanges(ipPermission.getCidrBlocks());
+      }
+      Firewall.Rule.Builder ruleBuilder = Firewall.Rule.builder();
+      ruleBuilder.IpProtocol(ipPermission.getIpProtocol());
+      if (ipPermission.getToPort() > 0) {
+         ruleBuilder.addPortRange(ipPermission.getFromPort(), 
ipPermission.getToPort());
+      }
+      fwOptions.addAllowedRule(ruleBuilder.build());
+
+      AtomicReference<Operation> operation = 
Atomics.newReference(api.getFirewallApiForProject(userProject
+              .get()).createInNetwork(
+              uniqueFwName,
+              group.getUri(),
+              fwOptions));
+
+      retry(operationDonePredicate, operationCompleteCheckTimeout, 
operationCompleteCheckInterval,
+              MILLISECONDS).apply(operation);
+
+      checkState(!operation.get().getHttpError().isPresent(), "Could not 
create firewall, operation failed" + operation);
+
+      return getSecurityGroupById(group.getId());
+   }
+
+   @Override
+   public SecurityGroup addIpPermission(IpProtocol protocol, int fromPort, int 
toPort,
+           Multimap<String, String> tenantIdGroupNamePairs, Iterable<String> 
cidrBlocks,
+           Iterable<String> groupIds, SecurityGroup group) {
+
+      IpPermission.Builder permBuilder = IpPermission.builder();
+      permBuilder.ipProtocol(protocol);
+      permBuilder.fromPort(fromPort);
+      permBuilder.toPort(toPort);
+      permBuilder.groupIds(groupIds);
+      permBuilder.cidrBlocks(cidrBlocks);
+
+      return addIpPermission(permBuilder.build(), group);
+
+   }
+
+   @Override
+   public SecurityGroup removeIpPermission(IpPermission ipPermission, 
SecurityGroup group) {
+      checkNotNull(group, "group");
+      checkNotNull(ipPermission, "ipPermission");
+
+      
checkNotNull(api.getNetworkApiForProject(userProject.get()).get(group.getId()) 
== null, "network for group is null");
+
+      ListOptions options = new ListOptions.Builder().filter("network eq .*/" 
+ group.getName());
+
+      FluentIterable<Firewall> fws = 
api.getFirewallApiForProject(userProject.get()).list(options).concat();
+
+      for (Firewall fw : fws) {
+         if (equalsIpPermission(ipPermission).apply(fw)) {
+            AtomicReference<Operation> operation = 
Atomics.newReference(api.getFirewallApiForProject(userProject.get())
+                    .delete(fw.getName()));
+
+            retry(operationDonePredicate, operationCompleteCheckTimeout, 
operationCompleteCheckInterval,
+                    MILLISECONDS).apply(operation);
+
+            checkState(!operation.get().getHttpError().isPresent(), "Could not 
delete firewall, operation failed" + operation);
+         }
+      }
+
+      return getSecurityGroupById(group.getId());
+   }
+
+   @Override
+   public SecurityGroup removeIpPermission(IpProtocol protocol, int fromPort, 
int toPort,
+                                        Multimap<String, String> 
tenantIdGroupNamePairs, Iterable<String> cidrBlocks,
+                                        Iterable<String> groupIds, 
SecurityGroup group) {
+
+      IpPermission.Builder permBuilder = IpPermission.builder();
+      permBuilder.ipProtocol(protocol);
+      permBuilder.fromPort(fromPort);
+      permBuilder.toPort(toPort);
+      permBuilder.groupIds(groupIds);
+      permBuilder.cidrBlocks(cidrBlocks);
+
+      return removeIpPermission(permBuilder.build(), group);
+
+   }
+
+   @Override
+   public boolean supportsTenantIdGroupNamePairs() {
+      return false;
+   }
+
+   @Override
+   public boolean supportsTenantIdGroupIdPairs() {
+      return false;
+   }
+
+   @Override
+   public boolean supportsGroupIds() {
+      return true;
+   }
+
+   @Override
+   public boolean supportsPortRangesForGroups() {
+      return true;
+   }
+
+   private SecurityGroup groupForTagsInNetwork(Network nw, final Set <String> 
tags) {
+      ListOptions opts = new Builder().filter("network eq .*/" + nw.getName());
+      Set<Firewall> fws = 
api.getFirewallApiForProject(userProject.get()).list(opts).concat()
+              .filter(new Predicate<Firewall>() {
+                 @Override
+                 public boolean apply(final Firewall input) {
+                    // If any of the targetTags on the firewall apply or the 
firewall has no target tags...
+                    return Iterables.any(input.getTargetTags(), 
Predicates.in(tags))
+                            || 
Predicates.equalTo(0).apply(input.getTargetTags().size());
+                 }
+              }).toSet();
+
+      if (fws.isEmpty()) {
+         return null;
+      }
+
+      return groupConverter.apply(nw);
+   }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/4203d59b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/BuildInstanceMetadata.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/BuildInstanceMetadata.java
 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/BuildInstanceMetadata.java
new file mode 100644
index 0000000..80b18b1
--- /dev/null
+++ 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/BuildInstanceMetadata.java
@@ -0,0 +1,46 @@
+/*
+ * 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.googlecomputeengine.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.lang.String.format;
+
+import javax.inject.Singleton;
+
+import org.jclouds.compute.options.TemplateOptions;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Prepares metadata from the provided TemplateOptions
+ */
+@Singleton
+public class BuildInstanceMetadata implements Function<TemplateOptions, 
ImmutableMap.Builder<String, String>> {
+
+   @Override
+   public ImmutableMap.Builder apply(TemplateOptions input) {
+      ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
+      if (input.getPublicKey() != null) {
+         builder.put("sshKeys", format("%s:%s %s@localhost", 
checkNotNull(input.getLoginUser(),
+                 "loginUser cannot be null"), input.getPublicKey(), 
input.getLoginUser()));
+      }
+      builder.putAll(input.getUserMetadata());
+      return builder;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/4203d59b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallTagNamingConvention.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallTagNamingConvention.java
 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallTagNamingConvention.java
new file mode 100644
index 0000000..1d2508b
--- /dev/null
+++ 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallTagNamingConvention.java
@@ -0,0 +1,62 @@
+/*
+ * 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.googlecomputeengine.compute.functions;
+
+import com.google.common.base.Predicate;
+import org.jclouds.compute.functions.GroupNamingConvention;
+
+import javax.inject.Inject;
+
+/**
+ * The convention for naming instance tags that firewall rules recognise.
+ */
+public class FirewallTagNamingConvention {
+
+   public static class Factory {
+
+      private final GroupNamingConvention.Factory namingConvention;
+
+      @Inject
+      public Factory(GroupNamingConvention.Factory namingConvention) {
+         this.namingConvention = namingConvention;
+      }
+
+      public FirewallTagNamingConvention get(String groupName) {
+         return new 
FirewallTagNamingConvention(namingConvention.create().sharedNameForGroup(groupName));
+      }
+   }
+
+   private final String sharedResourceName;
+
+   public FirewallTagNamingConvention(String sharedResourceName) {
+      this.sharedResourceName = sharedResourceName;
+   }
+
+   public String name(int port) {
+      return String.format("%s-port-%s", sharedResourceName, port);
+   }
+
+   public Predicate<? super String> isFirewallTag() {
+      return new Predicate<String>() {
+         @Override
+         public boolean apply(String input) {
+            return input != null && input.startsWith(sharedResourceName + 
"-port-");
+         }
+      };
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/4203d59b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermission.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermission.java
 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermission.java
new file mode 100644
index 0000000..ea069e0
--- /dev/null
+++ 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermission.java
@@ -0,0 +1,87 @@
+/*
+ * 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.googlecomputeengine.compute.functions;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.googlecomputeengine.domain.Firewall;
+import org.jclouds.googlecomputeengine.domain.Firewall.Rule;
+import org.jclouds.logging.Logger;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Range;
+
+/**
+ * A function for transforming a GCE-specific Firewall into a generic
+ * IpPermission object.
+ */
+public class FirewallToIpPermission implements Function<Firewall, 
Iterable<IpPermission>> {
+   @Resource
+   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+   protected Logger logger = Logger.NULL;
+
+   public FirewallToIpPermission() {
+   }
+
+
+   @Override
+   public Iterable<IpPermission> apply(Firewall fw) {
+      ImmutableSet.Builder setBuilder = ImmutableSet.builder();
+
+      for (Rule rule : fw.getAllowed()) {
+         if (!rule.getPorts().isEmpty()) {
+            for (Range<Integer> r : rule.getPorts().asRanges()) {
+               IpPermission.Builder builder = populateBuilder(fw, 
rule.getIpProtocol());
+               builder.fromPort(r.lowerEndpoint());
+               builder.toPort(r.upperEndpoint());
+               setBuilder.add(builder.build());
+            }
+         } else {
+            setBuilder.add(populateBuilder(fw, rule.getIpProtocol()).build());
+         }
+      }
+
+      return setBuilder.build();
+   }
+
+   /**
+    * Convenience method for populating common parts of the IpPermission.
+    * @param fw
+    * @param protocol
+    * @return a pre-populated builder.
+    */
+   private IpPermission.Builder populateBuilder(Firewall fw, IpProtocol 
protocol) {
+      IpPermission.Builder builder = IpPermission.builder();
+
+      builder.ipProtocol(protocol);
+
+      if (!fw.getSourceRanges().isEmpty()) {
+         builder.cidrBlocks(fw.getSourceRanges());
+      }
+      if (!fw.getSourceTags().isEmpty()) {
+         builder.groupIds(fw.getSourceTags());
+      }
+
+      return builder;
+   }
+}
+

http://git-wip-us.apache.org/repos/asf/stratos/blob/4203d59b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImage.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImage.java
 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImage.java
new file mode 100644
index 0000000..b783fc9
--- /dev/null
+++ 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImage.java
@@ -0,0 +1,80 @@
+/*
+ * 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.googlecomputeengine.compute.functions;
+
+import static com.google.common.base.Joiner.on;
+import static com.google.common.collect.Iterables.getLast;
+import static com.google.common.collect.Iterables.limit;
+import static com.google.common.collect.Iterables.skip;
+import static org.jclouds.compute.domain.Image.Status;
+
+import java.util.List;
+
+import org.jclouds.compute.domain.ImageBuilder;
+import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.googlecomputeengine.domain.Image;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+
+/**
+ * Transforms a google compute domain specific image to a generic Image object.
+ */
+public class GoogleComputeEngineImageToImage implements Function<Image, 
org.jclouds.compute.domain.Image> {
+
+
+   @Override
+   public org.jclouds.compute.domain.Image apply(Image image) {
+      ImageBuilder builder = new ImageBuilder()
+              .id(image.getName())
+              .name(image.getName())
+              .providerId(image.getId())
+              .description(image.getDescription().orNull())
+              .status(Status.AVAILABLE)
+              .uri(image.getSelfLink());
+
+      List<String> splits = Lists.newArrayList(image.getName().split("-"));
+      OperatingSystem.Builder osBuilder = defaultOperatingSystem(image);
+      if (splits == null || splits.size() == 0 || splits.size() < 3) {
+         return builder.operatingSystem(osBuilder.build()).build();
+      }
+
+      OsFamily family = OsFamily.fromValue(splits.get(0));
+      if (family != OsFamily.UNRECOGNIZED) {
+         osBuilder.family(family);
+      }
+
+      String version = on(".").join(limit(skip(splits, 1), splits.size() - 2));
+      osBuilder.version(version);
+
+      if (image.getDeprecated().isPresent()) {
+         builder.userMetadata(ImmutableMap.of("deprecatedState", 
image.getDeprecated().get().getState().orNull()));
+      }
+      builder.version(getLast(splits));
+      return builder.operatingSystem(osBuilder.build()).build();
+   }
+
+   private OperatingSystem.Builder defaultOperatingSystem(Image image) {
+      return OperatingSystem.builder()
+              .family(OsFamily.LINUX)
+              .is64Bit(true)
+              .description(image.getName());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/4203d59b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/InstanceInZoneToNodeMetadata.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/InstanceInZoneToNodeMetadata.java
 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/InstanceInZoneToNodeMetadata.java
new file mode 100644
index 0000000..c1ddea1
--- /dev/null
+++ 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/InstanceInZoneToNodeMetadata.java
@@ -0,0 +1,150 @@
+/*
+ * 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.googlecomputeengine.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.jclouds.compute.util.ComputeServiceUtils.groupFromMapOrName;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GCE_IMAGE_METADATA_KEY;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.NodeMetadataBuilder;
+import org.jclouds.compute.functions.GroupNamingConvention;
+import org.jclouds.domain.Location;
+import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import org.jclouds.googlecomputeengine.config.UserProject;
+import org.jclouds.googlecomputeengine.domain.Instance;
+import org.jclouds.googlecomputeengine.domain.InstanceInZone;
+import org.jclouds.googlecomputeengine.domain.SlashEncodedIds;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Transforms a google compute domain Instance into a generic NodeMetatada 
object.
+ */
+public class InstanceInZoneToNodeMetadata implements Function<InstanceInZone, 
NodeMetadata> {
+
+   private final Map<Instance.Status, NodeMetadata.Status> 
toPortableNodeStatus;
+   private final GroupNamingConvention nodeNamingConvention;
+   private final Supplier<Map<URI, ? extends Image>> images;
+   private final Supplier<Map<URI, ? extends Hardware>> hardwares;
+   private final Supplier<Map<URI, ? extends Location>> locations;
+   private final FirewallTagNamingConvention.Factory 
firewallTagNamingConvention;
+   private final GoogleComputeEngineApi api;
+   private final Supplier<String> userProject;
+
+   @Inject
+   public InstanceInZoneToNodeMetadata(Map<Instance.Status, 
NodeMetadata.Status> toPortableNodeStatus,
+                                 GroupNamingConvention.Factory 
namingConvention,
+                                 @Memoized Supplier<Map<URI, ? extends Image>> 
images,
+                                 @Memoized Supplier<Map<URI, ? extends 
Hardware>> hardwares,
+                                 @Memoized Supplier<Map<URI, ? extends 
Location>> locations,
+                                 FirewallTagNamingConvention.Factory 
firewallTagNamingConvention,
+                                 GoogleComputeEngineApi api,
+                                 @UserProject Supplier<String> userProject) {
+      this.toPortableNodeStatus = toPortableNodeStatus;
+      this.nodeNamingConvention = namingConvention.createWithoutPrefix();
+      this.images = images;
+      this.hardwares = hardwares;
+      this.locations = locations;
+      this.firewallTagNamingConvention = 
checkNotNull(firewallTagNamingConvention, "firewallTagNamingConvention");
+      this.api = checkNotNull(api, "api");
+      this.userProject = checkNotNull(userProject, "userProject");
+   }
+
+   @Override
+   public NodeMetadata apply(InstanceInZone instanceInZone) {
+      Instance input = instanceInZone.getInstance();
+
+      String group = groupFromMapOrName(input.getMetadata().getItems(),
+                                               input.getName(), 
nodeNamingConvention);
+      FluentIterable<String> tags = 
FluentIterable.from(input.getTags().getItems());
+      if (group != null) {
+         tags = 
tags.filter(Predicates.not(firewallTagNamingConvention.get(group).isFirewallTag()));
+      }
+
+      NodeMetadataBuilder builder = new NodeMetadataBuilder();
+
+      
builder.id(SlashEncodedIds.fromTwoIds(checkNotNull(locations.get().get(input.getZone()),
+                                                                "location for 
%s", input.getZone())
+                                                    .getId(), 
input.getName()).slashEncode())
+              .name(input.getName())
+              .providerId(input.getId())
+              .hostname(input.getName())
+              .location(checkNotNull(locations.get().get(input.getZone()), 
"location for %s", input.getZone()))
+              .hardware(hardwares.get().get(input.getMachineType()))
+              .status(toPortableNodeStatus.get(input.getStatus()))
+              .tags(tags)
+              .uri(input.getSelfLink())
+              .userMetadata(input.getMetadata().getItems())
+              .group(group)
+              .privateAddresses(collectPrivateAddresses(input))
+              .publicAddresses(collectPublicAddresses(input));
+
+      if (input.getMetadata().getItems().containsKey(GCE_IMAGE_METADATA_KEY)) {
+         try {
+            URI imageUri = URI.create(input.getMetadata().getItems()
+                                              .get(GCE_IMAGE_METADATA_KEY));
+
+            Map<URI, ? extends Image> imagesMap = images.get();
+
+            Image image = checkNotNull(imagesMap.get(imageUri),
+                                       "no image for %s. images: %s", imageUri,
+                                       imagesMap.values());
+            builder.imageId(image.getId());
+         } catch (IllegalArgumentException e) {
+            // Swallow any exception here - it just means we don't actually 
have a valid image URI, so we skip it.
+         }
+      }
+
+      return builder.build();
+   }
+
+   private Set<String> collectPrivateAddresses(Instance input) {
+      ImmutableSet.Builder<String> privateAddressesBuilder = 
ImmutableSet.builder();
+      for (Instance.NetworkInterface networkInterface : 
input.getNetworkInterfaces()) {
+         if (networkInterface.getNetworkIP().isPresent()) {
+            privateAddressesBuilder.add(networkInterface.getNetworkIP().get());
+         }
+      }
+      return privateAddressesBuilder.build();
+   }
+
+   private Set<String> collectPublicAddresses(Instance input) {
+      ImmutableSet.Builder<String> publicAddressesBuilder = 
ImmutableSet.builder();
+      for (Instance.NetworkInterface networkInterface : 
input.getNetworkInterfaces()) {
+         for (Instance.NetworkInterface.AccessConfig accessConfig : 
networkInterface.getAccessConfigs()) {
+            if (accessConfig.getNatIP().isPresent()) {
+               publicAddressesBuilder.add(accessConfig.getNatIP().get());
+            }
+         }
+      }
+      return publicAddressesBuilder.build();
+   }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/4203d59b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/MachineTypeInZoneToHardware.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/MachineTypeInZoneToHardware.java
 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/MachineTypeInZoneToHardware.java
new file mode 100644
index 0000000..16091cd
--- /dev/null
+++ 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/MachineTypeInZoneToHardware.java
@@ -0,0 +1,100 @@
+/*
+ * 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.googlecomputeengine.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.getOnlyElement;
+
+import java.net.URI;
+import java.util.Map;
+
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.HardwareBuilder;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.Processor;
+import org.jclouds.compute.domain.Volume;
+import org.jclouds.compute.domain.VolumeBuilder;
+import org.jclouds.domain.Location;
+import org.jclouds.googlecomputeengine.domain.MachineType;
+import org.jclouds.googlecomputeengine.domain.MachineTypeInZone;
+import org.jclouds.googlecomputeengine.domain.SlashEncodedIds;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Inject;
+
+/**
+ * Transforms a google compute domain specific machine type to a generic 
Hardware object.
+ */
+public class MachineTypeInZoneToHardware implements 
Function<MachineTypeInZone, Hardware> {
+
+   private final Supplier<Map<URI, ? extends Location>> locations;
+
+   @Inject
+   public MachineTypeInZoneToHardware(@Memoized Supplier<Map<URI, ? extends 
Location>> locations) {
+      this.locations = locations;
+   }
+
+   @Override
+   public Hardware apply(final MachineTypeInZone input) {
+      Iterable<? extends Location> zonesForMachineType = 
filter(locations.get().values(), new Predicate<Location>() {
+         @Override
+         public boolean apply(Location l) {
+            return l.getId().equals(input.getMachineType().getZone());
+         }
+      });
+
+      Location location = checkNotNull(getOnlyElement(zonesForMachineType),
+              "location for %s",
+              input.getMachineType().getZone());
+
+      // TODO Figure out a robust way to deal with machineTypes with 
imageSizeGb==0 rather than just blocking them.
+      return new HardwareBuilder()
+              .id(SlashEncodedIds.fromTwoIds(input.getMachineType().getZone(), 
input.getMachineType().getName()).slashEncode())
+              .location(location)
+              .name(input.getMachineType().getName())
+              .hypervisor("kvm")
+              .processor(new Processor(input.getMachineType().getGuestCpus(), 
1.0))
+              .providerId(input.getMachineType().getId())
+              .ram(input.getMachineType().getMemoryMb())
+              .uri(input.getMachineType().getSelfLink())
+              .userMetadata(ImmutableMap.of("imageSpaceGb", 
Integer.toString(input.getMachineType().getImageSpaceGb())))
+              .volumes(collectVolumes(input.getMachineType()))
+              .supportsImage(input.getMachineType().getImageSpaceGb() > 0
+                      ? Predicates.<Image>alwaysTrue()
+                      : Predicates.<Image>alwaysFalse())
+              .build();
+   }
+
+   private Iterable<Volume> collectVolumes(MachineType input) {
+      ImmutableSet.Builder<Volume> volumes = ImmutableSet.builder();
+      for (MachineType.ScratchDisk disk : input.getScratchDisks()) {
+         volumes.add(new VolumeBuilder()
+                 .type(Volume.Type.LOCAL)
+                 .size(new Integer(disk.getDiskGb()).floatValue())
+                 .bootDevice(true)
+                 .durable(false).build());
+      }
+      return volumes.build();
+   }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/4203d59b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroup.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroup.java
 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroup.java
new file mode 100644
index 0000000..1a9be54
--- /dev/null
+++ 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroup.java
@@ -0,0 +1,82 @@
+/*
+ * 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.googlecomputeengine.compute.functions;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.domain.SecurityGroupBuilder;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import org.jclouds.googlecomputeengine.config.UserProject;
+import org.jclouds.googlecomputeengine.domain.Firewall;
+import org.jclouds.googlecomputeengine.domain.Network;
+import org.jclouds.googlecomputeengine.options.ListOptions;
+import org.jclouds.logging.Logger;
+import org.jclouds.net.domain.IpPermission;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * A function for transforming a GCE-specific Network into a generic
+ * SecurityGroup object.
+ */
+public class NetworkToSecurityGroup implements Function<Network, 
SecurityGroup> {
+   @Resource
+   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+   protected Logger logger = Logger.NULL;
+
+   private final Function<Firewall, Iterable<IpPermission>> firewallToPerms;
+   private final GoogleComputeEngineApi api;
+   private final Supplier<String> project;
+
+   @Inject
+   public NetworkToSecurityGroup(Function<Firewall, Iterable<IpPermission>> 
firewallToPerms,
+                                 GoogleComputeEngineApi api,
+                                 @UserProject Supplier<String> project) {
+      this.firewallToPerms = firewallToPerms;
+      this.api = api;
+      this.project = project;
+   }
+
+   @Override
+   public SecurityGroup apply(Network network)  {
+      SecurityGroupBuilder builder = new SecurityGroupBuilder();
+
+      builder.id(network.getName());
+      builder.providerId(network.getId());
+      builder.name(network.getName());
+      builder.uri(network.getSelfLink());
+
+      ImmutableSet.Builder permBuilder = ImmutableSet.builder();
+
+      ListOptions options = new ListOptions.Builder().filter("network eq .*/" 
+ network.getName());
+
+      for (Firewall fw : 
api.getFirewallApiForProject(project.get()).list(options).concat()) {
+         permBuilder.addAll(firewallToPerms.apply(fw));
+      }
+
+      builder.ipPermissions(permBuilder.build());
+
+      return builder.build();
+   }
+}
+

http://git-wip-us.apache.org/repos/asf/stratos/blob/4203d59b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/OrphanedGroupsFromDeadNodes.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/OrphanedGroupsFromDeadNodes.java
 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/OrphanedGroupsFromDeadNodes.java
new file mode 100644
index 0000000..3301c8f
--- /dev/null
+++ 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/OrphanedGroupsFromDeadNodes.java
@@ -0,0 +1,57 @@
+/*
+ * 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.googlecomputeengine.compute.functions;
+
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.domain.NodeMetadata;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Sets;
+
+@Singleton
+public class OrphanedGroupsFromDeadNodes implements Function<Set<? extends 
NodeMetadata>, Set<String>> {
+
+   private final Predicate<String> isOrphanedGroupPredicate;
+
+   @Inject
+   public OrphanedGroupsFromDeadNodes(Predicate<String> 
isOrphanedGroupPredicate) {
+      this.isOrphanedGroupPredicate = isOrphanedGroupPredicate;
+   }
+
+
+   @Override
+   public Set<String> apply(Set<? extends NodeMetadata> deadNodes) {
+      Set<String> groups = Sets.newLinkedHashSet();
+      for (NodeMetadata deadNode : deadNodes) {
+         groups.add(deadNode.getGroup());
+      }
+      Set<String> orphanedGroups = Sets.newLinkedHashSet();
+      for (String group : groups) {
+         if (isOrphanedGroupPredicate.apply(group)) {
+            orphanedGroups.add(group);
+         }
+      }
+      return orphanedGroups;
+   }
+
+
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/4203d59b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/RegionToLocation.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/RegionToLocation.java
 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/RegionToLocation.java
new file mode 100644
index 0000000..2f880de
--- /dev/null
+++ 
b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/RegionToLocation.java
@@ -0,0 +1,45 @@
+/*
+ * 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.googlecomputeengine.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GOOGLE_PROVIDER_LOCATION;
+
+import org.jclouds.domain.Location;
+import org.jclouds.domain.LocationBuilder;
+import org.jclouds.domain.LocationScope;
+import org.jclouds.googlecomputeengine.domain.Region;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Transforms a google compute domain specific region to a generic Region 
object.
+ */
+public class RegionToLocation implements Function<Region, Location> {
+
+   @Override
+   public Location apply(Region input) {
+      return new LocationBuilder()
+              .description(input.getDescription().orNull())
+              .metadata(ImmutableMap.of("selfLink", (Object) 
checkNotNull(input.getSelfLink(), "region URI")))
+              .id(input.getName())
+              .scope(LocationScope.REGION)
+              .parent(GOOGLE_PROVIDER_LOCATION)
+              .build();
+   }
+}

Reply via email to