You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ab...@apache.org on 2013/09/06 19:39:58 UTC

[09/11] JCLOUDS-209. Move to GCE v1beta15 API, with new features/methods included

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/InstanceInZone.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/InstanceInZone.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/InstanceInZone.java
new file mode 100644
index 0000000..18f8e5b
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/InstanceInZone.java
@@ -0,0 +1,55 @@
+/*
+ * 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.Objects.equal;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * @author Adam Lowe
+ */
+public class InstanceInZone extends SlashEncodedIds {
+   protected final Instance instance;
+
+   public InstanceInZone(Instance instance, String zoneId) {
+      super(zoneId, checkNotNull(instance, "instance").getName());
+      this.instance = instance;
+   }
+
+   public Instance getInstance() {
+      return instance;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) return true;
+      if (obj == null || getClass() != obj.getClass()) return false;
+      InstanceInZone that = InstanceInZone.class.cast(obj);
+      return equal(this.instance, that.instance)
+              && equal(this.firstId, that.firstId)
+              && equal(this.secondId, that.secondId);
+   }
+
+   @Override
+   public String toString() {
+      return "[instance=" + instance + ", zoneId=" + firstId + "]";
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/InstanceTemplate.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/InstanceTemplate.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/InstanceTemplate.java
index de93d7c..a8d52c2 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/InstanceTemplate.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/InstanceTemplate.java
@@ -16,18 +16,18 @@
  */
 package org.jclouds.googlecomputeengine.domain;
 
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
+import static com.google.common.base.Objects.equal;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.jclouds.googlecomputeengine.domain.Instance.NetworkInterface.AccessConfig.Type;
 
 import java.net.URI;
 import java.util.Map;
 import java.util.Set;
 
-import static com.google.common.base.Objects.equal;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.jclouds.googlecomputeengine.domain.Instance.NetworkInterface.AccessConfig.Type;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
 
 /**
  * Optional information for creating an instance.
@@ -39,16 +39,13 @@ public class InstanceTemplate {
    protected String name;
    protected String description;
    protected URI machineType;
-   protected URI zone;
    protected URI image;
-   protected Set<String> tags = Sets.newLinkedHashSet();
    protected Set<Instance.ServiceAccount> serviceAccounts = Sets.newLinkedHashSet();
 
    protected transient Set<PersistentDisk> disks = Sets.newLinkedHashSet();
    protected transient Set<NetworkInterface> networkInterfaces = Sets.newLinkedHashSet();
    protected transient Map<String, String> metadata = Maps.newLinkedHashMap();
    protected transient String machineTypeName;
-   protected transient String zoneName;
 
 
    protected InstanceTemplate(URI machineType) {
@@ -100,39 +97,6 @@ public class InstanceTemplate {
    }
 
    /**
-    * @see org.jclouds.googlecomputeengine.domain.Instance#getZone()
-    */
-   public InstanceTemplate zone(String zoneName) {
-      this.zoneName = zoneName;
-      return this;
-   }
-
-   /**
-    * @see org.jclouds.googlecomputeengine.domain.Instance#getZone()
-    */
-   public InstanceTemplate zone(URI zone) {
-      this.zone = zone;
-      return this;
-   }
-
-   /**
-    * @see org.jclouds.googlecomputeengine.domain.Instance#getTags()
-    */
-   public InstanceTemplate addTag(String tag) {
-      this.tags.add(checkNotNull(tag, "tag"));
-      return this;
-   }
-
-   /**
-    * @see org.jclouds.googlecomputeengine.domain.Instance#getTags()
-    */
-   public InstanceTemplate tags(Set<String> tags) {
-      this.tags = Sets.newLinkedHashSet();
-      this.tags.addAll(checkNotNull(tags, "tags"));
-      return this;
-   }
-
-   /**
     * @see org.jclouds.googlecomputeengine.domain.Instance#getDisks()
     */
    public InstanceTemplate addDisk(PersistentDisk.Mode mode, URI source) {
@@ -161,7 +125,7 @@ public class InstanceTemplate {
     * @see org.jclouds.googlecomputeengine.domain.Instance#getNetworkInterfaces()
     */
    public InstanceTemplate addNetworkInterface(URI network) {
-      this.networkInterfaces.add(new NetworkInterface(checkNotNull(network, "network"), null,null));
+      this.networkInterfaces.add(new NetworkInterface(checkNotNull(network, "network"), null, null));
       return this;
    }
 
@@ -281,33 +245,12 @@ public class InstanceTemplate {
    }
 
    /**
-    * @see org.jclouds.googlecomputeengine.domain.Instance#getTags()
-    */
-   public Set<String> getTags() {
-      return tags;
-   }
-
-   /**
     * @see org.jclouds.googlecomputeengine.domain.Instance#getName()
     */
    public String getName() {
       return name;
    }
 
-   /**
-    * @see org.jclouds.googlecomputeengine.domain.Instance#getZone()
-    */
-   public URI getZone() {
-      return zone;
-   }
-
-   /**
-    * @see org.jclouds.googlecomputeengine.domain.Instance#getZone()
-    */
-   public String getZoneName() {
-      return zoneName;
-   }
-
    public static Builder builder() {
       return new Builder();
    }
@@ -332,9 +275,7 @@ public class InstanceTemplate {
                  .networkInterfaces(instanceTemplate.getNetworkInterfaces())
                  .name(instanceTemplate.getName())
                  .description(instanceTemplate.getDescription())
-                 .zone(instanceTemplate.getZone())
                  .image(instanceTemplate.getImage())
-                 .tags(instanceTemplate.getTags())
                  .disks(instanceTemplate.getDisks())
                  .metadata(instanceTemplate.getMetadata())
                  .serviceAccounts(instanceTemplate.getServiceAccounts());
@@ -431,7 +372,6 @@ public class InstanceTemplate {
       if (object instanceof InstanceTemplate) {
          final InstanceTemplate other = InstanceTemplate.class.cast(object);
          return equal(description, other.description)
-                 && equal(tags, other.tags)
                  && equal(image, other.image)
                  && equal(disks, other.disks)
                  && equal(networkInterfaces, other.networkInterfaces)
@@ -447,7 +387,7 @@ public class InstanceTemplate {
     */
    @Override
    public int hashCode() {
-      return Objects.hashCode(description, tags, image, disks, networkInterfaces, metadata, serviceAccounts);
+      return Objects.hashCode(description, image, disks, networkInterfaces, metadata, serviceAccounts);
    }
 
    /**
@@ -457,8 +397,6 @@ public class InstanceTemplate {
       Objects.ToStringHelper toString = Objects.toStringHelper("")
               .omitNullValues();
       toString.add("description", description);
-      if (tags.size() > 0)
-         toString.add("tags", tags);
       if (disks.size() > 0)
          toString.add("disks", disks);
       if (metadata.size() > 0)

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Kernel.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Kernel.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Kernel.java
index 9256a9f..1834078 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Kernel.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Kernel.java
@@ -16,26 +16,40 @@
  */
 package org.jclouds.googlecomputeengine.domain;
 
-import com.google.common.annotations.Beta;
+import static com.google.common.base.Optional.fromNullable;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.beans.ConstructorProperties;
 import java.net.URI;
 import java.util.Date;
 
+import com.google.common.annotations.Beta;
+import com.google.common.base.Optional;
+
 /**
  * Represents a kernel.
  *
  * @author David Alves
- * @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/kernels"/>
+ * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15/kernels"/>
  */
 @Beta
 public final class Kernel extends Resource {
+   private final Optional<Deprecated> deprecated;
 
    @ConstructorProperties({
-           "id", "creationTimestamp", "selfLink", "name", "description"
+           "id", "creationTimestamp", "selfLink", "name", "description", "deprecated"
    })
-   private Kernel(String id, Date creationTimestamp, URI selfLink, String name, String description) {
+   private Kernel(String id, Date creationTimestamp, URI selfLink, String name, String description,
+                  Deprecated deprecated) {
       super(Kind.KERNEL, id, creationTimestamp, selfLink, name, description);
+      this.deprecated = fromNullable(deprecated);
+   }
+
+   /**
+    * @return the deprecation information for this kernel
+    */
+   public Optional<Deprecated> getDeprecated() {
+      return deprecated;
    }
 
    public static Builder builder() {
@@ -48,6 +62,16 @@ public final class Kernel extends Resource {
 
    public static final class Builder extends Resource.Builder<Builder> {
 
+      private Deprecated deprecated;
+
+      /**
+       * @see Kernel#getDeprecated()
+       */
+      public Builder deprecated(Deprecated deprecated) {
+         this.deprecated = checkNotNull(deprecated, "deprecated");
+         return this;
+      }
+
       @Override
       protected Builder self() {
          return this;
@@ -55,11 +79,12 @@ public final class Kernel extends Resource {
 
       public Kernel build() {
          return new Kernel(super.id, super.creationTimestamp, super.selfLink, super.name,
-                 super.description);
+                 super.description, deprecated);
       }
 
       public Builder fromKernel(Kernel in) {
-         return super.fromResource(in);
+         return super.fromResource(in)
+                 .deprecated(in.getDeprecated().orNull());
       }
    }
 

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/ListPage.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/ListPage.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/ListPage.java
index bca5711..98660c3 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/ListPage.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/ListPage.java
@@ -16,19 +16,20 @@
  */
 package org.jclouds.googlecomputeengine.domain;
 
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableSet;
-import org.jclouds.collect.IterableWithMarker;
+import static com.google.common.base.Objects.equal;
+import static com.google.common.base.Objects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.jclouds.googlecomputeengine.domain.Resource.Kind;
 
 import java.beans.ConstructorProperties;
 import java.net.URI;
 import java.util.Iterator;
 
-import static com.google.common.base.Objects.equal;
-import static com.google.common.base.Objects.toStringHelper;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.jclouds.googlecomputeengine.domain.Resource.Kind;
+import org.jclouds.collect.IterableWithMarker;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
 
 /**
  * The collection returned from any <code>listFirstPage()</code> method.

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/MachineType.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/MachineType.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/MachineType.java
index d106b9b..fd1aa58 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/MachineType.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/MachineType.java
@@ -16,26 +16,24 @@
  */
 package org.jclouds.googlecomputeengine.domain;
 
-import com.google.common.annotations.Beta;
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
+import static com.google.common.base.Objects.equal;
+import static com.google.common.base.Objects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.beans.ConstructorProperties;
 import java.net.URI;
 import java.util.Date;
 import java.util.List;
-import java.util.Set;
 
-import static com.google.common.base.Objects.equal;
-import static com.google.common.base.Objects.toStringHelper;
-import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
 
 /**
  * Represents a machine type used to host an instance.
  *
  * @author David Alves
- * @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/machineTypes"/>
+ * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15/machineTypes"/>
  */
 @Beta
 public final class MachineType extends Resource {
@@ -43,26 +41,26 @@ public final class MachineType extends Resource {
    private final Integer guestCpus;
    private final Integer memoryMb;
    private final Integer imageSpaceGb;
-   private final List<EphemeralDisk> ephemeralDisks;
+   private final List<ScratchDisk> scratchDisks;
    private final Integer maximumPersistentDisks;
    private final Long maximumPersistentDisksSizeGb;
-   private final Set<String> availableZone;
+   private final String zone;
 
    @ConstructorProperties({
            "id", "creationTimestamp", "selfLink", "name", "description", "guestCpus", "memoryMb",
-           "imageSpaceGb", "ephemeralDisks", "maximumPersistentDisks", "maximumPersistentDisksSizeGb", "availableZone"
+           "imageSpaceGb", "scratchDisks", "maximumPersistentDisks", "maximumPersistentDisksSizeGb", "zone"
    })
    private MachineType(String id, Date creationTimestamp, URI selfLink, String name, String description,
-                       int guestCpus, int memoryMb, int imageSpaceGb, List<EphemeralDisk> ephemeralDisks,
-                       int maximumPersistentDisks, long maximumPersistentDisksSizeGb, Set<String> availableZone) {
+                       int guestCpus, int memoryMb, int imageSpaceGb, List<ScratchDisk> scratchDisks,
+                       int maximumPersistentDisks, long maximumPersistentDisksSizeGb, String zone) {
       super(Kind.MACHINE_TYPE, id, creationTimestamp, selfLink, name, description);
       this.guestCpus = checkNotNull(guestCpus, "guestCpus of %s", name);
       this.memoryMb = checkNotNull(memoryMb, "memoryMb of %s", name);
       this.imageSpaceGb = checkNotNull(imageSpaceGb, "imageSpaceGb of %s", name);
-      this.ephemeralDisks = ephemeralDisks == null ? ImmutableList.<EphemeralDisk>of() : ephemeralDisks;
+      this.scratchDisks = scratchDisks == null ? ImmutableList.<ScratchDisk>of() : scratchDisks;
       this.maximumPersistentDisks = checkNotNull(maximumPersistentDisks, "maximumPersistentDisks of %s", name);
       this.maximumPersistentDisksSizeGb = maximumPersistentDisksSizeGb;
-      this.availableZone = availableZone == null ? ImmutableSet.<String>of() : availableZone;
+      this.zone = checkNotNull(zone, "zone of %s", name);
    }
 
    /**
@@ -87,10 +85,10 @@ public final class MachineType extends Resource {
    }
 
    /**
-    * @return extended ephemeral disks assigned to the instance.
+    * @return extended scratch disks assigned to the instance.
     */
-   public List<EphemeralDisk> getEphemeralDisks() {
-      return ephemeralDisks;
+   public List<ScratchDisk> getScratchDisks() {
+      return scratchDisks;
    }
 
    /**
@@ -110,8 +108,21 @@ public final class MachineType extends Resource {
    /**
     * @return the zones that this machine type can run in.
     */
-   public Set<String> getAvailableZone() {
-      return availableZone;
+   public String getZone() {
+      return zone;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) return true;
+      if (obj == null || getClass() != obj.getClass()) return false;
+      MachineType that = MachineType.class.cast(obj);
+      return equal(this.kind, that.kind)
+              && equal(this.name, that.name)
+              && equal(this.zone, that.zone);
    }
 
    /**
@@ -122,10 +133,10 @@ public final class MachineType extends Resource {
               .add("guestCpus", guestCpus)
               .add("memoryMb", memoryMb)
               .add("imageSpaceGb", imageSpaceGb)
-              .add("ephemeralDisks", ephemeralDisks)
+              .add("scratchDisks", scratchDisks)
               .add("maximumPersistentDisks", maximumPersistentDisks)
               .add("maximumPersistentDisksSizeGb", maximumPersistentDisksSizeGb)
-              .add("availableZone", availableZone);
+              .add("zone", zone);
    }
 
    /**
@@ -149,10 +160,10 @@ public final class MachineType extends Resource {
       private Integer guestCpus;
       private Integer memoryMb;
       private Integer imageSpaceGb;
-      private ImmutableList.Builder<EphemeralDisk> ephemeralDisks = ImmutableList.builder();
+      private ImmutableList.Builder<ScratchDisk> scratchDisks = ImmutableList.builder();
       private Integer maximumPersistentDisks;
       private Long maximumPersistentDisksSizeGb;
-      private ImmutableSet.Builder<String> availableZone = ImmutableSet.builder();
+      private String zone;
 
       /**
        * @see MachineType#getGuestCpus()
@@ -179,18 +190,18 @@ public final class MachineType extends Resource {
       }
 
       /**
-       * @see MachineType#getEphemeralDisks()
+       * @see MachineType#getScratchDisks()
        */
-      public Builder addEphemeralDisk(int diskGb) {
-         this.ephemeralDisks.add(EphemeralDisk.builder().diskGb(diskGb).build());
+      public Builder addScratchDisk(int diskGb) {
+         this.scratchDisks.add(ScratchDisk.builder().diskGb(diskGb).build());
          return this;
       }
 
       /**
-       * @see MachineType#getEphemeralDisks()
+       * @see MachineType#getScratchDisks()
        */
-      public Builder ephemeralDisks(List<EphemeralDisk> ephemeralDisks) {
-         this.ephemeralDisks.addAll(ephemeralDisks);
+      public Builder scratchDisks(List<ScratchDisk> scratchDisks) {
+         this.scratchDisks.addAll(scratchDisks);
          return this;
       }
 
@@ -211,18 +222,10 @@ public final class MachineType extends Resource {
       }
 
       /**
-       * @see MachineType#getAvailableZone()
-       */
-      public Builder addAvailableZone(String availableZone) {
-         this.availableZone.add(availableZone);
-         return this;
-      }
-
-      /**
-       * @see MachineType#getAvailableZone()
+       * @see MachineType#getZone()
        */
-      public Builder availableZones(Set<String> availableZone) {
-         this.availableZone.addAll(availableZone);
+      public Builder zone(String zone) {
+         this.zone = zone;
          return this;
       }
 
@@ -233,35 +236,35 @@ public final class MachineType extends Resource {
 
       public MachineType build() {
          return new MachineType(id, creationTimestamp, selfLink, name, description, guestCpus, memoryMb,
-                 imageSpaceGb, ephemeralDisks.build(), maximumPersistentDisks, maximumPersistentDisksSizeGb,
-                 availableZone.build());
+                 imageSpaceGb, scratchDisks.build(), maximumPersistentDisks, maximumPersistentDisksSizeGb,
+                 zone);
       }
 
 
       public Builder fromMachineType(MachineType in) {
-         return super.fromResource(in).memoryMb(in.getMemoryMb()).imageSpaceGb(in.getImageSpaceGb()).ephemeralDisks(in
-                 .getEphemeralDisks()).maximumPersistentDisks(in.getMaximumPersistentDisks())
-                 .maximumPersistentDisksSizeGb(in.getMaximumPersistentDisksSizeGb()).availableZones(in
-                         .getAvailableZone());
+         return super.fromResource(in).memoryMb(in.getMemoryMb()).imageSpaceGb(in.getImageSpaceGb()).scratchDisks(in
+                 .getScratchDisks()).maximumPersistentDisks(in.getMaximumPersistentDisks())
+                 .maximumPersistentDisksSizeGb(in.getMaximumPersistentDisksSizeGb()).zone(in
+                         .getZone());
       }
    }
 
    /**
-    * An ephemeral disk of a MachineType
+    * An scratch disk of a MachineType
     */
-   public static final class EphemeralDisk {
+   public static final class ScratchDisk {
 
       private final int diskGb;
 
       @ConstructorProperties({
               "diskGb"
       })
-      private EphemeralDisk(int diskGb) {
+      private ScratchDisk(int diskGb) {
          this.diskGb = diskGb;
       }
 
       /**
-       * @return size of the ephemeral disk, defined in GB.
+       * @return size of the scratch disk, defined in GB.
        */
       public int getDiskGb() {
          return diskGb;
@@ -282,7 +285,7 @@ public final class MachineType extends Resource {
       public boolean equals(Object obj) {
          if (this == obj) return true;
          if (obj == null || getClass() != obj.getClass()) return false;
-         EphemeralDisk that = EphemeralDisk.class.cast(obj);
+         ScratchDisk that = ScratchDisk.class.cast(obj);
          return equal(this.diskGb, that.diskGb);
       }
 
@@ -307,7 +310,7 @@ public final class MachineType extends Resource {
       }
 
       public Builder toBuilder() {
-         return builder().fromEphemeralDisk(this);
+         return builder().fromScratchDisk(this);
       }
 
       public static class Builder {
@@ -315,18 +318,18 @@ public final class MachineType extends Resource {
          private int diskGb;
 
          /**
-          * @see org.jclouds.googlecomputeengine.domain.MachineType.EphemeralDisk#getDiskGb()
+          * @see org.jclouds.googlecomputeengine.domain.MachineType.ScratchDisk#getDiskGb()
           */
          public Builder diskGb(int diskGb) {
             this.diskGb = diskGb;
             return this;
          }
 
-         public EphemeralDisk build() {
-            return new EphemeralDisk(diskGb);
+         public ScratchDisk build() {
+            return new ScratchDisk(diskGb);
          }
 
-         public Builder fromEphemeralDisk(EphemeralDisk in) {
+         public Builder fromScratchDisk(ScratchDisk in) {
             return new Builder().diskGb(in.getDiskGb());
          }
       }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/MachineTypeInZone.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/MachineTypeInZone.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/MachineTypeInZone.java
new file mode 100644
index 0000000..2ba3d49
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/MachineTypeInZone.java
@@ -0,0 +1,55 @@
+/*
+ * 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.Objects.equal;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * @author Adam Lowe
+ */
+public class MachineTypeInZone extends SlashEncodedIds {
+   protected final MachineType machineType;
+
+   public MachineTypeInZone(MachineType machineType, String zoneId) {
+      super(zoneId, checkNotNull(machineType, "machineType").getName());
+      this.machineType = machineType;
+   }
+
+   public MachineType getMachineType() {
+      return machineType;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) return true;
+      if (obj == null || getClass() != obj.getClass()) return false;
+      MachineTypeInZone that = MachineTypeInZone.class.cast(obj);
+      return equal(this.machineType, that.machineType)
+              && equal(this.firstId, that.firstId)
+              && equal(this.secondId, that.secondId);
+   }
+
+   @Override
+   public String toString() {
+      return "[machineType=" + machineType + ", zoneId=" + firstId + "]";
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Metadata.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Metadata.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Metadata.java
new file mode 100644
index 0000000..66c6636
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Metadata.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.googlecomputeengine.domain;
+
+import static com.google.common.base.Objects.equal;
+import static com.google.common.base.Objects.toStringHelper;
+
+import java.beans.ConstructorProperties;
+import java.util.Map;
+
+import org.jclouds.javax.annotation.Nullable;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Metadata for an instance or project, with their fingerprint.
+ * @author Andrew Bayer
+ */
+public class Metadata {
+   @Nullable
+   private final String fingerprint;
+   private final Map<String, String> items;
+
+   @ConstructorProperties({"fingerprint", "items"})
+   public Metadata(@Nullable String fingerprint, @Nullable Map<String, String> items) {
+      this.fingerprint = fingerprint;
+      this.items = items == null ? ImmutableMap.<String,String>of() : items;
+   }
+
+   /**
+    * @return an optional map of metadata key/value pairs for this instance/project
+    */
+   public Map<String, String> getItems() {
+      return items;
+   }
+
+   /**
+    * Gets the fingerprint for the items - needed for updating them.
+    *
+    * @return the fingerprint string for the items.
+    */
+   public String getFingerprint() {
+      return fingerprint;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(fingerprint, items);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) return true;
+      if (obj == null || getClass() != obj.getClass()) return false;
+      Metadata that = Metadata.class.cast(obj);
+      return equal(this.items, that.items)
+              && equal(this.fingerprint, that.fingerprint);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected Objects.ToStringHelper string() {
+      return toStringHelper(this)
+              .add("items", items)
+              .add("fingerprint", fingerprint);
+   }
+
+   public static Builder builder() {
+      return new Builder();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+
+   public static final class Builder {
+
+      private ImmutableMap.Builder<String,String> items = ImmutableMap.builder();
+      private String fingerprint;
+
+      /**
+       * @see Metadata#getItems()
+       */
+      public Builder addItem(String key, String value) {
+         this.items.put(key, value);
+         return this;
+      }
+
+      /**
+       * @see Metadata#getItems()
+       */
+      public Builder items(Map<String, String> items) {
+         this.items.putAll(items);
+         return this;
+      }
+
+      /**
+       * @see org.jclouds.googlecomputeengine.domain.Metadata#getFingerprint()
+       */
+      public Builder fingerprint(String fingerprint) {
+         this.fingerprint = fingerprint;
+         return this;
+      }
+
+      public Metadata build() {
+         return new Metadata(this.fingerprint, this.items.build());
+      }
+
+      public Builder fromMetadata(Metadata in) {
+         return this.fingerprint(in.getFingerprint())
+                 .items(in.getItems());
+      }
+   }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Network.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Network.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Network.java
index c862798..2fe913c 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Network.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Network.java
@@ -17,22 +17,22 @@
 package org.jclouds.googlecomputeengine.domain;
 
 
-import com.google.common.annotations.Beta;
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
+import static com.google.common.base.Optional.fromNullable;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.beans.ConstructorProperties;
 import java.net.URI;
 import java.util.Date;
 
-import static com.google.common.base.Optional.fromNullable;
-import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
 
 /**
  * Represents a network used to enable instance communication.
  *
  * @author David Alves
- * @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/networks"/>
+ * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15/networks"/>
  */
 @Beta
 public final class Network extends Resource {

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Operation.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Operation.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Operation.java
index cf685ed..f387aee 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Operation.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Operation.java
@@ -16,27 +16,29 @@
  */
 package org.jclouds.googlecomputeengine.domain;
 
-import com.google.common.annotations.Beta;
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableList;
-import org.jclouds.http.HttpResponse;
+import static com.google.common.base.Objects.equal;
+import static com.google.common.base.Objects.toStringHelper;
+import static com.google.common.base.Optional.fromNullable;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.beans.ConstructorProperties;
 import java.net.URI;
 import java.util.Date;
 import java.util.List;
 
-import static com.google.common.base.Objects.equal;
-import static com.google.common.base.Objects.toStringHelper;
-import static com.google.common.base.Optional.fromNullable;
-import static com.google.common.base.Preconditions.checkNotNull;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.javax.annotation.Nullable;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
 
 /**
  * Describes an operation being executed on some Resource
  *
  * @author David Alves
- * @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/operations"/>
+ * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15/operations"/>
  */
 @Beta
 public class Operation extends Resource {
@@ -60,12 +62,14 @@ public class Operation extends Resource {
    private final Optional<HttpResponse> httpError;
    private final String operationType;
    private final List<Error> errors;
+   private final Optional<URI> zone;
+   private final Optional<URI> region;
 
    protected Operation(String id, Date creationTimestamp, URI selfLink, String name, String description,
                        URI targetLink, String targetId, String clientOperationId, Status status,
                        String statusMessage, String user, Integer progress, Date insertTime, Date startTime,
                        Date endTime, Integer httpErrorStatusCode, String httpErrorMessage, String operationType,
-                       List<Error> errors) {
+                       @Nullable List<Error> errors, URI region, URI zone) {
       super(Kind.OPERATION, id, creationTimestamp, selfLink, name, description);
       this.targetLink = checkNotNull(targetLink, "targetLink of %s", name);
       this.targetId = fromNullable(targetId);
@@ -85,6 +89,8 @@ public class Operation extends Resource {
               : Optional.<HttpResponse>absent();
       this.operationType = checkNotNull(operationType, "insertTime of %s", name);
       this.errors = errors == null ? ImmutableList.<Error>of() : ImmutableList.copyOf(errors);
+      this.region = fromNullable(region);
+      this.zone = fromNullable(zone);
    }
 
    /**
@@ -95,6 +101,14 @@ public class Operation extends Resource {
    }
 
    /**
+    * @return An optional identifier specified by the client when the mutation was initiated. Must be unique for all
+    *         operation resources in the project.
+    */
+   public Optional<String> getClientOperationId() {
+      return clientOperationId;
+   }
+
+   /**
     * @return unique target id which identifies a particular incarnation of the target.
     */
    public Optional<String> getTargetId() {
@@ -102,11 +116,17 @@ public class Operation extends Resource {
    }
 
    /**
-    * @return An optional identifier specified by the client when the mutation was initiated. Must be unique for all
-    *         operation resources in the project.
+    * @return region this operation is in, if any.
     */
-   public Optional<String> getClientOperationId() {
-      return clientOperationId;
+   public Optional<URI> getRegion() {
+      return region;
+   }
+
+   /**
+    * @return zone this operation is in, if any.
+    */
+   public Optional<URI> getZone() {
+      return zone;
    }
 
    /**
@@ -199,7 +219,9 @@ public class Operation extends Resource {
               .add("endTime", endTime.orNull())
               .add("httpError", httpError.orNull())
               .add("operationType", operationType)
-              .add("errors", errors);
+              .add("errors", errors)
+              .add("region", region.orNull())
+              .add("zone", zone.orNull());
    }
 
    /**
@@ -234,6 +256,8 @@ public class Operation extends Resource {
       private String httpErrorMessage;
       private String operationType;
       private ImmutableList.Builder<Error> errors = ImmutableList.builder();
+      private URI region;
+      private URI zone;
 
       /**
        * @see Operation#getTargetLink()
@@ -244,6 +268,22 @@ public class Operation extends Resource {
       }
 
       /**
+       * @see Operation#getRegion()
+       */
+      public Builder region(URI region) {
+         this.region = region;
+         return self();
+      }
+
+      /**
+       * @see Operation#getZone()
+       */
+      public Builder zone(URI zone) {
+         this.zone = zone;
+         return self();
+      }
+
+      /**
        * @see Operation#getTargetId()
        */
       public Builder targetId(String targetId) {
@@ -365,7 +405,7 @@ public class Operation extends Resource {
          return new Operation(super.id, super.creationTimestamp, super.selfLink, super.name,
                  super.description, targetLink, targetId, clientOperationId, status, statusMessage, user, progress,
                  insertTime, startTime, endTime, httpErrorStatusCode, httpErrorMessage, operationType,
-                 errors.build());
+                 errors.build(), region, zone);
       }
 
       public Builder fromOperation(Operation in) {
@@ -382,7 +422,8 @@ public class Operation extends Resource {
                  .endTime(in.getEndTime().orNull())
                  .httpErrorStatusCode(in.getHttpError().isPresent() ? in.getHttpError().get().getStatusCode() : null)
                  .httpErrorMessage(in.getHttpError().isPresent() ? in.getHttpError().get().getMessage() : null)
-                 .operationType(in.getOperationType()).errors(in.getErrors());
+                 .operationType(in.getOperationType()).errors(in.getErrors())
+                 .zone(in.getZone().orNull()).region(in.getRegion().orNull());
       }
    }
 

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Project.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Project.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Project.java
index 33de1b9..0292c71 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Project.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Project.java
@@ -16,21 +16,20 @@
  */
 package org.jclouds.googlecomputeengine.domain;
 
-import com.google.common.annotations.Beta;
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import org.jclouds.javax.annotation.Nullable;
+import static com.google.common.base.Objects.equal;
+import static com.google.common.base.Objects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.beans.ConstructorProperties;
 import java.net.URI;
 import java.util.Date;
-import java.util.Map;
 import java.util.Set;
 
-import static com.google.common.base.Objects.equal;
-import static com.google.common.base.Objects.toStringHelper;
-import static com.google.common.base.Preconditions.checkNotNull;
+import org.jclouds.javax.annotation.Nullable;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableSet;
 
 /**
  * A Project resource is the root collection and settings resource for all Google Compute Engine resources.
@@ -41,15 +40,14 @@ import static com.google.common.base.Preconditions.checkNotNull;
 @Beta
 public class Project extends Resource {
 
-   private final Map<String, String> commonInstanceMetadata;
+   private final Metadata commonInstanceMetadata;
    private final Set<Quota> quotas;
    private final Set<String> externalIpAddresses;
 
    protected Project(String id, Date creationTimestamp, URI selfLink, String name, String description,
-                     Map<String, String> commonInstanceMetadata, Set<Quota> quotas, Set<String> externalIpAddresses) {
+                     Metadata commonInstanceMetadata, Set<Quota> quotas, Set<String> externalIpAddresses) {
       super(Kind.PROJECT, id, creationTimestamp, selfLink, name, description);
-      this.commonInstanceMetadata = commonInstanceMetadata == null ? ImmutableMap.<String,
-              String>of() : ImmutableMap.copyOf(commonInstanceMetadata);
+      this.commonInstanceMetadata = checkNotNull(commonInstanceMetadata, "commonInstanceMetadata");
       this.quotas = quotas == null ? ImmutableSet.<Quota>of() : ImmutableSet.copyOf(quotas);
       this.externalIpAddresses = externalIpAddresses == null ? ImmutableSet.<String>of() : ImmutableSet.copyOf
               (externalIpAddresses);
@@ -58,7 +56,7 @@ public class Project extends Resource {
    /**
     * @return metadata key/value pairs available to all instances contained in this project.
     */
-   public Map<String, String> getCommonInstanceMetadata() {
+   public Metadata getCommonInstanceMetadata() {
       return commonInstanceMetadata;
    }
 
@@ -105,23 +103,15 @@ public class Project extends Resource {
 
    public static final class Builder extends Resource.Builder<Builder> {
 
-      private ImmutableMap.Builder<String, String> commonInstanceMetadata = ImmutableMap.builder();
+      private Metadata commonInstanceMetadata;
       private ImmutableSet.Builder<Quota> quotas = ImmutableSet.builder();
       private ImmutableSet.Builder<String> externalIpAddresses = ImmutableSet.builder();
 
       /**
        * @see Project#getCommonInstanceMetadata()
        */
-      public Builder addCommonInstanceMetadata(String key, String value) {
-         this.commonInstanceMetadata.put(key, value);
-         return this;
-      }
-
-      /**
-       * @see Project#getCommonInstanceMetadata()
-       */
-      public Builder commonInstanceMetadata(Map<String, String> commonInstanceMetadata) {
-         this.commonInstanceMetadata.putAll(checkNotNull(commonInstanceMetadata, "commonInstanceMetadata"));
+      public Builder commonInstanceMetadata(Metadata commonInstanceMetadata) {
+         this.commonInstanceMetadata = commonInstanceMetadata;
          return this;
       }
 
@@ -164,7 +154,7 @@ public class Project extends Resource {
 
       public Project build() {
          return new Project(super.id, super.creationTimestamp, super.selfLink, super.name,
-                 super.description, commonInstanceMetadata.build(), quotas.build(), externalIpAddresses.build());
+                 super.description, commonInstanceMetadata, quotas.build(), externalIpAddresses.build());
       }
 
       public Builder fromProject(Project in) {
@@ -176,7 +166,7 @@ public class Project extends Resource {
    /**
     * Quotas assigned to a given project
     *
-    * @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/projects#resource"/>
+    * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15/projects#resource"/>
     */
    public static final class Quota {
 

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Region.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Region.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Region.java
new file mode 100644
index 0000000..582cca2
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Region.java
@@ -0,0 +1,147 @@
+/*
+ * 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.beans.ConstructorProperties;
+import java.net.URI;
+import java.util.Date;
+import java.util.Set;
+
+import org.jclouds.javax.annotation.Nullable;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Represents a region resource.
+ *
+ * @author David Alves
+ * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15/regions"/>
+ */
+@Beta
+public final class Region extends Resource {
+
+   public enum Status {
+      UP,
+      DOWN
+   }
+
+   private final Status status;
+   private final Set<URI> zones;
+
+   @ConstructorProperties({
+           "id", "creationTimestamp", "selfLink", "name", "description", "status",
+           "zones"
+   })
+   private Region(String id, Date creationTimestamp, URI selfLink, String name, String description,
+                  Status status, Set<URI> zones) {
+      super(Kind.REGION, id, creationTimestamp, selfLink, name, description);
+      this.status = checkNotNull(status, "status of %name", name);
+      this.zones = zones == null ? ImmutableSet.<URI>of() : ImmutableSet
+              .copyOf(zones);
+   }
+
+   /**
+    * @return Status of the region. "UP" or "DOWN".
+    */
+   public Status getStatus() {
+      return status;
+   }
+
+   /**
+    * @return the zones that can be used in this region.
+    */
+   @Nullable
+   public Set<URI> getZones() {
+      return zones;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected Objects.ToStringHelper string() {
+      return super.string()
+              .add("status", status)
+              .add("zones", zones);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+
+   public static Builder builder() {
+      return new Builder();
+   }
+
+   public Builder toBuilder() {
+      return new Builder().fromRegion(this);
+   }
+
+   public static final class Builder extends Resource.Builder<Builder> {
+
+      private Status status;
+      private ImmutableSet.Builder<URI> zones = ImmutableSet.builder();
+
+      /**
+       * @see org.jclouds.googlecomputeengine.domain.Region#getStatus()
+       */
+      public Builder status(Status status) {
+         this.status = status;
+         return this;
+      }
+
+      /**
+       * @see Region#getZones()
+       */
+      public Builder zone(URI zone) {
+         this.zones.add(checkNotNull(zone, "zone"));
+         return this;
+      }
+
+      /**
+       * @see Region#getZones()
+       */
+      public Builder zones(Set<URI> zones) {
+         this.zones.addAll(checkNotNull(zones, "zones"));
+         return this;
+      }
+
+      @Override
+      protected Builder self() {
+         return this;
+      }
+
+      public Region build() {
+         return new Region(super.id, super.creationTimestamp, super.selfLink, super.name,
+                 super.description, status, zones.build());
+      }
+
+      public Builder fromRegion(Region in) {
+         return super.fromResource(in)
+                 .status(in.getStatus())
+                 .zones(in.getZones());
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Resource.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Resource.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Resource.java
index 19698d8..8abb381 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Resource.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Resource.java
@@ -16,6 +16,18 @@
  */
 package org.jclouds.googlecomputeengine.domain;
 
+import static com.google.common.base.Objects.ToStringHelper;
+import static com.google.common.base.Objects.equal;
+import static com.google.common.base.Objects.toStringHelper;
+import static com.google.common.base.Optional.fromNullable;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.beans.ConstructorProperties;
+import java.net.URI;
+import java.util.Date;
+
+import org.jclouds.javax.annotation.Nullable;
+
 import com.google.common.annotations.Beta;
 import com.google.common.base.CaseFormat;
 import com.google.common.base.Joiner;
@@ -23,17 +35,6 @@ import com.google.common.base.Objects;
 import com.google.common.base.Optional;
 import com.google.common.base.Splitter;
 import com.google.common.collect.Iterables;
-import org.jclouds.javax.annotation.Nullable;
-
-import java.beans.ConstructorProperties;
-import java.net.URI;
-import java.util.Date;
-
-import static com.google.common.base.Objects.ToStringHelper;
-import static com.google.common.base.Objects.equal;
-import static com.google.common.base.Objects.toStringHelper;
-import static com.google.common.base.Optional.fromNullable;
-import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
  * Base class for Google Compute Engine resources.
@@ -44,6 +45,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
 public class Resource {
 
    public enum Kind {
+      ADDRESS,
+      ADDRESS_LIST,
       DISK,
       DISK_LIST,
       FIREWALL,
@@ -61,6 +64,12 @@ public class Resource {
       PROJECT,
       NETWORK,
       NETWORK_LIST,
+      REGION,
+      REGION_LIST,
+      ROUTE,
+      ROUTE_LIST,
+      SNAPSHOT,
+      SNAPSHOT_LIST,
       ZONE,
       ZONE_LIST;
 

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Route.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Route.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Route.java
new file mode 100644
index 0000000..b15f986
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Route.java
@@ -0,0 +1,434 @@
+/*
+ * 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.Objects.equal;
+import static com.google.common.base.Objects.toStringHelper;
+import static com.google.common.base.Optional.fromNullable;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.beans.ConstructorProperties;
+import java.net.URI;
+import java.util.Date;
+import java.util.Map;
+import java.util.Set;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Represents a route resource.
+ *
+ * @author Andrew Bayer
+ * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15/routes"/>
+ */
+@Beta
+public final class Route extends Resource {
+
+   private final URI network;
+   private final Set<String> tags;
+   private final String destRange;
+   private final Integer priority;
+   private final Optional<URI> nextHopInstance;
+   private final Optional<String> nextHopIp;
+   private final Optional<URI> nextHopNetwork;
+   private final Optional<URI> nextHopGateway;
+   private final Set<Warning> warnings;
+
+   @ConstructorProperties({
+           "id", "creationTimestamp", "selfLink", "name", "description", "network", "tags",
+           "destRange", "priority", "nextHopInstance", "nextHopIp", "nextHopNetwork",
+           "nextHopGateway", "warnings"
+   })
+   private Route(String id, Date creationTimestamp, URI selfLink, String name, String description,
+                 URI network, Set<String> tags, String destRange, Integer priority,
+                 URI nextHopInstance, String nextHopIp, URI nextHopNetwork,
+                 URI nextHopGateway, Set<Warning> warnings) {
+      super(Kind.ROUTE, id, creationTimestamp, selfLink, name, description);
+      this.network = checkNotNull(network, "network for %name", name);
+      this.tags = tags == null ? ImmutableSet.<String>of() : tags;
+      this.destRange = checkNotNull(destRange, "destination range for %name", name);
+      this.priority = checkNotNull(priority, "priority of %name", name);
+      this.nextHopInstance = fromNullable(nextHopInstance);
+      this.nextHopIp = fromNullable(nextHopIp);
+      this.nextHopNetwork = fromNullable(nextHopNetwork);
+      this.nextHopGateway = fromNullable(nextHopGateway);
+      this.warnings = warnings == null ? ImmutableSet.<Warning>of() : warnings;
+   }
+
+   /**
+    * @return Network for this Route.
+    */
+   public URI getNetwork() {
+      return network;
+   }
+
+   /**
+    * @return The set of instance items to which this route applies.
+    */
+   public Set<String> getTags() {
+      return tags;
+   }
+
+   /**
+    * @return The destination range of outgoing packets that this route applies to.
+    */
+   public String getDestRange() {
+      return destRange;
+   }
+
+   /**
+    * @return The priority of this route. Priority is used to break ties in the case
+    *    where there is more than one matching route of maximum length. A lower value
+    *    is higher priority; a priority of 100 is higher than 200.
+    */
+   public Integer getPriority() {
+      return priority;
+   }
+
+   /**
+    * @return The fully-qualified URL to an instance that should handle matching packets.
+    */
+   public Optional<URI> getNextHopInstance() {
+      return nextHopInstance;
+   }
+
+   /**
+    * @return The network IP address of an instance that should handle matching packets.
+    */
+   public Optional<String> getNextHopIp() {
+      return nextHopIp;
+   }
+
+   /**
+    * @return The URL of the local network if it should handle matching packets.
+    */
+   public Optional<URI> getNextHopNetwork() {
+      return nextHopNetwork;
+   }
+
+   /**
+    * @return The URL to a gateway that should handle matching packets. Currently, this is only the internet gateway.
+    */
+   public Optional<URI> getNextHopGateway() {
+      return nextHopGateway;
+   }
+
+   /**
+    * @return If potential misconfigurations are detected for this route, this field will be populated with warning messages.
+    */
+   public Set<Warning> getWarnings() {
+      return warnings;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected Objects.ToStringHelper string() {
+      return super.string()
+              .add("network", network)
+              .add("tags", tags)
+              .add("destRange", destRange)
+              .add("priority", priority)
+              .add("nextHopInstance", nextHopInstance.orNull())
+              .add("nextHopIp", nextHopIp.orNull())
+              .add("nextHopNetwork", nextHopNetwork.orNull())
+              .add("nextHopGateway", nextHopGateway.orNull())
+              .add("warnings", warnings);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+
+   public static Builder builder() {
+      return new Builder();
+   }
+
+   public Builder toBuilder() {
+      return new Builder().fromRoute(this);
+   }
+
+   public static final class Builder extends Resource.Builder<Builder> {
+
+      private URI network;
+      private ImmutableSet.Builder<String> tags = ImmutableSet.builder();
+      private String destRange;
+      private Integer priority;
+      private URI nextHopInstance;
+      private String nextHopIp;
+      private URI nextHopNetwork;
+      private URI nextHopGateway;
+      private ImmutableSet.Builder<Warning> warnings = ImmutableSet.builder();
+
+
+      /**
+       * @see Route#getNetwork()
+       */
+      public Builder network(URI network) {
+         this.network = network;
+         return this;
+      }
+
+      /**
+       * @see Route#getTags()
+       */
+      public Builder addTag(String tag) {
+         this.tags.add(tag);
+         return this;
+      }
+
+      /**
+       * @see Route#getTags()
+       */
+      public Builder tags(Set<String> tags) {
+         this.tags.addAll(tags);
+         return this;
+      }
+
+      /**
+       * @see Route#getDestRange()
+       */
+      public Builder destRange(String destRange) {
+         this.destRange = destRange;
+         return this;
+      }
+
+      /**
+       * @see Route#getPriority()
+       */
+      public Builder priority(Integer priority) {
+         this.priority = priority;
+         return this;
+      }
+
+      /**
+       * @see Route#getNextHopInstance()
+       */
+      public Builder nextHopInstance(URI nextHopInstance) {
+         this.nextHopInstance = nextHopInstance;
+         return this;
+      }
+
+      /**
+       * @see Route#getNextHopIp()
+       */
+      public Builder nextHopIp(String nextHopIp) {
+         this.nextHopIp = nextHopIp;
+         return this;
+      }
+
+      /**
+       * @see Route#getNextHopNetwork()
+       */
+      public Builder nextHopNetwork(URI nextHopNetwork) {
+         this.nextHopNetwork = nextHopNetwork;
+         return this;
+      }
+
+      /**
+       * @see Route#getNextHopGateway()
+       */
+      public Builder nextHopGateway(URI nextHopGateway) {
+         this.nextHopGateway = nextHopGateway;
+         return this;
+      }
+
+      /**
+       * @see Route#getWarnings()
+       */
+      public Builder addWarning(Warning warning) {
+         this.warnings.add(warning);
+         return this;
+      }
+
+      /**
+       * @see Route#getWarnings()
+       */
+      public Builder warnings(Set<Warning> warnings) {
+         this.warnings.addAll(warnings);
+         return this;
+      }
+
+
+      @Override
+      protected Builder self() {
+         return this;
+      }
+
+      public Route build() {
+         return new Route(super.id, super.creationTimestamp, super.selfLink, super.name,
+                 super.description, network, tags.build(), destRange, priority,
+                 nextHopInstance, nextHopIp, nextHopNetwork, nextHopGateway,
+                 warnings.build());
+      }
+
+      public Builder fromRoute(Route in) {
+         return super.fromResource(in)
+                 .network(in.getNetwork())
+                 .tags(in.getTags())
+                 .destRange(in.getDestRange())
+                 .priority(in.getPriority())
+                 .nextHopInstance(in.getNextHopInstance().orNull())
+                 .nextHopIp(in.getNextHopIp().orNull())
+                 .nextHopNetwork(in.getNextHopNetwork().orNull())
+                 .nextHopGateway(in.getNextHopGateway().orNull())
+                 .warnings(in.getWarnings());
+      }
+   }
+
+   /**
+    * If potential misconfigurations are detected for this route, this field will be populated with warning messages.
+    */
+   public static class Warning {
+      private final String code;
+      private final Optional<String> message;
+      private final Map<String, String> data;
+
+      @ConstructorProperties({
+              "code", "message", "data"
+      })
+      public Warning(String code, String message, Map<String, String> data) {
+         this.code = checkNotNull(code, "code");
+         this.message = fromNullable(message);
+         this.data = data == null ? ImmutableMap.<String, String>of() : data;
+      }
+
+      /**
+       * @return The warning type identifier for this warning.
+       */
+      public String getCode() {
+         return code;
+      }
+
+      /**
+       * @return Optional human-readable details for this warning.
+       */
+      public Optional<String> getMessage() {
+         return message;
+      }
+
+      /**
+       * @return Metadata for this warning
+       */
+      public Map<String, String> getData() {
+         return data;
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      @Override
+      public int hashCode() {
+         return Objects.hashCode(code, message, data);
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      @Override
+      public boolean equals(Object obj) {
+         if (this == obj) return true;
+         if (obj == null || getClass() != obj.getClass()) return false;
+         Warning that = Warning.class.cast(obj);
+         return equal(this.code, that.code)
+                 && equal(this.message, that.message)
+                 && equal(this.data, that.data);
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      protected Objects.ToStringHelper string() {
+         return toStringHelper(this)
+                 .add("code", code)
+                 .add("message", message)
+                 .add("data", data);
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      @Override
+      public String toString() {
+         return string().toString();
+      }
+
+      public static Builder builder() {
+         return new Builder();
+      }
+
+      public Builder toBuilder() {
+         return builder().fromWarning(this);
+      }
+
+      public static final class Builder {
+         private String code;
+         private String message;
+         private ImmutableMap.Builder<String, String> data = ImmutableMap.builder();
+
+         /**
+          * @see Warning#getCode()
+          */
+         public Builder code(String code) {
+            this.code = code;
+            return this;
+         }
+
+         /**
+          * @see Warning#getMessage()
+          */
+         public Builder message(String message) {
+            this.message = message;
+            return this;
+         }
+
+         /**
+          * @see Warning#getData()
+          */
+         public Builder data(Map<String, String> data) {
+            this.data = new ImmutableMap.Builder<String, String>().putAll(data);
+            return this;
+         }
+
+         /**
+          * @see Warning#getData()
+          */
+         public Builder addData(String key, String value) {
+            this.data.put(checkNotNull(key, "key"), checkNotNull(value, "value of %s", key));
+            return this;
+         }
+
+         public Warning build() {
+            return new Warning(code, message, data.build());
+         }
+
+         public Builder fromWarning(Warning in) {
+            return this.code(in.getCode())
+                    .message(in.getMessage().orNull())
+                    .data(in.getData());
+         }
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/SlashEncodedIds.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/SlashEncodedIds.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/SlashEncodedIds.java
new file mode 100644
index 0000000..72c1dc5
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/SlashEncodedIds.java
@@ -0,0 +1,86 @@
+/*
+ * 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.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Iterables;
+
+/**
+ * @author Adam Lowe
+ */
+public class SlashEncodedIds {
+   public static SlashEncodedIds fromSlashEncoded(String id) {
+      Iterable<String> parts = Splitter.on('/').split(checkNotNull(id, "id"));
+      checkArgument(Iterables.size(parts) == 2, "id must be in format firstId/secondId");
+      return new SlashEncodedIds(Iterables.get(parts, 0), Iterables.get(parts, 1));
+   }
+
+   public static SlashEncodedIds fromTwoIds(String firstId, String secondId) {
+      return new SlashEncodedIds(firstId, secondId);
+   }
+
+   private static String slashEncodeTwoIds(String firstId, String secondId) {
+      return checkNotNull(firstId, "firstId") + "/" + checkNotNull(secondId, "secondId");
+   }
+
+   public String slashEncode() {
+      return slashEncodeTwoIds(firstId, secondId);
+   }
+
+   protected final String firstId;
+   protected final String secondId;
+
+   protected SlashEncodedIds(String firstId, String secondId) {
+      this.firstId = checkNotNull(firstId, "firstId");
+      this.secondId = checkNotNull(secondId, "secondId");
+   }
+
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(firstId, secondId);
+   }
+
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj)
+         return true;
+      if (obj == null)
+         return false;
+      if (getClass() != obj.getClass())
+         return false;
+      SlashEncodedIds other = (SlashEncodedIds) obj;
+      return Objects.equal(firstId, other.firstId) && Objects.equal(secondId, other.secondId);
+   }
+
+   public String getFirstId() {
+      return firstId;
+   }
+
+   public String getSecondId() {
+      return secondId;
+   }
+
+   @Override
+   public String toString() {
+      return "[firstId=" + firstId + ", secondId=" + secondId + "]";
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Snapshot.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Snapshot.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Snapshot.java
new file mode 100644
index 0000000..c487b7c
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Snapshot.java
@@ -0,0 +1,136 @@
+/*
+ * 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.Optional.fromNullable;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+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;
+
+/**
+ * A Persistent Disk Snapshot resource.
+ *
+ * @author Andrew Bayer
+ * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15/snapshots"/>
+ */
+@Beta
+public final class Snapshot extends AbstractDisk {
+
+   private final Optional<URI> sourceDisk;
+   private final String sourceDiskId;
+
+   @ConstructorProperties({
+           "id", "creationTimestamp", "selfLink", "name", "description", "diskSizeGb",
+           "status", "sourceDisk", "sourceDiskId"
+   })
+   private Snapshot(String id, Date creationTimestamp, URI selfLink, String name, String description,
+                    Integer sizeGb, String status, URI sourceDisk, String sourceDiskId) {
+      super(Kind.SNAPSHOT, id, creationTimestamp, selfLink, name, description, sizeGb, status);
+      this.sourceDisk = fromNullable(sourceDisk);
+      this.sourceDiskId = checkNotNull(sourceDiskId, "sourceDiskId of %s", name);
+   }
+
+   /**
+    * @return The source disk used to create this snapshot. Once the source disk
+    *   has been deleted from the system, this field will be cleared, and will
+    *   not be set even if a disk with the same name has been re-created (output only).
+    */
+   public Optional<URI> getSourceDisk() {
+      return sourceDisk;
+   }
+
+   /**
+    * @return The ID value of the disk used to create this snapshot. This value
+    *   may be used to determine whether the snapshot was taken from the current
+    *   or a previous instance of a given disk name.
+    */
+   public String getSourceDiskId() {
+      return sourceDiskId;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected Objects.ToStringHelper string() {
+      return super.string()
+              .omitNullValues()
+              .add("sourceDisk", sourceDisk.orNull())
+              .add("sourceDiskId", sourceDiskId);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+
+   public static Builder builder() {
+      return new Builder();
+   }
+
+   public Builder toBuilder() {
+      return new Builder().fromSnapshot(this);
+   }
+
+   public static final class Builder extends AbstractDisk.Builder<Builder> {
+
+      private URI sourceDisk;
+      private String sourceDiskId;
+
+      /**
+       * @see Snapshot#getSourceDisk()
+       */
+      public Builder sourceDisk(URI sourceDisk) {
+         this.sourceDisk = sourceDisk;
+         return this;
+      }
+
+      /**
+       * @see Snapshot#getSourceDiskId()
+       */
+      public Builder sourceDiskId(String sourceDiskId) {
+         this.sourceDiskId = sourceDiskId;
+         return this;
+      }
+
+      @Override
+      protected Builder self() {
+         return this;
+      }
+
+      public Snapshot build() {
+         return new Snapshot(super.id, super.creationTimestamp, super.selfLink, super.name,
+                 super.description, super.sizeGb, super.status, sourceDisk, sourceDiskId);
+      }
+
+      public Builder fromSnapshot(Snapshot in) {
+         return super.fromAbstractDisk(in)
+                 .sourceDisk(in.getSourceDisk().orNull())
+                 .sourceDiskId(in.getSourceDiskId());
+      }
+
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Zone.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Zone.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Zone.java
index 2d41a74..254b83d 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Zone.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Zone.java
@@ -16,27 +16,28 @@
  */
 package org.jclouds.googlecomputeengine.domain;
 
-import com.google.common.annotations.Beta;
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableSet;
-import org.jclouds.javax.annotation.Nullable;
+import static com.google.common.base.Objects.equal;
+import static com.google.common.base.Objects.toStringHelper;
+import static com.google.common.base.Optional.fromNullable;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.beans.ConstructorProperties;
 import java.net.URI;
 import java.util.Date;
 import java.util.Set;
 
-import static com.google.common.base.Objects.equal;
-import static com.google.common.base.Objects.toStringHelper;
-import static com.google.common.base.Optional.fromNullable;
-import static com.google.common.base.Preconditions.checkNotNull;
+import org.jclouds.javax.annotation.Nullable;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
 
 /**
  * Represents a zone resource.
  *
  * @author David Alves
- * @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/zones"/>
+ * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15/zones"/>
  */
 @Beta
 public final class Zone extends Resource {
@@ -181,7 +182,7 @@ public final class Zone extends Resource {
     * Scheduled maintenance windows for the zone. When the zone is in a maintenance window,
     * all resources which reside in the zone will be unavailable.
     *
-    * @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/zones"/>
+    * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15/zones"/>
     */
    public static final class MaintenanceWindow {
 

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/AddressApi.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/AddressApi.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/AddressApi.java
new file mode 100644
index 0000000..795f150
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/AddressApi.java
@@ -0,0 +1,188 @@
+/*
+ * 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.features;
+
+import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
+import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404;
+import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.collect.PagedIterable;
+import org.jclouds.googlecomputeengine.domain.Address;
+import org.jclouds.googlecomputeengine.domain.ListPage;
+import org.jclouds.googlecomputeengine.domain.Operation;
+import org.jclouds.googlecomputeengine.functions.internal.ParseAddresses;
+import org.jclouds.googlecomputeengine.options.ListOptions;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.oauth.v2.config.OAuthScopes;
+import org.jclouds.oauth.v2.filters.OAuthAuthenticator;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.MapBinder;
+import org.jclouds.rest.annotations.PayloadParam;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.ResponseParser;
+import org.jclouds.rest.annotations.SkipEncoding;
+import org.jclouds.rest.annotations.Transform;
+import org.jclouds.rest.binders.BindToJsonPayload;
+
+/**
+ * Provides access to Addresses via their REST API.
+ *
+ * @author Andrew Bayer
+ * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15/addresses"/>
+ */
+@SkipEncoding({'/', '='})
+@RequestFilters(OAuthAuthenticator.class)
+public interface AddressApi {
+
+   /**
+    * Returns the specified address resource.
+    *
+    * @param region     Name of the region the address is in.
+    * @param addressName name of the address resource to return.
+    * @return a Address resource.
+    */
+   @Named("Addresss:get")
+   @GET
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Path("/regions/{region}/addresses/{address}")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   Address getInRegion(@PathParam("region") String region, @PathParam("address") String addressName);
+
+   /**
+    * Creates a address resource in the specified project specifying the size of the address.
+    *
+    *
+    * @param region     the name of the region where the address is to be created.
+    * @param addressName the name of address.
+    * @return an Operation resource. To check on the status of an operation, poll the Operations resource returned to
+    *         you, and look for the status field.
+    */
+   @Named("Addresss:insert")
+   @POST
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("/regions/{region}/addresses")
+   @OAuthScopes({COMPUTE_SCOPE})
+   @MapBinder(BindToJsonPayload.class)
+   Operation createInRegion(@PathParam("region") String region, @PayloadParam("name") String addressName);
+
+   /**
+    * Deletes the specified address resource.
+    *
+    * @param region     the region the address is in.
+    * @param addressName name of the address resource to delete.
+    * @return an Operation resource. To check on the status of an operation, poll the Operations resource returned to
+    *         you, and look for the status field.
+    */
+   @Named("Addresss:delete")
+   @DELETE
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Path("/regions/{region}/addresses/{address}")
+   @OAuthScopes(COMPUTE_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   Operation deleteInRegion(@PathParam("region") String region, @PathParam("address") String addressName);
+
+   /**
+    * @see org.jclouds.googlecomputeengine.features.AddressApi#listAtMarkerInRegion(String, String, org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("Addresss:list")
+   @GET
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Path("/regions/{region}/addresses")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseAddresses.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<Address> listFirstPageInRegion(@PathParam("region") String region);
+
+   /**
+    * @see org.jclouds.googlecomputeengine.features.AddressApi#listAtMarkerInRegion(String, String, org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("Addresss:list")
+   @GET
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Path("/regions/{region}/addresses")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseAddresses.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<Address> listAtMarkerInRegion(@PathParam("region") String region, @QueryParam("pageToken") @Nullable String marker);
+
+   /**
+    * Retrieves the listPage of address resources contained within the specified project and region.
+    * By default the listPage as a maximum size of 100, if no options are provided or ListOptions#getMaxResults() has
+    * not been set.
+    *
+    * @param region        the region to search in
+    * @param marker      marks the beginning of the next list page
+    * @param listOptions listing options
+    * @return a page of the listPage
+    * @see org.jclouds.googlecomputeengine.options.ListOptions
+    * @see org.jclouds.googlecomputeengine.domain.ListPage
+    */
+   @Named("Addresss:list")
+   @GET
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Path("/regions/{region}/addresses")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseAddresses.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<Address> listAtMarkerInRegion(@PathParam("region") String region, @QueryParam("pageToken") @Nullable String marker, ListOptions listOptions);
+
+   /**
+    * A paged version of AddressApi#listPageInRegion(String)
+    *
+    * @param region the region to list in
+    * @return a Paged, Fluent Iterable that is able to fetch additional pages when required
+    * @see org.jclouds.collect.PagedIterable
+    * @see org.jclouds.googlecomputeengine.features.AddressApi#listAtMarkerInRegion(String, String, org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("Addresss:list")
+   @GET
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Path("/regions/{region}/addresses")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseAddresses.class)
+   @Transform(ParseAddresses.ToPagedIterable.class)
+   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
+   PagedIterable<Address> listInRegion(@PathParam("region") String region);
+
+   @Named("Addresss:list")
+   @GET
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Path("/regions/{region}/addresses")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseAddresses.class)
+   @Transform(ParseAddresses.ToPagedIterable.class)
+   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
+   PagedIterable<Address> listInRegion(@PathParam("region") String region, ListOptions options);
+
+}