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:40:00 UTC

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

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

Does not include aggregated list method calls, due to those calls not
working with service accounts.

Does not include image insert or deprecate due to the extremely
complex system for creating images in GCE, which makes writing tests
for that a pain. Will come in a later commit.


Project: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/commit/53386380
Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/tree/53386380
Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/diff/53386380

Branch: refs/heads/master
Commit: 53386380836e15ddb01e131b2ab9329e443d8b63
Parents: 2c45aca
Author: Andrew Bayer <an...@gmail.com>
Authored: Wed Jul 31 09:05:25 2013 -0700
Committer: Andrew Bayer <an...@gmail.com>
Committed: Wed Jul 31 09:05:25 2013 -0700

----------------------------------------------------------------------
 google-compute-engine/pom.xml                   | 220 +++++-----
 .../GoogleComputeEngineApi.java                 |  71 ++-
 .../GoogleComputeEngineApiMetadata.java         |  32 +-
 .../GoogleComputeEngineConstants.java           |   8 +-
 .../compute/GoogleComputeEngineService.java     |  44 +-
 .../GoogleComputeEngineServiceAdapter.java      | 168 +++++--
 ...GoogleComputeEngineServiceContextModule.java | 179 +++++---
 .../functions/BuildInstanceMetadata.java        |  11 +-
 .../GoogleComputeEngineImageToImage.java        |  25 +-
 .../functions/InstanceInZoneToNodeMetadata.java | 117 +++++
 .../functions/InstanceToNodeMetadata.java       | 111 -----
 .../functions/MachineTypeInZoneToHardware.java  | 102 +++++
 .../functions/MachineTypeToHardware.java        |  57 ---
 .../functions/OrphanedGroupsFromDeadNodes.java  |  12 +-
 .../compute/functions/RegionToLocation.java     |  47 ++
 .../compute/functions/ZoneToLocation.java       |   9 +-
 .../GoogleComputeEngineTemplateOptions.java     |  17 +-
 .../predicates/AllNodesInGroupTerminated.java   |  13 +-
 ...desWithGroupEncodedIntoNameThenAddToSet.java |  48 +-
 ...DefaultLoginCredentialsForImageStrategy.java |  18 +-
 ...eNodeCredentialsButOverrideFromTemplate.java |   9 +-
 .../GoogleComputeEngineHttpApiModule.java       |  78 +++-
 .../config/GoogleComputeEngineParserModule.java | 130 ++++--
 .../config/OAuthModuleWithoutTypeAdapters.java  |  19 +-
 .../googlecomputeengine/config/UserProject.java |   3 +-
 .../domain/AbstractDisk.java                    | 122 ++++++
 .../googlecomputeengine/domain/Address.java     | 178 ++++++++
 .../googlecomputeengine/domain/Deprecated.java  | 197 +++++++++
 .../googlecomputeengine/domain/Disk.java        |  71 +--
 .../googlecomputeengine/domain/Firewall.java    |  30 +-
 .../googlecomputeengine/domain/Image.java       |  50 ++-
 .../googlecomputeengine/domain/Instance.java    | 218 +++++++---
 .../domain/InstanceInZone.java                  |  55 +++
 .../domain/InstanceTemplate.java                |  80 +---
 .../googlecomputeengine/domain/Kernel.java      |  37 +-
 .../googlecomputeengine/domain/ListPage.java    |  17 +-
 .../googlecomputeengine/domain/MachineType.java | 119 ++---
 .../domain/MachineTypeInZone.java               |  55 +++
 .../googlecomputeengine/domain/Metadata.java    | 140 ++++++
 .../googlecomputeengine/domain/Network.java     |  12 +-
 .../googlecomputeengine/domain/Operation.java   |  77 +++-
 .../googlecomputeengine/domain/Project.java     |  44 +-
 .../googlecomputeengine/domain/Region.java      | 147 +++++++
 .../googlecomputeengine/domain/Resource.java    |  31 +-
 .../googlecomputeengine/domain/Route.java       | 434 +++++++++++++++++++
 .../domain/SlashEncodedIds.java                 |  86 ++++
 .../googlecomputeengine/domain/Snapshot.java    | 136 ++++++
 .../googlecomputeengine/domain/Zone.java        |  23 +-
 .../features/AddressApi.java                    | 188 ++++++++
 .../googlecomputeengine/features/DiskApi.java   |  78 ++--
 .../features/FirewallApi.java                   |  36 +-
 .../features/GlobalOperationApi.java            | 159 +++++++
 .../googlecomputeengine/features/ImageApi.java  |  20 +-
 .../features/InstanceApi.java                   | 213 +++++++--
 .../googlecomputeengine/features/KernelApi.java |  16 +-
 .../features/MachineTypeApi.java                |  43 +-
 .../features/NetworkApi.java                    |  29 +-
 .../features/OperationApi.java                  | 159 -------
 .../features/ProjectApi.java                    |  13 +-
 .../googlecomputeengine/features/RegionApi.java | 136 ++++++
 .../features/RegionOperationApi.java            | 164 +++++++
 .../googlecomputeengine/features/RouteApi.java  | 185 ++++++++
 .../features/SnapshotApi.java                   | 161 +++++++
 .../googlecomputeengine/features/ZoneApi.java   |   2 +-
 .../features/ZoneOperationApi.java              | 164 +++++++
 .../functions/internal/BaseToPagedIterable.java |  15 +-
 .../internal/BaseWithRegionToPagedIterable.java |  76 ++++
 .../internal/BaseWithZoneToPagedIterable.java   |  76 ++++
 .../functions/internal/PATCH.java               |   3 +-
 .../functions/internal/ParseAddresses.java      |  70 +++
 .../functions/internal/ParseDisks.java          |  22 +-
 .../functions/internal/ParseFirewalls.java      |  14 +-
 .../internal/ParseGlobalOperations.java         |  66 +++
 .../functions/internal/ParseImages.java         |  14 +-
 .../functions/internal/ParseInstances.java      |  22 +-
 .../functions/internal/ParseKernels.java        |  14 +-
 .../functions/internal/ParseMachineTypes.java   |  19 +-
 .../functions/internal/ParseNetworks.java       |  14 +-
 .../functions/internal/ParseOperations.java     |  64 ---
 .../internal/ParseRegionOperations.java         |  68 +++
 .../functions/internal/ParseRegions.java        |  66 +++
 .../functions/internal/ParseRoutes.java         |  66 +++
 .../functions/internal/ParseSnapshots.java      |  70 +++
 .../functions/internal/ParseZoneOperations.java |  68 +++
 .../functions/internal/ParseZones.java          |  14 +-
 .../handlers/FirewallBinder.java                |  13 +-
 .../GoogleComputeEngineErrorHandler.java        |   8 +-
 .../handlers/InstanceBinder.java                |  24 +-
 .../handlers/MetadataBinder.java                |  39 +-
 .../handlers/RouteBinder.java                   |  59 +++
 .../options/AttachDiskOptions.java              | 129 ++++++
 .../options/DeprecateOptions.java               | 127 ++++++
 .../options/FirewallOptions.java                |  10 +-
 .../options/ListOptions.java                    |   8 +-
 .../options/RouteOptions.java                   | 203 +++++++++
 .../GlobalOperationDonePredicate.java           |  61 +++
 .../predicates/OperationDonePredicate.java      |  60 ---
 .../RegionOperationDonePredicate.java           |  71 +++
 .../predicates/ZoneOperationDonePredicate.java  |  70 +++
 .../GoogleComputeEngineApiMetadataTest.java     |   5 +-
 .../PageSystemExpectTest.java                   |  14 +-
 .../GoogleComputeEngineServiceExpectTest.java   | 204 +++++----
 .../GoogleComputeEngineServiceLiveTest.java     |   4 +-
 .../GoogleComputeEngineImageToImageTest.java    |  10 +-
 .../OrphanedGroupsFromDeadNodesTest.java        |  23 +-
 .../features/AddressApiExpectTest.java          | 166 +++++++
 .../features/AddressApiLiveTest.java            |  74 ++++
 .../features/DiskApiExpectTest.java             |  92 ++--
 .../features/DiskApiLiveTest.java               |  20 +-
 .../features/FirewallApiExpectTest.java         |  62 +--
 .../features/FirewallApiLiveTest.java           |  33 +-
 .../features/GlobalOperationApiExpectTest.java  | 161 +++++++
 .../features/GlobalOperationApiLiveTest.java    |  94 ++++
 .../features/ImageApiExpectTest.java            |  33 +-
 .../features/ImageApiLiveTest.java              |  21 +-
 .../features/InstanceApiExpectTest.java         | 268 ++++++++++--
 .../features/InstanceApiLiveTest.java           | 138 +++++-
 .../features/KernelApiExpectTest.java           |  18 +-
 .../features/KernelApiLiveTest.java             |  19 +-
 .../features/MachineTypeApiExpectTest.java      |  36 +-
 .../features/MachineTypeApiLiveTest.java        |  23 +-
 .../features/NetworkApiExpectTest.java          |  30 +-
 .../features/NetworkApiLiveTest.java            |   4 +-
 .../features/OperationApiExpectTest.java        | 161 -------
 .../features/OperationApiLiveTest.java          |  93 ----
 .../features/ProjectApiExpectTest.java          |  41 +-
 .../features/ProjectApiLiveTest.java            |  43 +-
 .../features/RegionApiExpectTest.java           |  97 +++++
 .../features/RegionApiLiveTest.java             |  77 ++++
 .../features/RegionOperationApiExpectTest.java  | 198 +++++++++
 .../features/RegionOperationApiLiveTest.java    |  94 ++++
 .../features/RouteApiExpectTest.java            | 178 ++++++++
 .../features/RouteApiLiveTest.java              |  99 +++++
 .../features/SnapshotApiExpectTest.java         |  97 +++++
 .../features/SnapshotApiLiveTest.java           |  95 ++++
 .../features/ZoneApiExpectTest.java             |  16 +-
 .../features/ZoneApiLiveTest.java               |  19 +-
 .../features/ZoneOperationApiExpectTest.java    | 196 +++++++++
 .../features/ZoneOperationApiLiveTest.java      |  93 ++++
 .../GoogleComputeEngineErrorHandlerTest.java    |  18 +-
 .../BaseGoogleComputeEngineApiExpectTest.java   |   4 +-
 .../BaseGoogleComputeEngineApiLiveTest.java     |  71 ++-
 .../BaseGoogleComputeEngineExpectTest.java      |  73 ++--
 .../BaseGoogleComputeEngineParseTest.java       |   5 +-
 ...leComputeEngineServiceContextExpectTest.java |   7 +-
 .../parse/ParseAddressListTest.java             |  64 +++
 .../parse/ParseAddressTest.java                 |  54 +++
 .../parse/ParseDiskListTest.java                |  18 +-
 .../parse/ParseDiskTest.java                    |  13 +-
 .../parse/ParseFirewallListTest.java            |  16 +-
 .../parse/ParseFirewallTest.java                |  17 +-
 .../parse/ParseImageListTest.java               |  23 +-
 .../parse/ParseImageTest.java                   |  13 +-
 .../parse/ParseInstanceListTest.java            |  14 +-
 .../parse/ParseInstanceSerialOutputTest.java    |   6 +-
 .../parse/ParseInstanceTest.java                |  30 +-
 .../parse/ParseKernelListTest.java              |  29 +-
 .../parse/ParseKernelTest.java                  |  11 +-
 .../parse/ParseMachineTypeListTest.java         |  39 +-
 .../parse/ParseMachineTypeTest.java             |  16 +-
 .../parse/ParseMetadataTest.java                |  15 +-
 .../parse/ParseNetworkListTest.java             |  12 +-
 .../parse/ParseNetworkTest.java                 |  11 +-
 .../parse/ParseOperationListTest.java           |  15 +-
 .../parse/ParseOperationTest.java               |  16 +-
 .../parse/ParseProjectTest.java                 |  21 +-
 .../parse/ParseQuotaTest.java                   |   6 +-
 .../parse/ParseRegionListTest.java              |  66 +++
 .../parse/ParseRegionTest.java                  |  56 +++
 .../parse/ParseRouteListTest.java               |  65 +++
 .../parse/ParseRouteTest.java                   |  59 +++
 .../parse/ParseSnapshotListTest.java            |  67 +++
 .../parse/ParseSnapshotTest.java                |  55 +++
 .../parse/ParseZoneListTest.java                |  18 +-
 .../parse/ParseZoneTest.java                    |  11 +-
 .../src/test/resources/address_get.json         |  12 +
 .../src/test/resources/address_insert.json      |   1 +
 .../src/test/resources/address_list.json        |  31 ++
 .../test/resources/disk_create_snapshot.json    |   1 +
 .../src/test/resources/disk_get.json            |  16 +-
 .../src/test/resources/disk_insert.json         |   2 +-
 .../src/test/resources/disk_list.json           |  30 +-
 .../src/test/resources/firewall_get.json        |  52 +--
 .../src/test/resources/firewall_insert.json     |   2 +-
 .../src/test/resources/firewall_list.json       | 106 ++---
 .../src/test/resources/global_operation.json    |  15 +
 .../test/resources/global_operation_list.json   |  22 +
 .../src/test/resources/image_get.json           |  26 +-
 .../src/test/resources/image_insert.json        |   5 +-
 .../src/test/resources/image_list.json          |  44 +-
 .../resources/image_list_multiple_page_1.json   | 106 ++---
 .../resources/image_list_multiple_page_2.json   |  98 ++---
 .../test/resources/image_list_single_page.json  | 100 +++--
 .../resources/instance_add_access_config.json   |   8 +-
 .../test/resources/instance_attach_disk.json    |   6 +
 .../src/test/resources/instance_get.json        | 102 ++---
 .../src/test/resources/instance_insert.json     |   2 +-
 .../test/resources/instance_insert_simple.json  |   2 +-
 .../src/test/resources/instance_list.json       | 112 ++---
 .../instance_list_central1b_empty.json          |   6 +
 .../test/resources/instance_serial_port.json    |   4 +-
 .../test/resources/instance_set_metadata.json   |  10 +
 .../src/test/resources/kernel.json              |  12 +-
 .../src/test/resources/kernel_list.json         |  46 +-
 .../src/test/resources/logback.xml              |  41 +-
 .../src/test/resources/machinetype.json         |  39 +-
 .../src/test/resources/machinetype_list.json    |  94 ++--
 .../resources/machinetype_list_central1b.json   |  43 ++
 .../machinetype_list_central1b_empty.json       |   6 +
 .../src/test/resources/metadata.json            |   2 +-
 .../src/test/resources/network_get.json         |  16 +-
 .../src/test/resources/network_list.json        |  30 +-
 .../src/test/resources/operation.json           |  10 +-
 .../src/test/resources/operation_error.json     |  22 +-
 .../src/test/resources/operation_list.json      |  42 +-
 .../src/test/resources/project.json             | 131 +++---
 .../src/test/resources/region_get.json          |  13 +
 .../src/test/resources/region_list.json         |  32 ++
 .../src/test/resources/region_operation.json    |  16 +
 .../test/resources/region_operation_list.json   |  23 +
 .../src/test/resources/route_get.json           |  14 +
 .../src/test/resources/route_insert.json        |   1 +
 .../src/test/resources/route_list.json          |  34 ++
 .../src/test/resources/snapshot_get.json        |  13 +
 .../src/test/resources/snapshot_list.json       |  33 ++
 .../src/test/resources/tag_insert.json          |   1 +
 .../src/test/resources/zone_get.json            |  30 +-
 .../src/test/resources/zone_list.json           |  76 ++--
 .../src/test/resources/zone_list_short.json     |  24 +
 .../src/test/resources/zone_operation.json      |  16 +
 .../test/resources/zone_operation_error.json    |  25 ++
 .../src/test/resources/zone_operation_list.json |  23 +
 232 files changed, 10423 insertions(+), 2985 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/pom.xml
