You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ad...@apache.org on 2014/11/04 00:21:34 UTC

[13/14] JCLOUDS-750 Convert GoogleComputeEngine to AutoValue + general cleanup.

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/b41b0d04/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/CreateNetworkIfNeeded.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/CreateNetworkIfNeeded.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/CreateNetworkIfNeeded.java
new file mode 100644
index 0000000..b797b95
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/CreateNetworkIfNeeded.java
@@ -0,0 +1,97 @@
+/*
+ * 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.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.util.Predicates2.retry;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import org.jclouds.googlecomputeengine.compute.domain.NetworkAndAddressRange;
+import org.jclouds.googlecomputeengine.config.UserProject;
+import org.jclouds.googlecomputeengine.domain.Network;
+import org.jclouds.googlecomputeengine.domain.Operation;
+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.util.concurrent.Atomics;
+
+public class CreateNetworkIfNeeded implements Function<NetworkAndAddressRange, Network> {
+   @Resource @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+   private Logger logger = Logger.NULL;
+
+   private final GoogleComputeEngineApi api;
+   private final Supplier<String> userProject;
+   private final Predicate<AtomicReference<Operation>> operationDonePredicate;
+   private final long operationCompleteCheckInterval;
+   private final long operationCompleteCheckTimeout;
+
+   @Inject CreateNetworkIfNeeded(GoogleComputeEngineApi api, @UserProject Supplier<String> userProject,
+         @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.operationCompleteCheckInterval = checkNotNull(operationCompleteCheckInterval,
+            "operation completed check interval");
+      this.operationCompleteCheckTimeout = checkNotNull(operationCompleteCheckTimeout,
+            "operation completed check timeout");
+      this.operationDonePredicate = checkNotNull(operationDonePredicate, "operationDonePredicate");
+   }
+
+   @Override
+   public Network apply(NetworkAndAddressRange input) {
+      checkNotNull(input, "input");
+
+      Network nw = api.getNetworkApi(userProject.get()).get(input.name());
+      if (nw != null) {
+         return nw;
+      }
+
+      if (input.gateway() != null) {
+         AtomicReference<Operation> operation = Atomics.newReference(api.getNetworkApi(userProject.get())
+               .createInIPv4RangeWithGateway(input.name(), input.rangeIPv4(), input.gateway()));
+         retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval, MILLISECONDS)
+               .apply(operation);
+
+         checkState(operation.get().httpErrorStatusCode() == null,
+               "Could not insert network, operation failed" + operation);
+      } else {
+         AtomicReference<Operation> operation = Atomics
+               .newReference(api.getNetworkApi(userProject.get()).createInIPv4Range(input.name(), input.rangeIPv4()));
+         retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval, MILLISECONDS)
+               .apply(operation);
+
+         checkState(operation.get().httpErrorStatusCode() == null,
+               "Could not insert network, operation failed" + operation);
+      }
+      return checkNotNull(api.getNetworkApi(userProject.get()).get(input.name()), "no network with name %s was found",
+            input.name());
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/b41b0d04/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FindNetworkOrCreate.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FindNetworkOrCreate.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FindNetworkOrCreate.java
new file mode 100644
index 0000000..2f4c7a4
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FindNetworkOrCreate.java
@@ -0,0 +1,50 @@
+/*
+ * 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.inject.Inject;
+
+import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import org.jclouds.googlecomputeengine.compute.domain.NetworkAndAddressRange;
+import org.jclouds.googlecomputeengine.config.UserProject;
+import org.jclouds.googlecomputeengine.domain.Network;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.common.cache.CacheLoader;
+
+public final class FindNetworkOrCreate extends CacheLoader<NetworkAndAddressRange, Network> {
+   private final GoogleComputeEngineApi api;
+   private final Function<NetworkAndAddressRange, Network> networkCreator;
+   private final Supplier<String> userProject;
+
+   @Inject FindNetworkOrCreate(GoogleComputeEngineApi api, Function<NetworkAndAddressRange, Network> networkCreator,
+         @UserProject Supplier<String> userProject) {
+      this.api = api;
+      this.networkCreator = networkCreator;
+      this.userProject = userProject;
+   }
+
+   @Override public Network load(NetworkAndAddressRange in) {
+      Network network = api.getNetworkApi(userProject.get()).get(in.name());
+      if (network != null) {
+         return network;
+      } else {
+         return networkCreator.apply(in);
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/b41b0d04/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallTagNamingConvention.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallTagNamingConvention.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallTagNamingConvention.java
index 1d2508b..51e331b 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallTagNamingConvention.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallTagNamingConvention.java
@@ -16,10 +16,11 @@
  */
 package org.jclouds.googlecomputeengine.compute.functions;
 
-import com.google.common.base.Predicate;
+import javax.inject.Inject;
+
 import org.jclouds.compute.functions.GroupNamingConvention;
 
-import javax.inject.Inject;
+import com.google.common.base.Predicate;
 
 /**
  * The convention for naming instance tags that firewall rules recognise.

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/b41b0d04/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermission.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermission.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermission.java
index ea069e0..4f58402 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermission.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermission.java
@@ -16,69 +16,49 @@
  */
 package org.jclouds.googlecomputeengine.compute.functions;
 
-import javax.annotation.Resource;
-import javax.inject.Named;
+import java.util.List;
 
-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;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
 
