You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2015/04/15 21:41:30 UTC

[25/39] jclouds git commit: JCLOUDS-750 At the cost of fiddling with type hierarchy adapters, remove lots of junk with google auto.

JCLOUDS-750 At the cost of fiddling with type hierarchy adapters, remove lots of junk with google auto.


Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/07d7a5a7
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/07d7a5a7
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/07d7a5a7

Branch: refs/heads/master
Commit: 07d7a5a749ddc1e248d24ae544e1a1258a677ba6
Parents: f94d0ca
Author: Adrian Cole <ad...@gmail.com>
Authored: Sat Oct 25 15:23:30 2014 -0700
Committer: Adrian Cole <ac...@twitter.com>
Committed: Mon Oct 27 09:27:54 2014 -0700

----------------------------------------------------------------------
 apis/oauth/pom.xml                              |  11 ++
 .../java/org/jclouds/oauth/v2/OAuthApi.java     |   1 -
 .../org/jclouds/oauth/v2/OAuthApiMetadata.java  |  10 +-
 .../jclouds/oauth/v2/config/OAuthModule.java    |  48 ++---
 .../oauth/v2/config/OAuthParserModule.java      | 159 +++++++++++++++++
 .../org/jclouds/oauth/v2/domain/ClaimSet.java   | 173 ++-----------------
 .../org/jclouds/oauth/v2/domain/Header.java     | 108 +-----------
 .../java/org/jclouds/oauth/v2/domain/Token.java | 134 ++------------
 .../jclouds/oauth/v2/domain/TokenRequest.java   | 116 +------------
 .../oauth/v2/domain/TokenRequestFormat.java     |   2 +-
 .../oauth/v2/filters/OAuthAuthenticator.java    |   2 +-
 .../oauth/v2/functions/BuildTokenRequest.java   |  37 ++--
 .../v2/internal/SubtypeAdapterFactory.java      |  42 +++++
 .../oauth/v2/json/ClaimSetTypeAdapter.java      |  59 -------
 .../oauth/v2/json/HeaderTypeAdapter.java        |  52 ------
 .../oauth/v2/json/JWTTokenRequestFormat.java    |  19 +-
 .../services/org.jclouds.apis.ApiMetadata       |  18 --
 .../org/jclouds/oauth/v2/OAuthTestUtils.java    |  26 ++-
 .../oauth/v2/features/OAuthApiExpectTest.java   |  99 -----------
 .../oauth/v2/features/OAuthApiLiveTest.java     |  10 +-
 .../oauth/v2/features/OAuthApiMockTest.java     | 114 ++++++++++++
 .../v2/internal/BaseOAuthApiExpectTest.java     |  23 ---
 .../BaseOAuthAuthenticatedApiLiveTest.java      |  13 +-
 .../oauth/v2/internal/BaseOAuthExpectTest.java  |  26 ---
 .../oauth/v2/internal/BaseOAuthParseTest.java   |  30 ++++
 .../v2/json/JWTTokenRequestFormatTest.java      |   9 +-
 .../jclouds/oauth/v2/parse/ParseTokenTest.java  |  18 +-
 27 files changed, 481 insertions(+), 878 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/pom.xml
----------------------------------------------------------------------
diff --git a/apis/oauth/pom.xml b/apis/oauth/pom.xml
index a157fde..7c22dcb 100644
--- a/apis/oauth/pom.xml
+++ b/apis/oauth/pom.xml
@@ -49,6 +49,12 @@
       <version>${jclouds.version}</version>
     </dependency>
     <dependency>
+      <groupId>com.google.auto.value</groupId>
+      <artifactId>auto-value</artifactId>
+      <version>1.0-rc2</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
       <groupId>org.apache.jclouds</groupId>
       <artifactId>jclouds-core</artifactId>
       <version>${jclouds.version}</version>
@@ -62,6 +68,11 @@
       <scope>test</scope>
     </dependency>
     <dependency>
+      <groupId>com.squareup.okhttp</groupId>
+      <artifactId>mockwebserver</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>ch.qos.logback</groupId>
       <artifactId>logback-classic</artifactId>
       <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/main/java/org/jclouds/oauth/v2/OAuthApi.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/OAuthApi.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/OAuthApi.java