----------------------------------------------------------------------
diff --git a/google-compute-engine/pom.xml b/google-compute-engine/pom.xml
index 2461328..375192c 100644
--- a/google-compute-engine/pom.xml
+++ b/google-compute-engine/pom.xml
@@ -17,111 +17,123 @@
     limitations under the License.
 
 -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.jclouds.labs</groupId>
-    <artifactId>jclouds-labs-google</artifactId>
-    <version>1.7.0-SNAPSHOT</version>
-  </parent>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.jclouds.labs</groupId>
+        <artifactId>jclouds-labs-google</artifactId>
+        <version>1.7.0-SNAPSHOT</version>
+    </parent>
 
-  <!-- TODO: when out of labs, switch to org.jclouds.provider -->
-  <groupId>org.apache.jclouds.labs</groupId>
-  <artifactId>google-compute-engine</artifactId>
-  <name>jclouds Google Compute Engine provider</name>
-  <description>jclouds components to access GoogleCompute</description>
+    <!-- TODO: when out of labs, switch to org.jclouds.provider -->
+    <groupId>org.apache.jclouds.labs</groupId>
+    <artifactId>google-compute-engine</artifactId>
+    <name>jclouds Google Compute Engine provider</name>
+    <description>jclouds components to access GoogleCompute</description>
 