-/**
- * 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();
+public final class FirewallToIpPermission implements Function<Firewall, Iterable<IpPermission>> {
+   @Override public Iterable<IpPermission> apply(Firewall fw) {
+      ImmutableList.Builder<IpPermission> rules = ImmutableList.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());
+      for (Rule rule : fw.allowed()) {
+         if (rule.ports() != null && !rule.ports().isEmpty()) {
+            for (String r : rule.ports()) {
+               IpPermission.Builder builder = populateBuilder(fw, rule.ipProtocol());
+               List<String> range = Splitter.on('-').splitToList(r);
+               int from = Integer.valueOf(range.get(0));
+               builder.fromPort(from);
+               builder.toPort(range.size() == 2 ? Integer.valueOf(range.get(1)) : from);
+               rules.add(builder.build());
             }
          } else {
-            setBuilder.add(populateBuilder(fw, rule.getIpProtocol()).build());
+            rules.add(populateBuilder(fw, rule.ipProtocol()).build());
          }
       }
 
-      return setBuilder.build();
+      return rules.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) {
+   private static IpPermission.Builder populateBuilder(Firewall fw, String protocol) {
       IpPermission.Builder builder = IpPermission.builder();
 
-      builder.ipProtocol(protocol);
+      builder.ipProtocol(IpProtocol.fromValue(protocol.toUpperCase()));
 
-      if (!fw.getSourceRanges().isEmpty()) {
-         builder.cidrBlocks(fw.getSourceRanges());
+      if (!fw.sourceRanges().isEmpty()) {
+         builder.cidrBlocks(fw.sourceRanges());
       }
-      if (!fw.getSourceTags().isEmpty()) {
-         builder.groupIds(fw.getSourceTags());
+      if (!fw.sourceTags().isEmpty()) {
+         builder.groupIds(fw.sourceTags());
       }
 
       return builder;

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/b41b0d04/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImage.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImage.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImage.java
index b783fc9..41b34bc 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImage.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImage.java
@@ -33,23 +33,17 @@ 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) {
+public final 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())
+              .id(image.name())
+              .name(image.name())
+              .providerId(image.id())
+              .description(image.description())
               .status(Status.AVAILABLE)
-              .uri(image.getSelfLink());
+              .uri(image.selfLink());
 
-      List<String> splits = Lists.newArrayList(image.getName().split("-"));
+      List<String> splits = Lists.newArrayList(image.name().split("-"));
       OperatingSystem.Builder osBuilder = defaultOperatingSystem(image);
       if (splits == null || splits.size() == 0 || splits.size() < 3) {
          return builder.operatingSystem(osBuilder.build()).build();
@@ -63,18 +57,14 @@ public class GoogleComputeEngineImageToImage implements Function<Image, org.jclo
       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()));
+      if (image.deprecated() != null) {
+         builder.userMetadata(ImmutableMap.of("deprecatedState", image.deprecated().state()));
       }
       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());
+      return OperatingSystem.builder().family(OsFamily.LINUX).is64Bit(true).description(image.name());
    }
-
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/b41b0d04/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/InstanceInZoneToNodeMetadata.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/InstanceInZoneToNodeMetadata.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/InstanceInZoneToNodeMetadata.java
index c1ddea1..11897a0 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/InstanceInZoneToNodeMetadata.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/InstanceInZoneToNodeMetadata.java
@@ -21,8 +21,8 @@ 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.List;
 import java.util.Map;
-import java.util.Set;
 
 import javax.inject.Inject;
 
@@ -33,22 +33,20 @@ 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.compute.domain.InstanceInZone;
+import org.jclouds.googlecomputeengine.compute.domain.SlashEncodedIds;
 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;
+import com.google.common.collect.ImmutableList;
 
 /**
  * Transforms a google compute domain Instance into a generic NodeMetatada object.
  */
-public class InstanceInZoneToNodeMetadata implements Function<InstanceInZone, NodeMetadata> {
+public final class InstanceInZoneToNodeMetadata implements Function<InstanceInZone, NodeMetadata> {
 
    private final Map<Instance.Status, NodeMetadata.Status> toPortableNodeStatus;
    private final GroupNamingConvention nodeNamingConvention;
@@ -56,60 +54,52 @@ public class InstanceInZoneToNodeMetadata implements Function<InstanceInZone, No
    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,
+   @Inject 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) {
+                                 FirewallTagNamingConvention.Factory firewallTagNamingConvention) {
       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) {
+   @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());
+      String group = groupFromMapOrName(input.metadata().items(),
+                                               input.name(), nodeNamingConvention);
+      FluentIterable<String> tags = FluentIterable.from(input.tags().items());
       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()))
+      builder.id(SlashEncodedIds.fromTwoIds(checkNotNull(locations.get().get(input.zone()),
+                                                                "location for %s", input.zone())
+                                                    .getId(), input.name()).slashEncode())
+              .name(input.name())
+              .providerId(input.id())
+              .hostname(input.name())
+              .location(checkNotNull(locations.get().get(input.zone()), "location for %s", input.zone()))
+              .hardware(hardwares.get().get(input.machineType()))
+              .status(toPortableNodeStatus.get(input.status()))
               .tags(tags)
-              .uri(input.getSelfLink())
-              .userMetadata(input.getMetadata().getItems())
+              .uri(input.selfLink())
+              .userMetadata(input.metadata().items())
               .group(group)
               .privateAddresses(collectPrivateAddresses(input))
               .publicAddresses(collectPublicAddresses(input));
 
