http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/29f4013d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/UrlMapValidateResult.java
----------------------------------------------------------------------
diff --git 
a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/UrlMapValidateResult.java
 
b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/UrlMapValidateResult.java
new file mode 100644
index 0000000..2d349c2
--- /dev/null
+++ 
b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/UrlMapValidateResult.java
@@ -0,0 +1,345 @@
+/*
+ * 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.Set;
+
+import org.jclouds.javax.annotation.Nullable;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Result of calling validate on an UrlMap resource.
+ * 
+ * @see <a 
href="https://developers.google.com/compute/docs/reference/latest/urlMaps/validate"/>
+ */
+public class UrlMapValidateResult {
+   
+   private final Boolean loadSucceeded;
+   private final Set<String> loadErrors;
+   private final Optional<Boolean> testPassed;
+   private final Set<TestFailure> testFailures;
+   
+   @ConstructorProperties({
+           "loadSucceeded", "loadErrors", "testPassed", "testFailures"
+   })
+   private UrlMapValidateResult(Boolean loadSucceeded, @Nullable Set<String> 
loadErrors,
+                                @Nullable Boolean testPassed,
+                                @Nullable Set<TestFailure> testFailures) {
+      this.loadSucceeded = loadSucceeded;
+      this.loadErrors = loadErrors == null ? ImmutableSet.<String>of() : 
loadErrors;
+      this.testPassed = fromNullable(testPassed);
+      this.testFailures = testFailures == null ? 
ImmutableSet.<TestFailure>of() : testFailures;
+   }
+   
+   /**
+    * @return if the loadSucceeded.
+    */
+   public Boolean getLoadSucceeded() {
+      return loadSucceeded;
+   }
+
+   /**
+    * @return the loadErrors.
+    */
+   public Set<String> getLoadErrors() {
+      return loadErrors;
+   }
+
+   /**
+    * @return if the testPassed.
+    */
+   public Optional<Boolean> getTestPassed() {
+      return testPassed;
+   }
+
+   /**
+    * @return the testFailures.
+    */
+   public Set<TestFailure> getTestFailures() {
+      return testFailures;
+   }
+   
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(loadSucceeded, loadErrors, testPassed,
+                              testFailures);
+   }
+   
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) return true;
+      if (obj == null || getClass() != obj.getClass()) return false;
+      UrlMapValidateResult that = UrlMapValidateResult.class.cast(obj);
+      return equal(this.loadSucceeded, that.loadSucceeded)
+              && equal(this.loadErrors, that.loadErrors)
+              && equal(this.testPassed, that.testPassed)
+              && equal(this.testFailures, that.testFailures);
+   }
+   
+   /**
+    **
+    * {@inheritDoc}
+    */
+   protected Objects.ToStringHelper string() {
+      return toStringHelper(this)
+              .omitNullValues()
+              .add("loadSucceeded", loadSucceeded)
+              .add("loadErrors", loadErrors)
+              .add("testPassed", testPassed.orNull())
+              .add("testFailures", testFailures);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+   
+   public static Builder builder() {
+      return new Builder();
+   }
+   
+   public Builder toBuilder() {
+      return new Builder().fromUrlMapValidateResult(this);
+   }
+   
+   public static class Builder {
+      
+      private Boolean loadSucceeded;
+      private ImmutableSet.Builder<String> loadErrors = 
ImmutableSet.<String>builder();
+      private Boolean testPassed;
+      private ImmutableSet.Builder<TestFailure> testFailures = 
ImmutableSet.<TestFailure>builder();
+      
+      /**
+       * @see UrlMapValidateResult#getLoadSucceeded()
+       */
+      public Builder loadSucceeded(Boolean loadSucceeded) {
+         this.loadSucceeded = loadSucceeded;
+         return this;
+      }
+      
+      /**
+       * @see UrlMapValidateResult#getLoadErrors()
+       */
+      public Builder addLoadError(String loadError) {
+         this.loadErrors.add(checkNotNull(loadError, "loadError"));
+         return this;
+      }
+      
+      /**
+       * @see UrlMapValidateResult#getLoadErrors()
+       */
+      public Builder loadErrors(Set<String> loadErrors) {
+         this.loadErrors = ImmutableSet.builder();
+         this.loadErrors.addAll(loadErrors);
+         return this;
+      }
+      
+      /**
+       * @see UrlMapValidateResult#getTestPassed()
+       */
+      public Builder testPassed(Boolean testPassed) {
+         this.testPassed = testPassed;
+         return this;
+      }
+      
+      /**
+       * @see UrlMapValidateResult#getTestFailure()
+       */
+      public Builder addTestFailure(TestFailure testFailure) {
+         this.testFailures.add(checkNotNull(testFailure, "testFailure"));
+         return this;
+      }
+      
+      /**
+       * @see UrlMapValidateResult#getTestFailure()
+       */
+      public Builder testFailures(Set<TestFailure> testFailures) {
+         this.testFailures = ImmutableSet.builder();
+         this.testFailures.addAll(testFailures);
+         return this;
+      }
+      
+      public UrlMapValidateResult build() {
+         return new UrlMapValidateResult(loadSucceeded, loadErrors.build(),
+                                         testPassed, testFailures.build());
+      }
+      
+      public Builder fromUrlMapValidateResult(UrlMapValidateResult in) {
+         return new Builder().loadErrors(in.getLoadErrors())
+                             .loadSucceeded(in.getLoadSucceeded())
+                             .testFailures(in.getTestFailures())
+                             .testPassed(in.getTestPassed().orNull());
+      }
+   }
+
+   public final static class TestFailure {
+      
+      private final String host;
+      private final String path;
+      private final URI expectedService;
+      private final URI actualService;
+      
+      @ConstructorProperties({
+              "host", "path", "expectedService", "actualService"
+      })
+      private TestFailure(String host, String path, URI expectedService,
+                          URI actualService) {
+         this.host = checkNotNull(host);
+         this.path = checkNotNull(path);
+         this.expectedService = checkNotNull(expectedService);
+         this.actualService = checkNotNull(actualService);
+      }
+
+      /**
+       * @return the host.
+       */
+      public String getHost() {
+         return host;
+      }
+
+      /**
+       * @return the path.
+       */
+      public String getPath() {
+         return path;
+      }
+
+      /**
+       * @return the expectedService.
+       */
+      public URI getExpectedService() {
+         return expectedService;
+      }
+
+      /**
+       * @return the actualService.
+       */
+      public URI getActualService() {
+         return actualService;
+      }
+      
+      /**
+       * {@inheritDoc}
+       */
+      @Override
+      public int hashCode() {
+         return Objects.hashCode(host, path, expectedService, actualService);
+      }
+      
+      /**
+       * {@inheritDoc}
+       */
+      @Override
+      public boolean equals(Object obj) {
+         if (this == obj) return true;
+         if (obj == null || getClass() != obj.getClass()) return false;
+         TestFailure that = TestFailure.class.cast(obj);
+         return equal(this.host, that.host)
+                 && equal(this.path, that.path)
+                 && equal(this.expectedService, that.expectedService)
+                 && equal(this.actualService, that.actualService);
+      }
+      
+      /**
+       **
+       * {@inheritDoc}
+       */
+      protected Objects.ToStringHelper string() {
+         return toStringHelper(this)
+                 .omitNullValues()
+                 .add("host", host)
+                 .add("path", path)
+                 .add("expectedService", expectedService)
+                 .add("actualService", actualService);
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      @Override
+      public String toString() {
+         return string().toString();
+      }
+      
+      public static Builder builder() {
+         return new Builder();
+      }
+      
+      public static class Builder {
+         
+         private String host;
+         private String path;
+         private URI expectedService;
+         private URI actualService;
+         
+         /**
+          * @see 
org.jclouds.googlecomputeengine.domain.UrlMapValidateResult.TestFailure#getHost()
+          */
+         public Builder host(String host) {
+            this.host = host;
+            return this;
+         }
+         
+         /**
+          * @see 
org.jclouds.googlecomputeengine.domain.UrlMapValidateResult.TestFailure#getPath()
+          */
+         public Builder path(String path) {
+            this.path = path;
+            return this;
+         }
+         
+         /**
+          * @see 
org.jclouds.googlecomputeengine.domain.UrlMapValidateResult.TestFailure#getExpectedService()
+          */
+         public Builder expectedService(URI expectedService) {
+            this.expectedService = expectedService;
+            return this;
+         }
+         
+         /**
+          * @see 
org.jclouds.googlecomputeengine.domain.UrlMapValidateResult.TestFailure#getActualService()
+          */
+         public Builder actualService(URI actualService) {
+            this.actualService = actualService;
+            return this;
+         }
+         
+         public TestFailure build() {
+            return new TestFailure(host, path, expectedService, actualService);
+         }
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/29f4013d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/BackendServiceApi.java
----------------------------------------------------------------------
diff --git 
a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/BackendServiceApi.java
 
b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/BackendServiceApi.java
new file mode 100644
index 0000000..7d1d5ea
--- /dev/null
+++ 
b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/BackendServiceApi.java
@@ -0,0 +1,267 @@
+/*
+ * 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 java.net.URI;
+import java.util.Set;
+
+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.PUT;
+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.BackendService;
+import org.jclouds.googlecomputeengine.domain.BackendServiceGroupHealth;
+import org.jclouds.googlecomputeengine.domain.ListPage;
+import org.jclouds.googlecomputeengine.domain.Operation;
+import org.jclouds.googlecomputeengine.functions.internal.PATCH;
+import org.jclouds.googlecomputeengine.functions.internal.ParseBackendServices;
+import org.jclouds.googlecomputeengine.handlers.PayloadBinder;
+import org.jclouds.googlecomputeengine.options.BackendServiceOptions;
+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.BinderParam;
+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 BackendServices via their REST API.
+ * <p/>
+ *
+ * @see <a 
href="https://developers.google.com/compute/docs/reference/v1/backendServices"/>
+ */
+@SkipEncoding({'/', '='})
+@RequestFilters(OAuthAuthenticator.class)
+@Consumes(MediaType.APPLICATION_JSON)
+public interface BackendServiceApi {
+   /**
+    * Returns the specified backend service resource.
+    *
+    * @param backendServiceName name of the backend service resource to return.
+    * @return a BackendService resource.
+    */
+   @Named("BackendServices:get")
+   @GET
+   @Path("/global/backendServices/{backendService}")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   BackendService get(@PathParam("backendService") String backendServiceName);
+
+   /**
+    * Creates a backend service resource in the specified project using the 
data
+    * included in the request.
+    *
+    * @param name            the name of the backend service to be inserted.
+    * @param backendService  options for this backend service.
+    * @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("BackendServices:insert")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("/global/backendServices")
+   @OAuthScopes({COMPUTE_SCOPE})
+   @MapBinder(PayloadBinder.class)
+   Operation create(@PayloadParam("name") String name,
+                    @PayloadParam("options") BackendServiceOptions 
backendService);
+   
+   /**
+    * Creates a backend service resource in the specified project using the 
data
+    * included in the request.
+    *
+    * @param name            the name of the backend service to be inserted.
+    * @param healthChecks    health checks to add to the backend service.
+    * @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("BackendServices:insert")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("/global/backendServices")
+   @OAuthScopes({COMPUTE_SCOPE})
+   @MapBinder(BindToJsonPayload.class)
+   Operation create(@PayloadParam("name") String name,
+                    @PayloadParam("healthChecks") Set<URI> healthChecks);
+
+   /**
+    * Updates the specified backend service resource with the data included in
+    * the request.
+    *
+    * @param backendServiceName    the name backend service to be updated.
+    * @param backendServiceOptions the new backend service.
+    * @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("BackendServices:update")
+   @PUT
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("/global/backendServices/{backendService}")
+   @OAuthScopes({COMPUTE_SCOPE})
+   Operation update(@PathParam("backendService") String backendServiceName,
+                    @BinderParam(BindToJsonPayload.class) 
BackendServiceOptions backendServiceOptions);
+
+   /**
+    * Updates the specified backend service resource, with patch semantics, 
with
+    * the data included in the request.
+    *
+    * @param backendServiceName    the name backend service to be updated.
+    * @param backendServiceOptions the new backend service.
+    * @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("BackendServices:patch")
+   @PATCH
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("/global/backendServices/{backendService}")
+   @OAuthScopes({COMPUTE_SCOPE})
+   Operation patch(@PathParam("backendService") String backendServiceName,
+                   @BinderParam(PayloadBinder.class) BackendServiceOptions 
backendServiceOptions);
+   
+   /**
+    * Gets the most recent health check results for this backend service. Note
+    * that health check results will only be returned if the backend service 
has
+    *  a valid global forwarding rule referencing it.
+    *
+    * @param backendServiceName    the name backend service to get health 
stats on.
+    * @param group                 the group in the backend service to get 
health stats on.
+    * @return a BackendServiceGroupHealth resource denoting the health states 
of
+    *         instances in the specified group.
+    */
+   // The documentation does not reflect the fact that compute_scope is needed 
for this operation.
+   // Running getHealth with compute_readonly_scope will return with an error 
saying the 
+   // resource /projects/<project name> could not be found.
+   @Named("BackendServices:getHealth")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("/global/backendServices/{backendService}/getHealth")
+   @OAuthScopes({COMPUTE_SCOPE})
+   @MapBinder(BindToJsonPayload.class)
+   BackendServiceGroupHealth getHealth(@PathParam("backendService") String 
backendServiceName,
+                                       @PayloadParam("group") URI group);
+
+   /**
+    * Deletes the specified backend service resource.
+    *
+    * @param backendServiceName  name of the backend service 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("BackendServices:delete")
+   @DELETE
+   @Path("/global/backendServices/{backendService}")
+   @OAuthScopes(COMPUTE_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   Operation delete(@PathParam("backendService") String backendServiceName);
+
+   /**
+    * @see BackendServiceApi#listAtMarker(String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("BackendServices:list")
+   @GET
+   @Path("/global/backendServices")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseBackendServices.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<BackendService> listFirstPage();
+
+   /**
+    * @see BackendServiceApi#listAtMarker(String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("BackendServices:list")
+   @GET
+   @Path("/global/backendServices")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseBackendServices.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<BackendService> listAtMarker(@QueryParam("pageToken") @Nullable 
String marker);
+
+   /**
+    * Retrieves the list of backend service resources available to the 
specified
+    * project. By default the list as a maximum size of 100, if no options are
+    * provided or ListOptions#getMaxResults() has not been set.
+    *
+    * @param marker      marks the beginning of the next list page.
+    * @param listOptions listing options.
+    * @return a page of the list.
+    * @see ListOptions
+    * @see org.jclouds.googlecomputeengine.domain.ListPage
+    */
+   @Named("BackendServices:list")
+   @GET
+   @Path("/global/backendServices")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseBackendServices.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<BackendService> listAtMarker(@QueryParam("pageToken") @Nullable 
String marker, ListOptions options);
+
+   /**
+    * @see 
BackendServiceApi#list(org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("BackendServices:list")
+   @GET
+   @Path("/global/backendServices")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseBackendServices.class)
+   @Transform(ParseBackendServices.ToPagedIterable.class)
+   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
+   PagedIterable<BackendService> list();
+
+   /**
+    * A paged version of BackendserviceApi#list().
+    *
+    * @return a Paged, Fluent Iterable that is able to fetch additional pages
+    *         when required.
+    * @see PagedIterable
+    * @see BackendServiceApi#listAtMarker(String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("BackendServices:list")
+   @GET
+   @Path("/global/backendServices")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseBackendServices.class)
+   @Transform(ParseBackendServices.ToPagedIterable.class)
+   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
+   PagedIterable<BackendService> list(ListOptions options);
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/29f4013d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ForwardingRuleApi.java
----------------------------------------------------------------------
diff --git 
a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ForwardingRuleApi.java
 
b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ForwardingRuleApi.java
index cb4160e..862a126 100644
--- 
a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ForwardingRuleApi.java
+++ 
b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ForwardingRuleApi.java
@@ -153,3 +153,4 @@ public interface ForwardingRuleApi {
       }
    }
 }
+

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/29f4013d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ResourceViewApi.java
----------------------------------------------------------------------
diff --git 
a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ResourceViewApi.java
 
b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ResourceViewApi.java
new file mode 100644
index 0000000..1d9e421
--- /dev/null
+++ 
b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ResourceViewApi.java
@@ -0,0 +1,614 @@
+/*
+ * 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.NDEV_CLOUD_MAN_READONLY_SCOPE;
+import static 
org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.NDEV_CLOUD_MAN_SCOPE;
+
+import java.net.URI;
+import java.util.Set;
+
+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.ResourceViewEndpoint;
+import org.jclouds.googlecomputeengine.domain.ListPage;
+import org.jclouds.googlecomputeengine.domain.ResourceView;
+import 
org.jclouds.googlecomputeengine.functions.internal.ParseRegionResourceViewMembers;
+import 
org.jclouds.googlecomputeengine.functions.internal.ParseRegionResourceViews;
+import 
org.jclouds.googlecomputeengine.functions.internal.ParseZoneResourceViewMembers;
+import 
org.jclouds.googlecomputeengine.functions.internal.ParseZoneResourceViews;
+import org.jclouds.googlecomputeengine.handlers.PayloadBinder;
+import org.jclouds.googlecomputeengine.options.ListOptions;
+import org.jclouds.googlecomputeengine.options.ResourceViewOptions;
+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.Endpoint;
+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 Resource Views via their REST API.
+ *
+ * @see <a 
href="https://developers.google.com/compute/docs/resource-views/v1beta1/regionViews"/>
+ * @see <a 
href="https://developers.google.com/compute/docs/resource-views/v1beta1/zoneViews"/>
+ */
+@SkipEncoding({'/', '='})
+@RequestFilters(OAuthAuthenticator.class)
+@Consumes(MediaType.APPLICATION_JSON)
+@Endpoint(value = ResourceViewEndpoint.class)
+public interface ResourceViewApi {
+
+   /**
+    * Returns the specified resource view resource.
+    *
+    * @param zone                Name of the zone the resource view is in.
+    * @param resourceViewName    Name of the resource view resource to return.
+    * @return a ResourceView resource.
+    */
+   @Named("ResourceViews:get")
+   @GET
+   @Path("/zones/{zone}/resourceViews/{resourceView}")
+   @OAuthScopes(NDEV_CLOUD_MAN_READONLY_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   ResourceView getInZone(@PathParam("zone") String zone,
+                          @PathParam("resourceView") String resourceViewName);
+   
+   /**
+    * Returns the specified resource view resource.
+    *
+    * @param region                Name of the region the resource view is in.
+    * @param resourceViewName      Name of the resource view resource to 
return.
+    * @return a ResourceView resource.
+    */
+   @Named("ResourceViews:get")
+   @GET
+   @Path("/regions/{region}/resourceViews/{resourceView}")
+   @OAuthScopes(NDEV_CLOUD_MAN_READONLY_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   ResourceView getInRegion(@PathParam("region") String region,
+                            @PathParam("resourceView") String 
resourceViewName);
+
+   /**
+    * Creates a zone resource view resource.
+    *
+    * @param zone       the zone this resource view will live in.
+    * @param name       the name of resource view.
+    * @return a ResourceView resource.
+    */
+   @Named("ResourceViews:insert")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("/zones/{zone}/resourceViews")
+   @OAuthScopes(NDEV_CLOUD_MAN_SCOPE)
+   @MapBinder(BindToJsonPayload.class)
+   ResourceView createInZone(@PathParam("zone") String zone,
+                             @PayloadParam("name") String name);
+   
+   /**
+    * Creates a zone resource view resource with the given options.
+    *
+    * @param zone       the zone this resource view will live in.
+    * @param name       the name of resource view.
+    * @param options    the options this resource view will have.
+    * @return a ResourceView resource.
+    */
+   @Named("ResourceViews:insert")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("/zones/{zone}/resourceViews")
+   @OAuthScopes(NDEV_CLOUD_MAN_SCOPE)
+   @MapBinder(PayloadBinder.class)
+   ResourceView createInZone(@PathParam("zone") String zone,
+                             @PayloadParam("name") String name,
+                             @PayloadParam("options") ResourceViewOptions 
options);
+   
+   /**
+    * Creates a region resource view resource.
+    *
+    * @param region     the region this resource view will live in.
+    * @param name       the name of resource view.
+    * @return a ResourceView resource.
+    */
+   @Named("ResourceViews:insert")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("/regions/{region}/resourceViews")
+   @OAuthScopes(NDEV_CLOUD_MAN_SCOPE)
+   @MapBinder(BindToJsonPayload.class)
+   ResourceView createInRegion(@PathParam("region") String region,
+                               @PayloadParam("name") String name);
+   
+   /**
+    * Creates a region resource view resource with the given options.
+    *
+    * @param region     the region this resource view will live in.
+    * @param name       the name of resource view.
+    * @param options    the options this resource view will have.
+    * @return a ResourceView resource.
+    */
+   @Named("ResourceViews:insert")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("/regions/{region}/resourceViews")
+   @OAuthScopes(NDEV_CLOUD_MAN_SCOPE)
+   @MapBinder(PayloadBinder.class)
+   ResourceView createInRegion(@PathParam("region") String region,
+                               @PayloadParam("name") String name,
+                               @PayloadParam("options") ResourceViewOptions 
options);
+   
+   /**
+    * Adds the given resources to the resource view resource with the given 
name.
+    *
+    * @param zone                the zone this resource view lives in.
+    * @param resourceViewName    the name of resource view.
+    * @param resources           the resources to add to this resource view.
+    */
+   @Named("ResourceViews:addResources")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("/zones/{zone}/resourceViews/{resourceView}/addResources")
+   @OAuthScopes(NDEV_CLOUD_MAN_SCOPE)
+   @MapBinder(BindToJsonPayload.class)
+   void addResourcesInZone(@PathParam("zone") String zone,
+                           @PathParam("resourceView") String resourceViewName,
+                           @PayloadParam("resources") Set<URI> resources);
+   
+   /**
+    * Adds the given resources to the resource view resource with the given 
name.
+    *
+    * @param region              the region this resource view lives in.
+    * @param resourceViewName    the name of resource view.
+    * @param resources           the resources to add to this resource view.
+    */
+   @Named("ResourceViews:addResources")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("/regions/{region}/resourceViews/{resourceView}/addResources")
+   @OAuthScopes(NDEV_CLOUD_MAN_SCOPE)
+   @MapBinder(BindToJsonPayload.class)
+   void addResourcesInRegion(@PathParam("region") String region,
+                             @PathParam("resourceView") String 
resourceViewName,
+                             @PayloadParam("resources") Set<URI> resources);
+   
+   /**
+    * Removes the given resources from the resource view resource with the 
given name.
+    *
+    * @param zone                the zone this resource view lives in.
+    * @param resourceViewName    the name of resource view.
+    * @param resources           the resources to remove from this resource 
view.
+    */
+   @Named("ResourceViews:removeResources")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("/zones/{zone}/resourceViews/{resourceView}/removeResources")
+   @OAuthScopes(NDEV_CLOUD_MAN_SCOPE)
+   @MapBinder(BindToJsonPayload.class)
+   void removeResourcesInZone(@PathParam("zone") String zone,
+                              @PathParam("resourceView") String 
resourceViewName,
+                              @PayloadParam("resources") Set<URI> resources);
+   
+   /**
+    * Removes the given resources from the resource view resource with the 
given name.
+    *
+    * @param region              the region this resource view lives in.
+    * @param resourceViewName    the name of resource view.
+    * @param resources           the resources to remove from this resource 
view.
+    */
+   @Named("ResourceViews:removeResources")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("/regions/{region}/resourceViews/{resourceView}/removeResources")
+   @OAuthScopes(NDEV_CLOUD_MAN_SCOPE)
+   @MapBinder(BindToJsonPayload.class)
+   void removeResourcesInRegion(@PathParam("region") String region,
+                                @PathParam("resourceView") String 
resourceViewName,
+                                @PayloadParam("resources") Set<URI> resources);
+   
+   /**
+    * @see ResourceViewApi#listResourcesAtMarkerInZone(String, String, String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("ResourceViews:listResources")
+   @POST
+   @Path("/zones/{zone}/resourceViews/{resourceView}/resources")
+   @OAuthScopes(NDEV_CLOUD_MAN_READONLY_SCOPE)
+   @ResponseParser(ParseZoneResourceViewMembers.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<URI> listResourcesFirstPageInZone(@PathParam("zone") String zone,
+                                              @PathParam("resourceView") 
String resourceViewName);
+
+   /**
+    * @see ResourceViewApi#listResourcesAtMarkerInZone(String, String, String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("ResourceViews:listResources")
+   @POST
+   @Path("/zones/{zone}/resourceViews/{resourceView}/resources")
+   @OAuthScopes(NDEV_CLOUD_MAN_READONLY_SCOPE)
+   @ResponseParser(ParseZoneResourceViewMembers.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<URI> listResourcesAtMarkerInZone(@PathParam("zone") String zone,
+                                             @PathParam("resourceView") String 
resourceViewName,
+                                             @QueryParam("pageToken") 
@Nullable String marker);
+
+   /**
+    * Retrieves the listPage of resource view resources contained within the 
specified project and zone.
+    * By default the listPage as a maximum size of 100, if no options are 
provided or ListOptions#getMaxResults() has
+    * not been set.
+    *
+    * @param zone                the zone to search in.
+    * @param resourceViewName    the name of the resource view resource to 
search under.
+    * @param marker              marks the beginning of the next list page.
+    * @param listOptions         listing options.
+    * @return a page of the listPage.
+    * @see ListOptions
+    * @see org.jclouds.googlecomputeengine.domain.ListPage
+    */
+   @Named("ResourceViews:listResources")
+   @POST
+   @Path("/zones/{zone}/resourceViews/{resourceView}/resources")
+   @OAuthScopes(NDEV_CLOUD_MAN_READONLY_SCOPE)
+   @ResponseParser(ParseZoneResourceViewMembers.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<URI> listResourcesAtMarkerInZone(@PathParam("zone") String zone,
+                                             @PathParam("resourceView") String 
resourceViewName,
+                                             @QueryParam("pageToken") 
@Nullable String marker, 
+                                             ListOptions listOptions);
+
+   /**
+    * A paged version of ResourceViewApi#listResourcesAtMarkerInZone(String, 
String).
+    *
+    * @param zone                the zone to list in.
+    * @param resourceViewName    resource view resources to list in.
+    * @return a Paged, Fluent Iterable that is able to fetch additional pages 
when required.
+    * @see PagedIterable
+    * @see ResourceViewApi#listResourcesAtMarkerInZone(String, String, String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("ResourceViews:listResources")
+   @POST
+   @Path("/zones/{zone}/resourceViews/{resourceView}/resources")
+   @OAuthScopes(NDEV_CLOUD_MAN_READONLY_SCOPE)
+   @ResponseParser(ParseZoneResourceViewMembers.class)
+   @Transform(ParseZoneResourceViewMembers.ToPagedIterable.class)
+   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
+   PagedIterable<URI> listResourcesInZone(@PathParam("zone") String zone,
+                                          @PathParam("resourceView") String 
resourceViewName);
+
+   /**
+    * A paged version of ResourceViewApi#listResourcesAtMarkerInZone(String, 
String).
+    *
+    * @param zone                the zone to list in.
+    * @param resourceViewName    resource view resources to list in.
+    * @param listOptions         listing options.
+    * @return a Paged, Fluent Iterable that is able to fetch additional pages 
when required.
+    * @see PagedIterable
+    * @see ResourceViewApi#listResourcesAtMarkerInZone(String, String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("ResourceViews:listResources")
+   @POST
+   @Path("/zones/{zone}/resourceViews/{resourceView}/resources")
+   @OAuthScopes(NDEV_CLOUD_MAN_READONLY_SCOPE)
+   @ResponseParser(ParseZoneResourceViewMembers.class)
+   @Transform(ParseZoneResourceViewMembers.ToPagedIterable.class)
+   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
+   PagedIterable<URI> listResourcesInZone(@PathParam("zone") String zone,
+                                          @PathParam("resourceView") String 
resourceViewName,
+                                          ListOptions options);
+   
+   /**
+    * @see ResourceViewApi#listResourcesAtMarkerInRegion(String, String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("ResourceViews:listResources")
+   @POST
+   @Path("/regions/{region}/resourceViews/{resourceView}/resources")
+   @OAuthScopes(NDEV_CLOUD_MAN_READONLY_SCOPE)
+   @ResponseParser(ParseRegionResourceViewMembers.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<URI> listResourcesFirstPageInRegion(@PathParam("region") String 
zone,
+                                                @PathParam("resourceView") 
String resourceViewName);
+
+   /**
+    * @see ResourceViewApi#listResourcesAtMarkerInRegion(String, String, 
String, org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("ResourceViews:listResources")
+   @POST
+   @Path("/regions/{region}/resourceViews/{resourceView}/resources")
+   @OAuthScopes(NDEV_CLOUD_MAN_READONLY_SCOPE)
+   @ResponseParser(ParseRegionResourceViewMembers.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<URI> listResourcesAtMarkerInRegion(@PathParam("region") String 
region,
+                                               @PathParam("resourceView") 
String resourceViewName,
+                                               @QueryParam("pageToken") 
@Nullable String marker);
+
+   /**
+    * Retrieves the listPage of resource view resources contained within the 
specified project and zone.
+    * 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 resourceViewName    the name of the resource view resource to 
search under.
+    * @param marker              marks the beginning of the next list page.
+    * @param listOptions         listing options.
+    * @return a page of the listPage.
+    * @see ListOptions
+    * @see org.jclouds.googlecomputeengine.domain.ListPage
+    */
+   @Named("ResourceViews:listResources")
+   @POST
+   @Path("/regions/{region}/resourceViews/{resourceView}/resources")
+   @OAuthScopes(NDEV_CLOUD_MAN_READONLY_SCOPE)
+   @ResponseParser(ParseRegionResourceViewMembers.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<URI> listResourcesAtMarkerInRegion(@PathParam("region") String 
region,
+                                               @PathParam("resourceView") 
String resourceViewName,
+                                               @QueryParam("pageToken") 
@Nullable String marker, 
+                                               ListOptions listOptions);
+
+   /**
+    * A paged version of ResourceViewApi#listResourcesAtMarkerInRegion(String, 
String).
+    *
+    * @param region              the region to list in.
+    * @param resourceViewName    resource view resources to list in.
+    * @return a Paged, Fluent Iterable that is able to fetch additional pages 
when required.
+    * @see PagedIterable
+    * @see ResourceViewApi#listResourcesAtMarkerInZone(String, String, String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("ResourceViews:listResources")
+   @POST
+   @Path("/regions/{region}/resourceViews/{resourceView}/resources")
+   @OAuthScopes(NDEV_CLOUD_MAN_READONLY_SCOPE)
+   @ResponseParser(ParseRegionResourceViewMembers.class)
+   @Transform(ParseRegionResourceViewMembers.ToPagedIterable.class)
+   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
+   PagedIterable<URI> listResourcesInRegion(@PathParam("region") String region,
+                                            @PathParam("resourceView") String 
resourceViewName);
+
+   /**
+    * A paged version of ResourceViewApi#listResourcesAtMarkerInRegion(String, 
String).
+    *
+    * @param region              the region to list in.
+    * @param resourceViewName    resource view resources to list in.
+    * @param listOptions         listing options.
+    * @return a Paged, Fluent Iterable that is able to fetch additional pages 
when required.
+    * @see PagedIterable
+    * @see ResourceViewApi#listResourcesAtMarkerInRegion(String, String, 
String, org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("ResourceViews:listResources")
+   @POST
+   @Path("/regions/{region}/resourceViews/{resourceView}/resources")
+   @OAuthScopes(NDEV_CLOUD_MAN_READONLY_SCOPE)
+   @ResponseParser(ParseRegionResourceViewMembers.class)
+   @Transform(ParseRegionResourceViewMembers.ToPagedIterable.class)
+   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
+   PagedIterable<URI> listResourcesInRgion(@PathParam("region") String region,
+                                           @PathParam("resourceView") String 
resourceViewName,
+                                           ListOptions options);
+
+   /**
+    * Deletes the specified resource view resource.
+    *
+    * @param zone                the zone the resource view is in.
+    * @param resourceViewName    name of the resource view 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("ResourceViews:delete")
+   @DELETE
+   @Path("/zones/{zone}/resourceViews/{resourceView}")
+   @OAuthScopes(NDEV_CLOUD_MAN_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   void deleteInZone(@PathParam("zone") String zone,
+                     @PathParam("resourceView") String resourceViewName);
+   
+   /**
+    * Deletes the specified resource view resource.
+    *
+    * @param region              the region the resource view is in.
+    * @param resourceViewName    name of the resource view 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("ResourceViews:delete")
+   @DELETE
+   @Path("/regions/{region}/resourceViews/{resourceView}")
+   @OAuthScopes(NDEV_CLOUD_MAN_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   void deleteInRegion(@PathParam("region") String zone,
+                       @PathParam("resourceView") String resourceViewName);
+
+   /**
+    * @see ResourceViewApi#listAtMarkerInZone(String, String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("ResourceViews:list")
+   @GET
+   @Path("/zones/{zone}/resourceViews")
+   @OAuthScopes(NDEV_CLOUD_MAN_READONLY_SCOPE)
+   @ResponseParser(ParseZoneResourceViews.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<ResourceView> listFirstPageInZone(@PathParam("zone") String zone);
+
+   /**
+    * @see ResourceViewApi#listAtMarkerInZone(String, String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("ResourceViews:list")
+   @GET
+   @Path("/zones/{zone}/resourceViews")
+   @OAuthScopes(NDEV_CLOUD_MAN_READONLY_SCOPE)
+   @ResponseParser(ParseZoneResourceViews.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<ResourceView> listAtMarkerInZone(@PathParam("zone") String zone,
+                                             @QueryParam("pageToken") 
@Nullable String marker);
+
+   /**
+    * Retrieves the listPage of resource view resources contained within the 
specified project and zone.
+    * By default the listPage as a maximum size of 100, if no options are 
provided or ListOptions#getMaxResults() has
+    * not been set.
+    *
+    * @param zone        the zone to search in.
+    * @param marker      marks the beginning of the next list page.
+    * @param listOptions listing options.
+    * @return a page of the listPage.
+    * @see ListOptions
+    * @see org.jclouds.googlecomputeengine.domain.ListPage
+    */
+   @Named("ResourceViews:list")
+   @GET
+   @Path("/zones/{zone}/resourceViews")
+   @OAuthScopes(NDEV_CLOUD_MAN_READONLY_SCOPE)
+   @ResponseParser(ParseZoneResourceViews.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<ResourceView> listAtMarkerInZone(@PathParam("zone") String zone,
+                                             @QueryParam("pageToken") 
@Nullable String marker,
+                                             ListOptions listOptions);
+
+   /**
+    * A paged version of ResourceViewApi#listAtMarkerInZone(String).
+    *
+    * @param zone the zone to list in.
+    * @return a Paged, Fluent Iterable that is able to fetch additional pages 
when required.
+    * @see PagedIterable
+    * @see ResourceViewApi#listAtMarkerInZone(String, String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("ResourceViews:list")
+   @GET
+   @Path("/zones/{zone}/resourceViews")
+   @OAuthScopes(NDEV_CLOUD_MAN_READONLY_SCOPE)
+   @ResponseParser(ParseZoneResourceViews.class)
+   @Transform(ParseZoneResourceViews.ToPagedIterable.class)
+   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
+   PagedIterable<ResourceView> listInZone(@PathParam("zone") String zone);
+
+   /**
+    * A paged version of ResourceViewApi#listMarkerInZone(String).
+    *
+    * @param zone the zone to list in.
+    * @return a Paged, Fluent Iterable that is able to fetch additional pages 
when required.
+    * @see PagedIterable
+    * @see ResourceViewApi#listAtMarkerInZone(String, String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("ResourceViews:list")
+   @GET
+   @Path("/zones/{zone}/resourceViews")
+   @OAuthScopes(NDEV_CLOUD_MAN_READONLY_SCOPE)
+   @ResponseParser(ParseZoneResourceViews.class)
+   @Transform(ParseZoneResourceViews.ToPagedIterable.class)
+   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
+   PagedIterable<ResourceView> listInZone(@PathParam("zone") String zone,
+                                          ListOptions options);
+   
+   /**
+    * @see ResourceViewApi#listAtMarkerInRegion(String, String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("ResourceViews:list")
+   @GET
+   @Path("/regions/{region}/resourceViews")
+   @OAuthScopes(NDEV_CLOUD_MAN_READONLY_SCOPE)
+   @ResponseParser(ParseRegionResourceViews.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<ResourceView> listFirstPageInRegion(@PathParam("region") String 
region);
+
+   /**
+    * @see ResourceViewApi#listAtMarkerInRegion(String, String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("ResourceViews:list")
+   @GET
+   @Path("/regions/{region}/resourceViews")
+   @OAuthScopes(NDEV_CLOUD_MAN_READONLY_SCOPE)
+   @ResponseParser(ParseRegionResourceViews.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<ResourceView> listAtMarkerInRegion(@PathParam("region") String 
region,
+                                               @QueryParam("pageToken") 
@Nullable String marker);
+
+   /**
+    * Retrieves the listPage of resource view 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 ListOptions
+    * @see org.jclouds.googlecomputeengine.domain.ListPage
+    */
+   @Named("ResourceViews:list")
+   @GET
+   @Path("/regions/{region}/resourceViews")
+   @OAuthScopes(NDEV_CLOUD_MAN_READONLY_SCOPE)
+   @ResponseParser(ParseRegionResourceViews.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<ResourceView> listAtMarkerInRegion(@PathParam("region") String 
region,
+                                               @QueryParam("pageToken") 
@Nullable String marker,
+                                               ListOptions listOptions);
+
+   /**
+    * A paged version of ResourceViewApi#listAtMarkerInRegion(String).
+    *
+    * @param region the region to list in.
+    * @return a Paged, Fluent Iterable that is able to fetch additional pages 
when required.
+    * @see PagedIterable
+    * @see ResourceViewApi#listAtMarkerInRegion(String, String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("ResourceViews:list")
+   @GET
+   @Path("/regions/{region}/resourceViews")
+   @OAuthScopes(NDEV_CLOUD_MAN_READONLY_SCOPE)
+   @ResponseParser(ParseZoneResourceViews.class)
+   @Transform(ParseRegionResourceViews.ToPagedIterable.class)
+   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
+   PagedIterable<ResourceView> listInRegion(@PathParam("region") String 
region);
+
+   /**
+    * A paged version of ResourceViewApi#listAtMarkerInRegion(String).
+    *
+    * @param region the region to list in.
+    * @return a Paged, Fluent Iterable that is able to fetch additional pages 
when required.
+    * @see PagedIterable
+    * @see ResourceViewApi#listAtMarkerInRegion(String, String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("ResourceViews:list")
+   @GET
+   @Path("/regions/{region}/resourceViews")
+   @OAuthScopes(NDEV_CLOUD_MAN_READONLY_SCOPE)
+   @ResponseParser(ParseZoneResourceViews.class)
+   @Transform(ParseRegionResourceViews.ToPagedIterable.class)
+   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
+   PagedIterable<ResourceView> listInRegion(@PathParam("region") String region,
+                                            ListOptions options);
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/29f4013d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/TargetHttpProxyApi.java
----------------------------------------------------------------------
diff --git 
a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/TargetHttpProxyApi.java
 
b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/TargetHttpProxyApi.java
new file mode 100644
index 0000000..e1d038c
--- /dev/null
+++ 
b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/TargetHttpProxyApi.java
@@ -0,0 +1,214 @@
+/*
+ * 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 java.net.URI;
+
+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.ListPage;
+import org.jclouds.googlecomputeengine.domain.Operation;
+import org.jclouds.googlecomputeengine.domain.TargetHttpProxy;
+import 
org.jclouds.googlecomputeengine.functions.internal.ParseTargetHttpProxies;
+import org.jclouds.googlecomputeengine.handlers.PayloadBinder;
+import org.jclouds.googlecomputeengine.options.ListOptions;
+import org.jclouds.googlecomputeengine.options.TargetHttpProxyOptions;
+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 Target Http Proxies via their REST API.
+ * <p/>
+ *
+ * @see <a 
href="https://developers.google.com/compute/docs/reference/latest/targetHttpProxies"/>
+ */
+@SkipEncoding({'/', '='})
+@Consumes(MediaType.APPLICATION_JSON)
+@RequestFilters(OAuthAuthenticator.class)
+public interface TargetHttpProxyApi {
+   /**
+    * Returns the specified target http proxy resource.
+    *
+    * @param targetHttpProxyName name of the targetHttpProxy resource to 
return.
+    * @return an TargetHttpProxy resource.
+    */
+   @Named("TargetHttpProxys:get")
+   @GET
+   @Path("/global/targetHttpProxies/{targetHttpProxy}")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   TargetHttpProxy get(@PathParam("targetHttpProxy") String 
targetHttpProxyName);
+
+   /**
+    * Creates a TargetHttpProxy resource in the specified project using the 
data included in the request.
+    *
+    * @param name            the name of the targetHttpProxy to be inserted.
+    * @param targetHttpProxyOptions the options of the targetHttpProxy to add.
+    * @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("TargetHttpProxys:insert")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("/global/targetHttpProxies")
+   @OAuthScopes({COMPUTE_SCOPE})
+   @MapBinder(PayloadBinder.class)
+   Operation create(@PayloadParam("name") String name,
+                    @PayloadParam("options") TargetHttpProxyOptions 
targetHttpProxyOptions);
+   
+   /**
+    * Creates a targetHttpProxy resource in the specified project using the 
given URI for the urlMap.
+    *
+    * @param name            the name of the targetHttpProxy to be inserted.
+    * @param urlMap          URI of the urlMap this proxy points to.
+    * @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("TargetHttpProxys:insert")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("/global/targetHttpProxies")
+   @OAuthScopes({COMPUTE_SCOPE})
+   @MapBinder(BindToJsonPayload.class)
+   Operation create(@PayloadParam("name") String name, @PayloadParam("urlMap") 
URI urlMap);
+
+   /**
+    * Updates the specified targetHttpProxy resource with the data included in 
the request.
+    *
+    * @param targetHttpProxyName    the name targetHttpProxy to be updated.
+    * @param urlMap                 the new url map this target http proxy 
points to.
+    * @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("TargetHttpProxys:setUrlMap")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("targetHttpProxies/{targetHttpProxy}/setUrlMap")
+   @OAuthScopes({COMPUTE_SCOPE})
+   @MapBinder(BindToJsonPayload.class)
+   Operation setUrlMap(@PathParam("targetHttpProxy") String 
targetHttpProxyName,
+                       @PayloadParam("urlMap") URI urlMap);
+
+   /**
+    * Deletes the specified image resource.
+    *
+    * @param targetHttpProxyName name of the targetHttpProxy 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.  If the image did not exist 
the result is null.
+    */
+   @Named("TargetHttpProxys:delete")
+   @DELETE
+   @Path("/global/targetHttpProxies/{targetHttpProxy}")
+   @OAuthScopes(COMPUTE_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   Operation delete(@PathParam("targetHttpProxy") String targetHttpProxyName);
+
+   /**
+    * @see TargetHttpProxyApi#list(String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("TargetHttpProxys:list")
+   @GET
+   @Path("/global/targetHttpProxies")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseTargetHttpProxies.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<TargetHttpProxy> listFirstPage();
+
+   /**
+    * @see TargetHttpProxyApi#list(String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("TargetHttpProxys:list")
+   @GET
+   @Path("/global/targetHttpProxies")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseTargetHttpProxies.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<TargetHttpProxy> listAtMarker(@QueryParam("pageToken") @Nullable 
String marker);
+
+   /**
+    * Retrieves the list of targetHttpProxy resources available to the 
specified project.
+    * By default the list as a maximum size of 100, if no options are provided 
or ListOptions#getMaxResults() has not
+    * been set.
+    *
+    * @param marker      marks the beginning of the next list page.
+    * @param listOptions listing options.
+    * @return a page of the list.
+    * @see ListOptions
+    * @see org.jclouds.googlecomputeengine.domain.ListPage
+    */
+   @Named("TargetHttpProxys:list")
+   @GET
+   @Path("/global/targetHttpProxies")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseTargetHttpProxies.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<TargetHttpProxy> list(@QueryParam("pageToken") @Nullable String 
marker, ListOptions options);
+
+   /**
+    * @see 
TargetHttpProxyApi#list(org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("TargetHttpProxys:list")
+   @GET
+   @Path("/global/targetHttpProxies")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseTargetHttpProxies.class)
+   @Transform(ParseTargetHttpProxies.ToPagedIterable.class)
+   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
+   PagedIterable<TargetHttpProxy> list();
+
+   /**
+    * A paged version of TargetHttpProxyApi#list().
+    *
+    * @return a Paged, Fluent Iterable that is able to fetch additional pages 
when required.
+    * @see PagedIterable
+    * @see TargetHttpProxyApi#list(String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("TargetHttpProxys:list")
+   @GET
+   @Path("/global/targetHttpProxies")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseTargetHttpProxies.class)
+   @Transform(ParseTargetHttpProxies.ToPagedIterable.class)
+   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
+   PagedIterable<TargetHttpProxy> list(ListOptions options);
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/29f4013d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/UrlMapApi.java
----------------------------------------------------------------------
diff --git 
a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/UrlMapApi.java
 
b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/UrlMapApi.java
new file mode 100644
index 0000000..41122e4
--- /dev/null
+++ 
b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/UrlMapApi.java
@@ -0,0 +1,267 @@
+/*
+ * 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 java.net.URI;
+
+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.PUT;
+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.ListPage;
+import org.jclouds.googlecomputeengine.domain.Operation;
+import org.jclouds.googlecomputeengine.domain.UrlMap;
+import org.jclouds.googlecomputeengine.domain.UrlMapValidateResult;
+import org.jclouds.googlecomputeengine.functions.internal.PATCH;
+import org.jclouds.googlecomputeengine.functions.internal.ParseUrlMaps;
+import org.jclouds.googlecomputeengine.handlers.PayloadBinder;
+import org.jclouds.googlecomputeengine.options.ListOptions;
+import org.jclouds.googlecomputeengine.options.UrlMapOptions;
+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.BinderParam;
+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 UrlMaps via their REST API.
+ * <p/>
+ *
+ * @see <a 
href="https://developers.google.com/compute/docs/reference/latest/urlMaps"/>
+ */
+@SkipEncoding({'/', '='})
+@RequestFilters(OAuthAuthenticator.class)
+@Consumes(MediaType.APPLICATION_JSON)
+public interface UrlMapApi {
+   /**
+    * Returns the specified urlMap resource.
+    *
+    * @param urlMapName name of the urlMap resource to return.
+    * @return an UrlMap resource.
+    */
+   @Named("UrlMaps:get")
+   @GET
+   @Path("/global/urlMaps/{urlMap}")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   UrlMap get(@PathParam("urlMap") String urlMapName);
+
+   /**
+    * Creates a urlMap resource in the specified project using the data 
included in the request.
+    *
+    * @param name            the name of the urlMap to be inserted.
+    * @param urlMapOptions   the options of the urlMap to add.
+    * @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("UrlMaps:insert")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("/global/urlMaps")
+   @OAuthScopes({COMPUTE_SCOPE})
+   @MapBinder(PayloadBinder.class)
+   Operation create(@PayloadParam("name") String name, 
@PayloadParam("options") UrlMapOptions urlMapOptions);
+   
+   /**
+    * Creates a urlMap resource in the specified project using the data 
included in the request.
+    *
+    * @param name            the name of the urlMap to be inserted.
+    * @param defaultService  the default backend service of the urlMap to add.
+    * @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("UrlMaps:insert")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("/global/urlMaps")
+   @OAuthScopes({COMPUTE_SCOPE})
+   @MapBinder(BindToJsonPayload.class)
+   Operation create(@PayloadParam("name") String name,
+                    @PayloadParam("defaultService") URI defaultService);
+
+   /**
+    * Updates the specified urlMap resource with the data included in the 
request.
+    *
+    * @param urlMapName    the name urlMap to be updated.
+    * @param urlMapOptions the new urlMap options.
+    * @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("UrlMaps:update")
+   @PUT
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("/global/urlMaps/{urlMap}")
+   @OAuthScopes({COMPUTE_SCOPE})
+   Operation update(@PathParam("urlMap") String urlMapName,
+                    @BinderParam(BindToJsonPayload.class) UrlMapOptions 
urlMapOptions);
+
+   /**
+    * Updates the specified urlMap resource, with patch semantics, with the 
data included in the request.
+    *
+    * @param urlMapName    the name urlMap to be updated.
+    * @param urlMapOptions the new urlMap options.
+    * @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("UrlMaps:patch")
+   @PATCH
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("/global/urlMaps/{urlMap}")
+   @OAuthScopes({COMPUTE_SCOPE})
+   Operation patch(@PathParam("urlMap") String urlMapName,
+                   @BinderParam(BindToJsonPayload.class) UrlMapOptions 
urlMapOptions);
+
+   /**
+    * Deletes the specified urlMap resource.
+    *
+    * @param urlMapName name of the urlMap 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.  If the image did not exist 
the result is null.
+    */
+   @Named("UrlMaps:delete")
+   @DELETE
+   @Path("/global/urlMaps/{urlMap}")
+   @OAuthScopes(COMPUTE_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   Operation delete(@PathParam("urlMap") String urlMapName);
+   
+   /**
+    * Runs the tests specified for the give urlMap resource.
+    *
+    * @param urlMapName name of the urlMap to run tests on.
+    * @param options    options that represent the url map to be tested.
+    * @return the result of the tests for the given urlMap resource.
+    */
+   @Named("UrlMaps:validate")
+   @POST
+   @Path("/global/urlMaps/{urlMap}/validate")
+   @OAuthScopes(COMPUTE_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   @MapBinder(BindToJsonPayload.class)
+   UrlMapValidateResult validate(@PathParam("urlMap") String urlMapName,
+                                 @PayloadParam("resource") UrlMapOptions 
options);
+   
+   /**
+    * Runs the tests specified for the give urlMap resource.
+    *
+    * @param urlMapName name of the urlMap to run tests on.
+    * @param urlMap     the url map to be tested.
+    * @return the result of the tests for the given urlMap resource.
+    */
+   @Named("UrlMaps:validate")
+   @POST
+   @Path("/global/urlMaps/{urlMap}/validate")
+   @OAuthScopes(COMPUTE_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   @MapBinder(BindToJsonPayload.class)
+   UrlMapValidateResult validate(@PathParam("urlMap") String urlMapName,
+                                 @PayloadParam("resource") UrlMap urlMap);
+
+   /**
+    * @see UrlMapApi#listAtMarker(String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("UrlMaps:list")
+   @GET
+   @Path("/global/urlMaps")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseUrlMaps.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<UrlMap> listFirstPage();
+
+   /**
+    * @see UrlMapApi#listAtMarker(String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("UrlMaps:list")
+   @GET
+   @Path("/global/urlMaps")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseUrlMaps.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<UrlMap> listAtMarker(@QueryParam("pageToken") @Nullable String 
marker);
+
+   /**
+    * Retrieves the list of urlMap resources available to the specified 
project.
+    * By default the list as a maximum size of 100, if no options are provided 
or ListOptions#getMaxResults() has not
+    * been set.
+    *
+    * @param marker      marks the beginning of the next list page.
+    * @param listOptions listing options.
+    * @return a page of the list.
+    * @see ListOptions
+    * @see org.jclouds.googlecomputeengine.domain.ListPage
+    */
+   @Named("UrlMaps:list")
+   @GET
+   @Path("/global/urlMaps")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseUrlMaps.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<UrlMap> listAtMarker(@QueryParam("pageToken") @Nullable String 
marker, ListOptions options);
+
+   /**
+    * @see UrlMapApi#list(org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("UrlMaps:list")
+   @GET
+   @Path("/global/urlMaps")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseUrlMaps.class)
+   @Transform(ParseUrlMaps.ToPagedIterable.class)
+   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
+   PagedIterable<UrlMap> list();
+
+   /**
+    * A paged version of UrlMapApi#list().
+    *
+    * @return a Paged, Fluent Iterable that is able to fetch additional pages 
when required.
+    * @see PagedIterable
+    * @see UrlMapApi#listAtMarker(String, 
org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("UrlMaps:list")
+   @GET
+   @Path("/global/urlMaps")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseUrlMaps.class)
+   @Transform(ParseUrlMaps.ToPagedIterable.class)
+   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
+   PagedIterable<UrlMap> list(ListOptions options);
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/29f4013d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/BaseWithRegionAndNameToPagedIterable.java
----------------------------------------------------------------------
diff --git 
a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/BaseWithRegionAndNameToPagedIterable.java
 
b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/BaseWithRegionAndNameToPagedIterable.java
new file mode 100644
index 0000000..4018a5f
--- /dev/null
+++ 
b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/BaseWithRegionAndNameToPagedIterable.java
@@ -0,0 +1,83 @@
+/*
+ * 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.functions.internal;
+
+import static com.google.common.base.Optional.fromNullable;
+import static com.google.common.base.Predicates.instanceOf;
+import static com.google.common.collect.Iterables.tryFind;
+
+import org.jclouds.collect.IterableWithMarker;
+import org.jclouds.collect.PagedIterable;
+import org.jclouds.collect.PagedIterables;
+import org.jclouds.googlecomputeengine.domain.ListPage;
+import org.jclouds.googlecomputeengine.options.ListOptions;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.rest.InvocationContext;
+import org.jclouds.rest.internal.GeneratedHttpRequest;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
+
+@Beta
+public abstract class BaseWithRegionAndNameToPagedIterable<T, I extends 
BaseWithRegionAndNameToPagedIterable<T, I>>
+        implements Function<ListPage<T>, PagedIterable<T>>, 
InvocationContext<I> {
+
+   private GeneratedHttpRequest request;
+
+   @Override
+   public PagedIterable<T> apply(ListPage<T> input) {
+      if (input.nextMarker() == null)
+         return PagedIterables.of(input);
+
+      Optional<Object> project = tryFind(request.getCaller().get().getArgs(),
+                                         instanceOf(String.class));
+
+      Optional<Object> region = 
fromNullable(Iterables.get(request.getInvocation().getArgs(),
+                                                           0, null));
+      
+      Optional<Object> name = 
fromNullable(Iterables.get(request.getInvocation().getArgs(),
+                                                         1, null));
+
+      Optional<Object> listOptions = tryFind(request.getInvocation().getArgs(),
+                                             instanceOf(ListOptions.class));
+
+      assert project.isPresent() : String.format("programming error, method %s 
should have a string param for the "
+              + "project", request.getCaller().get().getInvokable());
+
+      assert region.isPresent() : String.format("programming error, method %s 
should have a string param for the "
+              + "zone", request.getCaller().get().getInvokable());
+
+      return PagedIterables.advance(
+              input, fetchNextPage(project.get().toString(),
+                                   region.get().toString(), 
name.get().toString(),
+                                   (ListOptions) listOptions.orNull()));
+   }
+
+   protected abstract Function<Object, IterableWithMarker<T>> 
fetchNextPage(String projectName,
+                                                                            
String regionName,
+                                                                            
String name,
+                                                                            
ListOptions listOptions);
+
+   @SuppressWarnings("unchecked")
+   @Override
+   public I setContext(HttpRequest request) {
+      this.request = GeneratedHttpRequest.class.cast(request);
+      return (I) this;
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/29f4013d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/BaseWithZoneAndNameToPagedIterable.java
----------------------------------------------------------------------
diff --git 
a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/BaseWithZoneAndNameToPagedIterable.java
 
b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/BaseWithZoneAndNameToPagedIterable.java
new file mode 100644
index 0000000..d3c67ec
--- /dev/null
+++ 
b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/BaseWithZoneAndNameToPagedIterable.java
@@ -0,0 +1,83 @@
+/*
+ * 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.functions.internal;
+
+import static com.google.common.base.Optional.fromNullable;
+import static com.google.common.base.Predicates.instanceOf;
+import static com.google.common.collect.Iterables.tryFind;
+
+import org.jclouds.collect.IterableWithMarker;
+import org.jclouds.collect.PagedIterable;
+import org.jclouds.collect.PagedIterables;
+import org.jclouds.googlecomputeengine.domain.ListPage;
+import org.jclouds.googlecomputeengine.options.ListOptions;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.rest.InvocationContext;
+import org.jclouds.rest.internal.GeneratedHttpRequest;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
+
+@Beta
+public abstract class BaseWithZoneAndNameToPagedIterable<T, I extends 
BaseWithZoneAndNameToPagedIterable<T, I>>
+        implements Function<ListPage<T>, PagedIterable<T>>, 
InvocationContext<I> {
+
+   private GeneratedHttpRequest request;
+
+   @Override
+   public PagedIterable<T> apply(ListPage<T> input) {
+      if (input.nextMarker() == null)
+         return PagedIterables.of(input);
+
+      Optional<Object> project = tryFind(request.getCaller().get().getArgs(),
+                                         instanceOf(String.class));
+
+      Optional<Object> zone = 
fromNullable(Iterables.get(request.getInvocation().getArgs(),
+                                                         0, null));
+      
+      Optional<Object> name = 
fromNullable(Iterables.get(request.getInvocation().getArgs(),
+                                                         1, null));
+
+      Optional<Object> listOptions = tryFind(request.getInvocation().getArgs(),
+                                             instanceOf(ListOptions.class));
+
+      assert project.isPresent() : String.format("programming error, method %s 
should have a string param for the "
+              + "project", request.getCaller().get().getInvokable());
+
+      assert zone.isPresent() : String.format("programming error, method %s 
should have a string param for the "
+              + "zone", request.getCaller().get().getInvokable());
+
+      return PagedIterables.advance(
+              input, fetchNextPage(project.get().toString(), 
zone.get().toString(),
+                                   name.get().toString(),
+                                   (ListOptions) listOptions.orNull()));
+   }
+
+   protected abstract Function<Object, IterableWithMarker<T>> 
fetchNextPage(String projectName,
+                                                                            
String zoneName,
+                                                                            
String name,
+                                                                            
ListOptions listOptions);
+
+   @SuppressWarnings("unchecked")
+   @Override
+   public I setContext(HttpRequest request) {
+      this.request = GeneratedHttpRequest.class.cast(request);
+      return (I) this;
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/29f4013d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/ParseBackendServices.java
----------------------------------------------------------------------
diff --git 
a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/ParseBackendServices.java
 
b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/ParseBackendServices.java
new file mode 100644
index 0000000..52172e3
--- /dev/null
+++ 
b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/ParseBackendServices.java
@@ -0,0 +1,63 @@
+/*
+ * 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.functions.internal;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import javax.inject.Inject;
+
+import org.jclouds.collect.IterableWithMarker;
+import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import org.jclouds.googlecomputeengine.domain.BackendService;
+import org.jclouds.googlecomputeengine.domain.ListPage;
+import org.jclouds.googlecomputeengine.options.ListOptions;
+import org.jclouds.http.functions.ParseJson;
+import org.jclouds.json.Json;
+
+import com.google.common.base.Function;
+import com.google.inject.TypeLiteral;
+
+public class ParseBackendServices extends ParseJson<ListPage<BackendService>> {
+
+   @Inject
+   public ParseBackendServices(Json json) {
+      super(json, new TypeLiteral<ListPage<BackendService>>() {
+      });
+   }
+
+   public static class ToPagedIterable extends 
BaseToPagedIterable<BackendService, ToPagedIterable> {
+
+      private final GoogleComputeEngineApi api;
+
+      @Inject
+      protected ToPagedIterable(GoogleComputeEngineApi api) {
+         this.api = checkNotNull(api, "api");
+      }
+
+      @Override
+      protected Function<Object, IterableWithMarker<BackendService>> 
fetchNextPage(final String projectName,
+                                                                               
    final ListOptions options) {
+         return new Function<Object, IterableWithMarker<BackendService>>() {
+
+            @Override
+            public IterableWithMarker<BackendService> apply(Object input) {
+               return 
api.getBackendServiceApiForProject(projectName).listAtMarker(input.toString(), 
options);
+            }
+         };
+      }
+   }
+}

Reply via email to