index 1b20734..4a12d8d 100644
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/OAuthApi.java
+++ b/apis/oauth/src/main/java/org/jclouds/oauth/v2/OAuthApi.java
@@ -57,5 +57,4 @@ public interface OAuthApi extends Closeable {
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    Token authenticate(@BinderParam(OAuthTokenBinder.class) TokenRequest tokenRequest) throws AuthorizationException;
-
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/main/java/org/jclouds/oauth/v2/OAuthApiMetadata.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/OAuthApiMetadata.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/OAuthApiMetadata.java
index 3ef26e6..d946d70 100644
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/OAuthApiMetadata.java
+++ b/apis/oauth/src/main/java/org/jclouds/oauth/v2/OAuthApiMetadata.java
@@ -22,16 +22,17 @@ import static org.jclouds.oauth.v2.config.OAuthProperties.SIGNATURE_OR_MAC_ALGOR
 import java.net.URI;
 import java.util.Properties;
 
+import org.jclouds.apis.ApiMetadata;
 import org.jclouds.oauth.v2.config.OAuthHttpApiModule;
 import org.jclouds.oauth.v2.config.OAuthModule;
+import org.jclouds.oauth.v2.config.OAuthParserModule;
 import org.jclouds.rest.internal.BaseHttpApiMetadata;
 
+import com.google.auto.service.AutoService;
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.Module;
 
-/**
- * Implementation of {@link ApiMetadata} for OAuth 2 API
- */
+@AutoService(ApiMetadata.class)
 public class OAuthApiMetadata extends BaseHttpApiMetadata<OAuthApi> {
 
    @Override
@@ -64,7 +65,8 @@ public class OAuthApiMetadata extends BaseHttpApiMetadata<OAuthApi> {
          .documentation(URI.create("TODO"))
          .version("2")
          .defaultProperties(OAuthApiMetadata.defaultProperties())
-         .defaultModules(ImmutableSet.<Class<? extends Module>>of(OAuthModule.class, OAuthHttpApiModule.class));
+         .defaultModules(ImmutableSet
+               .<Class<? extends Module>>of(OAuthModule.class, OAuthParserModule.class, OAuthHttpApiModule.class));
       }
 
       @Override

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/main/java/org/jclouds/oauth/v2/config/OAuthModule.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/config/OAuthModule.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/config/OAuthModule.java
index 1041c07..788dac4 100644
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/config/OAuthModule.java
+++ b/apis/oauth/src/main/java/org/jclouds/oauth/v2/config/OAuthModule.java
@@ -16,21 +16,10 @@
  */
 package org.jclouds.oauth.v2.config;
 
-import com.google.common.base.Function;
-import com.google.common.base.Supplier;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import com.google.common.collect.ImmutableMap;
-import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import com.google.inject.Provides;
-import com.google.inject.Singleton;
-import com.google.inject.TypeLiteral;
-import com.google.inject.name.Named;
-import org.jclouds.oauth.v2.domain.ClaimSet;
-import org.jclouds.oauth.v2.domain.Header;
+import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
+
+import java.util.concurrent.TimeUnit;
+
 import org.jclouds.oauth.v2.domain.OAuthCredentials;
 import org.jclouds.oauth.v2.domain.Token;
 import org.jclouds.oauth.v2.domain.TokenRequest;
@@ -41,28 +30,25 @@ import org.jclouds.oauth.v2.functions.BuildTokenRequest;
 import org.jclouds.oauth.v2.functions.FetchToken;
 import org.jclouds.oauth.v2.functions.OAuthCredentialsSupplier;
 import org.jclouds.oauth.v2.functions.SignOrProduceMacForToken;
-import org.jclouds.oauth.v2.json.ClaimSetTypeAdapter;
-import org.jclouds.oauth.v2.json.HeaderTypeAdapter;
 import org.jclouds.rest.internal.GeneratedHttpRequest;
 
-import java.lang.reflect.Type;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.inject.AbstractModule;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Provides;
+import com.google.inject.Singleton;
+import com.google.inject.TypeLiteral;
+import com.google.inject.name.Named;
 
-/**
- * Base OAuth module
- */
 public class OAuthModule extends AbstractModule {
 
-
-   @Override
-   protected void configure() {
+   @Override protected void configure() {
       bind(new TypeLiteral<Function<byte[], byte[]>>() {}).to(SignOrProduceMacForToken.class);
-      bind(new TypeLiteral<Map<Type, Object>>() {}).toInstance(ImmutableMap.<Type, Object>of(
-            Header.class, new HeaderTypeAdapter(),
-            ClaimSet.class, new ClaimSetTypeAdapter()));
       bind(CredentialType.class).toProvider(CredentialTypeFromPropertyOrDefault.class);
       bind(new TypeLiteral<Supplier<OAuthCredentials>>() {}).to(OAuthCredentialsSupplier.class);
       bind(new TypeLiteral<Function<GeneratedHttpRequest, TokenRequest>>() {}).to(BuildTokenRequest.class);

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/main/java/org/jclouds/oauth/v2/config/OAuthParserModule.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/config/OAuthParserModule.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/config/OAuthParserModule.java
new file mode 100644
index 0000000..4768e6b
--- /dev/null
+++ b/apis/oauth/src/main/java/org/jclouds/oauth/v2/config/OAuthParserModule.java
@@ -0,0 +1,159 @@
+/*
+ * 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.oauth.v2.config;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Singleton;
+
+import org.jclouds.oauth.v2.domain.ClaimSet;
+import org.jclouds.oauth.v2.domain.Header;
+import org.jclouds.oauth.v2.domain.Token;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.gson.Gson;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import com.google.inject.AbstractModule;
+import com.google.inject.Provides;
+
+/** Configures type adapter factories for {@link Header}, {@link ClaimSet}, and {@link Token}. */
+public final class OAuthParserModule extends AbstractModule {
+   @Override protected void configure() {
+   }
+
+   // TODO: change jclouds core to use collaborative set bindings
+   @Provides @Singleton public Set<TypeAdapterFactory> typeAdapterFactories() {
+      return ImmutableSet
+            .<TypeAdapterFactory>of(new HeaderTypeAdapter(), new ClaimSetTypeAdapter(), new TokenAdapter());
+   }
+
+   private static final class HeaderTypeAdapter extends SubtypeAdapterFactory<Header> {
+      HeaderTypeAdapter() {
+         super(Header.class);
+      }
+
+      @Override public void write(JsonWriter out, Header value) throws IOException {
+         out.beginObject();
+         out.name("alg");
+         out.value(value.signerAlgorithm());
+         out.name("typ");
+         out.value(value.type());
+         out.endObject();
+      }
+
+      @Override public Header read(JsonReader in) throws IOException {
+         in.beginObject();
+         in.nextName();
+         String signerAlgorithm = in.nextString();
+         in.nextName();
+         String type = in.nextString();
+         in.endObject();
+         return Header.create(signerAlgorithm, type);
+      }
+   }
+
+   private static final class ClaimSetTypeAdapter extends SubtypeAdapterFactory<ClaimSet> {
+      ClaimSetTypeAdapter() {
+         super(ClaimSet.class);
+      }
+
+      @Override public void write(JsonWriter out, ClaimSet value) throws IOException {
+         out.beginObject();
+         for (Map.Entry<String, String> entry : value.claims().entrySet()) {
+            out.name(entry.getKey());
+            out.value(entry.getValue());
+         }
+         out.name("exp");
+         out.value(value.expirationTime());
+         out.name("iat");
+         out.value(value.emissionTime());
+         out.endObject();
+      }
+
+      @Override public ClaimSet read(JsonReader in) throws IOException {
+         Map<String, String> claims = new LinkedHashMap<String, String>();
+         in.beginObject();
+         while (in.hasNext()) {
+            claims.put(in.nextName(), in.nextString());
+         }
+         in.endObject();
+         return ClaimSet.create(0, 0, Collections.unmodifiableMap(claims));
+      }
+   }
+
+   /** OAuth is used in apis that may not default to snake case. Explicity control case format. */
+   private static final class TokenAdapter extends SubtypeAdapterFactory<Token> {
+      TokenAdapter() {
+         super(Token.class);
+      }
+
+      @Override public void write(JsonWriter out, Token value) throws IOException {
+         out.beginObject();
+         out.name("access_token");
+         out.value(value.accessToken());
+         out.name("token_type");
+         out.value(value.tokenType());
+         out.name("expires_in");
+         out.value(value.expiresIn());
+         out.endObject();
+      }
+
+      @Override public Token read(JsonReader in) throws IOException {
+         String accessToken = null;
+         String tokenType = null;
+         int expiresIn = 0;
+         in.beginObject();
+         while (in.hasNext()) {
+            String name = in.nextName();
+            if (name.equals("access_token")) {
+               accessToken = in.nextString();
+            } else if (name.equals("token_type")) {
+               tokenType = in.nextString();
+            } else if (name.equals("expires_in")) {
+               expiresIn = in.nextInt();
+            } else {
+               in.skipValue();
+            }
+         }
+         in.endObject();
+         return Token.create(accessToken, tokenType, expiresIn);
+      }
+   }
+
+   private abstract static class SubtypeAdapterFactory<T> extends TypeAdapter<T> implements TypeAdapterFactory {
+      private final Class<T> baseClass;
+
+      private SubtypeAdapterFactory(Class<T> baseClass) {
+         this.baseClass = baseClass;
+      }
+
+      @Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
+         if (!(baseClass.isAssignableFrom(typeToken.getRawType()))) {
+            return null;
+         }
+         return (TypeAdapter<T>) this;
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/ClaimSet.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/ClaimSet.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/ClaimSet.java
index 5c0b348..e265e90 100644
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/ClaimSet.java
+++ b/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/ClaimSet.java
@@ -16,176 +16,27 @@
  */
 package org.jclouds.oauth.v2.domain;
 
-import com.google.common.base.Objects;
-import com.google.common.base.Splitter;
-import com.google.common.collect.ForwardingMap;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-
 import java.util.Map;
-import java.util.Set;
 
-import static com.google.common.base.Objects.ToStringHelper;
-import static com.google.common.base.Objects.equal;
-import static com.google.common.base.Objects.toStringHelper;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
+import com.google.auto.value.AutoValue;
 
 /**
- * The claimset for the token.
+ * The claimset for the {@linkplain Token}.
  *
- * @see <a
- *      href="https://developers.google.com/accounts/docs/OAuth2ServiceAccount"
- *      >doc</a>
+ * @see <a href="https://developers.google.com/accounts/docs/OAuth2ServiceAccount">doc</a>
  */
-public class ClaimSet extends ForwardingMap<String, String> {
-
-   public static Builder builder() {
-      return new Builder();
-   }
-
-   public Builder toBuilder() {
-      return builder().fromClaimSet(this);
-   }
-
-   public static class Builder {
-
-      private Set<String> requiredClaims;
-      private ImmutableMap.Builder<String, String> claims = new ImmutableMap.Builder<String, String>();
-      private long emissionTime;
-      private long expirationTime;
-
-      public Builder() {
-         this(ImmutableSet.<String>of());
-      }
+@AutoValue
+public abstract class ClaimSet {
 
-      /**
-       * Constructor that allows to predefine a mandatory set of claims as a comma-separated string, e.g, "iss,iat".
-       */
-      public Builder(String commaSeparatedRequiredClaims) {
-         this(ImmutableSet.copyOf(Splitter.on(",").split(checkNotNull(commaSeparatedRequiredClaims))));
-      }
+   /** The emission time, in seconds since the epoch. */
+   public abstract long emissionTime();
 
-      /**
-       * Constructor that allows to predefine a mandatory set of claims as a set of strings.
-       */
-      public Builder(Set<String> requiredClaims) {
-         this.requiredClaims = ImmutableSet.copyOf(checkNotNull(requiredClaims));
-      }
-
-      /**
-       * Adds a Claim, i.e. key/value pair, e.g., "scope":"all_permissions".
-       */
-      public Builder addClaim(String name, String value) {
-         claims.put(checkNotNull(name), checkNotNull(value, "value of %s", name));
-         return this;
-      }
-
-      /**
-       * @see ClaimSet#getEmissionTime()
-       */
-      public Builder emissionTime(long emmissionTime) {
-         this.emissionTime = emmissionTime;
-         return this;
-      }
-
-      /**
-       * @see ClaimSet#getExpirationTime()
-       */
-      public Builder expirationTime(long expirationTime) {
-         this.expirationTime = expirationTime;
-         return this;
-      }
-
-      /**
-       * Adds a map containing multiple claims
-       */
-      public Builder addAllClaims(Map<String, String> claims) {
-         this.claims.putAll(checkNotNull(claims));
-         return this;
-      }
-
-      public ClaimSet build() {
-         Map<String, String> claimsMap = claims.build();
-         checkState(Sets.intersection(claimsMap.keySet(), requiredClaims).size() == requiredClaims.size(),
-                 "not all required claims were present");
-         if (expirationTime == 0) {
-            expirationTime = emissionTime + 3600;
-         }
-         return new ClaimSet(claimsMap, emissionTime, expirationTime);
-      }
-
-      public Builder fromClaimSet(ClaimSet claimSet) {
-         return new Builder().addAllClaims(claimSet.claims).expirationTime(expirationTime).emissionTime(emissionTime);
-      }
-   }
+   /** The expiration time, in seconds since the emission time. */
+   public abstract long expirationTime();
 
-   private final Map<String, String> claims;
-   private final long emissionTime;
-   private final long expirationTime;
-
-   private ClaimSet(Map<String, String> claims, long emissionTime, long expirationTime) {
-      this.claims = claims;
-      this.emissionTime = emissionTime;
-      this.expirationTime = expirationTime;
-   }
-
-   /**
-    * The emission time, in seconds since the epoch.
-    */
-   public long getEmissionTime() {
-      return emissionTime;
-   }
-
-   /**
-    * The expiration time, in seconds since the emission time.
-    */
-   public long getExpirationTime() {
-      return expirationTime;
-   }
-
-   /**
-    * @returns the claims.
-    */
-   @Override
-   protected Map<String, String> delegate() {
-      return claims;
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   public int hashCode() {
-      return Objects.hashCode(claims);
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   public boolean equals(Object obj) {
-      if (this == obj)
-         return true;
-      if (obj == null)
-         return false;
-      if (getClass() != obj.getClass())
-         return false;
-      ClaimSet other = (ClaimSet) obj;
-      return equal(claims, other.claims);
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   public String toString() {
-      return string().toString();
-   }
+   public abstract Map<String, String> claims();
 
-   protected ToStringHelper string() {
-      return toStringHelper(this).omitNullValues().add("claims", claims)
-              .add("emissionTime", emissionTime).add("expirationTIme", expirationTime);
+   public static ClaimSet create(long emissionTime, long expirationTime, Map<String, String> claims) {
+      return new AutoValue_ClaimSet(emissionTime, expirationTime, claims);
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/Header.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/Header.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/Header.java
index c230e1d..9146824 100644
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/Header.java
+++ b/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/Header.java
@@ -16,113 +16,23 @@
  */
 package org.jclouds.oauth.v2.domain;
 
-import com.google.common.base.Objects;
-
-import static com.google.common.base.Objects.equal;
-import static com.google.common.base.Objects.toStringHelper;
-import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.auto.value.AutoValue;
 
 /**
  * The header for the OAuth token, contains the signer algorithm's name and the type of the token
  *
  * @see <a href="https://developers.google.com/accounts/docs/OAuth2ServiceAccount">doc</a>
  */
-public class Header {
-
-   public static Builder builder() {
-      return new Builder();
-   }
-
-   public Builder toBuilder() {
-      return builder().fromHeader(this);
-   }
-
-   public static class Builder {
-
-      private String signerAlgorithm;
-      private String type;
-
-      /**
-       * @see Header#getSignerAlgorithm()
-       */
-      public Builder signerAlgorithm(String signerAlgorithm) {
-         this.signerAlgorithm = checkNotNull(signerAlgorithm);
-         return this;
-      }
-
-      /**
-       * @see Header#getType()
-       */
-      public Builder type(String type) {
-         this.type = checkNotNull(type);
-         return this;
-      }
-
-      public Header build() {
-         return new Header(signerAlgorithm, type);
-      }
-
-      public Builder fromHeader(Header header) {
-         return new Builder().signerAlgorithm(header.signerAlgorithm).type(header.type);
-      }
-   }
+@AutoValue
+public abstract class Header {
 
-   private final String signerAlgorithm;
-   private final String type;
+   /** The name of the algorithm used to compute the signature, e.g., {@code RS256}. */
+   public abstract String signerAlgorithm();
 
-   protected Header(String signerAlgorithm, String type) {
-      this.signerAlgorithm = checkNotNull(signerAlgorithm);
-      this.type = checkNotNull(type);
-   }
-
-   /**
-    * The name of the algorithm used to compute the signature, e.g., "RS256"
-    */
-   public String getSignerAlgorithm() {
-      return signerAlgorithm;
-   }
-
-   /**
-    * The type of the token, e.g., "JWT"
-    */
-   public String getType() {
-      return type;
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   public boolean equals(Object obj) {
-      if (this == obj)
-         return true;
-      if (obj == null)
-         return false;
-      if (getClass() != obj.getClass())
-         return false;
-      Header other = (Header) obj;
-      return equal(this.signerAlgorithm, other.signerAlgorithm) && equal(this.type,
-              other.type);
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   public int hashCode() {
-      return Objects.hashCode(signerAlgorithm, type);
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   public String toString() {
-      return string().toString();
-   }
+   /** The type of the token, e.g., {@code JWT}. */
+   public abstract String type();
 
-   protected Objects.ToStringHelper string() {
-      return toStringHelper(this).omitNullValues().add("signerAlgorithm", signerAlgorithm)
-              .add("type", type);
+   public static Header create(String signerAlgorithm, String type){
+      return new AutoValue_Header(signerAlgorithm, type);
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/Token.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/Token.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/Token.java
index a18a7eb..cf7ce57 100644
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/Token.java
+++ b/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/Token.java
@@ -16,134 +16,24 @@
  */
 package org.jclouds.oauth.v2.domain;
 
-import com.google.common.base.Objects;
-
-import java.beans.ConstructorProperties;
-
-import static com.google.common.base.Objects.equal;
-import static com.google.common.base.Objects.toStringHelper;
-import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.auto.value.AutoValue;
 
 /**
  * The oauth token, obtained upon a successful token request and ready to embed in requests.
  */
-public class Token {
-
-   public static Builder builder() {
-      return new Builder();
-   }
-
-   public Builder toBuilder() {
-      return builder().fromToken(this);
-   }
-
-   public static class Builder {
-
-      private String accessToken;
-      private String tokenType;
-      private long expiresIn;
-
-      /**
-       * @see Token#getAccessToken()
-       */
-      public Builder accessToken(String accessToken) {
-         this.accessToken = checkNotNull(accessToken);
-         return this;
-      }
-
-      /**
-       * @see Token#getTokenType()
-       */
-      public Builder tokenType(String tokenType) {
-         this.tokenType = checkNotNull(tokenType);
-         return this;
-      }
-
-      /**
-       * @see Token#getExpiresIn()
-       */
-      public Builder expiresIn(long expiresIn) {
-         this.expiresIn = expiresIn;
-         return this;
-      }
-
-      public Token build() {
-         return new Token(accessToken, tokenType, expiresIn);
-      }
-
-      public Builder fromToken(Token token) {
-         return new Builder().accessToken(token.accessToken).tokenType(token.tokenType).expiresIn(token.expiresIn);
-      }
-   }
+@AutoValue
+public abstract class Token {
+   /** The access token obtained from the OAuth server. */
+   public abstract String accessToken();
 
-   private final String accessToken;
-   private final String tokenType;
-   private final long expiresIn;
+   /** The type of the token, e.g., {@code Bearer}. */
+   public abstract String tokenType();
 
-   @ConstructorProperties({"access_token", "token_type", "expires_in"})
-   protected Token(String accessToken, String tokenType, long expiresIn) {
-      this.accessToken = accessToken;
-      this.tokenType = tokenType;
-      this.expiresIn = expiresIn;
-   }
-
-   /**
-    * The access token obtained from the OAuth server.
-    */
-   public String getAccessToken() {
-      return accessToken;
-   }
-
-   /**
-    * The type of the token, e.g., "Bearer"
-    */
-   public String getTokenType() {
-      return tokenType;
-   }
-
-   /**
-    * In how many seconds this token expires.
-    */
-   public long getExpiresIn() {
-      return expiresIn;
-   }
+   /** In how many seconds this token expires. */
+   public abstract long expiresIn();
 
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   public boolean equals(Object obj) {
-      if (this == obj)
-         return true;
-      if (obj == null)
-         return false;
-      if (getClass() != obj.getClass())
-         return false;
-      Token other = (Token) obj;
-      return equal(this.accessToken, other.accessToken) && equal(this.tokenType,
-              other.tokenType) && equal(this.expiresIn,
-              other.expiresIn);
+   public static Token
+   create(String accessToken, String tokenType, long expiresIn) {
+      return new AutoValue_Token(accessToken, tokenType, expiresIn);
    }
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   public int hashCode() {
-      return Objects.hashCode(accessToken, tokenType, expiresIn);
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   public String toString() {
-      return string().toString();
-   }
-
-   protected Objects.ToStringHelper string() {
-      return toStringHelper(this).omitNullValues().add("accessToken", accessToken)
-              .add("tokenType", tokenType).add("expiresIn", expiresIn);
-   }
-
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/TokenRequest.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/TokenRequest.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/TokenRequest.java
index 7d1a6a4..a0154bf 100644
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/TokenRequest.java
+++ b/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/TokenRequest.java
@@ -16,116 +16,14 @@
  */
 package org.jclouds.oauth.v2.domain;
 
-import com.google.common.base.Objects;
+import com.google.auto.value.AutoValue;
 
-import static com.google.common.base.Objects.equal;
-import static com.google.common.base.Objects.toStringHelper;
-import static com.google.common.base.Preconditions.checkNotNull;
+@AutoValue
+public abstract class TokenRequest {
+   public abstract Header header();
+   public abstract ClaimSet claimSet();
 
-/**
- * A complete token request.
- */
-public class TokenRequest {
-
-   public static Builder builder() {
-      return new Builder();
-   }
-
-   public Builder toBuilder() {
-      return builder().fromTokenRequest(this);
-   }
-
-   public static class Builder {
-      private Header header;
-      private ClaimSet claimSet;
-
-      /**
-       * @see TokenRequest#getClaimSet()
-       */
-      public Builder header(Header header) {
-         this.header = header;
-         return this;
-      }
-
-      /**
-       * @see TokenRequest#getHeader()
-       */
-      public Builder claimSet(ClaimSet claimSet) {
-         this.claimSet = claimSet;
-         return this;
-      }
-
-      public TokenRequest build() {
-         return new TokenRequest(header, claimSet);
-      }
-
-      public Builder fromTokenRequest(TokenRequest tokeRequest) {
-         return new Builder().header(tokeRequest.header).claimSet(tokeRequest.claimSet);
-      }
+   public static TokenRequest create(Header header, ClaimSet claimSet) {
+      return new AutoValue_TokenRequest(header, claimSet);
    }
-
-   private final Header header;
-   private final ClaimSet claimSet;
-
-   public TokenRequest(Header header, ClaimSet claimSet) {
-      this.header = checkNotNull(header);
-      this.claimSet = checkNotNull(claimSet);
-   }
-
-   /**
-    * The header of this token request.
-    *
-    * @see Header
-    */
-   public Header getHeader() {
-      return header;
-   }
-
-   /**
-    * The claim set of this token request.
-    *
-    * @see ClaimSet
-    */
-   public ClaimSet getClaimSet() {
-      return claimSet;
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   public boolean equals(Object obj) {
-      if (this == obj)
-         return true;
-      if (obj == null)
-         return false;
-      if (getClass() != obj.getClass())
-         return false;
-      TokenRequest other = (TokenRequest) obj;
-      return equal(this.header, other.header) && equal(this.claimSet,
-              other.claimSet);
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   public int hashCode() {
-      return Objects.hashCode(header, claimSet);
-   }
-
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   public String toString() {
-      return string().toString();
-   }
-
-   protected Objects.ToStringHelper string() {
-      return toStringHelper(this).omitNullValues().add("header", header)
-              .add("claimSet", claimSet);
-   }
-
-
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/TokenRequestFormat.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/TokenRequestFormat.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/TokenRequestFormat.java
index f4b80c1..7099592 100644
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/TokenRequestFormat.java
+++ b/apis/oauth/src/main/java/org/jclouds/oauth/v2/domain/TokenRequestFormat.java
@@ -36,7 +36,7 @@ public interface TokenRequestFormat {
    /**
     * The name of the type of the token request, e.g., "JWT"
     */
-   String getTypeName();
+   String type();
 
    /**
     * The claims that must be present in the token request for it to be valid.

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/main/java/org/jclouds/oauth/v2/filters/OAuthAuthenticator.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/filters/OAuthAuthenticator.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/filters/OAuthAuthenticator.java
index c5c7b6f..40fc0cf 100644
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/filters/OAuthAuthenticator.java
+++ b/apis/oauth/src/main/java/org/jclouds/oauth/v2/filters/OAuthAuthenticator.java
@@ -54,7 +54,7 @@ public class OAuthAuthenticator implements OAuthAuthenticationFilter {
       TokenRequest tokenRequest = tokenRequestBuilder.apply(generatedHttpRequest);
       Token token = tokenFetcher.apply(tokenRequest);
       return request.toBuilder().addHeader("Authorization", String.format("%s %s",
-              token.getTokenType(), token.getAccessToken())).build();
+              token.tokenType(), token.accessToken())).build();
 
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/main/java/org/jclouds/oauth/v2/functions/BuildTokenRequest.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/functions/BuildTokenRequest.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/functions/BuildTokenRequest.java
index 7b869dc..664dcab 100644
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/functions/BuildTokenRequest.java
+++ b/apis/oauth/src/main/java/org/jclouds/oauth/v2/functions/BuildTokenRequest.java
@@ -22,6 +22,8 @@ import static org.jclouds.oauth.v2.config.OAuthProperties.AUDIENCE;
 import static org.jclouds.oauth.v2.config.OAuthProperties.SCOPES;
 import static org.jclouds.oauth.v2.config.OAuthProperties.SIGNATURE_OR_MAC_ALGORITHM;
 
+import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.Map;
 
 import javax.inject.Singleton;
@@ -38,7 +40,6 @@ import org.jclouds.rest.internal.GeneratedHttpRequest;
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.base.Supplier;
-import com.google.common.collect.ImmutableMap;
 import com.google.common.reflect.Invokable;
 import com.google.inject.Inject;
 import com.google.inject.name.Named;
@@ -61,7 +62,7 @@ public class BuildTokenRequest implements Function<GeneratedHttpRequest, TokenRe
 
    @Inject(optional = true)
    @Named(ADDITIONAL_CLAIMS)
-   protected Map<String, String> additionalClaims = ImmutableMap.of();
+   protected Map<String, String> additionalClaims = Collections.emptyMap();
 
    @Inject(optional = true)
    @Named(SCOPES)
@@ -93,24 +94,20 @@ public class BuildTokenRequest implements Function<GeneratedHttpRequest, TokenRe
       long now = timeSourceMillisSinceEpoch.get() / 1000;
 
       // fetch the token
-      Header header = new Header.Builder()
-              .signerAlgorithm(signatureAlgorithm)
-              .type(tokenRequestFormat.getTypeName())
-              .build();
-
-      ClaimSet claimSet = new ClaimSet.Builder(this.tokenRequestFormat.requiredClaims())
-              .addClaim("iss", credentialsSupplier.get().identity)
-              .addClaim("scope", getOAuthScopes(request))
-              .addClaim("aud", assertionTargetDescription)
-              .emissionTime(now)
-              .expirationTime(now + tokenDuration)
-              .addAllClaims(additionalClaims)
-              .build();
-
-      return new TokenRequest.Builder()
-              .header(header)
-              .claimSet(claimSet)
-              .build();
+      Header header = Header.create(signatureAlgorithm, tokenRequestFormat.type());
+
+      Map<String, String> claims = new LinkedHashMap<String, String>();
+      claims.put("iss", credentialsSupplier.get().identity);
+      claims.put("scope", getOAuthScopes(request));
+      claims.put("aud", assertionTargetDescription);
+      claims.putAll(additionalClaims);
+
+      checkState(claims.keySet().containsAll(tokenRequestFormat.requiredClaims()),
+            "not all required claims were present");
+
+      ClaimSet claimSet = ClaimSet.create(now, now + tokenDuration, Collections.unmodifiableMap(claims));
+
+      return TokenRequest.create(header, claimSet);
    }
 
    protected String getOAuthScopes(GeneratedHttpRequest request) {

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/main/java/org/jclouds/oauth/v2/internal/SubtypeAdapterFactory.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/internal/SubtypeAdapterFactory.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/internal/SubtypeAdapterFactory.java
new file mode 100644
index 0000000..f09bea6
--- /dev/null
+++ b/apis/oauth/src/main/java/org/jclouds/oauth/v2/internal/SubtypeAdapterFactory.java
@@ -0,0 +1,42 @@
+/*
+ * 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.oauth.v2.internal;
+
+import com.google.gson.Gson;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+
+/**
+ * Type adapter used to serialize all subtypes of a value. This can be used to force serialization for an {@link
+ * com.google.auto.value.AutoValue} generated class.
+ */
+public abstract class SubtypeAdapterFactory<T> extends TypeAdapter<T> implements TypeAdapterFactory {
+   private final Class<T> baseClass;
+
+   protected SubtypeAdapterFactory(Class<T> baseClass) {
+      this.baseClass = baseClass;
+   }
+
+   /** Accepts duty for any subtype. When using AutoValue properly, this will be the generated form. */
+   @Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
+      if (!(baseClass.isAssignableFrom(typeToken.getRawType()))) {
+         return null;
+      }
+      return (TypeAdapter<T>) this;
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/main/java/org/jclouds/oauth/v2/json/ClaimSetTypeAdapter.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/json/ClaimSetTypeAdapter.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/json/ClaimSetTypeAdapter.java
deleted file mode 100644
index 62b3a26..0000000
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/json/ClaimSetTypeAdapter.java
+++ /dev/null
@@ -1,59 +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.oauth.v2.json;
-
-import com.google.gson.TypeAdapter;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import org.jclouds.oauth.v2.domain.ClaimSet;
-
-import java.io.IOException;
-import java.util.Map;
-
-/**
- * JSON TypeAdapter for the ClaimSet type. Pull the claims maps to the root level and adds two properties for the
- * expiration time and issuing time.
- */
-public class ClaimSetTypeAdapter extends TypeAdapter<ClaimSet> {
-
-   @Override
-   public void write(JsonWriter out, ClaimSet value) throws IOException {
-      out.beginObject();
-      for (Map.Entry<String, String> entry : value.entrySet()) {
-         out.name(entry.getKey());
-         out.value(entry.getValue());
-      }
-      out.name("exp");
-      out.value(value.getExpirationTime());
-      out.name("iat");
-      out.value(value.getEmissionTime());
-      out.endObject();
-   }
-
-   @Override
-   public ClaimSet read(JsonReader in) throws IOException {
-      ClaimSet.Builder builder = new ClaimSet.Builder();
-      in.beginObject();
-      while (in.hasNext()) {
-         String claimName = in.nextName();
-         String claimValue = in.nextString();
-         builder.addClaim(claimName, claimValue);
-      }
-      in.endObject();
-      return builder.build();
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/main/java/org/jclouds/oauth/v2/json/HeaderTypeAdapter.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/json/HeaderTypeAdapter.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/json/HeaderTypeAdapter.java
deleted file mode 100644
index f911a54..0000000
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/json/HeaderTypeAdapter.java
+++ /dev/null
@@ -1,52 +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.oauth.v2.json;
-
-import com.google.gson.TypeAdapter;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import org.jclouds.oauth.v2.domain.Header;
-
-import java.io.IOException;
-
-/**
- * JSON TypeAdapter for the Header type. Simply transforms the field names.
- */
-public class HeaderTypeAdapter extends TypeAdapter<Header> {
-
-   @Override
-   public void write(JsonWriter out, Header value) throws IOException {
-      out.beginObject();
-      out.name("alg");
-      out.value(value.getSignerAlgorithm());
-      out.name("typ");
-      out.value(value.getType());
-      out.endObject();
-   }
-
-   @Override
-   public Header read(JsonReader in) throws IOException {
-      Header.Builder builder = new Header.Builder();
-      in.beginObject();
-      in.nextName();
-      builder.signerAlgorithm(in.nextString());
-      in.nextName();
-      builder.type(in.nextString());
-      in.endObject();
-      return builder.build();
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/main/java/org/jclouds/oauth/v2/json/JWTTokenRequestFormat.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/main/java/org/jclouds/oauth/v2/json/JWTTokenRequestFormat.java b/apis/oauth/src/main/java/org/jclouds/oauth/v2/json/JWTTokenRequestFormat.java
index 265cb26..41d9804 100644
--- a/apis/oauth/src/main/java/org/jclouds/oauth/v2/json/JWTTokenRequestFormat.java
+++ b/apis/oauth/src/main/java/org/jclouds/oauth/v2/json/JWTTokenRequestFormat.java
@@ -24,7 +24,6 @@ import static org.jclouds.io.Payloads.newUrlEncodedFormPayload;
 import java.util.Set;
 
 import javax.inject.Inject;
-import javax.inject.Singleton;
 
 import org.jclouds.http.HttpRequest;
 import org.jclouds.io.Payload;
@@ -45,7 +44,6 @@ import com.google.common.collect.ImmutableSet;
  * https://developers.google.com/accounts/docs/OAuth2ServiceAccount
  * <p/>
  */
-@Singleton
 public class JWTTokenRequestFormat implements TokenRequestFormat {
 
    private static final String ASSERTION_FORM_PARAM = "assertion";
@@ -55,18 +53,15 @@ public class JWTTokenRequestFormat implements TokenRequestFormat {
    private final Function<byte[], byte[]> signer;
    private final Json json;
 
-   @Inject
-   public JWTTokenRequestFormat(Function<byte[], byte[]> signer, Json json) {
+   @Inject JWTTokenRequestFormat(Function<byte[], byte[]> signer, Json json) {
       this.signer = signer;
       this.json = json;
    }
 
-   @SuppressWarnings("unchecked")
-   @Override
-   public <R extends HttpRequest> R formatRequest(R request, TokenRequest tokenRequest) {
+   @Override public <R extends HttpRequest> R formatRequest(R request, TokenRequest tokenRequest) {
 
-      String encodedHeader = json.toJson(tokenRequest.getHeader());
-      String encodedClaimSet = json.toJson(tokenRequest.getClaimSet());
+      String encodedHeader = json.toJson(tokenRequest.header());
+      String encodedClaimSet = json.toJson(tokenRequest.claimSet());
 
       encodedHeader = base64Url().omitPadding().encode(encodedHeader.getBytes(UTF_8));
       encodedClaimSet = base64Url().omitPadding().encode(encodedClaimSet.getBytes(UTF_8));
@@ -83,13 +78,11 @@ public class JWTTokenRequestFormat implements TokenRequestFormat {
       return (R) request.toBuilder().payload(payload).build();
    }
 
-   @Override
-   public String getTypeName() {
+   @Override public String type() {
       return "JWT";
    }
 
-   @Override
-   public Set<String> requiredClaims() {
+   @Override public Set<String> requiredClaims() {
       // exp and ist (expiration and emission times) are assumed mandatory already
       return ImmutableSet.of("iss", "scope", "aud");
    }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/main/resources/META-INF/services/org.jclouds.apis.ApiMetadata
----------------------------------------------------------------------
diff --git a/apis/oauth/src/main/resources/META-INF/services/org.jclouds.apis.ApiMetadata b/apis/oauth/src/main/resources/META-INF/services/org.jclouds.apis.ApiMetadata
deleted file mode 100644
index d7064de..0000000
--- a/apis/oauth/src/main/resources/META-INF/services/org.jclouds.apis.ApiMetadata
+++ /dev/null
@@ -1,18 +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.
-#
-
-org.jclouds.oauth.v2.OAuthApiMetadata

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/test/java/org/jclouds/oauth/v2/OAuthTestUtils.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/test/java/org/jclouds/oauth/v2/OAuthTestUtils.java b/apis/oauth/src/test/java/org/jclouds/oauth/v2/OAuthTestUtils.java
index 901cdfe..438d624 100644
--- a/apis/oauth/src/test/java/org/jclouds/oauth/v2/OAuthTestUtils.java
+++ b/apis/oauth/src/test/java/org/jclouds/oauth/v2/OAuthTestUtils.java
@@ -16,35 +16,33 @@
  */
 package org.jclouds.oauth.v2;
 
-import com.google.common.base.Charsets;
-import com.google.common.base.Throwables;
-import com.google.common.io.Files;
-import org.jclouds.oauth.v2.config.CredentialType;
-import org.jclouds.oauth.v2.config.OAuthProperties;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Throwables.propagate;
+import static org.jclouds.oauth.v2.config.OAuthProperties.AUDIENCE;
+import static org.jclouds.util.Strings2.toStringAndClose;
 
 import java.io.File;
 import java.io.IOException;
 import java.util.Properties;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.jclouds.oauth.v2.config.OAuthProperties.AUDIENCE;
+import org.jclouds.oauth.v2.config.CredentialType;
+import org.jclouds.oauth.v2.config.OAuthProperties;
+
+import com.google.common.base.Charsets;
+import com.google.common.io.Files;
 
-/**
- * Utils for OAuth tests.
- */
 public class OAuthTestUtils {
 
    public static Properties defaultProperties(Properties properties) {
       try {
          properties = properties == null ? new Properties() : properties;
          properties.put("oauth.identity", "foo");
-         properties.put("oauth.credential",
-            Files.asCharSource(new File("src/test/resources/testpk.pem"), Charsets.UTF_8).read());
+         properties.put("oauth.credential", toStringAndClose(OAuthTestUtils.class.getResourceAsStream("/testpk.pem")));
          properties.put("oauth.endpoint", "http://localhost:5000/o/oauth2/token");
          properties.put(AUDIENCE, "https://accounts.google.com/o/oauth2/token");
          return properties;
       } catch (IOException e) {
-         throw Throwables.propagate(e);
+         throw propagate(e);
       }
    }
 
@@ -75,7 +73,7 @@ public class OAuthTestUtils {
       try {
          credentialFromFile = Files.toString(new File(val), Charsets.UTF_8);
       } catch (IOException e) {
-         throw Throwables.propagate(e);
+         throw propagate(e);
       }
       overrides.setProperty(key, credentialFromFile);
       return credentialFromFile;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/test/java/org/jclouds/oauth/v2/features/OAuthApiExpectTest.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/test/java/org/jclouds/oauth/v2/features/OAuthApiExpectTest.java b/apis/oauth/src/test/java/org/jclouds/oauth/v2/features/OAuthApiExpectTest.java
deleted file mode 100644
index 2008e5d..0000000
--- a/apis/oauth/src/test/java/org/jclouds/oauth/v2/features/OAuthApiExpectTest.java
+++ /dev/null
@@ -1,99 +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.oauth.v2.features;
-
-import static com.google.common.base.Charsets.UTF_8;
-import static com.google.common.io.BaseEncoding.base64Url;
-import static org.testng.Assert.assertEquals;
-
-import java.net.URI;
-import java.util.Properties;
-
-import javax.ws.rs.core.MediaType;
-
-import org.jclouds.http.HttpRequest;
-import org.jclouds.http.HttpResponse;
-import org.jclouds.oauth.v2.OAuthApi;
-import org.jclouds.oauth.v2.OAuthTestUtils;
-import org.jclouds.oauth.v2.domain.ClaimSet;
-import org.jclouds.oauth.v2.domain.Header;
-import org.jclouds.oauth.v2.domain.Token;
-import org.jclouds.oauth.v2.domain.TokenRequest;
-import org.jclouds.oauth.v2.internal.BaseOAuthApiExpectTest;
-import org.testng.annotations.Test;
-
-/**
- * Tests that a token requess is well formed.
- */
-@Test(groups = "unit")
-public class OAuthApiExpectTest extends BaseOAuthApiExpectTest {
-
-   private static final String header = "{\"alg\":\"RS256\",\"typ\":\"JWT\"}";
-
-   private static final String claims = "{\"iss\":\"761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer" +
-           ".gserviceaccount.com\"," +
-           "\"scope\":\"https://www.googleapis.com/auth/prediction\",\"aud\":\"https://accounts.google" +
-           ".com/o/oauth2/token\",\"exp\":1328573381,\"iat\":1328569781}";
-
-   private static final Token TOKEN = new Token.Builder().accessToken
-           ("1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M").tokenType("Bearer").expiresIn(3600).build();
-
-   private static final ClaimSet CLAIM_SET = new ClaimSet.Builder().addClaim("iss",
-           "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer" +
-                   ".gserviceaccount.com")
-           .addClaim("scope", "https://www.googleapis.com/auth/prediction")
-           .addClaim("aud", "https://accounts.google.com/o/oauth2/token")
-           .expirationTime(1328573381)
-           .emissionTime(1328569781).build();
-
-   private static final Header HEADER = new Header.Builder().signerAlgorithm("RS256").type("JWT").build();
-
-   private static final String URL_ENCODED_TOKEN_REQUEST =
-           "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&" +
-                   // Base64 Encoded Header
-                   "assertion=" + base64Url().omitPadding().encode(header.getBytes(UTF_8)) + "." +
-                   // Base64 Encoded Claims
-                   base64Url().omitPadding().encode(claims.getBytes(UTF_8)) + "." +
-                   // Base64 encoded {header}.{claims} signature (using SHA256)
-                   "W2Lesr_98AzVYiMbzxFqmwcOjpIWlwqkC6pNn1fXND9oSDNNnFhy-AAR6DKH-x9ZmxbY80" +
-                   "R5fH-OCeWumXlVgceKN8Z2SmgQsu8ElTpypQA54j_5j8vUImJ5hsOUYPeyF1U2BUzZ3L5g" +
-                   "03PXBA0YWwRU9E1ChH28dQBYuGiUmYw";
-
-   private static final HttpRequest TOKEN_REQUEST = HttpRequest.builder()
-           .method("POST")
-           .endpoint(URI.create("http://localhost:5000/o/oauth2/token"))
-           .addHeader("Accept", MediaType.APPLICATION_JSON)
-           .payload(payloadFromStringWithContentType(URL_ENCODED_TOKEN_REQUEST, "application/x-www-form-urlencoded"))
-           .build();
-
-   private static final HttpResponse TOKEN_RESPONSE = HttpResponse.builder().statusCode(200).payload(
-           payloadFromString("{\n" +
-                   "  \"access_token\" : \"1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M\",\n" +
-                   "  \"token_type\" : \"Bearer\",\n" +
-                   "  \"expires_in\" : 3600\n" +
-                   "}")).build();
-
-   @Override
-   protected Properties setupProperties() {
-      return OAuthTestUtils.defaultProperties(super.setupProperties());
-   }
-
-   public void testGenerateJWTRequest() {
-      OAuthApi api = requestSendsResponse(TOKEN_REQUEST, TOKEN_RESPONSE);
-      assertEquals(api.authenticate(new TokenRequest(HEADER, CLAIM_SET)), TOKEN);
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/test/java/org/jclouds/oauth/v2/features/OAuthApiLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/test/java/org/jclouds/oauth/v2/features/OAuthApiLiveTest.java b/apis/oauth/src/test/java/org/jclouds/oauth/v2/features/OAuthApiLiveTest.java
index 4ac5950..5b1e0e6 100644
--- a/apis/oauth/src/test/java/org/jclouds/oauth/v2/features/OAuthApiLiveTest.java
+++ b/apis/oauth/src/test/java/org/jclouds/oauth/v2/features/OAuthApiLiveTest.java
@@ -34,6 +34,8 @@ import org.jclouds.oauth.v2.domain.TokenRequest;
 import org.jclouds.oauth.v2.internal.BaseOAuthApiLiveTest;
 import org.testng.annotations.Test;
 
+import com.google.common.collect.ImmutableMap;
+
 /**
  * A live test for authentication. Requires the following properties to be set:
  * - test.oauth.endpoint
@@ -62,17 +64,17 @@ public class OAuthApiLiveTest extends BaseOAuthApiLiveTest {
       checkState(OAuthConstants.OAUTH_ALGORITHM_NAMES_TO_SIGNATURE_ALGORITHM_NAMES.containsKey(signatureAlgorithm)
               , String.format("Algorithm not supported: " + signatureAlgorithm));
 
-      Header header = Header.builder().signerAlgorithm(signatureAlgorithm).type("JWT").build();
+      Header header = Header.create(signatureAlgorithm, "JWT");
 
       String scopes = getMandatoryProperty(properties, SCOPES);
       String audience = getMandatoryProperty(properties, AUDIENCE);
 
       long now = nowInSeconds();
 
-      ClaimSet claimSet = ClaimSet.builder().addClaim("aud", audience).addClaim("scope", scopes).addClaim("iss",
-              identity).emissionTime(now).expirationTime(now + 3600).build();
+      ClaimSet claimSet = ClaimSet.create(now, now + 3600,
+            ImmutableMap.of("aud", audience, "scope", scopes, "iss", identity));
 
-      TokenRequest tokenRequest = TokenRequest.builder().header(header).claimSet(claimSet).build();
+      TokenRequest tokenRequest = TokenRequest.create(header, claimSet);
       Token token = api.authenticate(tokenRequest);
 
       assertNotNull(token, "no token when authenticating " + tokenRequest);

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/test/java/org/jclouds/oauth/v2/features/OAuthApiMockTest.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/test/java/org/jclouds/oauth/v2/features/OAuthApiMockTest.java b/apis/oauth/src/test/java/org/jclouds/oauth/v2/features/OAuthApiMockTest.java
new file mode 100644
index 0000000..95cc537
--- /dev/null
+++ b/apis/oauth/src/test/java/org/jclouds/oauth/v2/features/OAuthApiMockTest.java
@@ -0,0 +1,114 @@
+/*
+ * 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.oauth.v2.features;
+
+import static com.google.common.base.Charsets.UTF_8;
+import static com.google.common.io.BaseEncoding.base64Url;
+import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor;
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static org.jclouds.Constants.PROPERTY_MAX_RETRIES;
+import static org.jclouds.oauth.v2.config.OAuthProperties.AUDIENCE;
+import static org.jclouds.util.Strings2.toStringAndClose;
+import static org.testng.Assert.assertEquals;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Properties;
+
+import org.jclouds.ContextBuilder;
+import org.jclouds.concurrent.config.ExecutorServiceModule;
+import org.jclouds.oauth.v2.OAuthApi;
+import org.jclouds.oauth.v2.OAuthApiMetadata;
+import org.jclouds.oauth.v2.OAuthTestUtils;
+import org.jclouds.oauth.v2.domain.ClaimSet;
+import org.jclouds.oauth.v2.domain.Header;
+import org.jclouds.oauth.v2.domain.Token;
+import org.jclouds.oauth.v2.domain.TokenRequest;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.io.BaseEncoding;
+import com.google.inject.Module;
+import com.squareup.okhttp.mockwebserver.MockResponse;
+import com.squareup.okhttp.mockwebserver.MockWebServer;
+import com.squareup.okhttp.mockwebserver.RecordedRequest;
+
+@Test(groups = "unit", testName = "OAuthApiMockTest")
+public class OAuthApiMockTest {
+
+   private static final String header = "{\"alg\":\"RS256\",\"typ\":\"JWT\"}";
+
+   private static final String claims = "{\"iss\":\"761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer" +
+         ".gserviceaccount.com\"," +
+         "\"scope\":\"https://www.googleapis.com/auth/prediction\",\"aud\":\"https://accounts.google" +
+         ".com/o/oauth2/token\",\"exp\":1328573381,\"iat\":1328569781}";
+
+   private static final Token TOKEN = Token.create("1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M", "Bearer", 3600);
+
+   private static final ClaimSet CLAIM_SET = ClaimSet.create(1328569781, 1328573381, ImmutableMap
+         .of("iss", "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com", "scope",
+               "https://www.googleapis.com/auth/prediction", "aud", "https://accounts.google.com/o/oauth2/token"));
+
+   private static final Header HEADER = Header.create("RS256", "JWT");
+
+   public void testGenerateJWTRequest() throws Exception {
+      MockWebServer server = new MockWebServer();
+      server.enqueue(new MockResponse().setBody("{\n" +
+                  "  \"access_token\" : \"1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M\",\n" +
+                  "  \"token_type\" : \"Bearer\",\n" +
+                  "  \"expires_in\" : 3600\n" +
+                  "}"));
+      server.play();
+
+      OAuthApi api = api(server.getUrl("/"));
+
+      assertEquals(api.authenticate(TokenRequest.create(HEADER, CLAIM_SET)), TOKEN);
+
+      RecordedRequest request = server.takeRequest();
+      assertEquals(request.getMethod(), "POST");
+      assertEquals(request.getHeader("Accept"), APPLICATION_JSON);
+      assertEquals(request.getHeader("Content-Type"), "application/x-www-form-urlencoded");
+
+      assertEquals(new String(request.getBody(), UTF_8), //
+            "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&" +
+                  // Base64 Encoded Header
+                  "assertion=" +
+                  Joiner.on('.').join(encoding.encode(header.getBytes(UTF_8)), encoding.encode(claims.getBytes(UTF_8)),
+                  // Base64 encoded {header}.{claims} signature (using SHA256)
+                  "W2Lesr_98AzVYiMbzxFqmwcOjpIWlwqkC6pNn1fXND9oSDNNnFhy-AAR6DKH-x9ZmxbY80" +
+                  "R5fH-OCeWumXlVgceKN8Z2SmgQsu8ElTpypQA54j_5j8vUImJ5hsOUYPeyF1U2BUzZ3L5g" +
+                  "03PXBA0YWwRU9E1ChH28dQBYuGiUmYw"));
+
+   }
+
+   private final BaseEncoding encoding = base64Url().omitPadding();
+
+   private OAuthApi api(URL url) throws IOException {
+      Properties overrides = new Properties();
+      overrides.put(AUDIENCE, "https://accounts.google.com/o/oauth2/token");
+      overrides.put(PROPERTY_MAX_RETRIES, "1");
+
+      return ContextBuilder.newBuilder(new OAuthApiMetadata())
+            .credentials("foo", toStringAndClose(OAuthTestUtils.class.getResourceAsStream("/testpk.pem")))
+            .endpoint(url.toString())
+            .overrides(overrides)
+            .modules(ImmutableSet.<Module>of(new ExecutorServiceModule(sameThreadExecutor())))
+            .buildApi(OAuthApi.class);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/test/java/org/jclouds/oauth/v2/internal/BaseOAuthApiExpectTest.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/test/java/org/jclouds/oauth/v2/internal/BaseOAuthApiExpectTest.java b/apis/oauth/src/test/java/org/jclouds/oauth/v2/internal/BaseOAuthApiExpectTest.java
deleted file mode 100644
index a44bad1..0000000
--- a/apis/oauth/src/test/java/org/jclouds/oauth/v2/internal/BaseOAuthApiExpectTest.java
+++ /dev/null
@@ -1,23 +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.oauth.v2.internal;
-
-import org.jclouds.oauth.v2.OAuthApi;
-
-public class BaseOAuthApiExpectTest extends BaseOAuthExpectTest<OAuthApi> {
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/test/java/org/jclouds/oauth/v2/internal/BaseOAuthAuthenticatedApiLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/test/java/org/jclouds/oauth/v2/internal/BaseOAuthAuthenticatedApiLiveTest.java b/apis/oauth/src/test/java/org/jclouds/oauth/v2/internal/BaseOAuthAuthenticatedApiLiveTest.java
index aefdcdd..4652c0c 100644
--- a/apis/oauth/src/test/java/org/jclouds/oauth/v2/internal/BaseOAuthAuthenticatedApiLiveTest.java
+++ b/apis/oauth/src/test/java/org/jclouds/oauth/v2/internal/BaseOAuthAuthenticatedApiLiveTest.java
@@ -37,6 +37,7 @@ import org.jclouds.oauth.v2.domain.TokenRequest;
 import org.testng.annotations.Test;
 
 import com.google.common.base.Function;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.reflect.TypeToken;
 import com.google.inject.Injector;
 import com.google.inject.Key;
@@ -75,18 +76,14 @@ public abstract class BaseOAuthAuthenticatedApiLiveTest<A extends Closeable> ext
       // obtain the scopes from the subclass
       String scopes = getScopes();
 
-      Header header = Header.builder().signerAlgorithm(signatureAlgorithm).type("JWT").build();
+      Header header = Header.create(signatureAlgorithm, "JWT");
 
       long now = SECONDS.convert(System.currentTimeMillis(), MILLISECONDS);
 
-      ClaimSet claimSet = ClaimSet.builder()
-                                  .addClaim("aud", audience)
-                                  .addClaim("scope", scopes)
-                                  .addClaim("iss", identity)
-                                  .emissionTime(now)
-                                  .expirationTime(now + 3600).build();
+      ClaimSet claimSet = ClaimSet.create(now, now + 3600,
+            ImmutableMap.of("aud", audience, "scope", scopes, "iss", identity));
 
-      TokenRequest tokenRequest = TokenRequest.builder().header(header).claimSet(claimSet).build();
+      TokenRequest tokenRequest = TokenRequest.create(header, claimSet);
 
       Token token = oauthApi.authenticate(tokenRequest);
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/test/java/org/jclouds/oauth/v2/internal/BaseOAuthExpectTest.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/test/java/org/jclouds/oauth/v2/internal/BaseOAuthExpectTest.java b/apis/oauth/src/test/java/org/jclouds/oauth/v2/internal/BaseOAuthExpectTest.java
deleted file mode 100644
index 18fe151..0000000
--- a/apis/oauth/src/test/java/org/jclouds/oauth/v2/internal/BaseOAuthExpectTest.java
+++ /dev/null
@@ -1,26 +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.oauth.v2.internal;
-
-import org.jclouds.rest.internal.BaseRestApiExpectTest;
-
-public class BaseOAuthExpectTest<T> extends BaseRestApiExpectTest<T> {
-
-   public BaseOAuthExpectTest() {
-      provider = "oauth";
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/test/java/org/jclouds/oauth/v2/internal/BaseOAuthParseTest.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/test/java/org/jclouds/oauth/v2/internal/BaseOAuthParseTest.java b/apis/oauth/src/test/java/org/jclouds/oauth/v2/internal/BaseOAuthParseTest.java
new file mode 100644
index 0000000..ae47cfd
--- /dev/null
+++ b/apis/oauth/src/test/java/org/jclouds/oauth/v2/internal/BaseOAuthParseTest.java
@@ -0,0 +1,30 @@
+/*
+ * 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.oauth.v2.internal;
+
+import org.jclouds.json.BaseItemParserTest;
+import org.jclouds.json.config.GsonModule;
+import org.jclouds.oauth.v2.config.OAuthParserModule;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
+public abstract class BaseOAuthParseTest<T> extends BaseItemParserTest<T> {
+   @Override protected Injector injector() {
+      return Guice.createInjector(new GsonModule(), new OAuthParserModule());
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/test/java/org/jclouds/oauth/v2/json/JWTTokenRequestFormatTest.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/test/java/org/jclouds/oauth/v2/json/JWTTokenRequestFormatTest.java b/apis/oauth/src/test/java/org/jclouds/oauth/v2/json/JWTTokenRequestFormatTest.java
index fa3307f..bc82809 100644
--- a/apis/oauth/src/test/java/org/jclouds/oauth/v2/json/JWTTokenRequestFormatTest.java
+++ b/apis/oauth/src/test/java/org/jclouds/oauth/v2/json/JWTTokenRequestFormatTest.java
@@ -34,6 +34,7 @@ import org.jclouds.util.Strings2;
 import org.testng.annotations.Test;
 
 import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 
 @Test(groups = "unit")
@@ -47,10 +48,10 @@ public class JWTTokenRequestFormatTest {
       TokenRequestFormat tokenRequestFormat = ContextBuilder.newBuilder(new OAuthApiMetadata()).overrides
               (OAuthTestUtils.defaultProperties(null)).build().utils()
               .injector().getInstance(TokenRequestFormat.class);
-      Header header = new Header.Builder().signerAlgorithm("a").type("b").build();
-      ClaimSet claimSet = new ClaimSet.Builder().addClaim("ist", STRING_THAT_GENERATES_URL_UNSAFE_BASE64_ENCODING)
-              .build();
-      TokenRequest tokenRequest = new TokenRequest.Builder().claimSet(claimSet).header(header).build();
+      Header header = Header.create("a", "b");
+      ClaimSet claimSet = ClaimSet.create(0, 0,
+            ImmutableMap.of("ist", STRING_THAT_GENERATES_URL_UNSAFE_BASE64_ENCODING));
+      TokenRequest tokenRequest = TokenRequest.create(header, claimSet);
       HttpRequest request = tokenRequestFormat.formatRequest(HttpRequest.builder().method("GET").endpoint
               ("http://localhost").build(), tokenRequest);
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/07d7a5a7/apis/oauth/src/test/java/org/jclouds/oauth/v2/parse/ParseTokenTest.java
----------------------------------------------------------------------
diff --git a/apis/oauth/src/test/java/org/jclouds/oauth/v2/parse/ParseTokenTest.java b/apis/oauth/src/test/java/org/jclouds/oauth/v2/parse/ParseTokenTest.java
index bcaa9e4..d564359 100644
--- a/apis/oauth/src/test/java/org/jclouds/oauth/v2/parse/ParseTokenTest.java
+++ b/apis/oauth/src/test/java/org/jclouds/oauth/v2/parse/ParseTokenTest.java
@@ -16,15 +16,16 @@
  */
 package org.jclouds.oauth.v2.parse;
 
-import org.jclouds.json.BaseItemParserTest;
-import org.jclouds.oauth.v2.domain.Token;
-import org.testng.annotations.Test;
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 import javax.ws.rs.Consumes;
-import javax.ws.rs.core.MediaType;
 
-@Test(groups = "unit")
-public class ParseTokenTest extends BaseItemParserTest<Token> {
+import org.jclouds.oauth.v2.domain.Token;
+import org.jclouds.oauth.v2.internal.BaseOAuthParseTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "ParseTokenTest")
+public class ParseTokenTest extends BaseOAuthParseTest<Token> {
 
    @Override
    public String resource() {
@@ -32,9 +33,8 @@ public class ParseTokenTest extends BaseItemParserTest<Token> {
    }
 
    @Override
-   @Consumes(MediaType.APPLICATION_JSON)
+   @Consumes(APPLICATION_JSON)
    public Token expected() {
-      return Token.builder().expiresIn(3600).tokenType("Bearer").accessToken
-              ("1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M").build();
+      return Token.create("1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M", "Bearer", 3600);
    }
 }