-      if (input.getMetadata().getItems().containsKey(GCE_IMAGE_METADATA_KEY)) {
+      if (input.metadata().items().containsKey(GCE_IMAGE_METADATA_KEY)) {
          try {
-            URI imageUri = URI.create(input.getMetadata().getItems()
+            URI imageUri = URI.create(input.metadata().items()
                                               .get(GCE_IMAGE_METADATA_KEY));
 
             Map<URI, ? extends Image> imagesMap = images.get();
@@ -126,22 +116,22 @@ public class InstanceInZoneToNodeMetadata implements Function<InstanceInZone, No
       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());
+   private List<String> collectPrivateAddresses(Instance input) {
+      ImmutableList.Builder<String> privateAddressesBuilder = ImmutableList.builder();
+      for (Instance.NetworkInterface networkInterface : input.networkInterfaces()) {
+         if (networkInterface.networkIP() != null) {
+            privateAddressesBuilder.add(networkInterface.networkIP());
          }
       }
       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());
+   private List<String> collectPublicAddresses(Instance input) {
+      ImmutableList.Builder<String> publicAddressesBuilder = ImmutableList.builder();
+      for (Instance.NetworkInterface networkInterface : input.networkInterfaces()) {
+         for (Instance.NetworkInterface.AccessConfig accessConfig : networkInterface.accessConfigs()) {
+            if (accessConfig.natIP() != null) {
+               publicAddressesBuilder.add(accessConfig.natIP());
             }
          }
       }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/b41b0d04/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/MachineTypeInZoneToHardware.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/MachineTypeInZoneToHardware.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/MachineTypeInZoneToHardware.java
index 08ba6d5..b17fb23 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/MachineTypeInZoneToHardware.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/MachineTypeInZoneToHardware.java
@@ -31,9 +31,9 @@ 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.compute.domain.MachineTypeInZone;
+import org.jclouds.googlecomputeengine.compute.domain.SlashEncodedIds;
 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;
@@ -59,34 +59,34 @@ public class MachineTypeInZoneToHardware implements Function<MachineTypeInZone,
       Iterable<? extends Location> zonesForMachineType = filter(locations.get().values(), new Predicate<Location>() {
          @Override
          public boolean apply(Location l) {
-            return l.getId().equals(input.getMachineType().getZone());
+            return l.getId().equals(input.machineType().zone());
          }
       });
 
       Location location = checkNotNull(getOnlyElement(zonesForMachineType),
               "location for %s",
-              input.getMachineType().getZone());
+              input.machineType().zone());
 
       return new HardwareBuilder()
-              .id(SlashEncodedIds.fromTwoIds(input.getMachineType().getZone(), input.getMachineType().getName()).slashEncode())
+              .id(SlashEncodedIds.fromTwoIds(input.machineType().zone(), input.machineType().name()).slashEncode())
               .location(location)
-              .name(input.getMachineType().getName())
+              .name(input.machineType().name())
               .hypervisor("kvm")
-              .processor(new Processor(input.getMachineType().getGuestCpus(), 1.0))
-              .providerId(input.getMachineType().getId())
-              .ram(input.getMachineType().getMemoryMb())
-              .uri(input.getMachineType().getSelfLink())
-              .volumes(collectVolumes(input.getMachineType()))
+              .processor(new Processor(input.machineType().guestCpus(), 1.0))
+              .providerId(input.machineType().id())
+              .ram(input.machineType().memoryMb())
+              .uri(input.machineType().selfLink())
+              .volumes(collectVolumes(input.machineType()))
               .supportsImage(Predicates.<Image>alwaysTrue())
               .build();
    }
 
    private Iterable<Volume> collectVolumes(MachineType input) {
       ImmutableSet.Builder<Volume> volumes = ImmutableSet.builder();
-      for (MachineType.ScratchDisk disk : input.getScratchDisks()) {
+      for (MachineType.ScratchDisk disk : input.scratchDisks()) {
          volumes.add(new VolumeBuilder()
                  .type(Volume.Type.LOCAL)
-                 .size(Integer.valueOf(disk.getDiskGb()).floatValue())
+                 .size(Float.valueOf(disk.diskGb()))
                  .bootDevice(true)
                  .durable(false).build());
       }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/b41b0d04/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroup.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroup.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroup.java
index 790f233..8747b44 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroup.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroup.java
@@ -61,14 +61,14 @@ public class NetworkToSecurityGroup implements Function<Network, SecurityGroup>
    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());
+      builder.id(network.name());
+      builder.providerId(network.id());
+      builder.name(network.name());
+      builder.uri(network.selfLink());
 
       ImmutableSet.Builder permBuilder = ImmutableSet.builder();
 
-      ListOptions options = new ListOptions.Builder().filter("network eq .*/" + network.getName());
+      ListOptions options = new ListOptions.Builder().filter("network eq .*/" + network.name());
 
       for (Firewall fw : api.getFirewallApi(project.get()).list(options).concat()) {
          permBuilder.addAll(firewallToPerms.apply(fw));

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/b41b0d04/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/RegionToLocation.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/RegionToLocation.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/RegionToLocation.java
index 2f880de..bd2613f 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/RegionToLocation.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/RegionToLocation.java
@@ -35,9 +35,9 @@ 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())
+              .description(input.description())
+              .metadata(ImmutableMap.of("selfLink", (Object) checkNotNull(input.selfLink(), "region URI")))
+              .id(input.name())
               .scope(LocationScope.REGION)
               .parent(GOOGLE_PROVIDER_LOCATION)
               .build();

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/b41b0d04/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/ZoneToLocation.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/ZoneToLocation.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/ZoneToLocation.java
index 0dc1c78..b4455b9 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/ZoneToLocation.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/ZoneToLocation.java
@@ -35,9 +35,9 @@ public class ZoneToLocation implements Function<Zone, Location> {
    @Override
    public Location apply(Zone input) {
       return new LocationBuilder()
-              .description(input.getDescription().orNull())
-              .metadata(ImmutableMap.of("selfLink", (Object) checkNotNull(input.getSelfLink(), "zone URI")))
-              .id(input.getName())
+              .description(input.description())
+              .metadata(ImmutableMap.of("selfLink", (Object) checkNotNull(input.selfLink(), "zone URI")))
+              .id(input.name())
               .scope(LocationScope.ZONE)
               .parent(GOOGLE_PROVIDER_LOCATION)
               .build();

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/b41b0d04/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/loaders/FindNetworkOrCreate.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/loaders/FindNetworkOrCreate.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/loaders/FindNetworkOrCreate.java
deleted file mode 100644
index a849178..0000000
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/loaders/FindNetworkOrCreate.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.googlecomputeengine.compute.loaders;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import javax.annotation.Resource;
-import javax.inject.Inject;
-import javax.inject.Named;
-
-import org.jclouds.compute.reference.ComputeServiceConstants;
-import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
-import org.jclouds.googlecomputeengine.config.UserProject;
-import org.jclouds.googlecomputeengine.domain.Network;
-import org.jclouds.googlecomputeengine.domain.internal.NetworkAndAddressRange;
-import org.jclouds.logging.Logger;
-
-import com.google.common.base.Function;
-import com.google.common.base.Supplier;
-import com.google.common.cache.CacheLoader;
-
-public class FindNetworkOrCreate extends CacheLoader<NetworkAndAddressRange, Network> {
-   @Resource
-   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
-   protected Logger logger = Logger.NULL;
-   protected final GoogleComputeEngineApi api;
-   protected final Function<NetworkAndAddressRange, Network> networkCreator;
-   protected final Supplier<String> userProject;
-
-   @Inject
-   public FindNetworkOrCreate(GoogleComputeEngineApi api,
-                              Function<NetworkAndAddressRange, Network> networkCreator,
-                              @UserProject Supplier<String> userProject) {
-      this.api = checkNotNull(api, "api");
-      this.networkCreator = checkNotNull(networkCreator, "networkCreator");
-      this.userProject = checkNotNull(userProject, "userProject");
-   }
-
-   @Override
-   public Network load(NetworkAndAddressRange in) {
-      Network network = api.getNetworkApi(userProject.get()).get(in.getName());
-      if (network != null) {
-         return network;
-      } else {
-         return networkCreator.apply(in);
-      }
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/b41b0d04/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/options/GoogleComputeEngineTemplateOptions.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/options/GoogleComputeEngineTemplateOptions.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/options/GoogleComputeEngineTemplateOptions.java
index c6aad00..9bb670f 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/options/GoogleComputeEngineTemplateOptions.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/options/GoogleComputeEngineTemplateOptions.java
@@ -20,18 +20,18 @@ import static com.google.common.base.Optional.fromNullable;
 import static org.jclouds.googlecomputeengine.domain.Instance.ServiceAccount;
 
 import java.net.URI;
+import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import org.jclouds.compute.options.TemplateOptions;
 import org.jclouds.domain.LoginCredentials;
 import org.jclouds.googlecomputeengine.domain.Instance;
-import org.jclouds.googlecomputeengine.domain.InstanceTemplate.PersistentDisk;
+import org.jclouds.googlecomputeengine.domain.templates.InstanceTemplate.PersistentDisk;
 import org.jclouds.scriptbuilder.domain.Statement;
 
 import com.google.common.base.Optional;
 import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
+import com.google.common.collect.Lists;
 
 /**
  * Instance options specific to Google Compute Engine.
@@ -39,10 +39,9 @@ import com.google.common.collect.Sets;
 public class GoogleComputeEngineTemplateOptions extends TemplateOptions {
 
    private Optional<URI> network = Optional.absent();
-   private Optional<String> networkName = Optional.absent();
-   private Set<Instance.ServiceAccount> serviceAccounts = Sets.newLinkedHashSet();
+   private List<Instance.ServiceAccount> serviceAccounts = Lists.newArrayList();
    private boolean enableNat = true;
-   private Set<PersistentDisk> disks = Sets.newLinkedHashSet();
+   private List<PersistentDisk> disks = Lists.newArrayList();
    private Optional<Long> bootDiskSize = Optional.absent();
    private boolean keepBootDisk = false;
 
@@ -96,14 +95,14 @@ public class GoogleComputeEngineTemplateOptions extends TemplateOptions {
     * @see #getServiceAccounts()
     * @see ServiceAccount
     */
-   public GoogleComputeEngineTemplateOptions serviceAccounts(Set<ServiceAccount> serviceAccounts) {
-      this.serviceAccounts = Sets.newLinkedHashSet(serviceAccounts);
+   public GoogleComputeEngineTemplateOptions serviceAccounts(List<ServiceAccount> serviceAccounts) {
+      this.serviceAccounts = Lists.newArrayList(serviceAccounts);
       return this;
    }
 
    /**
     * @see #getDisks()
-    * @see org.jclouds.googlecomputeengine.domain.InstanceTemplate.PersistentDisk
+    * @see org.jclouds.googlecomputeengine.domain.templates.InstanceTemplate.PersistentDisk
     */
    public GoogleComputeEngineTemplateOptions addDisk(PersistentDisk disk) {
       this.disks.add(disk);
@@ -112,10 +111,10 @@ public class GoogleComputeEngineTemplateOptions extends TemplateOptions {
 
    /**
     * @see #getDisks()
-    * @see org.jclouds.googlecomputeengine.domain.InstanceTemplate.PersistentDisk
+    * @see org.jclouds.googlecomputeengine.domain.templates.InstanceTemplate.PersistentDisk
     */
-   public GoogleComputeEngineTemplateOptions disks(Set<PersistentDisk> disks) {
-      this.disks = Sets.newLinkedHashSet(disks);
+   public GoogleComputeEngineTemplateOptions disks(List<PersistentDisk> disks) {
+      this.disks = Lists.newArrayList(disks);
       return this;
    }
 
@@ -330,14 +329,14 @@ public class GoogleComputeEngineTemplateOptions extends TemplateOptions {
    /**
     * @return the ServiceAccounts to enable in the instances.
     */
-   public Set<Instance.ServiceAccount> getServiceAccounts() {
+   public List<Instance.ServiceAccount> getServiceAccounts() {
       return serviceAccounts;
    }
 
    /**
     * @return the PersistentDisks for this instance.
     */
-   public Set<PersistentDisk> getDisks() {
+   public List<PersistentDisk> getDisks() {
       return disks;
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/b41b0d04/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java
index 622bc84..b2ba892 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java
@@ -16,14 +16,14 @@
  */
 package org.jclouds.googlecomputeengine.compute.strategy;
 
-import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
-import static com.google.common.collect.ImmutableSet.of;
+import static com.google.common.collect.ImmutableList.of;
 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.util.Predicates2.retry;
 
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
@@ -41,22 +41,23 @@ import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
 import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
 import org.jclouds.compute.strategy.ListNodesStrategy;
 import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import org.jclouds.googlecomputeengine.compute.domain.NetworkAndAddressRange;
 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.Firewall;
+import org.jclouds.googlecomputeengine.domain.Firewall.Rule;
 import org.jclouds.googlecomputeengine.domain.Network;
 import org.jclouds.googlecomputeengine.domain.Operation;
-import org.jclouds.googlecomputeengine.domain.internal.NetworkAndAddressRange;
 import org.jclouds.googlecomputeengine.features.FirewallApi;
 import org.jclouds.googlecomputeengine.options.FirewallOptions;
 
 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.ImmutableList;
+import com.google.common.collect.Lists;
 import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
 import com.google.common.util.concurrent.Atomics;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
@@ -75,8 +76,7 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
    private final long operationCompleteCheckTimeout;
    private final FirewallTagNamingConvention.Factory firewallTagNamingConvention;
 
-   @Inject
-   protected CreateNodesWithGroupEncodedIntoNameThenAddToSet(
+   @Inject CreateNodesWithGroupEncodedIntoNameThenAddToSet(
            CreateNodeWithGroupEncodedIntoName addNodeWithGroupStrategy,
            ListNodesStrategy listNodesStrategy,
            GroupNamingConvention.Factory namingConvention,
@@ -93,19 +93,16 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
            FirewallTagNamingConvention.Factory firewallTagNamingConvention) {
       super(addNodeWithGroupStrategy, listNodesStrategy, namingConvention, userExecutor,
               customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory);
-
-      this.api = checkNotNull(api, "google compute api");
-      this.userProject = checkNotNull(userProject, "user project name");
-      this.operationCompleteCheckInterval = checkNotNull(operationCompleteCheckInterval,
-              "operation completed check interval");
-      this.operationCompleteCheckTimeout = checkNotNull(operationCompleteCheckTimeout,
-              "operation completed check timeout");
-      this.operationDonePredicate = checkNotNull(operationDonePredicate, "operationDonePredicate");
-      this.networkMap = checkNotNull(networkMap, "networkMap");
-      this.firewallTagNamingConvention = checkNotNull(firewallTagNamingConvention, "firewallTagNamingConvention");
+      this.api = api;
+      this.userProject = userProject;
+      this.operationCompleteCheckInterval = operationCompleteCheckInterval;
+      this.operationCompleteCheckTimeout = operationCompleteCheckTimeout;
+      this.operationDonePredicate = operationDonePredicate;
+      this.networkMap = networkMap;
+      this.firewallTagNamingConvention = firewallTagNamingConvention;
    }
 
-   @Override
+   @Override // TODO: why synchronized?
    public synchronized Map<?, ListenableFuture<Void>> execute(String group, int count,
                                                               Template template,
                                                               Set<NodeMetadata> goodNodes,
@@ -121,7 +118,7 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
       // get or insert the network and insert a firewall with the users configuration
       Network network = getOrCreateNetwork(templateOptions, sharedResourceName);
       getOrCreateFirewalls(templateOptions, network, firewallTagNamingConvention.get(group));
-      templateOptions.network(network.getSelfLink());
+      templateOptions.network(network.selfLink());
       templateOptions.userMetadata(ComputeServiceConstants.NODE_GROUP_KEY, group);
 
       return super.execute(group, count, mutableTemplate, goodNodes, badNodes, customizationResponses);
@@ -134,7 +131,7 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
 
       String networkName = templateOptions.getNetworkName().or(sharedResourceName);
 
-      return networkMap.apply(new NetworkAndAddressRange(networkName, DEFAULT_INTERNAL_NETWORK_RANGE, null));
+      return networkMap.apply(NetworkAndAddressRange.create(networkName, DEFAULT_INTERNAL_NETWORK_RANGE, null));
    }
 
    /**
@@ -150,24 +147,24 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
 
       String projectName = userProject.get();
       FirewallApi firewallApi = api.getFirewallApi(projectName);
-      Set<AtomicReference<Operation>> operations = Sets.newLinkedHashSet();
-
+      List<AtomicReference<Operation>> operations = Lists.newArrayList();
 
       for (Integer port : templateOptions.getInboundPorts()) {
          String name = naming.name(port);
          Firewall firewall = firewallApi.get(name);
          if (firewall == null) {
-            ImmutableSet<Firewall.Rule> rules = ImmutableSet.of(Firewall.Rule.permitTcpRule(port), Firewall.Rule.permitUdpRule(port));
+            List<String> ports = ImmutableList.of(String.valueOf(port));
+            List<Rule> rules = ImmutableList.of(Rule.create("tcp", ports), Rule.create("udp", ports));
             FirewallOptions firewallOptions = new FirewallOptions()
                     .name(name)
-                    .network(network.getSelfLink())
+                    .network(network.selfLink())
                     .allowedRules(rules)
                     .sourceTags(templateOptions.getTags())
                     .sourceRanges(of(DEFAULT_INTERNAL_NETWORK_RANGE, EXTERIOR_RANGE))
-                    .targetTags(ImmutableSet.of(name));
+                    .targetTags(ImmutableList.of(name));
             AtomicReference<Operation> operation = Atomics.newReference(firewallApi.createInNetwork(
-                    firewallOptions.getName(),
-                    network.getSelfLink(),
+                    firewallOptions.name(),
+                    network.selfLink(),
                     firewallOptions));
             operations.add(operation);
          }
@@ -176,7 +173,7 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
       for (AtomicReference<Operation> operation : operations) {
          retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval,
                  MILLISECONDS).apply(operation);
-         checkState(!operation.get().getHttpError().isPresent(),
+         checkState(operation.get().httpErrorStatusCode() == null,
                "Could not insert firewall, operation failed" + operation);
       }
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/b41b0d04/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineHttpApiModule.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineHttpApiModule.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineHttpApiModule.java
index 2a1b3f2..d63f175 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineHttpApiModule.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineHttpApiModule.java
@@ -29,9 +29,9 @@ import javax.inject.Singleton;
 
 import org.jclouds.domain.Credentials;
 import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import org.jclouds.googlecomputeengine.compute.domain.SlashEncodedIds;
 import org.jclouds.googlecomputeengine.domain.Operation;
 import org.jclouds.googlecomputeengine.domain.Project;
-import org.jclouds.googlecomputeengine.domain.SlashEncodedIds;
 import org.jclouds.googlecomputeengine.handlers.GoogleComputeEngineErrorHandler;
 import org.jclouds.googlecomputeengine.predicates.GlobalOperationDonePredicate;
 import org.jclouds.googlecomputeengine.predicates.RegionOperationDonePredicate;
@@ -112,7 +112,7 @@ public class GoogleComputeEngineHttpApiModule extends HttpApiModule<GoogleComput
                        }
                     }
                     Project project = api.getProjectApi().get(projectName);
-                    return project.getName();
+                    return project.name();
                  }
               }, creds), seconds, TimeUnit.SECONDS);
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/b41b0d04/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineParserModule.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineParserModule.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineParserModule.java
index e42cbc7..c0a7883 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineParserModule.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineParserModule.java
@@ -18,42 +18,38 @@ package org.jclouds.googlecomputeengine.config;
 
 import static org.jclouds.googlecomputeengine.domain.Firewall.Rule;
 
-import java.beans.ConstructorProperties;
+import java.io.IOException;
 import java.lang.reflect.Type;
-import java.net.URI;
-import java.util.Date;
 import java.util.Map;
 import java.util.Set;
 
 import javax.inject.Singleton;
 
 import org.jclouds.googlecomputeengine.domain.Firewall;
-import org.jclouds.googlecomputeengine.domain.Instance;
-import org.jclouds.googlecomputeengine.domain.InstanceTemplate;
 import org.jclouds.googlecomputeengine.domain.Metadata;
-import org.jclouds.googlecomputeengine.domain.Operation;
-import org.jclouds.googlecomputeengine.domain.Project;
-import org.jclouds.googlecomputeengine.domain.Quota;
+import org.jclouds.googlecomputeengine.domain.templates.InstanceTemplate;
 import org.jclouds.googlecomputeengine.options.FirewallOptions;
 import org.jclouds.googlecomputeengine.options.RouteOptions;
 import org.jclouds.json.config.GsonModule;
-import org.jclouds.net.domain.IpProtocol;
 
 import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Range;
+import com.google.common.collect.ImmutableSet;
+import com.google.gson.Gson;
 import com.google.gson.JsonArray;
-import com.google.gson.JsonDeserializationContext;
-import com.google.gson.JsonDeserializer;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
-import com.google.gson.JsonParseException;
 import com.google.gson.JsonPrimitive;
 import com.google.gson.JsonSerializationContext;
 import com.google.gson.JsonSerializer;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
 import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
 
-public class GoogleComputeEngineParserModule extends AbstractModule {
+public final class GoogleComputeEngineParserModule extends AbstractModule {
 
    @Override protected void configure() {
       bind(GsonModule.DateAdapter.class).to(GsonModule.Iso8601DateAdapter.class);
@@ -61,89 +57,37 @@ public class GoogleComputeEngineParserModule extends AbstractModule {
 
    @Provides @Singleton public Map<Type, Object> typeAdapters() {
       return new ImmutableMap.Builder<Type, Object>()
-              .put(Metadata.class, new MetadataTypeAdapter())
-              .put(Operation.class, new OperationTypeAdapter())
-              .put(Project.class, new ProjectTypeAdapter())
-              .put(Instance.class, new InstanceTypeAdapter())
-              .put(InstanceTemplate.class, new InstanceTemplateTypeAdapter())
-              .put(FirewallOptions.class, new FirewallOptionsTypeAdapter())
-              .put(RouteOptions.class, new RouteOptionsTypeAdapter())
-              .put(Rule.class, new RuleTypeAdapter())
-              .build();
+            .put(InstanceTemplate.class, new InstanceTemplateTypeAdapter())
+            .put(FirewallOptions.class, new FirewallOptionsTypeAdapter())
+            .put(RouteOptions.class, new RouteOptionsTypeAdapter()).build();
    }
 
-   /**
-    * Parser for operations that unwraps errors avoiding an extra intermediate object.
-    *
-    * @see <a href="https://developers.google.com/compute/docs/reference/v1/operations"/>
-    */
-   private static class OperationTypeAdapter implements JsonDeserializer<Operation> {
-
-      @Override
-      public Operation deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws
-              JsonParseException {
-         Operation.Builder operationBuilder = ((Operation) context.deserialize(json,
-                 OperationInternal.class)).toBuilder();
-         JsonObject error = json.getAsJsonObject().getAsJsonObject("error");
-         if (error != null) {
-            JsonArray array = error.getAsJsonArray("errors");
-            if (array != null) {
-               for (JsonElement element : array) {
-                  operationBuilder.addError((Operation.Error) context.deserialize(element, Operation.Error.class));
-               }
-            }
-         }
-         return operationBuilder.build();
-      }
-
-      private static class OperationInternal extends Operation {
-         @ConstructorProperties({
-                 "id", "creationTimestamp", "selfLink", "name", "description", "targetLink", "targetId",
-                 "clientOperationId", "status", "statusMessage", "user", "progress", "insertTime", "startTime",
-                 "endTime", "httpErrorStatusCode", "httpErrorMessage", "operationType", "region", "zone"
-         })
-         private OperationInternal(String id, Date creationTimestamp, URI selfLink, String name,
-                                   String description, URI targetLink, String targetId, String clientOperationId,
-                                   Status status, String statusMessage, String user, int progress, Date insertTime,
-                                   Date startTime, Date endTime, int httpErrorStatusCode, String httpErrorMessage,
-                                   String operationType, URI region, URI zone) {
-            super(id, creationTimestamp, selfLink, name, description, targetLink, targetId, clientOperationId,
-                    status, statusMessage, user, progress, insertTime, startTime, endTime, httpErrorStatusCode,
-                    httpErrorMessage, operationType, null, region, zone);
-         }
-      }
+   // TODO: change jclouds core to use collaborative set bindings
+   @Provides @Singleton public Set<TypeAdapterFactory> typeAdapterFactories() {
+      return ImmutableSet.<TypeAdapterFactory>of(new MetadataTypeAdapter());
    }
 
    private static class InstanceTemplateTypeAdapter implements JsonSerializer<InstanceTemplate> {
 
-      @Override
-      public JsonElement serialize(InstanceTemplate src, Type typeOfSrc, JsonSerializationContext context) {
+      @Override public JsonElement serialize(InstanceTemplate src, Type typeOfSrc, JsonSerializationContext context) {
          InstanceTemplateInternal template = new InstanceTemplateInternal(src);
          JsonObject instance = (JsonObject) context.serialize(template, InstanceTemplateInternal.class);
 
          // deal with network
          JsonArray networkInterfaces = new JsonArray();
-         for (InstanceTemplate.NetworkInterface networkInterface : template.getNetworkInterfaces()){
+         for (InstanceTemplate.NetworkInterface networkInterface : template.networkInterfaces()) {
             networkInterfaces.add(context.serialize(networkInterface, InstanceTemplate.NetworkInterface.class));
          }
          instance.add("networkInterfaces", networkInterfaces);
 
          // deal with persistent disks
-         if (src.getDisks() != null && !src.getDisks().isEmpty()) {
-            JsonArray disks = new JsonArray();
-            for (InstanceTemplate.PersistentDisk persistentDisk : src.getDisks()) {
-               JsonObject disk = (JsonObject) context.serialize(persistentDisk, InstanceTemplate.PersistentDisk.class);
-               disk.addProperty("type", "PERSISTENT");
-               disks.add(disk);
-            }
-            instance.add("disks", disks);
+         if (!src.disks().isEmpty()) {
+            instance.add("disks", context.serialize(src.disks()));
          }
 
          // deal with metadata
-         if (src.getMetadata() != null && !src.getMetadata().isEmpty()) {
-            Metadata metadata = Metadata.builder()
-                    .items(src.getMetadata())
-                    .build();
+         if (!src.metadata().isEmpty()) {
+            Metadata metadata = Metadata.create(null, src.metadata());
             JsonObject metadataJson = (JsonObject) context.serialize(metadata);
             instance.add("metadata", metadataJson);
             return instance;
@@ -154,142 +98,95 @@ public class GoogleComputeEngineParserModule extends AbstractModule {
 
       private static class InstanceTemplateInternal extends InstanceTemplate {
          private InstanceTemplateInternal(InstanceTemplate template) {
-            super(template.getMachineType());
-            name(template.getName());
-            description(template.getDescription());
-            image(template.getImage());
-            serviceAccounts(template.getServiceAccounts());
-            networkInterfaces(template.getNetworkInterfaces());
+            machineType(template.machineType());
+            name(template.name());
+            description(template.description());
+            image(template.image());
+            serviceAccounts(template.serviceAccounts());
+            networkInterfaces(template.networkInterfaces());
          }
       }
    }
 
-   private static class InstanceTypeAdapter implements JsonDeserializer<Instance> {
+   private static class MetadataTypeAdapter extends SubtypeAdapterFactory<Metadata> {
 
-      @Override
-      public Instance deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws
-              JsonParseException {
-         Instance.Builder instanceBuilder = ((Instance) context.deserialize(json,
-                 InstanceInternal.class)).toBuilder();
-         JsonObject object = (JsonObject) json;
-         if (object.get("disks") != null) {
-            JsonArray disks = (JsonArray) object.get("disks");
-            for (JsonElement element : disks) {
-               JsonObject disk = (JsonObject) element;
-               if (disk.get("type").getAsString().equals("PERSISTENT")) {
-                  instanceBuilder.addDisk((Instance.PersistentAttachedDisk) context.deserialize(disk,
-                          Instance.PersistentAttachedDisk.class));
-               } else {
-                  instanceBuilder.addDisk((Instance.AttachedDisk) context.deserialize(disk,
-                          Instance.AttachedDisk.class));
-               }
-            }
-
-         }
-
-         return Instance.builder().fromInstance(instanceBuilder.build()).build();
+      private MetadataTypeAdapter() {
+         super(Metadata.class);
       }
 
-
-      private static class InstanceInternal extends Instance {
-         @ConstructorProperties({
-                 "id", "creationTimestamp", "selfLink", "name", "description", "tags", "machineType",
-                 "status", "statusMessage", "zone", "networkInterfaces", "metadata", "serviceAccounts"
-         })
-         private InstanceInternal(String id, Date creationTimestamp, URI selfLink, String name, String description,
-                                  Tags tags, URI machineType, Status status, String statusMessage,
-                                  URI zone, Set<NetworkInterface> networkInterfaces, Metadata metadata,
-                                  Set<ServiceAccount> serviceAccounts) {
-            super(id, creationTimestamp, selfLink, name, description, tags, machineType,
-                    status, statusMessage, zone, networkInterfaces, null, metadata, serviceAccounts);
+      @Override public void write(JsonWriter out, Metadata src) throws IOException {
+         out.beginObject();
+         out.name("kind").value("compute#metadata");
+         out.name("items");
+         out.beginArray();
+         for (Map.Entry<String, String> entry : src.items().entrySet()) {
+            out.beginObject();
+            out.name("key").value(entry.getKey());
+            out.name("value").value(entry.getValue());
+            out.endObject();
+         }
+         out.endArray();
+         if (src.fingerprint() != null) {
+            out.name("fingerprint").value(src.fingerprint());
          }
+         out.endObject();
       }
-   }
-
-   private static class MetadataTypeAdapter implements JsonDeserializer<Metadata>, JsonSerializer<Metadata> {
 
-      @Override
-      public Metadata deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws
-              JsonParseException {
+      @Override public Metadata read(JsonReader in) throws IOException {
+         String fingerprint = null;
          ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
-         JsonObject metadata = json.getAsJsonObject();
-         JsonArray items = metadata.getAsJsonArray("items");
-         if (items != null) {
-            for (JsonElement element : items) {
-               JsonObject object = element.getAsJsonObject();
-               builder.put(object.get("key").getAsString(), object.get("value").getAsString());
+         in.beginObject();
+         while (in.hasNext()) {
+            String name = in.nextName();
+            if (name.equals("items")) {
+               in.beginArray();
+               while (in.hasNext()) {
+                  in.beginObject();
+                  String key = null;
+                  String value = null;
+                  while (in.hasNext()) {
+                     name = in.nextName();
+                     if (name.equals("key")) {
+                        key = in.nextString();
+                     } else if (name.equals("value")) {
+                        value = in.nextString();
+                     } else {
+                        in.skipValue();
+                     }
+                  }
+                  builder.put(key, value);
+                  in.endObject();
+               }
+               in.endArray();
+            } else if (name.equals("fingerprint")) {
+               fingerprint = in.nextString();
+            } else {
+               in.skipValue();
             }
          }
-         String fingerprint = null;
-         if (metadata.getAsJsonPrimitive("fingerprint") != null) {
-            fingerprint = metadata.getAsJsonPrimitive("fingerprint").getAsString();
-         } else {
-            fingerprint = "";
-         }
-         return new Metadata(fingerprint, builder.build());
-      }
-
-      @Override
-      public JsonElement serialize(Metadata src, Type typeOfSrc, JsonSerializationContext context) {
-         JsonObject metadataObject = new JsonObject();
-         metadataObject.add("kind", new JsonPrimitive("compute#metadata"));
-         JsonArray items = new JsonArray();
-         for (Map.Entry<String, String> entry : src.getItems().entrySet()) {
-            JsonObject object = new JsonObject();
-            object.addProperty("key", entry.getKey());
-            object.addProperty("value", entry.getValue());
-            items.add(object);
-         }
-         metadataObject.add("items", items);
-         if (src.getFingerprint() != null) {
-            metadataObject.addProperty("fingerprint", src.getFingerprint());
-         }
-         return metadataObject;
-      }
-   }
-
-   private static class ProjectTypeAdapter implements JsonDeserializer<Project> {
-
-      @Override
-      public Project deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws
-              JsonParseException {
-         return Project.builder().fromProject((Project) context.deserialize(json, ProjectInternal.class)).build();
-      }
-
-      private static class ProjectInternal extends Project {
-
-         @ConstructorProperties({
-                 "id", "creationTimestamp", "selfLink", "name", "description", "commonInstanceMetadata", "quotas",
-                 "externalIpAddresses"
-         })
-         private ProjectInternal(String id, Date creationTimestamp, URI selfLink, String name, String description,
-                                 Metadata commonInstanceMetadata, Set<Quota> quotas, Set<String> externalIpAddresses) {
-            super(id, creationTimestamp, selfLink, name, description, commonInstanceMetadata, quotas,
-                    externalIpAddresses);
-         }
-
+         in.endObject();
+         return Metadata.create(fingerprint, builder.build());
       }
    }
 
    private static class FirewallOptionsTypeAdapter implements JsonSerializer<FirewallOptions> {
 
-      @Override
-      public JsonElement serialize(FirewallOptions src, Type typeOfSrc, JsonSerializationContext context) {
+      @Override public JsonElement serialize(FirewallOptions src, Type typeOfSrc, JsonSerializationContext context) {
          JsonObject firewall = new JsonObject();
-         if (src.getName() != null) {
-            firewall.addProperty("name", src.getName());
+         if (src.name() != null) {
+            firewall.addProperty("name", src.name());
          }
-         if (src.getNetwork() != null) {
-            firewall.addProperty("network", src.getNetwork().toString());
+         if (src.network() != null) {
+            firewall.addProperty("network", src.network().toString());
          }
-         if (!src.getSourceRanges().isEmpty()) {
-            firewall.add("sourceRanges", buildArrayOfStrings(src.getSourceRanges()));
+         if (!src.sourceRanges().isEmpty()) {
+            firewall.add("sourceRanges", buildArrayOfStrings(src.sourceRanges()));
          }
-         if (!src.getSourceTags().isEmpty()) {
-            firewall.add("sourceTags", buildArrayOfStrings(src.getSourceTags()));
+         if (!src.sourceTags().isEmpty()) {
+            firewall.add("sourceTags", buildArrayOfStrings(src.sourceTags()));
          }
-         if (!src.getTargetTags().isEmpty()) {
-            firewall.add("targetTags", buildArrayOfStrings(src.getTargetTags()));
+         if (!src.targetTags().isEmpty()) {
+            firewall.add("targetTags", buildArrayOfStrings(src.targetTags()));
          }
          if (!src.getAllowed().isEmpty()) {
             JsonArray rules = new JsonArray();
@@ -304,11 +201,10 @@ public class GoogleComputeEngineParserModule extends AbstractModule {
 
    private static class RouteOptionsTypeAdapter implements JsonSerializer<RouteOptions> {
 
-      @Override
-      public JsonElement serialize(RouteOptions src, Type typeOfSrc, JsonSerializationContext context) {
+      @Override public JsonElement serialize(RouteOptions src, Type typeOfSrc, JsonSerializationContext context) {
          JsonObject route = new JsonObject();
-         if (src.getName() != null) {
-            route.addProperty("name", src.getName());
+         if (src.name() != null) {
+            route.addProperty("name", src.name());
          }
          if (src.getNetwork() != null) {
             route.addProperty("network", src.getNetwork().toString());
@@ -341,7 +237,7 @@ public class GoogleComputeEngineParserModule extends AbstractModule {
       }
    }
 
-   private static JsonArray buildArrayOfStrings(Set<String> strings) {
+   private static JsonArray buildArrayOfStrings(Iterable<String> strings) {
       JsonArray array = new JsonArray();
       for (String string : strings) {
          array.add(new JsonPrimitive(string));
@@ -349,43 +245,18 @@ public class GoogleComputeEngineParserModule extends AbstractModule {
       return array;
    }
 
+   private abstract static class SubtypeAdapterFactory<T> extends TypeAdapter<T> implements TypeAdapterFactory {
+      private final Class<T> baseClass;
 
-   private static class RuleTypeAdapter implements JsonDeserializer<Firewall.Rule>, JsonSerializer<Firewall.Rule> {
-
-      @Override
-      public Firewall.Rule deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws
-              JsonParseException {
-         JsonObject rule = json.getAsJsonObject();
-         Rule.Builder builder = Rule.builder();
-         builder.IpProtocol(IpProtocol.fromValue(rule.get("IPProtocol").getAsString()));
-         if (rule.get("ports") != null) {
-            JsonArray ports = (JsonArray) rule.get("ports");
-            for (JsonElement port : ports) {
-               String portAsString = port.getAsString();
-               if (portAsString.contains("-")) {
-                  String[] split = portAsString.split("-");
-                  builder.addPortRange(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
-               } else {
-                  builder.addPort(Integer.parseInt(portAsString));
-               }
-            }
-         }
-         return builder.build();
+      private SubtypeAdapterFactory(Class<T> baseClass) {
+         this.baseClass = baseClass;
       }
 
-      @Override
-      public JsonElement serialize(Firewall.Rule src, Type typeOfSrc, JsonSerializationContext context) {
-         JsonObject ruleObject = new JsonObject();
-         ruleObject.addProperty("IPProtocol", src.getIpProtocol().value());
-         if (src.getPorts() != null && !src.getPorts().isEmpty()) {
-            JsonArray ports = new JsonArray();
-            for (Range<Integer> range : src.getPorts().asRanges()) {
-               ports.add(new JsonPrimitive(range.lowerEndpoint() == range.upperEndpoint() ? range.lowerEndpoint() + "" :
-                       range.lowerEndpoint() + "-" + range.upperEndpoint()));
-            }
-            ruleObject.add("ports", ports);
+      @Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
+         if (!(baseClass.isAssignableFrom(typeToken.getRawType()))) {
+            return null;
          }
-         return ruleObject;
+         return (TypeAdapter<T>) this;
       }
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/b41b0d04/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/AbstractDisk.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/AbstractDisk.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/AbstractDisk.java
deleted file mode 100644
index e4b7986..0000000
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/AbstractDisk.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.googlecomputeengine.domain;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.net.URI;
-import java.util.Date;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Objects;
-
-/**
- * A persistent disk resource
- */
-@Beta
-public abstract class AbstractDisk extends Resource {
-
-   protected final Integer sizeGb;
-   protected final String status;
-
-   protected AbstractDisk(Kind kind, String id, Date creationTimestamp, URI selfLink, String name, String description,
-                        Integer sizeGb, String status) {
-      super(kind, id, creationTimestamp, selfLink, name, description);
-      this.sizeGb = checkNotNull(sizeGb, "sizeGb of %s", name);
-      this.status = checkNotNull(status, "status of %s", name);
-   }
-
-   /**
-    * @return size of the persistent disk, specified in GB.
-    */
-   public int getSizeGb() {
-      return sizeGb;
-   }
-
-   /**
-    * @return the status of disk creation.
-    */
-   public String getStatus() {
-      return status;
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   protected Objects.ToStringHelper string() {
-      return super.string()
-              .omitNullValues()
-              .add("sizeGb", sizeGb)
-              .add("status", status);
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   public String toString() {
-      return string().toString();
-   }
-
-   public static Builder<?> builder() {
-      return new ConcreteBuilder();
-   }
-
-   public Builder<?> toBuilder() {
-      return new ConcreteBuilder().fromAbstractDisk(this);
-   }
-
-   public abstract static class Builder<T extends Builder<T>> extends Resource.Builder<T> {
-
-      protected Integer sizeGb;
-      protected String status;
-
-      /**
-       * @see org.jclouds.googlecomputeengine.domain.AbstractDisk#getSizeGb()
-       */
-      public T sizeGb(Integer sizeGb) {
-         this.sizeGb = sizeGb;
-         return self();
-      }
-
-      /**
-       * @see org.jclouds.googlecomputeengine.domain.AbstractDisk#getStatus()
-       */
-      public T status(String status) {
-         this.status = status;
-         return self();
-      }
-
-      public T fromAbstractDisk(AbstractDisk in) {
-         return super.fromResource(in)
-                 .sizeGb(in.getSizeGb())
-                 .status(in.getStatus());
-      }
-
-   }
-
-   private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
-      @Override
-      protected ConcreteBuilder self() {
-         return this;
-      }
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/b41b0d04/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Address.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Address.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Address.java
index 9b0d083..1dea66f 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Address.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Address.java
@@ -16,162 +16,46 @@
  */
 package org.jclouds.googlecomputeengine.domain;
 
-import java.beans.ConstructorProperties;
 import java.net.URI;
-import java.util.Date;
 
-import com.google.common.annotations.Beta;
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.json.SerializedNames;
 
-import static com.google.common.base.Objects.equal;
-import static com.google.common.base.Optional.fromNullable;
-import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.auto.value.AutoValue;
 
-/**
- * Represents an Address resource.
- */
-@Beta
-public final class Address extends Resource {
+@AutoValue
+public abstract class Address {
 
-   private final String status;
-   private final Optional<URI> user;
-   private final URI region;
-   private final String address;
+   public abstract String id();
 
-   @ConstructorProperties({
-           "id", "creationTimestamp", "selfLink", "name", "description", "status", "user",
-           "region", "address"
-   })
-   private Address(String id, Date creationTimestamp, URI selfLink, String name, String description,
-                   String status, URI user, URI region, String address) {
-      super(Kind.ADDRESS, id, creationTimestamp, selfLink, name, description);
-      this.status = checkNotNull(status, "status of %s", name);
-      this.user = fromNullable(user);
-      this.region = checkNotNull(region, "region of %s", name);
-      this.address = checkNotNull(address, "address of %s", name);
-   }
+   public abstract URI selfLink();
 
-   /**
-    * @return The status of the address. Valid items are RESERVED and IN USE.
-    *   A reserved address is currently available to the project and can be
-    *   used by a resource. An in-use address is currently being used by a resource.
-    */
-   public String getStatus() {
-      return status;
-   }
-
-   /**
-    * @return URL of the resource currently using this address.
-    */
-   public Optional<URI> getUser() {
-      return user;
-   }
+   public abstract String name();
 
-   /**
-    * @return URL of the region where the address resides.
-    */
-   public URI getRegion() {
-      return region;
-   }
+   @Nullable public abstract String description();
 
    /**
-    * @return The IP address represented by this resource.
+    * The status of the address. Valid items are RESERVED and IN USE.
+    * A reserved address is currently available to the project and can be
+    * used by a resource. An in-use address is currently being used by a resource.
     */
-   public String getAddress() {
-      return address;
-   }
+   public abstract String status(); // TODO: enum
 
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   public boolean equals(Object obj) {
-      if (this == obj) return true;
-      if (obj == null || getClass() != obj.getClass()) return false;
-      Address that = Address.class.cast(obj);
-      return equal(this.kind, that.kind)
-              && equal(this.name, that.name)
-              && equal(this.region, that.region);
-   }
+   /** URL of the resource currently using this address. */
+   @Nullable public abstract URI user();
 
-   /**
-    * {@inheritDoc}
-    */
-   @SuppressWarnings("deprecation")
-   @Override
-   protected Objects.ToStringHelper string() {
-      return super.string()
-              .omitNullValues()
-              .add("status", status)
-              .add("user", user.orNull())
-              .add("region", region)
-              .add("address", address);
-   }
+   /** URL of the region where the address resides. */
+   public abstract URI region();
 
-   public static Builder builder() {
-      return new Builder();
-   }
+   /** The IP address represented by this resource. */
+   public abstract String address();
 
-   public Builder toBuilder() {
-      return new Builder().fromAddress(this);
+   @SerializedNames({ "id", "selfLink", "name", "description", "status", "user", "region", "address" })
+   public static Address create(String id, URI selfLink, String name, String description, String status, URI user,
+         URI region, String address) {
+      return new AutoValue_Address(id, selfLink, name, description, status, user, region, address);
    }
 
-   public static final class Builder extends Resource.Builder<Builder> {
-      private String status;
-      private URI user;
-      private URI region;
-      private String address;
-
-      /**
-       * @see org.jclouds.googlecomputeengine.domain.Address#getStatus()
-       */
-      public Builder status(String status) {
-         this.status = status;
-         return this;
-      }
-
-      /**
-       * @see org.jclouds.googlecomputeengine.domain.Address#getUser()
-       */
-      public Builder user(URI user) {
-         this.user = user;
-         return this;
-      }
-
-      /**
-       * @see org.jclouds.googlecomputeengine.domain.Address#getRegion()
-       */
-      public Builder region(URI region) {
-         this.region = region;
-         return this;
-      }
-
-      /**
-       * @see org.jclouds.googlecomputeengine.domain.Address#getAddress()
-       */
-      public Builder address(String address) {
-         this.address = address;
-         return this;
-      }
-
-      @Override
-      protected Builder self() {
-         return this;
-      }
-
-      public Address build() {
-         return new Address(super.id, super.creationTimestamp, super.selfLink, super.name,
-                 super.description, status, user, region, address);
-      }
-
-      public Builder fromAddress(Address in) {
-         return super.fromResource(in)
-                 .status(in.getStatus())
-                 .user(in.getUser().orNull())
-                 .region(in.getRegion())
-                 .address(in.getAddress());
-      }
+   Address() {
    }
-
 }