-  <properties>
-    <test.google-compute-engine.identity>Email associated with the Google API client_id</test.google-compute-engine.identity>
-    <test.google-compute-engine.credential>Private key (PKCS12 file) associated with the Google API client_id</test.google-compute-engine.credential>
-    <test.google-compute-engine.api-version>v1beta13</test.google-compute-engine.api-version>
-    <test.google-compute-engine.build-version />
-  </properties>
+    <properties>
+        <test.google-compute-engine.identity>Email associated with the Google API client_id
+        </test.google-compute-engine.identity>
+        <test.google-compute-engine.credential>Private key (PKCS12 file) associated with the Google API client_id
+        </test.google-compute-engine.credential>
+        <test.google-compute-engine.api-version>v1beta15</test.google-compute-engine.api-version>
+        <test.google-compute-engine.build-version/>
+        <test.google-compute-engine.template>osFamily=GCEL,osVersionMatches=1[012].[01][04],locationId=us-central1-a,minRam=2048</test.google-compute-engine.template>
+    </properties>
 
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.jclouds</groupId>
-      <artifactId>jclouds-core</artifactId>
-      <version>${jclouds.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.jclouds.labs</groupId>
-      <artifactId>oauth</artifactId>
-      <version>${project.version}</version>
-      <type>jar</type>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.jclouds.labs</groupId>
-      <artifactId>oauth</artifactId>
-      <version>${project.version}</version>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.jclouds</groupId>
-      <artifactId>jclouds-compute</artifactId>
-      <version>${jclouds.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.jclouds</groupId>
-      <artifactId>jclouds-compute</artifactId>
-      <version>${jclouds.version}</version>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.jclouds</groupId>
-      <artifactId>jclouds-core</artifactId>
-      <version>${jclouds.version}</version>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.jclouds.driver</groupId>
-      <artifactId>jclouds-slf4j</artifactId>
-      <version>${jclouds.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.jclouds.driver</groupId>
-      <artifactId>jclouds-sshj</artifactId>
-      <version>${jclouds.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>ch.qos.logback</groupId>
-      <artifactId>logback-classic</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-  <profiles>
-    <profile>
-      <id>live</id>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-surefire-plugin</artifactId>
-            <executions>
-              <execution>
-                <id>integration</id>
-                <phase>integration-test</phase>
-                <goals>
-                  <goal>test</goal>
-                </goals>
-                <configuration>
-                  <systemPropertyVariables>
-                    <test.google-compute-engine.identity>${test.google-compute-engine.identity}</test.google-compute-engine.identity>
-                    <test.google-compute-engine.credential>${test.google-compute-engine.credential}</test.google-compute-engine.credential>
-                    <test.google-compute-engine.api-version>${test.google-compute-engine.api-version}</test.google-compute-engine.api-version>
-                    <test.google-compute-engine.build-version>${test.google-compute-engine.build-version}</test.google-compute-engine.build-version>
-                  </systemPropertyVariables>
-                </configuration>
-              </execution>
-            </executions>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-  </profiles>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.jclouds</groupId>
+            <artifactId>jclouds-core</artifactId>
+            <version>${jclouds.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jclouds.labs</groupId>
+            <artifactId>oauth</artifactId>
+            <version>${project.version}</version>
+            <type>jar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jclouds.labs</groupId>
+            <artifactId>oauth</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jclouds</groupId>
+            <artifactId>jclouds-compute</artifactId>
+            <version>${jclouds.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jclouds</groupId>
+            <artifactId>jclouds-compute</artifactId>
+            <version>${jclouds.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jclouds</groupId>
+            <artifactId>jclouds-core</artifactId>
+            <version>${jclouds.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jclouds.driver</groupId>
+            <artifactId>jclouds-slf4j</artifactId>
+            <version>${jclouds.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jclouds.driver</groupId>
+            <artifactId>jclouds-sshj</artifactId>
+            <version>${jclouds.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <profiles>
+        <profile>
+            <id>live</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>integration</id>
+                                <phase>integration-test</phase>
+                                <goals>
+                                    <goal>test</goal>
+                                </goals>
+                                <configuration>
+                                    <systemPropertyVariables>
+                                        <test.google-compute-engine.identity>${test.google-compute-engine.identity}
+                                        </test.google-compute-engine.identity>
+                                        <test.google-compute-engine.credential>
+                                            ${test.google-compute-engine.credential}
+                                        </test.google-compute-engine.credential>
+                                        <test.google-compute-engine.api-version>
+                                            ${test.google-compute-engine.api-version}
+                                        </test.google-compute-engine.api-version>
+                                        <test.google-compute-engine.build-version>
+                                            ${test.google-compute-engine.build-version}
+                                        </test.google-compute-engine.build-version>
+                                        <test.google-compute-engine.template>${test.google-compute-engine.template}</test.google-compute-engine.template>
+                                    </systemPropertyVariables>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
 </project>

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApi.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApi.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApi.java
index 2567f0b..1f49bcc 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApi.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApi.java
@@ -21,16 +21,22 @@ import java.io.Closeable;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 
+import org.jclouds.googlecomputeengine.features.AddressApi;
 import org.jclouds.googlecomputeengine.features.DiskApi;
 import org.jclouds.googlecomputeengine.features.FirewallApi;
+import org.jclouds.googlecomputeengine.features.GlobalOperationApi;
 import org.jclouds.googlecomputeengine.features.ImageApi;
 import org.jclouds.googlecomputeengine.features.InstanceApi;
 import org.jclouds.googlecomputeengine.features.KernelApi;
 import org.jclouds.googlecomputeengine.features.MachineTypeApi;
 import org.jclouds.googlecomputeengine.features.NetworkApi;
-import org.jclouds.googlecomputeengine.features.OperationApi;
 import org.jclouds.googlecomputeengine.features.ProjectApi;
+import org.jclouds.googlecomputeengine.features.RegionApi;
+import org.jclouds.googlecomputeengine.features.RegionOperationApi;
+import org.jclouds.googlecomputeengine.features.RouteApi;
+import org.jclouds.googlecomputeengine.features.SnapshotApi;
 import org.jclouds.googlecomputeengine.features.ZoneApi;
+import org.jclouds.googlecomputeengine.features.ZoneOperationApi;
 import org.jclouds.rest.annotations.Delegate;
 
 import com.google.common.annotations.Beta;
@@ -41,12 +47,21 @@ import com.google.common.annotations.Beta;
  * <p/>
  *
  * @author David Alves
- * @see <a href="https://developers.google.com/compute/docs/reference/v1beta13">api doc</a>
+ * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15">api doc</a>
  */
 @Beta
 public interface GoogleComputeEngineApi extends Closeable {
 
    /**
+    * Provides access to Address features
+    *
+    * @param projectName the name of the project
+    */
+   @Delegate
+   @Path("/projects/{project}")
+   AddressApi getAddressApiForProject(@PathParam("project") String projectName);
+
+   /**
     * Provides access to Disk features
     *
     * @param projectName the name of the project
@@ -65,6 +80,15 @@ public interface GoogleComputeEngineApi extends Closeable {
    FirewallApi getFirewallApiForProject(@PathParam("project") String projectName);
 
    /**
+    * Provides access to Global Operation features
+    *
+    * @param projectName the name of the project
+    */
+   @Delegate
+   @Path("/projects/{project}")
+   GlobalOperationApi getGlobalOperationApiForProject(@PathParam("project") String projectName);
+
+   /**
     * Provides access to Image features
     *
     * @param projectName the name of the project
@@ -110,19 +134,46 @@ public interface GoogleComputeEngineApi extends Closeable {
    NetworkApi getNetworkApiForProject(@PathParam("project") String projectName);
 
    /**
-    * Provides access to Operation features
+    * Provides access to Project features
+    */
+   @Delegate
+   ProjectApi getProjectApi();
+
+   /**
+    * Provides access to Region features
     *
     * @param projectName the name of the project
     */
    @Delegate
    @Path("/projects/{project}")
-   OperationApi getOperationApiForProject(@PathParam("project") String projectName);
+   RegionApi getRegionApiForProject(@PathParam("project") String projectName);
 
    /**
-    * Provides access to Project features
+    * Provides access to Region Operation features
+    *
+    * @param projectName the name of the project
     */
    @Delegate
-   ProjectApi getProjectApi();
+   @Path("/projects/{project}")
+   RegionOperationApi getRegionOperationApiForProject(@PathParam("project") String projectName);
+
+   /**
+    * Provides access to Route features
+    *
+    * @param projectName the name of the project
+    */
+   @Delegate
+   @Path("/projects/{project}")
+   RouteApi getRouteApiForProject(@PathParam("project") String projectName);
+
+   /**
+    * Provides access to Snapshot features
+    *
+    * @param projectName the name of the project
+    */
+   @Delegate
+   @Path("/projects/{project}")
+   SnapshotApi getSnapshotApiForProject(@PathParam("project") String projectName);
 
    /**
     * Provides access to Zone features
@@ -133,5 +184,13 @@ public interface GoogleComputeEngineApi extends Closeable {
    @Path("/projects/{project}")
    ZoneApi getZoneApiForProject(@PathParam("project") String projectName);
 
+   /**
+    * Provides access to Zone Operation features
+    *
+    * @param projectName the name of the project
+    */
+   @Delegate
+   @Path("/projects/{project}")
+   ZoneOperationApi getZoneOperationApiForProject(@PathParam("project") String projectName);
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApiMetadata.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApiMetadata.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApiMetadata.java
index c7e1f2a..0333f6c 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApiMetadata.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApiMetadata.java
@@ -41,7 +41,7 @@ import com.google.common.collect.ImmutableSet;
 import com.google.inject.Module;
 
 /**
- * Implementation of {@link ApiMetadata} for GoogleCompute v1beta13 API
+ * Implementation of {@link ApiMetadata} for GoogleCompute v1beta15 API
  *
  * @author David Alves
  */
@@ -77,21 +77,21 @@ public class GoogleComputeEngineApiMetadata extends BaseHttpApiMetadata<GoogleCo
 
       protected Builder() {
          id(GCE_PROVIDER_NAME)
-        .name("Google Compute Engine Api")
-        .identityName("Email associated with the Google API client_id")
-        .credentialName("Private key literal associated with the Google API client_id")
-        .documentation(URI.create("https://developers.google.com/compute/docs"))
-        .version("v1beta13")
-        .defaultEndpoint("https://www.googleapis.com/compute/v1beta13")
-        .defaultProperties(GoogleComputeEngineApiMetadata.defaultProperties())
-        .view(typeToken(ComputeServiceContext.class))
-        .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
-                .add(GoogleComputeEngineHttpApiModule.class)
-                .add(GoogleComputeEngineParserModule.class)
-                .add(OAuthAuthenticationModule.class)
-                .add(OAuthModuleWithoutTypeAdapters.class)
-                .add(GoogleComputeEngineServiceContextModule.class)
-                .build());
+                 .name("Google Compute Engine Api")
+                 .identityName("Email associated with the Google API client_id")
+                 .credentialName("Private key literal associated with the Google API client_id")
+                 .documentation(URI.create("https://developers.google.com/compute/docs"))
+                 .version("v1beta15")
+                 .defaultEndpoint("https://www.googleapis.com/compute/v1beta15")
+                 .defaultProperties(GoogleComputeEngineApiMetadata.defaultProperties())
+                 .view(typeToken(ComputeServiceContext.class))
+                 .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
+                         .add(GoogleComputeEngineHttpApiModule.class)
+                         .add(GoogleComputeEngineParserModule.class)
+                         .add(OAuthAuthenticationModule.class)
+                         .add(OAuthModuleWithoutTypeAdapters.class)
+                         .add(GoogleComputeEngineServiceContextModule.class)
+                         .build());
       }
 
       @Override

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineConstants.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineConstants.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineConstants.java
index dd83ce0..1334a32 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineConstants.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineConstants.java
@@ -16,11 +16,12 @@
  */
 package org.jclouds.googlecomputeengine;
 
-import com.google.common.annotations.Beta;
 import org.jclouds.domain.Location;
 import org.jclouds.domain.LocationBuilder;
 import org.jclouds.domain.LocationScope;
 
+import com.google.common.annotations.Beta;
+
 /**
  * @author David Alves
  */
@@ -37,6 +38,11 @@ public interface GoogleComputeEngineConstants {
 
    public static final String COMPUTE_READONLY_SCOPE = "https://www.googleapis.com/auth/compute.readonly";
 
+   public static final String STORAGE_READONLY_SCOPE = "https://www.googleapis.com/auth/devstorage.read_only";
+
+   public static final String STORAGE_WRITEONLY_SCOPE = "https://www.googleapis.com/auth/devstorage.write_only";
+
+
    /**
     * The total time, in msecs, to wait for an operation to complete.
     */

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineService.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineService.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineService.java
index e7b9e1c..4abcfc4 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineService.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineService.java
@@ -16,11 +16,23 @@
  */
 package org.jclouds.googlecomputeengine.compute;
 
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
-import com.google.common.util.concurrent.ListeningExecutorService;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
+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.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Provider;
+
 import org.jclouds.Constants;
 import org.jclouds.collect.Memoized;
 import org.jclouds.compute.ComputeServiceContext;
@@ -54,21 +66,11 @@ import org.jclouds.googlecomputeengine.domain.Operation;
 import org.jclouds.http.HttpResponse;
 import org.jclouds.scriptbuilder.functions.InitAdminAccess;
 
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Provider;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
-import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
-import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
-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 com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.util.concurrent.ListeningExecutorService;
 
 /**
  * @author David Alves
@@ -117,7 +119,7 @@ public class GoogleComputeEngineService extends BaseComputeService {
                                         GroupNamingConvention.Factory namingConvention,
                                         GoogleComputeEngineApi api,
                                         @UserProject Supplier<String> project,
-                                        Predicate<AtomicReference<Operation>> operationDonePredicate,
+                                        @Named("global") Predicate<AtomicReference<Operation>> operationDonePredicate,
                                         @Named(OPERATION_COMPLETE_INTERVAL) Long operationCompleteCheckInterval,
                                         @Named(OPERATION_COMPLETE_TIMEOUT) Long operationCompleteCheckTimeout) {
 

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java
index aaa6271..b949f13 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java
@@ -16,53 +16,62 @@
  */
 package org.jclouds.googlecomputeengine.compute;
 
-import com.google.common.base.Function;
-import com.google.common.base.Objects;
-import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.util.concurrent.UncheckedTimeoutException;
-import com.google.inject.Inject;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.collect.Iterables.contains;
+import static com.google.common.collect.Iterables.filter;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GOOGLE_PROJECT;
+import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_INTERVAL;
+import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_TIMEOUT;
+import static org.jclouds.googlecomputeengine.domain.Instance.NetworkInterface.AccessConfig.Type;
+import static org.jclouds.util.Predicates2.retry;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+
+import org.jclouds.collect.Memoized;
 import org.jclouds.compute.ComputeServiceAdapter;
 import org.jclouds.compute.domain.Hardware;
 import org.jclouds.compute.domain.Template;
 import org.jclouds.compute.options.TemplateOptions;
 import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.domain.Location;
 import org.jclouds.domain.LoginCredentials;
 import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
 import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
 import org.jclouds.googlecomputeengine.config.UserProject;
 import org.jclouds.googlecomputeengine.domain.Image;
 import org.jclouds.googlecomputeengine.domain.Instance;
+import org.jclouds.googlecomputeengine.domain.InstanceInZone;
 import org.jclouds.googlecomputeengine.domain.InstanceTemplate;
 import org.jclouds.googlecomputeengine.domain.MachineType;
+import org.jclouds.googlecomputeengine.domain.MachineTypeInZone;
 import org.jclouds.googlecomputeengine.domain.Operation;
+import org.jclouds.googlecomputeengine.domain.SlashEncodedIds;
 import org.jclouds.googlecomputeengine.domain.Zone;
 import org.jclouds.http.HttpResponse;
 import org.jclouds.logging.Logger;
 
-import javax.annotation.Resource;
-import javax.inject.Named;
-import java.net.URI;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-import static com.google.common.collect.Iterables.contains;
-import static com.google.common.collect.Iterables.filter;
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GOOGLE_PROJECT;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_INTERVAL;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_TIMEOUT;
-import static org.jclouds.googlecomputeengine.domain.Instance.NetworkInterface.AccessConfig.Type;
-import static org.jclouds.util.Predicates2.retry;
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.util.concurrent.UncheckedTimeoutException;
+import com.google.inject.Inject;
 
 /**
  * @author David Alves
  */
-public class GoogleComputeEngineServiceAdapter implements ComputeServiceAdapter<Instance, MachineType, Image, Zone> {
+public class GoogleComputeEngineServiceAdapter implements ComputeServiceAdapter<InstanceInZone, MachineTypeInZone, Image, Zone> {
 
    @Resource
    @Named(ComputeServiceConstants.COMPUTE_LOGGER)
@@ -70,6 +79,8 @@ public class GoogleComputeEngineServiceAdapter implements ComputeServiceAdapter<
 
    private final GoogleComputeEngineApi api;
    private final Supplier<String> userProject;
+   private final Supplier<Map<URI, ? extends Location>> zones;
+   private final Supplier<Map<URI, ? extends Hardware>> hardwareMap;
    private final Function<TemplateOptions, ImmutableMap.Builder<String, String>> metatadaFromTemplateOptions;
    private final Predicate<AtomicReference<Operation>> retryOperationDonePredicate;
    private final long operationCompleteCheckInterval;
@@ -80,9 +91,11 @@ public class GoogleComputeEngineServiceAdapter implements ComputeServiceAdapter<
                                             @UserProject Supplier<String> userProject,
                                             Function<TemplateOptions,
                                                     ImmutableMap.Builder<String, String>> metatadaFromTemplateOptions,
-                                            Predicate<AtomicReference<Operation>> operationDonePredicate,
+                                            @Named("zone") Predicate<AtomicReference<Operation>> operationDonePredicate,
                                             @Named(OPERATION_COMPLETE_INTERVAL) Long operationCompleteCheckInterval,
-                                            @Named(OPERATION_COMPLETE_TIMEOUT) Long operationCompleteCheckTimeout) {
+                                            @Named(OPERATION_COMPLETE_TIMEOUT) Long operationCompleteCheckTimeout,
+                                            @Memoized Supplier<Map<URI, ? extends Location>> zones,
+                                            @Memoized Supplier<Map<URI, ? extends Hardware>> hardwareMap) {
       this.api = checkNotNull(api, "google compute api");
       this.userProject = checkNotNull(userProject, "user project name");
       this.metatadaFromTemplateOptions = checkNotNull(metatadaFromTemplateOptions,
@@ -93,21 +106,24 @@ public class GoogleComputeEngineServiceAdapter implements ComputeServiceAdapter<
               "operation completed check timeout");
       this.retryOperationDonePredicate = retry(operationDonePredicate, operationCompleteCheckTimeout,
               operationCompleteCheckInterval, TimeUnit.MILLISECONDS);
+      this.zones = checkNotNull(zones, "zones");
+      this.hardwareMap = checkNotNull(hardwareMap, "hardwareMap");
    }
 
    @Override
-   public NodeAndInitialCredentials<Instance> createNodeWithGroupEncodedIntoName(
-           final String group, final String name, Template template) {
+   public NodeAndInitialCredentials<InstanceInZone> createNodeWithGroupEncodedIntoName(
+           final String group, final String name, final Template template) {
 
       checkNotNull(template, "template");
 
       GoogleComputeEngineTemplateOptions options = GoogleComputeEngineTemplateOptions.class.cast(template.getOptions()).clone();
       checkState(options.getNetwork().isPresent(), "network was not present in template options");
       Hardware hardware = checkNotNull(template.getHardware(), "hardware must be set");
-      URI machineType = checkNotNull(hardware.getUri(), "hardware uri must be set");
+
+      checkNotNull(hardware.getUri(), "hardware must have a URI");
 
       InstanceTemplate instanceTemplate = InstanceTemplate.builder()
-              .forMachineType(machineType);
+              .forMachineType(hardware.getUri());
 
       if (options.isEnableNat()) {
          instanceTemplate.addNetworkInterface(options.getNetwork().get(), Type.ONE_TO_ONE_NAT);
@@ -119,12 +135,11 @@ public class GoogleComputeEngineServiceAdapter implements ComputeServiceAdapter<
 
       ImmutableMap.Builder<String, String> metadataBuilder = metatadaFromTemplateOptions.apply(options);
       instanceTemplate.metadata(metadataBuilder.build());
-      instanceTemplate.tags(options.getTags());
       instanceTemplate.serviceAccounts(options.getServiceAccounts());
       instanceTemplate.image(checkNotNull(template.getImage().getUri(), "image URI is null"));
 
       Operation operation = api.getInstanceApiForProject(userProject.get())
-              .createInZone(name, instanceTemplate, template.getLocation().getId());
+              .createInZone(name, template.getLocation().getId(), instanceTemplate);
 
       if (options.shouldBlockUntilRunning()) {
          waitOperationDone(operation);
@@ -136,18 +151,52 @@ public class GoogleComputeEngineServiceAdapter implements ComputeServiceAdapter<
       retry(new Predicate<AtomicReference<Instance>>() {
          @Override
          public boolean apply(AtomicReference<Instance> input) {
-            input.set(api.getInstanceApiForProject(userProject.get()).get(name));
+            input.set(api.getInstanceApiForProject(userProject.get()).getInZone(template.getLocation().getId(),
+                    name));
             return input.get() != null;
          }
       }, operationCompleteCheckTimeout, operationCompleteCheckInterval, MILLISECONDS).apply(instance);
 
-      return new NodeAndInitialCredentials<Instance>(instance.get(), name, credentials);
+      if (options.getTags().size() > 0) {
+         Operation tagsOperation = api.getInstanceApiForProject(userProject.get()).setTagsInZone(template.getLocation().getId(),
+                 name, options.getTags(), instance.get().getTags().getFingerprint());
+
+         waitOperationDone(tagsOperation);
+
+         retry(new Predicate<AtomicReference<Instance>>() {
+            @Override
+            public boolean apply(AtomicReference<Instance> input) {
+               input.set(api.getInstanceApiForProject(userProject.get()).getInZone(template.getLocation().getId(),
+                       name));
+               return input.get() != null;
+            }
+         }, operationCompleteCheckTimeout, operationCompleteCheckInterval, MILLISECONDS).apply(instance);
+      }
+
+      InstanceInZone instanceInZone = new InstanceInZone(instance.get(), template.getLocation().getId());
+
+      return new NodeAndInitialCredentials<InstanceInZone>(instanceInZone, instanceInZone.slashEncode(), credentials);
    }
 
 
    @Override
-   public Iterable<MachineType> listHardwareProfiles() {
-      return api.getMachineTypeApiForProject(userProject.get()).list().concat();
+   public Iterable<MachineTypeInZone> listHardwareProfiles() {
+      ImmutableSet.Builder<MachineTypeInZone> builder = ImmutableSet.builder();
+
+      for (final Location zone : zones.get().values()) {
+         builder.addAll(api.getMachineTypeApiForProject(userProject.get())
+                 .listInZone(zone.getId())
+                 .concat()
+                 .transform(new Function<MachineType, MachineTypeInZone>() {
+
+                    @Override
+                    public MachineTypeInZone apply(MachineType arg0) {
+                       return new MachineTypeInZone(arg0, arg0.getZone());
+                    }
+                 }));
+      }
+
+      return builder.build();
    }
 
    @Override
@@ -170,34 +219,57 @@ public class GoogleComputeEngineServiceAdapter implements ComputeServiceAdapter<
    }
 
    @Override
-   public Instance getNode(String name) {
-      return api.getInstanceApiForProject(userProject.get()).get(name);
+   public InstanceInZone getNode(String name) {
+      SlashEncodedIds slashEncodedIds = SlashEncodedIds.fromSlashEncoded(name);
+
+      Instance instance= api.getInstanceApiForProject(userProject.get()).getInZone(slashEncodedIds.getFirstId(),
+              slashEncodedIds.getSecondId());
+
+      return instance == null ?  null : new InstanceInZone(instance, slashEncodedIds.getFirstId());
    }
 
    @Override
-   public Iterable<Instance> listNodes() {
-      return api.getInstanceApiForProject(userProject.get()).list().concat();
+   public Iterable<InstanceInZone> listNodes() {
+      return FluentIterable.from(zones.get().values()).transformAndConcat(new Function<Location, ImmutableSet<InstanceInZone>>() {
+         @Override
+         public ImmutableSet<InstanceInZone> apply(final Location input) {
+            return api.getInstanceApiForProject(userProject.get()).listInZone(input.getId()).concat()
+                    .transform(new Function<Instance, InstanceInZone>() {
+
+                       @Override
+                       public InstanceInZone apply(Instance arg0) {
+                          return new InstanceInZone(arg0, input.getId());
+                       }
+                    }).toSet();
+         }
+      }).toSet();
    }
 
    @Override
-   public Iterable<Instance> listNodesByIds(final Iterable<String> ids) {
-      return filter(listNodes(), new Predicate<Instance>() {
+   public Iterable<InstanceInZone> listNodesByIds(final Iterable<String> ids) {
+      return filter(listNodes(), new Predicate<InstanceInZone>() {
 
          @Override
-         public boolean apply(Instance instance) {
-            return contains(ids, instance.getName());
+         public boolean apply(InstanceInZone instanceInZone) {
+            return contains(ids, instanceInZone.getInstance().getName());
          }
       });
    }
 
    @Override
    public void destroyNode(final String name) {
-      waitOperationDone(api.getInstanceApiForProject(userProject.get()).delete(name));
+      SlashEncodedIds slashEncodedIds = SlashEncodedIds.fromSlashEncoded(name);
+
+      waitOperationDone(api.getInstanceApiForProject(userProject.get()).deleteInZone(slashEncodedIds.getFirstId(),
+              slashEncodedIds.getSecondId()));
    }
 
    @Override
-   public void rebootNode(String name) {
-      throw new UnsupportedOperationException("reboot is not supported by GCE");
+   public void rebootNode(final String name) {
+      SlashEncodedIds slashEncodedIds = SlashEncodedIds.fromSlashEncoded(name);
+
+      waitOperationDone(api.getInstanceApiForProject(userProject.get()).resetInZone(slashEncodedIds.getFirstId(),
+              slashEncodedIds.getSecondId()));
    }
 
    @Override

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/config/GoogleComputeEngineServiceContextModule.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/config/GoogleComputeEngineServiceContextModule.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/config/GoogleComputeEngineServiceContextModule.java
index f3ecb6c..1e3580b 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/config/GoogleComputeEngineServiceContextModule.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/config/GoogleComputeEngineServiceContextModule.java
@@ -16,15 +16,19 @@
  */
 package org.jclouds.googlecomputeengine.compute.config;
 
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
-import com.google.common.collect.ImmutableMap;
-import com.google.inject.Injector;
-import com.google.inject.Provides;
-import com.google.inject.TypeLiteral;
+import static com.google.common.collect.Iterables.transform;
+import static com.google.common.collect.Maps.uniqueIndex;
+import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
 import org.jclouds.collect.Memoized;
 import org.jclouds.compute.ComputeService;
 import org.jclouds.compute.ComputeServiceAdapter;
@@ -40,9 +44,10 @@ import org.jclouds.googlecomputeengine.compute.GoogleComputeEngineService;
 import org.jclouds.googlecomputeengine.compute.GoogleComputeEngineServiceAdapter;
 import org.jclouds.googlecomputeengine.compute.functions.BuildInstanceMetadata;
 import org.jclouds.googlecomputeengine.compute.functions.GoogleComputeEngineImageToImage;
-import org.jclouds.googlecomputeengine.compute.functions.InstanceToNodeMetadata;
-import org.jclouds.googlecomputeengine.compute.functions.MachineTypeToHardware;
+import org.jclouds.googlecomputeengine.compute.functions.InstanceInZoneToNodeMetadata;
+import org.jclouds.googlecomputeengine.compute.functions.MachineTypeInZoneToHardware;
 import org.jclouds.googlecomputeengine.compute.functions.OrphanedGroupsFromDeadNodes;
+import org.jclouds.googlecomputeengine.compute.functions.RegionToLocation;
 import org.jclouds.googlecomputeengine.compute.functions.ZoneToLocation;
 import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
 import org.jclouds.googlecomputeengine.compute.predicates.AllNodesInGroupTerminated;
@@ -52,22 +57,28 @@ import org.jclouds.googlecomputeengine.compute.strategy.UseNodeCredentialsButOve
 import org.jclouds.googlecomputeengine.config.UserProject;
 import org.jclouds.googlecomputeengine.domain.Image;
 import org.jclouds.googlecomputeengine.domain.Instance;
-import org.jclouds.googlecomputeengine.domain.MachineType;
+import org.jclouds.googlecomputeengine.domain.InstanceInZone;
+import org.jclouds.googlecomputeengine.domain.MachineTypeInZone;
+import org.jclouds.googlecomputeengine.domain.Region;
 import org.jclouds.googlecomputeengine.domain.Zone;
+import org.jclouds.rest.AuthorizationException;
+import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
 
-import javax.inject.Singleton;
-import java.net.URI;
-import java.util.Map;
-import java.util.Set;
-
-import static com.google.common.collect.Iterables.transform;
-import static com.google.common.collect.Maps.uniqueIndex;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableMap;
+import com.google.inject.Injector;
+import com.google.inject.Provides;
+import com.google.inject.TypeLiteral;
 
 /**
  * @author David Alves
  */
 public class GoogleComputeEngineServiceContextModule
-        extends ComputeServiceAdapterContextModule<Instance, MachineType, Image, Zone> {
+        extends ComputeServiceAdapterContextModule<InstanceInZone, MachineTypeInZone, Image, Zone> {
 
    @Override
    protected void configure() {
@@ -75,18 +86,22 @@ public class GoogleComputeEngineServiceContextModule
 
       bind(ComputeService.class).to(GoogleComputeEngineService.class);
 
-      bind(new TypeLiteral<ComputeServiceAdapter<Instance, MachineType, Image, Zone>>() {})
+      bind(new TypeLiteral<ComputeServiceAdapter<InstanceInZone, MachineTypeInZone, Image, Zone>>() {})
               .to(GoogleComputeEngineServiceAdapter.class);
 
-      bind(new TypeLiteral<Function<Instance, NodeMetadata>>() {})
-              .to(InstanceToNodeMetadata.class);
+      bind(new TypeLiteral<Function<InstanceInZone, NodeMetadata>>() {})
+              .to(InstanceInZoneToNodeMetadata.class);
 
-      bind(new TypeLiteral<Function<MachineType, Hardware>>() {})
-              .to(MachineTypeToHardware.class);
+      bind(new TypeLiteral<Function<MachineTypeInZone, Hardware>>() {})
+              .to(MachineTypeInZoneToHardware.class);
 
       bind(new TypeLiteral<Function<Image, org.jclouds.compute.domain.Image>>() {})
               .to(GoogleComputeEngineImageToImage.class);
 
+      bind(new TypeLiteral<Function<Region, Location>>() {
+      })
+              .to(RegionToLocation.class);
+
       bind(new TypeLiteral<Function<Zone, Location>>() {})
               .to(ZoneToLocation.class);
 
@@ -108,7 +123,7 @@ public class GoogleComputeEngineServiceContextModule
 
       bind(PrioritizeCredentialsFromTemplate.class).to(UseNodeCredentialsButOverrideFromTemplate.class);
 
-      install(new LocationsFromComputeServiceAdapterModule<Instance, MachineType, Image, Zone>() {});
+      install(new LocationsFromComputeServiceAdapterModule<InstanceInZone, MachineTypeInZone, Image, Zone>() {});
 
    }
 
@@ -116,56 +131,92 @@ public class GoogleComputeEngineServiceContextModule
    @Singleton
    @Memoized
    public Supplier<Map<URI, ? extends org.jclouds.compute.domain.Image>> provideImagesMap(
-           final Supplier<Set<? extends org.jclouds.compute.domain.Image>> images) {
-      return new Supplier<Map<URI, ? extends org.jclouds.compute.domain.Image>>() {
-         @Override
-         public Map<URI, ? extends org.jclouds.compute.domain.Image> get() {
-            return uniqueIndex(images.get(), new Function<org.jclouds.compute.domain.Image, URI>() {
-               @Override
-               public URI apply(org.jclouds.compute.domain.Image input) {
-                  return input.getUri();
-               }
-            });
-         }
-      };
+           AtomicReference<AuthorizationException> authException,
+           final Supplier<Set<? extends org.jclouds.compute.domain.Image>> images,
+           @Named(PROPERTY_SESSION_INTERVAL) long seconds) {
+      return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException,
+              new Supplier<Map<URI, ? extends org.jclouds.compute.domain.Image>>() {
+                 @Override
+                 public Map<URI, ? extends org.jclouds.compute.domain.Image> get() {
+                    return uniqueIndex(images.get(), new Function<org.jclouds.compute.domain.Image, URI>() {
+                       @Override
+                       public URI apply(org.jclouds.compute.domain.Image input) {
+                          return input.getUri();
+                       }
+                    });
+                 }
+              },
+              seconds, TimeUnit.SECONDS);
    }
 
    @Provides
    @Singleton
    @Memoized
    public Supplier<Map<URI, ? extends Hardware>> provideHardwaresMap(
-           final Supplier<Set<? extends Hardware>> hardwares) {
-      return new Supplier<Map<URI, ? extends Hardware>>() {
-         @Override
-         public Map<URI, ? extends Hardware> get() {
-            return uniqueIndex(hardwares.get(), new Function<Hardware, URI>() {
-               @Override
-               public URI apply(Hardware input) {
-                  return input.getUri();
-               }
-            });
-         }
-      };
+           AtomicReference<AuthorizationException> authException,
+           final Supplier<Set<? extends Hardware>> hardwares,
+           @Named(PROPERTY_SESSION_INTERVAL) long seconds) {
+      return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException,
+              new Supplier<Map<URI, ? extends Hardware>>() {
+                 @Override
+                 public Map<URI, ? extends Hardware> get() {
+                    return uniqueIndex(hardwares.get(), new Function<Hardware, URI>() {
+                       @Override
+                       public URI apply(Hardware input) {
+                          return input.getUri();
+                       }
+                    });
+                 }
+              },
+              seconds, TimeUnit.SECONDS);
    }
 
    @Provides
    @Singleton
    @Memoized
-   public Supplier<Map<URI, ? extends Location>> provideLocations(
+   public Supplier<Map<URI, ? extends Location>> provideZones(
+           AtomicReference<AuthorizationException> authException,
            final GoogleComputeEngineApi api, final Function<Zone, Location> zoneToLocation,
-           final @UserProject Supplier<String> userProject) {
-      return new Supplier<Map<URI, ? extends Location>>() {
-         @Override
-         public Map<URI, ? extends Location> get() {
-            return uniqueIndex(transform(api.getZoneApiForProject(userProject.get()).list().concat(), zoneToLocation),
-                    new Function<Location, URI>() {
-                       @Override
-                       public URI apply(Location input) {
-                          return (URI) input.getMetadata().get("selfLink");
-                       }
-                    });
-         }
-      };
+           final @UserProject Supplier<String> userProject,
+           @Named(PROPERTY_SESSION_INTERVAL) long seconds) {
+      return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException,
+              new Supplier<Map<URI, ? extends Location>>() {
+                 @Override
+                 public Map<URI, ? extends Location> get() {
+                    return uniqueIndex(transform(api.getZoneApiForProject(userProject.get()).list().concat(), zoneToLocation),
+                            new Function<Location, URI>() {
+                               @Override
+                               public URI apply(Location input) {
+                                  return (URI) input.getMetadata().get("selfLink");
+                               }
+                            });
+                 }
+              },
+              seconds, TimeUnit.SECONDS);
+   }
+
+   @Provides
+   @Singleton
+   @Memoized
+   public Supplier<Map<URI, Region>> provideRegions(
+           AtomicReference<AuthorizationException> authException,
+           final GoogleComputeEngineApi api,
+           final @UserProject Supplier<String> userProject,
+           @Named(PROPERTY_SESSION_INTERVAL) long seconds) {
+      return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException,
+              new Supplier<Map<URI, Region>>() {
+                 @Override
+                 public Map<URI, Region> get() {
+                    return uniqueIndex(api.getRegionApiForProject(userProject.get()).list().concat(),
+                            new Function<Region, URI>() {
+                               @Override
+                               public URI apply(Region input) {
+                                  return input.getSelfLink();
+                               }
+                            });
+                 }
+              },
+              seconds, TimeUnit.SECONDS);
    }
 
    @Override

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/BuildInstanceMetadata.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/BuildInstanceMetadata.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/BuildInstanceMetadata.java
index 85837a7..27564e6 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/BuildInstanceMetadata.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/BuildInstanceMetadata.java
@@ -16,14 +16,15 @@
  */
 package org.jclouds.googlecomputeengine.compute.functions;
 
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableMap;
-import org.jclouds.compute.options.TemplateOptions;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.lang.String.format;
 
 import javax.inject.Singleton;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-import static java.lang.String.format;
+import org.jclouds.compute.options.TemplateOptions;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableMap;
 
 /**
  * Prepares metadata from the provided TemplateOptions

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/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 ea5f893..f352879 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
@@ -16,21 +16,22 @@
  */
 package org.jclouds.googlecomputeengine.compute.functions;
 
-import com.google.common.base.Function;
-import com.google.common.collect.Lists;
-import org.jclouds.compute.domain.ImageBuilder;
-import org.jclouds.compute.domain.OperatingSystem;
-import org.jclouds.compute.domain.OsFamily;
-import org.jclouds.googlecomputeengine.domain.Image;
-
-import java.util.List;
-
 import static com.google.common.base.Joiner.on;
 import static com.google.common.collect.Iterables.getLast;
 import static com.google.common.collect.Iterables.limit;
 import static com.google.common.collect.Iterables.skip;
 import static org.jclouds.compute.domain.Image.Status;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GOOGLE_PROVIDER_LOCATION;
+
+import java.util.List;
+
+import org.jclouds.compute.domain.ImageBuilder;
+import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.googlecomputeengine.domain.Image;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
 
 /**
  * Transforms a google compute domain specific image to a generic Image object.
@@ -48,7 +49,6 @@ public class GoogleComputeEngineImageToImage implements Function<Image, org.jclo
               .providerId(image.getId())
               .description(image.getDescription().orNull())
               .status(Status.AVAILABLE)
-              .location(GOOGLE_PROVIDER_LOCATION)
               .uri(image.getSelfLink());
 
       List<String> splits = Lists.newArrayList(image.getName().split("-"));
@@ -65,6 +65,9 @@ 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()));
+      }
       builder.version(getLast(splits));
       return builder.operatingSystem(osBuilder.build()).build();
    }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/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
new file mode 100644
index 0000000..93ecaad
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/InstanceInZoneToNodeMetadata.java
@@ -0,0 +1,117 @@
+/*
+ * 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 java.net.URI;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.NodeMetadataBuilder;
+import org.jclouds.compute.functions.GroupNamingConvention;
+import org.jclouds.domain.Location;
+import org.jclouds.googlecomputeengine.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.Supplier;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Transforms a google compute domain Instance into a generic NodeMetatada object.
+ *
+ * @author David Alves
+ */
+public class InstanceInZoneToNodeMetadata implements Function<InstanceInZone, NodeMetadata> {
+
+   private final Map<Instance.Status, NodeMetadata.Status> toPortableNodeStatus;
+   private final GroupNamingConvention nodeNamingConvention;
+   private final Supplier<Map<URI, ? extends Image>> images;
+   private final Supplier<Map<URI, ? extends Hardware>> hardwares;
+   private final Supplier<Map<URI, ? extends Location>> locations;
+
+   @Inject
+   public InstanceInZoneToNodeMetadata(Map<Instance.Status, NodeMetadata.Status> toPortableNodeStatus,
+                                 GroupNamingConvention.Factory namingConvention,
+                                 @Memoized Supplier<Map<URI, ? extends Image>> images,
+                                 @Memoized Supplier<Map<URI, ? extends Hardware>> hardwares,
+                                 @Memoized Supplier<Map<URI, ? extends Location>> locations) {
+      this.toPortableNodeStatus = toPortableNodeStatus;
+      this.nodeNamingConvention = namingConvention.createWithoutPrefix();
+      this.images = images;
+      this.hardwares = hardwares;
+      this.locations = locations;
+   }
+
+   @Override
+   public NodeMetadata apply(InstanceInZone instanceInZone) {
+      Instance input = instanceInZone.getInstance();
+      Map<URI, ? extends Image> imagesMap = images.get();
+      Image image = checkNotNull(imagesMap.get(checkNotNull(input.getImage(), "image")),
+              "no image for %s. images: %s", input.getImage(), imagesMap.values());
+
+      return new NodeMetadataBuilder()
+              .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())
+              .imageId(image.getId())
+              .location(checkNotNull(locations.get().get(input.getZone()), "location for %s", input.getZone()))
+              .hardware(checkNotNull(hardwares.get().get(input.getMachineType()), "hardware type for %s",
+                      input.getMachineType().toString()))
+              .operatingSystem(image.getOperatingSystem())
+              .status(toPortableNodeStatus.get(input.getStatus()))
+              .tags(input.getTags().getItems())
+              .uri(input.getSelfLink())
+              .userMetadata(input.getMetadata().getItems())
+              .group(nodeNamingConvention.groupInUniqueNameOrNull(input.getName()))
+              .privateAddresses(collectPrivateAddresses(input))
+              .publicAddresses(collectPublicAddresses(input))
+              .build();
+   }
+
+   private Set<String> collectPrivateAddresses(Instance input) {
+      ImmutableSet.Builder<String> privateAddressesBuilder = ImmutableSet.builder();
+      for (Instance.NetworkInterface networkInterface : input.getNetworkInterfaces()) {
+         if (networkInterface.getNetworkIP().isPresent()) {
+            privateAddressesBuilder.add(networkInterface.getNetworkIP().get());
+         }
+      }
+      return privateAddressesBuilder.build();
+   }
+
+   private Set<String> collectPublicAddresses(Instance input) {
+      ImmutableSet.Builder<String> publicAddressesBuilder = ImmutableSet.builder();
+      for (Instance.NetworkInterface networkInterface : input.getNetworkInterfaces()) {
+         for (Instance.NetworkInterface.AccessConfig accessConfig : networkInterface.getAccessConfigs()) {
+            if (accessConfig.getNatIP().isPresent()) {
+               publicAddressesBuilder.add(accessConfig.getNatIP().get());
+            }
+         }
+      }
+      return publicAddressesBuilder.build();
+   }
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/InstanceToNodeMetadata.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/InstanceToNodeMetadata.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/InstanceToNodeMetadata.java
deleted file mode 100644
index 40be835..0000000
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/InstanceToNodeMetadata.java
+++ /dev/null
@@ -1,111 +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.functions;
-
-import com.google.common.base.Function;
-import com.google.common.base.Supplier;
-import com.google.common.collect.ImmutableSet;
-import org.jclouds.collect.Memoized;
-import org.jclouds.compute.domain.Hardware;
-import org.jclouds.compute.domain.Image;
-import org.jclouds.compute.domain.NodeMetadata;
-import org.jclouds.compute.domain.NodeMetadataBuilder;
-import org.jclouds.compute.functions.GroupNamingConvention;
-import org.jclouds.domain.Location;
-import org.jclouds.googlecomputeengine.domain.Instance;
-
-import javax.inject.Inject;
-import java.net.URI;
-import java.util.Map;
-import java.util.Set;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Transforms a google compute domain Instance into a generic NodeMetatada object.
- *
- * @author David Alves
- */
-public class InstanceToNodeMetadata implements Function<Instance, NodeMetadata> {
-
-   private final Map<Instance.Status, NodeMetadata.Status> toPortableNodeStatus;
-   private final GroupNamingConvention nodeNamingConvention;
-   private final Supplier<Map<URI, ? extends Image>> images;
-   private final Supplier<Map<URI, ? extends Hardware>> hardwares;
-   private final Supplier<Map<URI, ? extends Location>> locations;
-
-   @Inject
-   public InstanceToNodeMetadata(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) {
-      this.toPortableNodeStatus = toPortableNodeStatus;
-      this.nodeNamingConvention = namingConvention.createWithoutPrefix();
-      this.images = images;
-      this.hardwares = hardwares;
-      this.locations = locations;
-   }
-
-   @Override
-   public NodeMetadata apply(Instance input) {
-      Map<URI, ? extends Image> imagesMap = images.get();
-      Image image = checkNotNull(imagesMap.get(checkNotNull(input.getImage(), "image")),
-              "no image for %s. images: %s", input.getImage(), imagesMap.values());
-
-      return new NodeMetadataBuilder()
-              .id(input.getName())
-              .name(input.getName())
-              .providerId(input.getId())
-              .hostname(input.getName())
-              .imageId(image.getId())
-              .location(checkNotNull(locations.get().get(input.getZone()), "location for %s", input.getZone()))
-              .hardware(checkNotNull(hardwares.get().get(input.getMachineType()), "hardware type for %s",
-                      input.getMachineType().toString()))
-              .operatingSystem(image.getOperatingSystem())
-              .status(toPortableNodeStatus.get(input.getStatus()))
-              .tags(input.getTags())
-              .uri(input.getSelfLink())
-              .userMetadata(input.getMetadata())
-              .group(nodeNamingConvention.groupInUniqueNameOrNull(input.getName()))
-              .privateAddresses(collectPrivateAddresses(input))
-              .publicAddresses(collectPublicAddresses(input))
-              .build();
-   }
-
-   private Set<String> collectPrivateAddresses(Instance input) {
-      ImmutableSet.Builder<String> privateAddressesBuilder = ImmutableSet.builder();
-      for (Instance.NetworkInterface networkInterface : input.getNetworkInterfaces()) {
-         if (networkInterface.getNetworkIP().isPresent()) {
-            privateAddressesBuilder.add(networkInterface.getNetworkIP().get());
-         }
-      }
-      return privateAddressesBuilder.build();
-   }
-
-   private Set<String> collectPublicAddresses(Instance input) {
-      ImmutableSet.Builder<String> publicAddressesBuilder = ImmutableSet.builder();
-      for (Instance.NetworkInterface networkInterface : input.getNetworkInterfaces()) {
-         for (Instance.NetworkInterface.AccessConfig accessConfig : networkInterface.getAccessConfigs()) {
-            if (accessConfig.getNatIP().isPresent()) {
-               publicAddressesBuilder.add(accessConfig.getNatIP().get());
-            }
-         }
-      }
-      return publicAddressesBuilder.build();
-   }
-}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/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
new file mode 100644
index 0000000..9d94e32
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/MachineTypeInZoneToHardware.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.googlecomputeengine.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.getOnlyElement;
+
+import java.net.URI;
+import java.util.Map;
+
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.HardwareBuilder;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.Processor;
+import org.jclouds.compute.domain.Volume;
+import org.jclouds.compute.domain.VolumeBuilder;
+import org.jclouds.domain.Location;
+import org.jclouds.googlecomputeengine.domain.MachineType;
+import org.jclouds.googlecomputeengine.domain.MachineTypeInZone;
+import org.jclouds.googlecomputeengine.domain.SlashEncodedIds;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Inject;
+
+/**
+ * Transforms a google compute domain specific machine type to a generic Hardware object.
+ *
+ * @author David Alves
+ */
+public class MachineTypeInZoneToHardware implements Function<MachineTypeInZone, Hardware> {
+
+   private final Supplier<Map<URI, ? extends Location>> locations;
+
+   @Inject
+   public MachineTypeInZoneToHardware(@Memoized Supplier<Map<URI, ? extends Location>> locations) {
+      this.locations = locations;
+   }
+
+   @Override
+   public Hardware apply(final MachineTypeInZone input) {
+      Iterable<? extends Location> zonesForMachineType = filter(locations.get().values(), new Predicate<Location>() {
+         @Override
+         public boolean apply(Location l) {
+            return l.getId().equals(input.getMachineType().getZone());
+         }
+      });
+
+      Location location = checkNotNull(getOnlyElement(zonesForMachineType),
+              "location for %s",
+              input.getMachineType().getZone());
+
+      // TODO Figure out a robust way to deal with machineTypes with imageSizeGb==0 rather than just blocking them.
+      return new HardwareBuilder()
+              .id(SlashEncodedIds.fromTwoIds(input.getMachineType().getZone(), input.getMachineType().getName()).slashEncode())
+              .location(location)
+              .name(input.getMachineType().getName())
+              .hypervisor("kvm")
+              .processor(new Processor(input.getMachineType().getGuestCpus(), 1.0))
+              .providerId(input.getMachineType().getId())
+              .ram(input.getMachineType().getMemoryMb())
+              .uri(input.getMachineType().getSelfLink())
+              .userMetadata(ImmutableMap.of("imageSpaceGb", Integer.toString(input.getMachineType().getImageSpaceGb())))
+              .volumes(collectVolumes(input.getMachineType()))
+              .supportsImage(input.getMachineType().getImageSpaceGb() > 0
+                      ? Predicates.<Image>alwaysTrue()
+                      : Predicates.<Image>alwaysFalse())
+              .build();
+   }
+
+   private Iterable<Volume> collectVolumes(MachineType input) {
+      ImmutableSet.Builder<Volume> volumes = ImmutableSet.builder();
+      for (MachineType.ScratchDisk disk : input.getScratchDisks()) {
+         volumes.add(new VolumeBuilder()
+                 .type(Volume.Type.LOCAL)
+                 .size(new Integer(disk.getDiskGb()).floatValue())
+                 .bootDevice(true)
+                 .durable(false).build());
+      }
+      return volumes.build();
+   }
+}