diff --git a/gcloud-java-translate/pom.xml b/gcloud-java-translate/pom.xml
new file mode 100644
index 000000000000..f7c3c55e58f0
--- /dev/null
+++ b/gcloud-java-translate/pom.xml
@@ -0,0 +1,61 @@
+
+
+ 4.0.0
+ gcloud-java-translate
+ jar
+ GCloud Java translate
+ https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-translate
+
+ Java idiomatic client for Google Translate.
+
+
+ com.google.cloud
+ gcloud-java-pom
+ 0.2.7-SNAPSHOT
+
+
+ gcloud-java-translate
+
+
+
+ ${project.groupId}
+ gcloud-java-core
+ ${project.version}
+
+
+ com.google.apis
+ google-api-services-translate
+ v2-rev47-1.22.0
+ compile
+
+
+ com.google.guava
+ guava-jdk5
+
+
+ com.google.api-client
+ google-api-client
+
+
+
+
+ ${project.groupId}
+ gcloud-java-core
+ ${project.version}
+ test-jar
+ test
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+ org.easymock
+ easymock
+ 3.4
+ test
+
+
+
diff --git a/gcloud-java-translate/src/main/java/com/google/cloud/translate/Translate.java b/gcloud-java-translate/src/main/java/com/google/cloud/translate/Translate.java
new file mode 100644
index 000000000000..1b1a3b9b12be
--- /dev/null
+++ b/gcloud-java-translate/src/main/java/com/google/cloud/translate/Translate.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed 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 com.google.cloud.translate;
+
+import com.google.cloud.Service;
+
+/**
+ * An interface for Google Translate.
+ *
+ * @see Google Translate
+ */
+public interface Translate extends Service {
+}
diff --git a/gcloud-java-translate/src/main/java/com/google/cloud/translate/TranslateException.java b/gcloud-java-translate/src/main/java/com/google/cloud/translate/TranslateException.java
new file mode 100644
index 000000000000..f1d3c18fed8e
--- /dev/null
+++ b/gcloud-java-translate/src/main/java/com/google/cloud/translate/TranslateException.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed 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 com.google.cloud.translate;
+
+import com.google.cloud.BaseServiceException;
+import com.google.cloud.RetryHelper.RetryHelperException;
+import com.google.cloud.RetryHelper.RetryInterruptedException;
+import com.google.common.collect.ImmutableSet;
+
+import java.io.IOException;
+import java.util.Set;
+
+/**
+ * Google Translate service exception.
+ */
+public class TranslateException extends BaseServiceException {
+
+ private static final Set RETRYABLE_ERRORS = ImmutableSet.of(new Error(500, null));
+ private static final long serialVersionUID = 4747004866996469418L;
+
+ TranslateException(int code, String message) {
+ super(code, message, null, true, null);
+ }
+
+ TranslateException(int code, String message, Throwable cause) {
+ super(code, message, null, true, cause);
+ }
+
+ public TranslateException(IOException exception) {
+ super(exception, true);
+ }
+
+ @Override
+ protected Set retryableErrors() {
+ return RETRYABLE_ERRORS;
+ }
+
+ /**
+ * Translate RetryHelperException to the TranslateException that caused the error. This method
+ * will always throw an exception.
+ *
+ * @throws TranslateException when {@code ex} was caused by a {@code TranslateException}
+ * @throws RetryInterruptedException when {@code ex} is a {@code RetryInterruptedException}
+ */
+ static BaseServiceException translateAndThrow(RetryHelperException ex) {
+ BaseServiceException.translateAndPropagateIfPossible(ex);
+ throw new TranslateException(UNKNOWN_CODE, ex.getMessage(), ex.getCause());
+ }
+}
diff --git a/gcloud-java-translate/src/main/java/com/google/cloud/translate/TranslateFactory.java b/gcloud-java-translate/src/main/java/com/google/cloud/translate/TranslateFactory.java
new file mode 100644
index 000000000000..8c31c5505bd3
--- /dev/null
+++ b/gcloud-java-translate/src/main/java/com/google/cloud/translate/TranslateFactory.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed 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 com.google.cloud.translate;
+
+import com.google.cloud.ServiceFactory;
+
+/**
+ * An interface for Translates factories.
+ */
+public interface TranslateFactory extends ServiceFactory {
+}
diff --git a/gcloud-java-translate/src/main/java/com/google/cloud/translate/TranslateOptions.java b/gcloud-java-translate/src/main/java/com/google/cloud/translate/TranslateOptions.java
new file mode 100644
index 000000000000..599d4a1d389f
--- /dev/null
+++ b/gcloud-java-translate/src/main/java/com/google/cloud/translate/TranslateOptions.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed 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 com.google.cloud.translate;
+
+import static com.google.common.base.MoreObjects.firstNonNull;
+
+import com.google.cloud.AuthCredentials;
+import com.google.cloud.HttpServiceOptions;
+import com.google.cloud.translate.spi.DefaultTranslateRpc;
+import com.google.cloud.translate.spi.TranslateRpc;
+import com.google.cloud.translate.spi.TranslateRpcFactory;
+import com.google.common.collect.ImmutableSet;
+
+import java.util.Locale;
+import java.util.Set;
+
+public class TranslateOptions extends
+ HttpServiceOptions {
+
+ private static final long serialVersionUID = 5997441123713672886L;
+ private static final Set SCOPES = ImmutableSet.of();
+
+ private final String apiKey;
+ private final String targetLanguage;
+
+ public static class DefaultTranslateFactory implements TranslateFactory {
+
+ private static final TranslateFactory INSTANCE = new DefaultTranslateFactory();
+
+ @Override
+ public Translate create(TranslateOptions options) {
+ return null;
+ // todo(mziccard) uncomment as soon as TranslateImpl is implemented
+ // return new TranslateImpl(options);
+ }
+ }
+
+ public static class DefaultTranslateRpcFactory implements TranslateRpcFactory {
+
+ private static final TranslateRpcFactory INSTANCE = new DefaultTranslateRpcFactory();
+
+ @Override
+ public TranslateRpc create(TranslateOptions options) {
+ return new DefaultTranslateRpc(options);
+ }
+ }
+
+ public static class Builder extends
+ HttpServiceOptions.Builder {
+
+ private final String apiKey;
+ private String targetLanguage;
+
+ private Builder(String apiKey) {
+ this.apiKey = apiKey;
+ }
+
+ private Builder(TranslateOptions options) {
+ super(options);
+ this.apiKey = options.apiKey;
+ }
+
+ /**
+ * Sets project id. Setting a project id has no impact on the {@link Translate} service.
+ *
+ * @return the builder
+ */
+ @Override
+ public Builder projectId(String projectId) {
+ super.projectId(projectId);
+ return self();
+ }
+
+ /**
+ * Sets the service authentication credentials. Setting credentials has no impact on the
+ * {@link Translate} service.
+ *
+ * @return the builder
+ */
+ public Builder authCredentials(AuthCredentials authCredentials) {
+ super.authCredentials(authCredentials);
+ return self();
+ }
+
+ /**
+ * Sets the code for the default target language. If not set, english ({@code en}) is used.
+ *
+ * @return the builder
+ */
+ public Builder targetLanguage(String targetLanguage) {
+ this.targetLanguage = targetLanguage;
+ return self();
+ }
+
+ @Override
+ public TranslateOptions build() {
+ return new TranslateOptions(this);
+ }
+ }
+
+ private TranslateOptions(Builder builder) {
+ super(TranslateFactory.class, TranslateRpcFactory.class, builder);
+ this.apiKey = builder.apiKey;
+ this.targetLanguage = firstNonNull(builder.targetLanguage, Locale.ENGLISH.getLanguage());
+ }
+
+ @Override
+ protected TranslateFactory defaultServiceFactory() {
+ return DefaultTranslateFactory.INSTANCE;
+ }
+
+ @Override
+ protected TranslateRpcFactory defaultRpcFactory() {
+ return DefaultTranslateRpcFactory.INSTANCE;
+ }
+
+ @Override
+ protected boolean projectIdRequired() {
+ return false;
+ }
+
+ @Override
+ protected Set scopes() {
+ return SCOPES;
+ }
+
+ /**
+ * Returns the API key, to be used used to send requests.
+ */
+ public String apiKey() {
+ return apiKey;
+ }
+
+ /**
+ * Returns the code for the default target language.
+ */
+ public String targetLanguage() {
+ return targetLanguage;
+ }
+
+ /**
+ * Returns a default {@code TranslateOptions} instance given an API key. For instructions on
+ * how to get an API key see Translate
+ * quickstart.
+ */
+ public static TranslateOptions defaultInstance(String apiKey) {
+ return builder(apiKey).build();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Builder toBuilder() {
+ return new Builder(this);
+ }
+
+ @Override
+ public int hashCode() {
+ return baseHashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof TranslateOptions && baseEquals((TranslateOptions) obj);
+ }
+
+ /**
+ * Creates a builder for {@code TranslateOptions} objects given an api key. For instructions on
+ * how to get an API key see Translate
+ * quickstart.
+ */
+ public static Builder builder(String apiKey) {
+ return new Builder(apiKey);
+ }
+}
diff --git a/gcloud-java-translate/src/main/java/com/google/cloud/translate/spi/DefaultTranslateRpc.java b/gcloud-java-translate/src/main/java/com/google/cloud/translate/spi/DefaultTranslateRpc.java
new file mode 100644
index 000000000000..14f4a326399d
--- /dev/null
+++ b/gcloud-java-translate/src/main/java/com/google/cloud/translate/spi/DefaultTranslateRpc.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed 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 com.google.cloud.translate.spi;
+
+import static com.google.cloud.translate.spi.TranslateRpc.Option.SOURCE_LANGUAGE;
+import static com.google.cloud.translate.spi.TranslateRpc.Option.TARGET_LANGUAGE;
+import static com.google.common.base.MoreObjects.firstNonNull;
+
+import com.google.api.client.http.HttpRequestInitializer;
+import com.google.api.client.http.HttpTransport;
+import com.google.api.client.json.jackson.JacksonFactory;
+import com.google.api.services.translate.Translate;
+import com.google.api.services.translate.model.DetectionsResourceItems;
+import com.google.api.services.translate.model.LanguagesResource;
+import com.google.api.services.translate.model.TranslationsResource;
+import com.google.cloud.translate.TranslateException;
+import com.google.cloud.translate.TranslateOptions;
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+public class DefaultTranslateRpc implements TranslateRpc {
+
+ private final TranslateOptions options;
+ private final Translate translate;
+
+ public DefaultTranslateRpc(TranslateOptions options) {
+ HttpTransport transport = options.httpTransportFactory().create();
+ HttpRequestInitializer initializer = options.httpRequestInitializer();
+ this.options = options;
+ translate = new Translate.Builder(transport, new JacksonFactory(), initializer)
+ .setRootUrl(options.host())
+ .setApplicationName(options.applicationName())
+ .build();
+ }
+
+ private static TranslateException translate(IOException exception) {
+ return new TranslateException(exception);
+ }
+
+ @Override
+ public List> detect(List text) {
+ try {
+ List> detections =
+ translate.detections().list(text).setKey(options.apiKey()).execute().getDetections();
+ return detections != null ? detections : ImmutableList.>of();
+ } catch (IOException ex) {
+ throw translate(ex);
+ }
+ }
+
+ @Override
+ public List listSupportedLanguages(Map