Repository: googleapis/google-http-java-client
Pull request #1046 (2020-05-21 04:32:55)

fix: make google-http-client.properties file shading friendly
Fixes an issue when there are 2 versions of this library in a class path - 1) shaded/relocated library of `x.x.x` version inside a "jar-with-dependencies" and 2) non-shaded library of `y.y.y` version.

Because both of these libraries will load non-shaded `google-http-client.properties` file they will use the same `y.y.y` version even though shaded library has a `x.x.x` version.

BenWhitehead: @medb Can you describe why this change is needed? The properties file should be able to be loaded from an uber-jar or other shaded jar just fine without modification.

I have a local project on my machine I used to execute a few commands against Firestore (which is a downstream consumer of this library). This project is packaged as a "jar-with-dependencies" file. `HttpRequest` is able to load the properties files successfully as-is.

```
❱ java -jar target/cleanup-0.1.1-SNAPSHOT-jar-with-dependencies.jar 
HttpRequest.VERSION = 1.34.2
```

From this code
```java
public static void main(String[] args) {
  System.out.println("HttpRequest.VERSION = " + com.google.api.client.http.HttpRequest.VERSION);
}
```

medb: The issue is that if there are 2 versions of this library in a class path - 1) shaded library of `x.x.x` version inside a "jar-with-dependencies" and 2) non-shaded library of `y.y.y` version.

Because both of these libraries will load non-shaded `google-http-client.properties` they will use the same `y.y.y` version even though shaded library has a `x.x.x` version.

Patch:
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 54221045..30fdb7b9 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1,1 +1,10 @@
-* @googleapis/yoshi-java
+# Code owners file.
+# This file controls who is tagged for review for any given pull request.
+
+# For syntax help see:
+# https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax
+
+*                       @googleapis/yoshi-java
+
+# The java-samples-reviewers team is the default owner for samples changes
+samples/**/*.java       @googleapis/java-samples-reviewers
diff --git a/.github/readme/synth.py b/.github/readme/synth.py
new file mode 100644
index 00000000..7b48cc28
--- /dev/null
+++ b/.github/readme/synth.py
@@ -0,0 +1,19 @@
+# Copyright 2020 Google LLC
+#
+# 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.
+
+"""This script is used to synthesize generated the README for this library."""
+
+from synthtool.languages import java
+
+java.custom_templates(["java_library/README.md"])
diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml
new file mode 100644
index 00000000..af5dd3bd
--- /dev/null
+++ b/.github/sync-repo-settings.yaml
@@ -0,0 +1,45 @@
+# Whether or not rebase-merging is enabled on this repository.
+# Defaults to `true`
+rebaseMergeAllowed: false
+
+# Whether or not squash-merging is enabled on this repository.
+# Defaults to `true`
+squashMergeAllowed: true
+
+# Whether or not PRs are merged with a merge commit on this repository.
+# Defaults to `false`
+mergeCommitAllowed: false
+
+# Rules for master branch protection
+branchProtectionRules:
+# Identifies the protection rule pattern. Name of the branch to be protected.
+# Defaults to `master`
+- pattern: master
+  # Can admins overwrite branch protection.
+  # Defaults to `true`
+  isAdminEnforced: true
+  # Number of approving reviews required to update matching branches.
+  # Defaults to `1`
+  requiredApprovingReviewCount: 1
+  # Are reviews from code owners required to update matching branches.
+  # Defaults to `false`
+  requiresCodeOwnerReviews: true
+  # Require up to date branches
+  requiresStrictStatusChecks: false
+  # List of required status check contexts that must pass for commits to be accepted to matching branches.
+  requiredStatusCheckContexts:
+    - "Kokoro - Test: Binary Compatibility"
+    - "Kokoro - Test: Java 11"
+    - "Kokoro - Test: Java 7"
+    - "Kokoro - Test: Java 8"
+    - "Kokoro - Test: Linkage Monitor"
+    - "cla/google"
+
+# List of explicit permissions to add (additive only)
+permissionRules:
+- team: yoshi-admins
+  permission: admin
+- team: yoshi-java-admins
+  permission: admin
+- team: yoshi-java
+  permission: push
diff --git a/.github/workflows/auto-release.yaml b/.github/workflows/auto-release.yaml
new file mode 100644
index 00000000..bc1554ae
--- /dev/null
+++ b/.github/workflows/auto-release.yaml
@@ -0,0 +1,88 @@
+on:
+  pull_request:
+name: auto-release
+jobs:
+  approve:
+    runs-on: ubuntu-latest
+    if: contains(github.head_ref, 'release-v')
+    steps:
+    - uses: actions/github-script@v3.0.0
+      with:
+        github-token: ${{secrets.YOSHI_APPROVER_TOKEN}}
+        debug: true
+        script: |
+          // only approve PRs from release-please[bot]
+          if (context.payload.pull_request.user.login !== "release-please[bot]") {
+            return;
+          }
+
+          // only approve PRs like "chore: release <release version>"
+          if ( !context.payload.pull_request.title.startsWith("chore: release") ) {
+            return;
+          }
+
+          // only approve PRs with pom.xml and versions.txt changes
+          const filesPromise = github.pulls.listFiles.endpoint({
+            owner: context.repo.owner,
+            repo: context.repo.repo,
+            pull_number: context.payload.pull_request.number,
+          });
+          const changed_files = await github.paginate(filesPromise)
+
+          if ( changed_files.length < 1 ) {
+            console.log( "Not proceeding since PR is empty!" )
+            return;
+          }
+
+          if ( !changed_files.some(v => v.filename.includes("pom")) || !changed_files.some(v => v.filename.includes("versions.txt")) ) {
+            console.log( "PR file changes do not have pom.xml or versions.txt -- something is wrong. PTAL!" )
+            return;
+          }
+
+          // trigger auto-release when
+          // 1) it is a SNAPSHOT release (auto-generated post regular release)
+          // 2) there are dependency updates only
+          // 3) there are no open dependency update PRs in this repo (to avoid multiple releases)
+          if (
+            context.payload.pull_request.body.includes("Fix") ||
+            context.payload.pull_request.body.includes("Build") ||
+            context.payload.pull_request.body.includes("Documentation") ||
+            context.payload.pull_request.body.includes("BREAKING CHANGES") ||
+            context.payload.pull_request.body.includes("Features")
+          ) {
+            console.log( "Not auto-releasing since it is not a dependency-update-only release." );
+            return;
+          }
+
+          const promise = github.pulls.list.endpoint({
+            owner: context.repo.owner,
+            repo: context.repo.repo,
+            state: 'open'
+          });
+          const open_pulls = await github.paginate(promise)
+
+          if ( open_pulls.length > 1 && !context.payload.pull_request.title.includes("SNAPSHOT") ) {
+            for ( const pull of open_pulls ) {
+              if ( pull.title.startsWith("deps: update dependency") ) {
+                console.log( "Not auto-releasing yet since there are dependency update PRs open in this repo." );
+                return;
+              }
+            }
+          }
+
+          // approve release PR
+          await github.pulls.createReview({
+            owner: context.repo.owner,
+            repo: context.repo.repo,
+            body: 'Rubber stamped release!',
+            pull_number: context.payload.pull_request.number,
+            event: 'APPROVE'
+          });
+
+          // attach kokoro:force-run and automerge labels
+          await github.issues.addLabels({
+            owner: context.repo.owner,
+            repo: context.repo.repo,
+            issue_number: context.payload.pull_request.number,
+            labels: ['kokoro:force-run', 'automerge']
+          });
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 445b4bf8..68302207 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -36,11 +36,14 @@ jobs:
         JOB_TYPE: test
   dependencies:
     runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        java: [8, 11]
     steps:
     - uses: actions/checkout@v2
     - uses: actions/setup-java@v1
       with:
-        java-version: 8
+        java-version: ${{matrix.java}}
     - run: java -version
     - run: .kokoro/dependencies.sh
   linkage-monitor:
diff --git a/.github/workflows/samples.yaml b/.github/workflows/samples.yaml
new file mode 100644
index 00000000..c46230a7
--- /dev/null
+++ b/.github/workflows/samples.yaml
@@ -0,0 +1,14 @@
+on:
+  pull_request:
+name: samples
+jobs:
+  checkstyle:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions/setup-java@v1
+        with:
+          java-version: 8
+      - name: Run checkstyle
+        run: mvn -P lint --quiet --batch-mode checkstyle:check
+        working-directory: samples/snippets
diff --git a/.kokoro/build.sh b/.kokoro/build.sh
index 164a94c1..7eefde4a 100755
--- a/.kokoro/build.sh
+++ b/.kokoro/build.sh
@@ -39,7 +39,7 @@ retry_with_backoff 3 10 \
 
 # if GOOGLE_APPLICATION_CREDIENTIALS is specified as a relative path prepend Kokoro root directory onto it
 if [[ ! -z "${GOOGLE_APPLICATION_CREDENTIALS}" && "${GOOGLE_APPLICATION_CREDENTIALS}" != /* ]]; then
-    export GOOGLE_APPLICATION_CREDENTIALS=$(realpath ${KOKORO_ROOT}/src/${GOOGLE_APPLICATION_CREDENTIALS})
+    export GOOGLE_APPLICATION_CREDENTIALS=$(realpath ${KOKORO_GFILE_DIR}/${GOOGLE_APPLICATION_CREDENTIALS})
 fi
 
 RETURN_CODE=0
@@ -51,9 +51,7 @@ test)
     RETURN_CODE=$?
     ;;
 lint)
-    mvn \
-      -Penable-samples \
-      com.coveo:fmt-maven-plugin:check
+    mvn com.coveo:fmt-maven-plugin:check
     RETURN_CODE=$?
     ;;
 javadoc)
diff --git a/.kokoro/continuous/dependencies.cfg b/.kokoro/continuous/dependencies.cfg
deleted file mode 100644
index b89a2074..00000000
--- a/.kokoro/continuous/dependencies.cfg
+++ /dev/null
@@ -1,12 +0,0 @@
-# Format: //devtools/kokoro/config/proto/build.proto
-
-# Configure the docker image for kokoro-trampoline.
-env_vars: {
-  key: "TRAMPOLINE_IMAGE"
-  value: "gcr.io/cloud-devrel-kokoro-resources/java8"
-}
-
-env_vars: {
-  key: "TRAMPOLINE_BUILD_FILE"
-  value: "github/google-http-java-client/.kokoro/dependencies.sh"
-}
diff --git a/.kokoro/continuous/integration.cfg b/.kokoro/continuous/integration.cfg
deleted file mode 100644
index 3b017fc8..00000000
--- a/.kokoro/continuous/integration.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-# Format: //devtools/kokoro/config/proto/build.proto
-
-# Configure the docker image for kokoro-trampoline.
-env_vars: {
-  key: "TRAMPOLINE_IMAGE"
-  value: "gcr.io/cloud-devrel-kokoro-resources/java8"
-}
diff --git a/.kokoro/continuous/java11.cfg b/.kokoro/continuous/java11.cfg
deleted file mode 100644
index 709f2b4c..00000000
--- a/.kokoro/continuous/java11.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-# Format: //devtools/kokoro/config/proto/build.proto
-
-# Configure the docker image for kokoro-trampoline.
-env_vars: {
-  key: "TRAMPOLINE_IMAGE"
-  value: "gcr.io/cloud-devrel-kokoro-resources/java11"
-}
diff --git a/.kokoro/continuous/java7.cfg b/.kokoro/continuous/java7.cfg
deleted file mode 100644
index cb24f44e..00000000
--- a/.kokoro/continuous/java7.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-# Format: //devtools/kokoro/config/proto/build.proto
-
-# Configure the docker image for kokoro-trampoline.
-env_vars: {
-  key: "TRAMPOLINE_IMAGE"
-  value: "gcr.io/cloud-devrel-kokoro-resources/java7"
-}
diff --git a/.kokoro/continuous/java8-osx.cfg b/.kokoro/continuous/java8-osx.cfg
deleted file mode 100644
index b2354168..00000000
--- a/.kokoro/continuous/java8-osx.cfg
+++ /dev/null
@@ -1,3 +0,0 @@
-# Format: //devtools/kokoro/config/proto/build.proto
-
-build_file: "google-http-java-client/.kokoro/build.sh"
diff --git a/.kokoro/continuous/java8-win.cfg b/.kokoro/continuous/java8-win.cfg
deleted file mode 100644
index b44537d0..00000000
--- a/.kokoro/continuous/java8-win.cfg
+++ /dev/null
@@ -1,3 +0,0 @@
-# Format: //devtools/kokoro/config/proto/build.proto
-
-build_file: "google-http-java-client/.kokoro/build.bat"
diff --git a/.kokoro/continuous/lint.cfg b/.kokoro/continuous/lint.cfg
deleted file mode 100644
index 6d323c8a..00000000
--- a/.kokoro/continuous/lint.cfg
+++ /dev/null
@@ -1,13 +0,0 @@
-# Format: //devtools/kokoro/config/proto/build.proto
-
-# Configure the docker image for kokoro-trampoline.
-
-env_vars: {
-  key: "TRAMPOLINE_IMAGE"
-  value: "gcr.io/cloud-devrel-kokoro-resources/java8"
-}
-
-env_vars: {
-  key: "JOB_TYPE"
-  value: "lint"
-}
\ No newline at end of file
diff --git a/.kokoro/continuous/propose_release.cfg b/.kokoro/continuous/propose_release.cfg
deleted file mode 100644
index 715a53e1..00000000
--- a/.kokoro/continuous/propose_release.cfg
+++ /dev/null
@@ -1,53 +0,0 @@
-# Format: //devtools/kokoro/config/proto/build.proto
-
-# Build logs will be here
-action {
-  define_artifacts {
-    regex: "**/*sponge_log.xml"
-  }
-}
-
-# Download trampoline resources.
-gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
-
-# Use the trampoline script to run in docker.
-build_file: "google-http-java-client/.kokoro/trampoline.sh"
-
-# Configure the docker image for kokoro-trampoline.
-env_vars: {
-  key: "TRAMPOLINE_IMAGE"
-  value: "gcr.io/cloud-devrel-kokoro-resources/node:10-user"
-}
-
-env_vars: {
-  key: "TRAMPOLINE_BUILD_FILE"
-  value: "github/google-http-java-client/.kokoro/continuous/propose_release.sh"
-}
-
-# tokens used by release-please to keep an up-to-date release PR.
-before_action {
-  fetch_keystore {
-    keystore_resource {
-      keystore_config_id: 73713
-      keyname: "github-magic-proxy-key-release-please"
-    }
-  }
-}
-
-before_action {
-  fetch_keystore {
-    keystore_resource {
-      keystore_config_id: 73713
-      keyname: "github-magic-proxy-token-release-please"
-    }
-  }
-}
-
-before_action {
-  fetch_keystore {
-    keystore_resource {
-      keystore_config_id: 73713
-      keyname: "github-magic-proxy-url-release-please"
-    }
-  }
-}
diff --git a/.kokoro/continuous/readme.cfg b/.kokoro/continuous/readme.cfg
new file mode 100644
index 00000000..5056c884
--- /dev/null
+++ b/.kokoro/continuous/readme.cfg
@@ -0,0 +1,55 @@
+# Copyright 2020 Google LLC
+#
+# 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.
+
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+  key: "TRAMPOLINE_IMAGE"
+  value: "gcr.io/cloud-devrel-kokoro-resources/python-multi"
+}
+
+env_vars: {
+  key: "TRAMPOLINE_BUILD_FILE"
+  value: "github/google-http-java-client/.kokoro/readme.sh"
+}
+
+# Build logs will be here
+action {
+  define_artifacts {
+    regex: "**/*sponge_log.xml"
+    regex: "**/*sponge_log.log"
+  }
+}
+
+# The github token is stored here.
+before_action {
+  fetch_keystore {
+    keystore_resource {
+      keystore_config_id: 73713
+      keyname: "yoshi-automation-github-key"
+      # TODO(theacodes): remove this after secrets have globally propagated
+      backend_type: FASTCONFIGPUSH
+    }
+  }
+}
+
+# Common env vars for all repositories and builds.
+env_vars: {
+    key: "GITHUB_USER"
+    value: "yoshi-automation"
+}
+env_vars: {
+    key: "GITHUB_EMAIL"
+    value: "yoshi-automation@google.com"
+}
diff --git a/.kokoro/continuous/samples.cfg b/.kokoro/continuous/samples.cfg
deleted file mode 100644
index fa7b493d..00000000
--- a/.kokoro/continuous/samples.cfg
+++ /dev/null
@@ -1,31 +0,0 @@
-# Format: //devtools/kokoro/config/proto/build.proto
-
-# Configure the docker image for kokoro-trampoline.
-env_vars: {
-  key: "TRAMPOLINE_IMAGE"
-  value: "gcr.io/cloud-devrel-kokoro-resources/java8"
-}
-
-env_vars: {
-  key: "JOB_TYPE"
-  value: "samples"
-}
-
-env_vars: {
-    key: "GCLOUD_PROJECT"
-    value: "gcloud-devel"
-}
-
-env_vars: {
-    key: "GOOGLE_APPLICATION_CREDENTIALS"
-    value: "keystore/73713_java_it_service_account"
-}
-
-before_action {
-  fetch_keystore {
-    keystore_resource {
-      keystore_config_id: 73713
-      keyname: "java_it_service_account"
-    }
-  }
-}
diff --git a/.kokoro/dependencies.sh b/.kokoro/dependencies.sh
index cf3bb434..c91e5a56 100755
--- a/.kokoro/dependencies.sh
+++ b/.kokoro/dependencies.sh
@@ -41,12 +41,15 @@ echo "****************** DEPENDENCY LIST COMPLETENESS CHECK *******************"
 ## Run dependency list completeness check
 function completenessCheck() {
   # Output dep list with compile scope generated using the original pom
+  # Running mvn dependency:list on Java versions that support modules will also include the module of the dependency.
+  # This is stripped from the output as it is not present in the flattened pom.
+  # Only dependencies with 'compile' or 'runtime' scope are included from original dependency list.
   msg "Generating dependency list using original pom..."
-  mvn dependency:list -f pom.xml -Dsort=true | grep '\[INFO]    .*:.*:.*:.*:.*' | grep -v ':test$' >.org-list.txt
+  mvn dependency:list -f pom.xml -DincludeScope=runtime -Dsort=true | grep '\[INFO]    .*:.*:.*:.*:.*' | sed -e s/\\s--\\smodule.*// >.org-list.txt
 
-  # Output dep list generated using the flattened pom (test scope deps are ommitted)
+  # Output dep list generated using the flattened pom (only 'compile' and 'runtime' scopes)
   msg "Generating dependency list using flattened pom..."
-  mvn dependency:list -f .flattened-pom.xml -Dsort=true | grep '\[INFO]    .*:.*:.*:.*:.*' >.new-list.txt
+  mvn dependency:list -f .flattened-pom.xml -DincludeScope=runtime -Dsort=true | grep '\[INFO]    .*:.*:.*:.*:.*' >.new-list.txt
 
   # Compare two dependency lists
   msg "Comparing dependency lists..."
@@ -83,4 +86,4 @@ then
 else
   msg "Errors found. See log statements above."
   exit 1
-fi
+fi
\ No newline at end of file
diff --git a/.kokoro/nightly/dependencies.cfg b/.kokoro/nightly/dependencies.cfg
deleted file mode 100644
index b89a2074..00000000
--- a/.kokoro/nightly/dependencies.cfg
+++ /dev/null
@@ -1,12 +0,0 @@
-# Format: //devtools/kokoro/config/proto/build.proto
-
-# Configure the docker image for kokoro-trampoline.
-env_vars: {
-  key: "TRAMPOLINE_IMAGE"
-  value: "gcr.io/cloud-devrel-kokoro-resources/java8"
-}
-
-env_vars: {
-  key: "TRAMPOLINE_BUILD_FILE"
-  value: "github/google-http-java-client/.kokoro/dependencies.sh"
-}
diff --git a/.kokoro/nightly/integration.cfg b/.kokoro/nightly/integration.cfg
index 40c4abb7..0048c8ec 100644
--- a/.kokoro/nightly/integration.cfg
+++ b/.kokoro/nightly/integration.cfg
@@ -28,14 +28,10 @@ env_vars: {
 
 env_vars: {
   key: "GOOGLE_APPLICATION_CREDENTIALS"
-  value: "keystore/73713_java_it_service_account"
+  value: "secret_manager/java-it-service-account"
 }
 
-before_action {
-  fetch_keystore {
-    keystore_resource {
-      keystore_config_id: 73713
-      keyname: "java_it_service_account"
-    }
-  }
+env_vars: {
+  key: "SECRET_MANAGER_KEYS"
+  value: "java-it-service-account"
 }
diff --git a/.kokoro/nightly/lint.cfg b/.kokoro/nightly/lint.cfg
deleted file mode 100644
index 6d323c8a..00000000
--- a/.kokoro/nightly/lint.cfg
+++ /dev/null
@@ -1,13 +0,0 @@
-# Format: //devtools/kokoro/config/proto/build.proto
-
-# Configure the docker image for kokoro-trampoline.
-
-env_vars: {
-  key: "TRAMPOLINE_IMAGE"
-  value: "gcr.io/cloud-devrel-kokoro-resources/java8"
-}
-
-env_vars: {
-  key: "JOB_TYPE"
-  value: "lint"
-}
\ No newline at end of file
diff --git a/.kokoro/nightly/samples.cfg b/.kokoro/nightly/samples.cfg
index 20aabd55..f2542931 100644
--- a/.kokoro/nightly/samples.cfg
+++ b/.kokoro/nightly/samples.cfg
@@ -24,19 +24,15 @@ env_vars: {
 
 env_vars: {
   key: "GOOGLE_APPLICATION_CREDENTIALS"
-  value: "keystore/73713_java_it_service_account"
+  value: "secret_manager/java-docs-samples-service-account"
 }
 
 env_vars: {
-  key: "ENABLE_BUILD_COP"
-  value: "true"
+  key: "SECRET_MANAGER_KEYS"
+  value: "java-docs-samples-service-account"
 }
 
-before_action {
-  fetch_keystore {
-    keystore_resource {
-      keystore_config_id: 73713
-      keyname: "java_it_service_account"
-    }
-  }
+env_vars: {
+  key: "ENABLE_BUILD_COP"
+  value: "true"
 }
diff --git a/.kokoro/populate-secrets.sh b/.kokoro/populate-secrets.sh
new file mode 100755
index 00000000..f5251425
--- /dev/null
+++ b/.kokoro/populate-secrets.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+# Copyright 2020 Google LLC.
+#
+# 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.
+
+set -eo pipefail
+
+function now { date +"%Y-%m-%d %H:%M:%S" | tr -d '\n' ;}
+function msg { println "$*" >&2 ;}
+function println { printf '%s\n' "$(now) $*" ;}
+
+
+# Populates requested secrets set in SECRET_MANAGER_KEYS from service account:
+# kokoro-trampoline@cloud-devrel-kokoro-resources.iam.gserviceaccount.com
+SECRET_LOCATION="${KOKORO_GFILE_DIR}/secret_manager"
+msg "Creating folder on disk for secrets: ${SECRET_LOCATION}"
+mkdir -p ${SECRET_LOCATION}
+for key in $(echo ${SECRET_MANAGER_KEYS} | sed "s/,/ /g")
+do
+  msg "Retrieving secret ${key}"
+  docker run --entrypoint=gcloud \
+    --volume=${KOKORO_GFILE_DIR}:${KOKORO_GFILE_DIR} \
+    gcr.io/google.com/cloudsdktool/cloud-sdk \
+    secrets versions access latest \
+    --project cloud-devrel-kokoro-resources \
+    --secret ${key} > \
+    "${SECRET_LOCATION}/${key}"
+  if [[ $? == 0 ]]; then
+    msg "Secret written to ${SECRET_LOCATION}/${key}"
+  else
+    msg "Error retrieving secret ${key}"
+  fi
+done
diff --git a/.kokoro/presubmit/integration.cfg b/.kokoro/presubmit/integration.cfg
index 522e5b10..dded67a9 100644
--- a/.kokoro/presubmit/integration.cfg
+++ b/.kokoro/presubmit/integration.cfg
@@ -24,14 +24,10 @@ env_vars: {
 
 env_vars: {
   key: "GOOGLE_APPLICATION_CREDENTIALS"
-  value: "keystore/73713_java_it_service_account"
+  value: "secret_manager/java-it-service-account"
 }
 
-before_action {
-  fetch_keystore {
-    keystore_resource {
-      keystore_config_id: 73713
-      keyname: "java_it_service_account"
-    }
-  }
+env_vars: {
+  key: "SECRET_MANAGER_KEYS"
+  value: "java-it-service-account"
 }
diff --git a/.kokoro/presubmit/samples.cfg b/.kokoro/presubmit/samples.cfg
index 1171aead..01e09600 100644
--- a/.kokoro/presubmit/samples.cfg
+++ b/.kokoro/presubmit/samples.cfg
@@ -24,14 +24,10 @@ env_vars: {
 
 env_vars: {
   key: "GOOGLE_APPLICATION_CREDENTIALS"
-  value: "keystore/73713_java_it_service_account"
+  value: "secret_manager/java-docs-samples-service-account"
 }
 
-before_action {
-  fetch_keystore {
-    keystore_resource {
-      keystore_config_id: 73713
-      keyname: "java_it_service_account"
-    }
-  }
-}
+env_vars: {
+  key: "SECRET_MANAGER_KEYS"
+  value: "java-docs-samples-service-account"
+}
\ No newline at end of file
diff --git a/.kokoro/readme.sh b/.kokoro/readme.sh
new file mode 100755
index 00000000..0bcf9b61
--- /dev/null
+++ b/.kokoro/readme.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# Copyright 2020 Google LLC
+#
+# 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.
+
+set -eo pipefail
+
+cd ${KOKORO_ARTIFACTS_DIR}/github/google-http-java-client
+
+# Disable buffering, so that the logs stream through.
+export PYTHONUNBUFFERED=1
+
+# Kokoro exposes this as a file, but the scripts expect just a plain variable.
+export GITHUB_TOKEN=$(cat ${KOKORO_KEYSTORE_DIR}/73713_yoshi-automation-github-key)
+
+# Setup git credentials
+echo "https://${GITHUB_TOKEN}:@github.com" >> ~/.git-credentials
+git config --global credential.helper 'store --file ~/.git-credentials'
+
+python3.6 -m pip install git+https://github.com/googleapis/synthtool.git#egg=gcp-synthtool
+python3.6 -m autosynth.synth \
+    --repository=googleapis/google-http-java-client \
+    --synth-file-name=.github/readme/synth.py \
+    --metadata-path=.github/readme/synth.metadata \
+    --pr-title="chore: regenerate README" \
+    --branch-suffix="readme"
\ No newline at end of file
diff --git a/.kokoro/release/publish_javadoc.cfg b/.kokoro/release/publish_javadoc.cfg
index c5d16b78..2359ee9d 100644
--- a/.kokoro/release/publish_javadoc.cfg
+++ b/.kokoro/release/publish_javadoc.cfg
@@ -1,14 +1,24 @@
 # Format: //devtools/kokoro/config/proto/build.proto
+
+gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/doc-templates/"
+
 env_vars: {
   key: "STAGING_BUCKET"
   value: "docs-staging"
 }
 
+env_vars: {
+  key: "STAGING_BUCKET_V2"
+  value: "docs-staging-v2-staging"
+  # Production will be at: docs-staging-v2
+}
+
 env_vars: {
   key: "TRAMPOLINE_BUILD_FILE"
   value: "github/google-http-java-client/.kokoro/release/publish_javadoc.sh"
 }
 
+
 before_action {
   fetch_keystore {
     keystore_resource {
diff --git a/.kokoro/release/publish_javadoc.sh b/.kokoro/release/publish_javadoc.sh
index b65eb9f9..e078748a 100755
--- a/.kokoro/release/publish_javadoc.sh
+++ b/.kokoro/release/publish_javadoc.sh
@@ -24,6 +24,11 @@ if [[ -z "${STAGING_BUCKET}" ]]; then
   exit 1
 fi
 
+if [[ -z "${STAGING_BUCKET_V2}" ]]; then
+  echo "Need to set STAGING_BUCKET_V2 environment variable"
+  exit 1
+fi
+
 # work from the git root directory
 pushd $(dirname "$0")/../../
 
@@ -31,13 +36,13 @@ pushd $(dirname "$0")/../../
 python3 -m pip install gcp-docuploader
 
 # compile all packages
-mvn clean install -B -DskipTests=true
+mvn clean install -B -q -DskipTests=true
 
 NAME=google-http-client
 VERSION=$(grep ${NAME}: versions.txt | cut -d: -f3)
 
 # build the docs
-mvn site -B
+mvn site -B -q
 
 pushd target/site/apidocs
 
@@ -53,3 +58,19 @@ python3 -m docuploader upload . \
   --staging-bucket ${STAGING_BUCKET}
 
 popd
+
+# V2
+mvn clean site -B -q -Ddevsite.template="${KOKORO_GFILE_DIR}/java/"
+
+pushd target/devsite
+
+# create metadata
+python3 -m docuploader create-metadata \
+  --name ${NAME} \
+  --version ${VERSION} \
+  --language java
+
+# upload docs
+python3 -m docuploader upload . \
+  --credentials ${CREDENTIALS} \
+  --staging-bucket ${STAGING_BUCKET_V2}
diff --git a/.kokoro/release/stage.cfg b/.kokoro/release/stage.cfg
index 3463d3d7..103381c4 100644
--- a/.kokoro/release/stage.cfg
+++ b/.kokoro/release/stage.cfg
@@ -13,32 +13,7 @@ action {
   }
 }
 
-# Fetch the token needed for reporting release status to GitHub
-before_action {
-  fetch_keystore {
-    keystore_resource {
-      keystore_config_id: 73713
-      keyname: "yoshi-automation-github-key"
-    }
-  }
-}
-
-# Fetch magictoken to use with Magic Github Proxy
-before_action {
-  fetch_keystore {
-    keystore_resource {
-      keystore_config_id: 73713
-      keyname: "releasetool-magictoken"
-    }
-  }
-}
-
-# Fetch api key to use with Magic Github Proxy
-before_action {
-  fetch_keystore {
-    keystore_resource {
-      keystore_config_id: 73713
-      keyname: "magic-github-proxy-api-key"
-    }
-  }
+env_vars: {
+  key: "SECRET_MANAGER_KEYS"
+  value: "releasetool-publish-reporter-app,releasetool-publish-reporter-googleapis-installation,releasetool-publish-reporter-pem"
 }
diff --git a/.kokoro/trampoline.sh b/.kokoro/trampoline.sh
index ba17ce01..9da0f839 100644
--- a/.kokoro/trampoline.sh
+++ b/.kokoro/trampoline.sh
@@ -21,4 +21,6 @@ function cleanup() {
     echo "cleanup";
 }
 trap cleanup EXIT
+
+$(dirname $0)/populate-secrets.sh # Secret Manager secrets.
 python3 "${KOKORO_GFILE_DIR}/trampoline_v1.py"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f7ea60f0..3ea0f07a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,17 @@
 # Changelog
 
+## [1.36.0](https://www.github.com/googleapis/google-http-java-client/compare/v1.35.0...v1.36.0) (2020-06-30)
+
+
+### Features
+
+* add Android 19 compatible FileDataStoreFactory implementation ([#1070](https://www.github.com/googleapis/google-http-java-client/issues/1070)) ([1150acd](https://www.github.com/googleapis/google-http-java-client/commit/1150acd38aa3139eea4f2f718545c20d2493877e))
+
+
+### Bug Fixes
+
+* restore the thread's interrupted status after catching InterruptedException ([#1005](https://www.github.com/googleapis/google-http-java-client/issues/1005)) ([#1006](https://www.github.com/googleapis/google-http-java-client/issues/1006)) ([0a73a46](https://www.github.com/googleapis/google-http-java-client/commit/0a73a4628b6ec4420db6b9cdbcc68899f3807c5b))
+
 ## [1.35.0](https://www.github.com/googleapis/google-http-java-client/compare/v1.34.2...v1.35.0) (2020-04-27)
 
 
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 085021dd..f2dbdee0 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -99,7 +99,16 @@ mvn -Penable-samples clean verify
     ```
 
 2. [Activate](#profile-activation) the profile.
-3. Define your samples in a normal Maven project in the `samples/` directory
+3. Define your samples in a normal Maven project in the `samples/` directory.
+
+### Code Formatting
+
+Code in this repo is formatted with
+[google-java-format](https://github.com/google/google-java-format).
+To run formatting on your project, you can run:
+```
+mvn com.coveo:fmt-maven-plugin:format
+```
 
 ### Profile Activation
 
diff --git a/clirr-ignored-differences.xml b/clirr-ignored-differences.xml
deleted file mode 100644
index 0f0a72ed..00000000
--- a/clirr-ignored-differences.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- see http://www.mojohaus.org/clirr-maven-plugin/examples/ignored-differences.html -->
-<differences>
-  <difference>
-    <differenceType>7002</differenceType>
-    <className>com/google/api/client/json/webtoken/*</className>
-    <method>java.lang.String getX509Certificate()</method>
-  </difference>
-  <difference>
-    <differenceType>7002</differenceType>
-    <className>com/google/api/client/json/webtoken/*</className>
-    <method>com.google.api.client.json.webtoken.JsonWebSignature$Header setX509Certificate(java.lang.String)</method>
-  </difference>
-   <difference>
-     <differenceType>7002</differenceType>
-     <className>com/google/api/client/testing/http/MockHttpTransport</className>
-     <method>com.google.api.client.testing.http.MockHttpTransport$Builder builder()</method>
-  </difference>
-  <!-- 8001 (Class removed): className -->
-  <difference>
-    <differenceType>8001</differenceType>
-    <className>com/google/api/client/repackaged/**</className>
-  </difference>
-  <difference>
-    <differenceType>8001</differenceType>
-    <className>com/google/api/client/http/apache/**</className>
-  </difference>
-</differences>
diff --git a/docs/json.md b/docs/json.md
index 491d7344..1d6dbc7d 100644
--- a/docs/json.md
+++ b/docs/json.md
@@ -27,114 +27,304 @@ Android Honeycomb (SDK 3.0) and higher, and that is identical to the Google GSON
 
 User-defined JSON data models allow you to define Plain Old Java Objects (POJOs) and define how the
 library parses and serializes them to and from JSON. The code snippets below are part of a more
-complete example, [googleplus-simple-cmdline-sample][google-plus-sample], which demonstrates these
+complete example, [YouTube sample][youtube-sample], which demonstrates these
 concepts.
 
 ### Example
 
-The following JSON snippet shows the relevant fields of a typical Google+ activity feed:
+The following JSON snippet shows the relevant fields of a typical [YouTube video search][youtube-search]:
 
 ```json
 {
+ "kind": "youtube#searchListResponse",
+ "pageInfo": {
+  "totalResults": 1000000,
+  "resultsPerPage": 5
+ },
  "items": [
   {
-   "id": "z13lwnljpxjgt5wn222hcvzimtebslkul",
-   "url": "https://plus.google.com/116899029375914044550/posts/HYNhBAMeA7U",
-   "object": {
-    "content": "\u003cb\u003eWho will take the title of 2011 Angry Birds College Champ?\u003c/b\u003e\u003cbr /\u003e\u003cbr /\u003e\u003cbr /\u003eIt's the 2nd anniversary of Angry Birds this Sunday, December 11, and to celebrate this break-out game we're having an intercollegiate angry birds challenge for students to compete for the title of 2011 Angry Birds College Champion. Add \u003cspan class=\"proflinkWrapper\"\u003e\u003cspan class=\"proflinkPrefix\"\u003e+\u003c/span\u003e\u003ca href=\"https://plus.google.com/105912662528057048457\" class=\"proflink\" oid=\"105912662528057048457\"\u003eAngry Birds College Challenge\u003c/a\u003e\u003c/span\u003e to learn more. Good luck, and have fun!",
-    "plusoners": {
-     "totalItems": 27
+   "kind": "youtube#searchResult",
+   "id": {
+    "kind": "youtube#video",
+    "videoId": "e6Tudp5lqt8"
+   },
+   "snippet": {
+    "publishedAt": "2020-06-25T23:18:43Z",
+    "channelId": "UCKwGZZMrhNYKzucCtTPY2Nw",
+    "title": "Video 1 Title",
+    "description": "Video 1 Description",
+    "thumbnails": {
+     "default": {
+      "url": "https://i.ytimg.com/vi/e6Tudp5lqt8/default.jpg",
+      "width": 120,
+      "height": 90
+     },
+     "medium": {
+      "url": "https://i.ytimg.com/vi/e6Tudp5lqt8/mqdefault.jpg",
+      "width": 320,
+      "height": 180
+     },
+     "high": {
+      "url": "https://i.ytimg.com/vi/e6Tudp5lqt8/hqdefault.jpg",
+      "width": 480,
+      "height": 360
+     }
     }
    }
   },
   {
-   "id": "z13rtboyqt2sit45o04cdp3jxuf5cz2a3e4",
-   "url": "https://plus.google.com/116899029375914044550/posts/X8W8m9Hk5rE",
-   "object": {
-    "content": "CNN Heroes shines a spotlight on everyday people changing the world. Hear the top ten heroes' inspiring stories by tuning in to the CNN broadcast of "CNN Heroes: An All-Star Tribute" on Sunday, December 11, at 8pm ET/5 pm PT with host \u003cspan class=\"proflinkWrapper\"\u003e\u003cspan class=\"proflinkPrefix\"\u003e+\u003c/span\u003e\u003ca href=\"https://plus.google.com/106168900754103197479\" class=\"proflink\" oid=\"106168900754103197479\"\u003eAnderson Cooper 360\u003c/a\u003e\u003c/span\u003e, and donate to their causes online in a few simple steps with Google Wallet (formerly known as Google Checkout): \u003ca href=\"http://www.google.com/landing/cnnheroes/2011/\" \u003ehttp://www.google.com/landing/cnnheroes/2011/\u003c/a\u003e.",
-    "plusoners": {
-     "totalItems": 21
+   "kind": "youtube#searchResult",
+   "id": {
+    "kind": "youtube#video",
+    "videoId": "o-NtLpiMpw0"
+   },
+   "snippet": {
+    "publishedAt": "2020-06-25T17:28:52Z",
+    "channelId": "UClljAz6ZKy0XeViKsohdjqA",
+    "title": "Video Title 2",
+    "description": "Video 2 Description",
+    "thumbnails": {
+     "default": {
+      "url": "https://i.ytimg.com/vi/o-NtLpiMpw0/default.jpg",
+      "width": 120,
+      "height": 90
+     },
+     "medium": {
+      "url": "https://i.ytimg.com/vi/o-NtLpiMpw0/mqdefault.jpg",
+      "width": 320,
+      "height": 180
+     },
+     "high": {
+      "url": "https://i.ytimg.com/vi/o-NtLpiMpw0/hqdefault.jpg",
+      "width": 480,
+      "height": 360
+     }
     }
    }
   },
   {
-   "id": "z13wtpwpqvihhzeys04cdp3jxuf5cz2a3e4",
-   "url": "https://plus.google.com/116899029375914044550/posts/dBnaybdLgzU",
-   "object": {
-    "content": "Today we hosted one of our Big Tent events in The Hague. \u003cspan class=\"proflinkWrapper\"\u003e\u003cspan class=\"proflinkPrefix\"\u003e+\u003c/span\u003e\u003ca href=\"https://plus.google.com/104233435224873922474\" class=\"proflink\" oid=\"104233435224873922474\"\u003eEric Schmidt\u003c/a\u003e\u003c/span\u003e, Dutch Foreign Minister Uri Rosenthal, U.S. Secretary of State Hillary Clinton and many others came together to discuss free expression and the Internet. The Hague is our third Big Tent, a place where we bring together various viewpoints to discuss essential topics to the future of the Internet. Read more on the Official Google Blog here: \u003ca href=\"http://goo.gl/d9cSe\" \u003ehttp://goo.gl/d9cSe\u003c/a\u003e, and watch the video below for highlights from the day.",
-    "plusoners": {
-     "totalItems": 76
+   "kind": "youtube#searchResult",
+   "id": {
+    "kind": "youtube#video",
+    "videoId": "TPAahzXZFZo"
+   },
+   "snippet": {
+    "publishedAt": "2020-06-26T15:45:00Z",
+    "channelId": "UCR4Yfr8HAZJd9X24dwuAt1Q",
+    "title": "Video 3 Title",
+    "description": "Video 3 Description",
+    "thumbnails": {
+     "default": {
+      "url": "https://i.ytimg.com/vi/TPAahzXZFZo/default.jpg",
+      "width": 120,
+      "height": 90
+     },
+     "medium": {
+      "url": "https://i.ytimg.com/vi/TPAahzXZFZo/mqdefault.jpg",
+      "width": 320,
+      "height": 180
+     },
+     "high": {
+      "url": "https://i.ytimg.com/vi/TPAahzXZFZo/hqdefault.jpg",
+      "width": 480,
+      "height": 360
+     }
+    }
+   }
+  },
+  {
+   "kind": "youtube#searchResult",
+   "id": {
+    "kind": "youtube#video",
+    "videoId": "gBL-AelsdFk"
+   },
+   "snippet": {
+    "publishedAt": "2020-06-24T15:24:06Z",
+    "channelId": "UCFHZHhZaH7Rc_FOMIzUziJA",
+    "title": "Video 4 Title",
+    "description": "Video 4 Description",
+    "thumbnails": {
+     "default": {
+      "url": "https://i.ytimg.com/vi/gBL-AelsdFk/default.jpg",
+      "width": 120,
+      "height": 90
+     },
+     "medium": {
+      "url": "https://i.ytimg.com/vi/gBL-AelsdFk/mqdefault.jpg",
+      "width": 320,
+      "height": 180
+     },
+     "high": {
+      "url": "https://i.ytimg.com/vi/gBL-AelsdFk/hqdefault.jpg",
+      "width": 480,
+      "height": 360
+     }
+    }
+   }
+  },
+  {
+   "kind": "youtube#searchResult",
+   "id": {
+    "kind": "youtube#video",
+    "videoId": "9ofe8axKjH0"
+   },
+   "snippet": {
+    "publishedAt": "2020-06-26T11:59:32Z",
+    "channelId": "UCtNpbO2MtsVY4qW23WfnxGg",
+    "title": "Video 5 Title",
+    "description": "Video 5 Description",
+    "thumbnails": {
+     "default": {
+      "url": "https://i.ytimg.com/vi/9ofe8axKjH0/default.jpg",
+      "width": 120,
+      "height": 90
+     },
+     "medium": {
+      "url": "https://i.ytimg.com/vi/9ofe8axKjH0/mqdefault.jpg",
+      "width": 320,
+      "height": 180
+     },
+     "high": {
+      "url": "https://i.ytimg.com/vi/9ofe8axKjH0/hqdefault.jpg",
+      "width": 480,
+      "height": 360
+     }
     }
    }
   }
  ]
 }
+
 ```
 
 Here's one possible way to design the Java data classes to represent this:
 
 ```java
-/** Feed of Google+ activities. */
-public static class ActivityFeed {
-
-  /** List of Google+ activities. */
+public static class ListResponse {
   @Key("items")
-  private List<Activity> activities;
+  private List<SearchResult> searchResults;
+
+  @Key
+  private PageInfo pageInfo;
 
-  public List<Activity> getActivities() {
-    return activities;
+  public List<SearchResult> getSearchResults() {
+    return searchResults;
+  }
+
+  public PageInfo getPageInfo() {
+    return pageInfo;
   }
 }
 
-/** Google+ activity. */
-public static class Activity extends GenericJson {
+public static class PageInfo {
+  @Key
+  private long totalResults;
 
-  /** Activity URL. */
   @Key
-  private String url;
+  private long resultsPerPage;
 
-  public String getUrl() {
-    return url;
+  public long getTotalResults() {
+    return totalResults;
+  }
+
+  public long getResultsPerPage() {
+    return resultsPerPage;
+  }
+}
+
+public static class SearchResult {
+  @Key
+  private String kind;
+
+  @Key("id")
+  private VideoId videoId;
+
+  @Key
+  private Snippet snippet;
+
+  public String getKind() {
+    return kind;
   }
 
-  /** Activity object. */
-  @Key("object")
-  private ActivityObject activityObject;
+  public VideoId getId() {
+    return videoId;
+  }
 
-  public ActivityObject getActivityObject() {
-    return activityObject;
+  public Snippet getSnippet() {
+    return snippet;
   }
 }
 
-/** Google+ activity object. */
-public static class ActivityObject {
+public static class VideoId {
+  @Key
+  private String kind;
 
-  /** HTML-formatted content. */
   @Key
-  private String content;
+  private String videoId;
+
+  public String getKind() {
+    return kind;
+  }
 
-  public String getContent() {
-    return content;
+  public String getVideoId() {
+    return videoId;
   }
+}
+
+public static class Snippet {
+  @Key
+  private String publishedAt;
+
+  @Key
+  private String channelId;
 
-  /** People who +1'd this activity. */
   @Key
-  private PlusOners plusoners;
+  private String title;
 
-  public PlusOners getPlusOners() {
-    return plusoners;
+  @Key
+  private String description;
+
+  public String getPublishedAt() {
+    return publishedAt;
+  }
+
+  public String getChannelId() {
+    return channelId;
+  }
+
+  public String getTitle() {
+    return title;
+  }
+
+  public String getDescription() {
+    return description;
+  }
+
+  public Map<String, Thumbnail> getThumbnails() {
+    return thumbnails;
   }
 }
 
-/** People who +1'd an activity. */
-public static class PlusOners {
+public static class Thumbnail {
+  @Key
+  private String url;
+
+  @Key
+  private long width;
 
-  /** Total number of people who +1'd this activity. */
   @Key
-  private long totalItems;
+  private long height;
 
-  public long getTotalItems() {
-    return totalItems;
+  public String getUrl() {
+    return url;
+  }
+
+  public long getWidth() {
+    return width;
+  }
+
+  public long getHeight() {
+    return height;
   }
 }
 ```
@@ -143,20 +333,21 @@ A fully supported [HTTP JSON parser][json-parser] makes it easy to parse HTTP re
 of these user defined classes:
 
 ```java
-private static void parseResponse(HttpResponse response) throws IOException {
-  ActivityFeed feed = response.parseAs(ActivityFeed.class);
-  if (feed.getActivities().isEmpty()) {
-    System.out.println("No activities found.");
+public static ListResponse parseJson(HttpResponse httpResponse) throws IOException {
+  ListResponse listResponse = httpResponse.parseAs(ListResponse.class);
+  if (listResponse.getSearchResults().isEmpty()) {
+    System.out.println("No results found.");
   } else {
-    for (Activity activity : feed.getActivities()) {
+    for (SearchResult searchResult : listResponse.getSearchResults()) {
       System.out.println();
       System.out.println("-----------------------------------------------");
-      System.out.println("HTML Content: " + activity.getActivityObject().getContent());
-      System.out.println("+1's: " + activity.getActivityObject().getPlusOners().getTotalItems());
-      System.out.println("URL: " + activity.getUrl());
-      System.out.println("ID: " + activity.get("id"));
+      System.out.println("Kind: " + searchResult.getKind());
+      System.out.println("Video ID: " + searchResult.getId().getVideoId());
+      System.out.println("Title: " + searchResult.getSnippet().getTitle());
+      System.out.println("Description: " + searchResult.getSnippet().getDescription());
     }
   }
+  return listResponse;
 }
 ```
 
@@ -172,16 +363,16 @@ serialized to JSON.
 ### Visibility
 
 Visibility of the fields does not matter, nor does the existence of the getter or setter methods. So
-for example, the following alternative representation for `PlusOners` would work in the example
+for example, the following alternative representation for `VideoId` would work in the example
 given above:
 
 ```java
-/** People who +1'd an activity. */
-public static class AlternativePlusOnersWithPublicField {
+public static class VideoId {
+  @Key
+  public String kind;
 
-  /** Total number of people who +1'd this activity. */
   @Key
-  public long totalItems;
+  public String videoId;
 }
 ```
 
@@ -193,8 +384,8 @@ parser skips that other content when parsing the response from Google+.
 
 To retain the other content, declare your class to extend [`GenericJson`][generic-json]. Notice that
 `GenericJson` implements [`Map`][map], so we can use the `get` and `put` methods to set JSON
-content. See [`googleplus-simple-cmdline-sample`][google-plus-sample] for an example of how it was
-used in the `Activity` class above.
+content. See [`Youtube sample`][youtube-sample] for an example of how it was
+used in the `Snippet` class above.
 
 ### Map
 
@@ -268,7 +459,8 @@ private static void show(List<Item> items) {
 [gson-factory]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/json/gson/GsonFactory.html
 [gson]: https://github.com/google/gson
 [android-json-factory]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/extensions/android/json/AndroidJsonFactory.html
-[google-plus-sample]: https://github.com/googleapis/google-http-java-client/tree/master/samples/googleplus-simple-cmdline-sample
+[youtube-sample]: https://github.com/googleapis/google-http-java-client/tree/master/samples/snippets/src/main/java/com/example/json/YouTubeSample.java
+[youtube-search]: https://developers.google.com/youtube/v3/docs/search/list
 [json-parser]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/json/JsonParser.html
 [key-annotation]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/util/Key.html
 [generic-json]: https://googleapis.dev/java/google-http-client/latest/index.html?com/google/api/client/json/GenericJson.html
diff --git a/docs/setup.md b/docs/setup.md
index 32466270..9b7517bd 100644
--- a/docs/setup.md
+++ b/docs/setup.md
@@ -23,7 +23,7 @@ the `dependencyManagement` section of your `pom.xml`:
     <dependency>
       <groupId>com.google.cloud</groupId>
       <artifactId>libraries-bom</artifactId>
-      <version>7.0.0</version>
+      <version>12.0.0</version>
       <type>pom</type>
       <scope>import</scope>
      </dependency>
diff --git a/google-http-client-android/pom.xml b/google-http-client-android/pom.xml
index 4edeeb3a..8a91def7 100644
--- a/google-http-client-android/pom.xml
+++ b/google-http-client-android/pom.xml
@@ -4,11 +4,11 @@
   <parent>
     <groupId>com.google.http-client</groupId>
     <artifactId>google-http-client-parent</artifactId>
-    <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
+    <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
     <relativePath>../pom.xml</relativePath>
   </parent>
   <artifactId>google-http-client-android</artifactId>
-  <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-android:current} -->
+  <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-android:current} -->
   <name>Android Platform Extensions to the Google HTTP Client Library for Java.</name>
 
   <build>
diff --git a/google-http-client-android/src/main/java/com/google/api/client/extensions/android/util/store/FileDataStoreFactory.java b/google-http-client-android/src/main/java/com/google/api/client/extensions/android/util/store/FileDataStoreFactory.java
new file mode 100644
index 00000000..b9c808b5
--- /dev/null
+++ b/google-http-client-android/src/main/java/com/google/api/client/extensions/android/util/store/FileDataStoreFactory.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * 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
+ *
+ *    https://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.api.client.extensions.android.util.store;
+
+import com.google.api.client.util.IOUtils;
+import com.google.api.client.util.Maps;
+import com.google.api.client.util.store.AbstractDataStoreFactory;
+import com.google.api.client.util.store.AbstractMemoryDataStore;
+import com.google.api.client.util.store.DataStore;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.logging.Logger;
+
+/**
+ * Thread-safe file implementation of a credential store.
+ *
+ * <p>For security purposes, the file's permissions are set to be accessible only by the file's
+ * owner.
+ *
+ * <p>Note: This class was branched from the primary implementation in google-http-client to allow
+ * the mainline implementation to support Windows file permissions.
+ *
+ * @since 1.36
+ * @author Yaniv Inbar
+ */
+public class FileDataStoreFactory extends AbstractDataStoreFactory {
+
+  private static final Logger LOGGER = Logger.getLogger(FileDataStoreFactory.class.getName());
+
+  /** Directory to store data. */
+  private final File dataDirectory;
+
+  /** @param dataDirectory data directory */
+  public FileDataStoreFactory(File dataDirectory) throws IOException {
+    dataDirectory = dataDirectory.getCanonicalFile();
+    // error if it is a symbolic link
+    if (IOUtils.isSymbolicLink(dataDirectory)) {
+      throw new IOException("unable to use a symbolic link: " + dataDirectory);
+    }
+    // create parent directory (if necessary)
+    if (!dataDirectory.exists() && !dataDirectory.mkdirs()) {
+      throw new IOException("unable to create directory: " + dataDirectory);
+    }
+    this.dataDirectory = dataDirectory;
+    setPermissionsToOwnerOnly(dataDirectory);
+  }
+
+  /** Returns the data directory. */
+  public final File getDataDirectory() {
+    return dataDirectory;
+  }
+
+  @Override
+  protected <V extends Serializable> DataStore<V> createDataStore(String id) throws IOException {
+    return new FileDataStore<V>(this, dataDirectory, id);
+  }
+
+  /**
+   * File data store that inherits from the abstract memory data store because the key-value pairs
+   * are stored in a memory cache, and saved in the file (see {@link #save()} when changing values.
+   *
+   * @param <V> serializable type of the mapped value
+   */
+  static class FileDataStore<V extends Serializable> extends AbstractMemoryDataStore<V> {
+
+    /** File to store data. */
+    private final File dataFile;
+
+    FileDataStore(FileDataStoreFactory dataStore, File dataDirectory, String id)
+        throws IOException {
+      super(dataStore, id);
+      this.dataFile = new File(dataDirectory, id);
+      // error if it is a symbolic link
+      if (IOUtils.isSymbolicLink(dataFile)) {
+        throw new IOException("unable to use a symbolic link: " + dataFile);
+      }
+      // create new file (if necessary)
+      if (dataFile.createNewFile()) {
+        keyValueMap = Maps.newHashMap();
+        // save the credentials to create a new file
+        save();
+      } else {
+        // load credentials from existing file
+        keyValueMap = IOUtils.deserialize(new FileInputStream(dataFile));
+      }
+    }
+
+    @Override
+    public void save() throws IOException {
+      IOUtils.serialize(keyValueMap, new FileOutputStream(dataFile));
+    }
+
+    @Override
+    public FileDataStoreFactory getDataStoreFactory() {
+      return (FileDataStoreFactory) super.getDataStoreFactory();
+    }
+  }
+
+  /**
+   * Attempts to set the given file's permissions such that it can only be read, written, and
+   * executed by the file's owner.
+   *
+   * @param file the file's permissions to modify
+   */
+  static void setPermissionsToOwnerOnly(File file) {
+    // Disable access by other users if O/S allows it and set file permissions to readable and
+    // writable by user.
+    try {
+      if (!file.setReadable(false, false)
+          || !file.setWritable(false, false)
+          || !file.setExecutable(false, false)) {
+        LOGGER.warning("unable to change permissions for everybody: " + file);
+      }
+      if (!file.setReadable(true, true)
+          || !file.setWritable(true, true)
+          || !file.setExecutable(true, true)) {
+        LOGGER.warning("unable to change permissions for owner: " + file);
+      }
+    } catch (SecurityException exception) {
+      // ignored
+    } catch (IllegalArgumentException exception) {
+      // ignored
+    }
+  }
+}
diff --git a/google-http-client-apache-v2/pom.xml b/google-http-client-apache-v2/pom.xml
index 85f0d6ee..6a2171bf 100644
--- a/google-http-client-apache-v2/pom.xml
+++ b/google-http-client-apache-v2/pom.xml
@@ -4,11 +4,11 @@
   <parent>
     <groupId>com.google.http-client</groupId>
     <artifactId>google-http-client-parent</artifactId>
-    <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
+    <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
     <relativePath>../pom.xml</relativePath>
   </parent>
   <artifactId>google-http-client-apache-v2</artifactId>
-  <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-apache-v2:current} -->
+  <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-apache-v2:current} -->
   <name>Apache HTTP transport v2 for the Google HTTP Client Library for Java.</name>
 
   <build>
@@ -38,7 +38,7 @@
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>build-helper-maven-plugin</artifactId>
-        <version>3.1.0</version>
+        <version>3.2.0</version>
         <executions>
           <execution>
             <id>add-test-source</id>
diff --git a/google-http-client-appengine/pom.xml b/google-http-client-appengine/pom.xml
index 3df3f234..52232b21 100644
--- a/google-http-client-appengine/pom.xml
+++ b/google-http-client-appengine/pom.xml
@@ -4,11 +4,11 @@
   <parent>
     <groupId>com.google.http-client</groupId>
     <artifactId>google-http-client-parent</artifactId>
-    <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
+    <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
     <relativePath>../pom.xml</relativePath>
   </parent>
   <artifactId>google-http-client-appengine</artifactId>
-  <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-appengine:current} -->
+  <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-appengine:current} -->
   <name>Google App Engine extensions to the Google HTTP Client Library for Java.</name>
 
   <build>
diff --git a/google-http-client-assembly/pom.xml b/google-http-client-assembly/pom.xml
index 129acfef..5bc1d3a5 100644
--- a/google-http-client-assembly/pom.xml
+++ b/google-http-client-assembly/pom.xml
@@ -4,12 +4,12 @@
   <parent>
     <groupId>com.google.http-client</groupId>
     <artifactId>google-http-client-parent</artifactId>
-    <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
+    <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
     <relativePath>../pom.xml</relativePath>
   </parent>
   <groupId>com.google.http-client</groupId>
   <artifactId>google-http-client-assembly</artifactId>
-  <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-assembly:current} -->
+  <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-assembly:current} -->
   <packaging>pom</packaging>
   <name>Assembly for the Google HTTP Client Library for Java</name>
 
diff --git a/google-http-client-bom/pom.xml b/google-http-client-bom/pom.xml
index 826a8730..69f94e6a 100644
--- a/google-http-client-bom/pom.xml
+++ b/google-http-client-bom/pom.xml
@@ -3,7 +3,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.http-client</groupId>
   <artifactId>google-http-client-bom</artifactId>
-  <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-bom:current} -->
+  <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-bom:current} -->
   <packaging>pom</packaging>
 
   <name>Google HTTP Client Library for Java BOM</name>
@@ -63,52 +63,52 @@
       <dependency>
         <groupId>com.google.http-client</groupId>
         <artifactId>google-http-client</artifactId>
-        <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client:current} -->
+        <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.http-client</groupId>
         <artifactId>google-http-client-android</artifactId>
-        <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-android:current} -->
+        <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-android:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.http-client</groupId>
         <artifactId>google-http-client-apache-v2</artifactId>
-        <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-apache-v2:current} -->
+        <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-apache-v2:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.http-client</groupId>
         <artifactId>google-http-client-appengine</artifactId>
-        <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-appengine:current} -->
+        <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-appengine:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.http-client</groupId>
         <artifactId>google-http-client-findbugs</artifactId>
-        <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-findbugs:current} -->
+        <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-findbugs:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.http-client</groupId>
         <artifactId>google-http-client-gson</artifactId>
-        <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-gson:current} -->
+        <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-gson:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.http-client</groupId>
         <artifactId>google-http-client-jackson2</artifactId>
-        <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-jackson2:current} -->
+        <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-jackson2:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.http-client</groupId>
         <artifactId>google-http-client-protobuf</artifactId>
-        <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-protobuf:current} -->
+        <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-protobuf:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.http-client</groupId>
         <artifactId>google-http-client-test</artifactId>
-        <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-test:current} -->
+        <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-test:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.http-client</groupId>
         <artifactId>google-http-client-xml</artifactId>
-        <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-xml:current} -->
+        <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-xml:current} -->
       </dependency>
     </dependencies>
   </dependencyManagement>
@@ -136,7 +136,7 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-site-plugin</artifactId>
-        <version>3.9.0</version>
+        <version>3.9.1</version>
         <configuration>
           <skip>true</skip>
         </configuration>
diff --git a/google-http-client-findbugs/pom.xml b/google-http-client-findbugs/pom.xml
index 18851216..e416707f 100644
--- a/google-http-client-findbugs/pom.xml
+++ b/google-http-client-findbugs/pom.xml
@@ -4,11 +4,11 @@
   <parent>
     <groupId>com.google.http-client</groupId>
     <artifactId>google-http-client-parent</artifactId>
-    <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
+    <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
     <relativePath>../pom.xml</relativePath>
   </parent>
   <artifactId>google-http-client-findbugs</artifactId>
-  <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-findbugs:current} -->
+  <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-findbugs:current} -->
   <name>Google APIs Client Library Findbugs custom plugin.</name>
 
   <build>
diff --git a/google-http-client-gson/pom.xml b/google-http-client-gson/pom.xml
index 7631b01b..a0ce6b78 100644
--- a/google-http-client-gson/pom.xml
+++ b/google-http-client-gson/pom.xml
@@ -4,11 +4,11 @@
   <parent>
     <groupId>com.google.http-client</groupId>
     <artifactId>google-http-client-parent</artifactId>
-    <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
+    <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
     <relativePath>../pom.xml</relativePath>
   </parent>
   <artifactId>google-http-client-gson</artifactId>
-  <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-gson:current} -->
+  <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-gson:current} -->
   <name>GSON extensions to the Google HTTP Client Library for Java.</name>
 
   <build>
@@ -39,7 +39,7 @@
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>build-helper-maven-plugin</artifactId>
-        <version>3.1.0</version>
+        <version>3.2.0</version>
         <executions>
           <execution>
             <id>add-test-source</id>
diff --git a/google-http-client-jackson2/pom.xml b/google-http-client-jackson2/pom.xml
index 7b7e7b37..7e8a1e92 100644
--- a/google-http-client-jackson2/pom.xml
+++ b/google-http-client-jackson2/pom.xml
@@ -4,11 +4,11 @@
   <parent>
     <groupId>com.google.http-client</groupId>
     <artifactId>google-http-client-parent</artifactId>
-    <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
+    <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
     <relativePath>../pom.xml</relativePath>
   </parent>
   <artifactId>google-http-client-jackson2</artifactId>
-  <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-jackson2:current} -->
+  <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-jackson2:current} -->
   <name>Jackson 2 extensions to the Google HTTP Client Library for Java.</name>
 
   <build>
@@ -39,7 +39,7 @@
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>build-helper-maven-plugin</artifactId>
-        <version>3.1.0</version>
+        <version>3.2.0</version>
         <executions>
           <execution>
             <id>add-test-source</id>
diff --git a/google-http-client-protobuf/pom.xml b/google-http-client-protobuf/pom.xml
index fd3370f8..148605ac 100644
--- a/google-http-client-protobuf/pom.xml
+++ b/google-http-client-protobuf/pom.xml
@@ -4,11 +4,11 @@
   <parent>
     <groupId>com.google.http-client</groupId>
     <artifactId>google-http-client-parent</artifactId>
-    <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
+    <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
     <relativePath>../pom.xml</relativePath>
   </parent>
   <artifactId>google-http-client-protobuf</artifactId>
-  <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-protobuf:current} -->
+  <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-protobuf:current} -->
   <name>Protocol Buffer extensions to the Google HTTP Client Library for Java.</name>
 
   <build>
diff --git a/google-http-client-xml/pom.xml b/google-http-client-xml/pom.xml
index 480a1868..f1367996 100644
--- a/google-http-client-xml/pom.xml
+++ b/google-http-client-xml/pom.xml
@@ -4,11 +4,11 @@
   <parent>
     <groupId>com.google.http-client</groupId>
     <artifactId>google-http-client-parent</artifactId>
-    <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
+    <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
     <relativePath>../pom.xml</relativePath>
   </parent>
   <artifactId>google-http-client-xml</artifactId>
-  <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-xml:current} -->
+  <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-xml:current} -->
   <name>XML extensions to the Google HTTP Client Library for Java.</name>
 
   <build>
@@ -38,7 +38,7 @@
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>build-helper-maven-plugin</artifactId>
-        <version>3.1.0</version>
+        <version>3.2.0</version>
         <executions>
           <execution>
             <id>add-test-source</id>
diff --git a/google-http-client/pom.xml b/google-http-client/pom.xml
index eee0716d..bcd847b7 100644
--- a/google-http-client/pom.xml
+++ b/google-http-client/pom.xml
@@ -4,11 +4,11 @@
   <parent>
     <groupId>com.google.http-client</groupId>
     <artifactId>google-http-client-parent</artifactId>
-    <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
+    <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
     <relativePath>../pom.xml</relativePath>
   </parent>
   <artifactId>google-http-client</artifactId>
-  <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client:current} -->
+  <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client:current} -->
   <name>Google HTTP Client Library for Java</name>
   <description>
     Google HTTP Client Library for Java. Functionality that works on all supported Java platforms,
@@ -26,6 +26,23 @@
             <ignoredUnusedDeclaredDependencies>io.opencensus:opencensus-impl</ignoredUnusedDeclaredDependencies>
           </configuration>
         </plugin>
+        <plugin>
+          <groupId>org.codehaus.mojo</groupId>
+          <artifactId>animal-sniffer-maven-plugin</artifactId>
+          <executions>
+            <execution>
+              <id>android</id>
+              <goals>
+                <goal>check</goal>
+              </goals>
+              <configuration>
+                <ignores>
+                  <ignore>java.nio.file.*</ignore>
+                </ignores>
+              </configuration>
+            </execution>
+          </executions>
+        </plugin>
       </plugins>
     </pluginManagement>
     <plugins>
diff --git a/google-http-client/src/main/java/com/google/api/client/http/HttpRequest.java b/google-http-client/src/main/java/com/google/api/client/http/HttpRequest.java
index a521c539..0b9b2abb 100644
--- a/google-http-client/src/main/java/com/google/api/client/http/HttpRequest.java
+++ b/google-http-client/src/main/java/com/google/api/client/http/HttpRequest.java
@@ -1224,7 +1224,8 @@ public final class HttpRequest {
     // this value should be read and cached for later use
     String version = "unknown-version";
     try (InputStream inputStream =
-        HttpRequest.class.getResourceAsStream("/google-http-client.properties")) {
+        HttpRequest.class.getResourceAsStream(
+            "/com/google/api/client/http/google-http-client.properties")) {
       if (inputStream != null) {
         final Properties properties = new Properties();
         properties.load(inputStream);
diff --git a/google-http-client/src/main/java/com/google/api/client/http/UrlEncodedContent.java b/google-http-client/src/main/java/com/google/api/client/http/UrlEncodedContent.java
index eb6428b1..ea08b1e1 100644
--- a/google-http-client/src/main/java/com/google/api/client/http/UrlEncodedContent.java
+++ b/google-http-client/src/main/java/com/google/api/client/http/UrlEncodedContent.java
@@ -42,20 +42,43 @@ import java.util.Map;
  *
  * <p>Implementation is not thread-safe.
  *
- * @since 1.0
  * @author Yaniv Inbar
+ * @since 1.0
  */
 public class UrlEncodedContent extends AbstractHttpContent {
 
   /** Key name/value data. */
   private Object data;
 
-  /** @param data key name/value data */
+  /** Use URI Path encoder flag. False by default (use legacy and deprecated escapeUri) */
+  private boolean uriPathEncodingFlag;
+
+  /**
+   * Initialize the UrlEncodedContent with the legacy and deprecated escapeUri encoder
+   *
+   * @param data key name/value data
+   */
   public UrlEncodedContent(Object data) {
     super(UrlEncodedParser.MEDIA_TYPE);
     setData(data);
+    this.uriPathEncodingFlag = false;
   }
 
+  /**
+   * Initialize the UrlEncodedContent with or without the legacy and deprecated escapeUri encoder
+   *
+   * @param data key name/value data
+   * @param useUriPathEncoding escapes the string value so it can be safely included in URI path
+   *     segments. For details on escaping URIs, see <a
+   *     href="http://tools.ietf.org/html/rfc3986#section-2.4">RFC 3986 - section 2.4</a>
+   */
+  public UrlEncodedContent(Object data, boolean useUriPathEncoding) {
+    super(UrlEncodedParser.MEDIA_TYPE);
+    setData(data);
+    this.uriPathEncodingFlag = useUriPathEncoding;
+  }
+
+  @Override
   public void writeTo(OutputStream out) throws IOException {
     Writer writer = new BufferedWriter(new OutputStreamWriter(out, getCharset()));
     boolean first = true;
@@ -66,10 +89,10 @@ public class UrlEncodedContent extends AbstractHttpContent {
         Class<? extends Object> valueClass = value.getClass();
         if (value instanceof Iterable<?> || valueClass.isArray()) {
           for (Object repeatedValue : Types.iterableOf(value)) {
-            first = appendParam(first, writer, name, repeatedValue);
+            first = appendParam(first, writer, name, repeatedValue, this.uriPathEncodingFlag);
           }
         } else {
-          first = appendParam(first, writer, name, value);
+          first = appendParam(first, writer, name, value, this.uriPathEncodingFlag);
         }
       }
     }
@@ -125,7 +148,8 @@ public class UrlEncodedContent extends AbstractHttpContent {
     return result;
   }
 
-  private static boolean appendParam(boolean first, Writer writer, String name, Object value)
+  private static boolean appendParam(
+      boolean first, Writer writer, String name, Object value, boolean uriPathEncodingFlag)
       throws IOException {
     // ignore nulls
     if (value == null || Data.isNull(value)) {
@@ -139,8 +163,13 @@ public class UrlEncodedContent extends AbstractHttpContent {
     }
     writer.write(name);
     String stringValue =
-        CharEscapers.escapeUri(
-            value instanceof Enum<?> ? FieldInfo.of((Enum<?>) value).getName() : value.toString());
+        value instanceof Enum<?> ? FieldInfo.of((Enum<?>) value).getName() : value.toString();
+
+    if (uriPathEncodingFlag) {
+      stringValue = CharEscapers.escapeUriPath(stringValue);
+    } else {
+      stringValue = CharEscapers.escapeUri(stringValue);
+    }
     if (stringValue.length() != 0) {
       writer.write("=");
       writer.write(stringValue);
diff --git a/google-http-client/src/main/java/com/google/api/client/util/store/FileDataStoreFactory.java b/google-http-client/src/main/java/com/google/api/client/util/store/FileDataStoreFactory.java
index a39356ff..5bcab867 100644
--- a/google-http-client/src/main/java/com/google/api/client/util/store/FileDataStoreFactory.java
+++ b/google-http-client/src/main/java/com/google/api/client/util/store/FileDataStoreFactory.java
@@ -45,6 +45,11 @@ import java.util.logging.Logger;
  * <p>For security purposes, the file's permissions are set such that the file is only accessible by
  * the file's owner.
  *
+ * <p>Note: this class is not compatible with Android lower than API level 26 (Oreo). For an
+ * implementation compatible with Android < 26, please use
+ * com.google.api.client.extensions.android.util.store.FileDataStoreFactory which is provided by
+ * com.google.http-client:google-http-client-android.
+ *
  * @since 1.16
  * @author Yaniv Inbar
  */
@@ -61,7 +66,6 @@ public class FileDataStoreFactory extends AbstractDataStoreFactory {
   /** @param dataDirectory data directory */
   public FileDataStoreFactory(File dataDirectory) throws IOException {
     dataDirectory = dataDirectory.getCanonicalFile();
-    this.dataDirectory = dataDirectory;
     // error if it is a symbolic link
     if (IOUtils.isSymbolicLink(dataDirectory)) {
       throw new IOException("unable to use a symbolic link: " + dataDirectory);
@@ -70,6 +74,7 @@ public class FileDataStoreFactory extends AbstractDataStoreFactory {
     if (!dataDirectory.exists() && !dataDirectory.mkdirs()) {
       throw new IOException("unable to create directory: " + dataDirectory);
     }
+    this.dataDirectory = dataDirectory;
 
     if (IS_WINDOWS) {
       setPermissionsToOwnerOnlyWindows(dataDirectory);
diff --git a/pom.xml b/pom.xml
index 173281b7..cc2c2582 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.http-client</groupId>
   <artifactId>google-http-client-parent</artifactId>
-  <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
+  <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
   <packaging>pom</packaging>
   <name>Parent for the Google HTTP Client Library for Java</name>
   <description>Google HTTP Client Library for Java</description>
@@ -118,7 +118,7 @@
       <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
-        <version>4.13</version>
+        <version>4.13.1</version>
       </dependency>
       <dependency>
         <groupId>com.google.truth</groupId>
@@ -339,7 +339,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-checkstyle-plugin</artifactId>
-          <version>3.1.0</version>
+          <version>3.1.1</version>
         </plugin>
         <plugin>
           <groupId>org.codehaus.mojo</groupId>
@@ -359,12 +359,12 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-project-info-reports-plugin</artifactId>
-          <version>3.1.0</version>
+          <version>3.1.1</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-site-plugin</artifactId>
-          <version>3.9.0</version>
+          <version>3.9.1</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
@@ -374,7 +374,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-resources-plugin</artifactId>
-          <version>3.1.0</version>
+          <version>3.2.0</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
@@ -484,8 +484,7 @@
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>clirr-maven-plugin</artifactId>
         <configuration>
-          <comparisonVersion>1.19.0</comparisonVersion>
-          <ignoredDifferencesFile>${basedir}/../clirr-ignored-differences.xml</ignoredDifferencesFile>
+          <ignoredDifferencesFile>clirr-ignored-differences.xml</ignoredDifferencesFile>
           <logResults>true</logResults>
         </configuration>
         <executions>
@@ -499,25 +498,39 @@
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>animal-sniffer-maven-plugin</artifactId>
-        <configuration>
-          <signature>
-            <groupId>org.codehaus.mojo.signature</groupId>
-            <artifactId>java17</artifactId>
-            <version>1.0</version>
-          </signature>
-        </configuration>
         <executions>
           <execution>
+            <id>java7</id>
+            <goals>
+              <goal>check</goal>
+            </goals>
+            <configuration>
+              <signature>
+                <groupId>org.codehaus.mojo.signature</groupId>
+                <artifactId>java17</artifactId>
+                <version>1.0</version>
+              </signature>
+            </configuration>
+          </execution>
+          <execution>
+            <id>android</id>
             <goals>
               <goal>check</goal>
             </goals>
+            <configuration>
+              <signature>
+                <groupId>net.sf.androidscents.signature</groupId>
+                <artifactId>android-api-level-19</artifactId>
+                <version>4.4.2_r4</version>
+              </signature>
+            </configuration>
           </execution>
         </executions>
       </plugin>
       <!-- Build the dependencies report at package time (needed for the assembly artifact). -->
       <plugin>
         <artifactId>maven-project-info-reports-plugin</artifactId>
-        <version>3.1.0</version>
+        <version>3.1.1</version>
         <executions>
           <execution>
             <goals>
@@ -560,17 +573,17 @@
       - google-api-java-client/google-api-client-assembly/android-properties (make the filenames match the version here)
       - Internally, update the default features.json file
     -->
-    <project.http-client.version>1.35.1-SNAPSHOT</project.http-client.version><!-- {x-version-update:google-http-client-parent:current} -->
+    <project.http-client.version>1.36.1-SNAPSHOT</project.http-client.version><!-- {x-version-update:google-http-client-parent:current} -->
     <project.appengine.version>1.9.71</project.appengine.version>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <project.jsr305.version>3.0.2</project.jsr305.version>
     <project.gson.version>2.8.6</project.gson.version>
-    <project.jackson-core2.version>2.11.0</project.jackson-core2.version>
-    <project.protobuf-java.version>3.12.2</project.protobuf-java.version>
+    <project.jackson-core2.version>2.11.3</project.jackson-core2.version>
+    <project.protobuf-java.version>3.13.0</project.protobuf-java.version>
     <project.guava.version>29.0-android</project.guava.version>
     <project.xpp3.version>1.1.4c</project.xpp3.version>
     <project.commons-logging.version>1.2</project.commons-logging.version>
-    <project.httpclient.version>4.5.12</project.httpclient.version>
+    <project.httpclient.version>4.5.13</project.httpclient.version>
     <project.httpcore.version>4.4.13</project.httpcore.version>
     <project.opencensus.version>0.24.0</project.opencensus.version>
     <project.root-directory>..</project.root-directory>
diff --git a/samples/dailymotion-simple-cmdline-sample/pom.xml b/samples/dailymotion-simple-cmdline-sample/pom.xml
index b8458eb5..48af1b95 100644
--- a/samples/dailymotion-simple-cmdline-sample/pom.xml
+++ b/samples/dailymotion-simple-cmdline-sample/pom.xml
@@ -4,7 +4,7 @@
   <parent>
     <groupId>com.google.http-client</groupId>
     <artifactId>google-http-client-parent</artifactId>
-    <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
+    <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <artifactId>dailymotion-simple-cmdline-sample</artifactId>
@@ -15,7 +15,7 @@
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>exec-maven-plugin</artifactId>
-        <version>1.6.0</version>
+        <version>3.0.0</version>
         <executions>
           <execution>
             <goals>
diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml
index 86d1a433..4074dc1c 100644
--- a/samples/install-without-bom/pom.xml
+++ b/samples/install-without-bom/pom.xml
@@ -14,7 +14,7 @@
   <parent>
     <groupId>com.google.cloud.samples</groupId>
     <artifactId>shared-configuration</artifactId>
-    <version>1.0.18</version>
+    <version>1.0.21</version>
   </parent>
 
   <properties>
@@ -36,7 +36,7 @@
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
-      <version>4.13</version>
+      <version>4.13.1</version>
       <scope>test</scope>
     </dependency>
     <dependency>
@@ -53,7 +53,7 @@
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>build-helper-maven-plugin</artifactId>
-        <version>3.1.0</version>
+        <version>3.2.0</version>
         <executions>
           <execution>
             <id>add-snippets-source</id>
diff --git a/samples/pom.xml b/samples/pom.xml
index b59d3cdf..823a7090 100644
--- a/samples/pom.xml
+++ b/samples/pom.xml
@@ -18,7 +18,7 @@
   <parent>
     <groupId>com.google.cloud.samples</groupId>
     <artifactId>shared-configuration</artifactId>
-    <version>1.0.18</version>
+    <version>1.0.21</version>
   </parent>
 
   <properties>
diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml
index bc295f22..4ce2f9b5 100644
--- a/samples/snapshot/pom.xml
+++ b/samples/snapshot/pom.xml
@@ -14,7 +14,7 @@
   <parent>
     <groupId>com.google.cloud.samples</groupId>
     <artifactId>shared-configuration</artifactId>
-    <version>1.0.18</version>
+    <version>1.0.21</version>
   </parent>
 
   <properties>
@@ -34,7 +34,7 @@
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
-      <version>4.13</version>
+      <version>4.13.1</version>
       <scope>test</scope>
     </dependency>
     <dependency>
@@ -52,7 +52,7 @@
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>build-helper-maven-plugin</artifactId>
-        <version>3.1.0</version>
+        <version>3.2.0</version>
         <executions>
           <execution>
             <id>add-snippets-source</id>
diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml
index 5e300f9a..db858e9e 100644
--- a/samples/snippets/pom.xml
+++ b/samples/snippets/pom.xml
@@ -14,7 +14,7 @@
   <parent>
     <groupId>com.google.cloud.samples</groupId>
     <artifactId>shared-configuration</artifactId>
-    <version>1.0.18</version>
+    <version>1.0.21</version>
   </parent>
 
   <properties>
@@ -24,13 +24,13 @@
   </properties>
 
 
-  <!-- [START google-http-client_install_with_bom] -->
+  <!-- [START google_http_client_install_with_bom] -->
   <dependencyManagement>
     <dependencies>
       <dependency>
         <groupId>com.google.cloud</groupId>
         <artifactId>libraries-bom</artifactId>
-        <version></version>
+        <version>12.0.0</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
@@ -42,12 +42,16 @@
       <groupId>com.google.http-client</groupId>
       <artifactId>google-http-client</artifactId>
     </dependency>
-    <!-- [END google-http-client_install_with_bom] -->
-
+    <!-- START_EXCLUDE -->
+    <dependency>
+      <groupId>com.google.http-client</groupId>
+      <artifactId>google-http-client-gson</artifactId>
+      <scope>test</scope>
+    </dependency>
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
-      <version>4.13</version>
+      <version>4.13.1</version>
       <scope>test</scope>
     </dependency>
     <dependency>
@@ -56,5 +60,13 @@
       <version>1.0.1</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>com.google.http-client</groupId>
+      <artifactId>google-http-client-gson</artifactId>
+      <version>1.36.0</version>
+      <scope>test</scope>
+    </dependency>
+    <!-- END_EXCLUDE -->
   </dependencies>
+  <!-- [END google_http_client_install_with_bom] -->
 </project>
diff --git a/samples/snippets/src/main/java/com/example/json/YouTubeSample.java b/samples/snippets/src/main/java/com/example/json/YouTubeSample.java
new file mode 100644
index 00000000..6aff2789
--- /dev/null
+++ b/samples/snippets/src/main/java/com/example/json/YouTubeSample.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * 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
+ *
+ *    https://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.example.json;
+
+import com.google.api.client.http.HttpResponse;
+import com.google.api.client.util.Key;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+public class YouTubeSample {
+  public static class ListResponse {
+    @Key("items")
+    private List<SearchResult> searchResults;
+
+    @Key
+    private PageInfo pageInfo;
+
+    public List<SearchResult> getSearchResults() {
+      return searchResults;
+    }
+
+    public PageInfo getPageInfo() {
+      return pageInfo;
+    }
+  }
+
+  public static class PageInfo {
+    @Key
+    private long totalResults;
+
+    @Key
+    private long resultsPerPage;
+
+    public long getTotalResults() {
+      return totalResults;
+    }
+
+    public long getResultsPerPage() {
+      return resultsPerPage;
+    }
+  }
+
+  public static class SearchResult {
+    @Key
+    private String kind;
+
+    @Key("id")
+    private VideoId videoId;
+
+    @Key
+    private Snippet snippet;
+
+    public String getKind() {
+      return kind;
+    }
+
+    public VideoId getId() {
+      return videoId;
+    }
+
+    public Snippet getSnippet() {
+      return snippet;
+    }
+  }
+
+  public static class VideoId {
+    @Key
+    private String kind;
+
+    @Key
+    private String videoId;
+
+    public String getKind() {
+      return kind;
+    }
+
+    public String getVideoId() {
+      return videoId;
+    }
+  }
+
+  public static class Snippet {
+    @Key
+    private String publishedAt;
+
+    @Key
+    private String channelId;
+
+    @Key
+    private String title;
+
+    @Key
+    private String description;
+
+    @Key
+    private Map<String, Thumbnail> thumbnails;
+
+    public String getPublishedAt() {
+      return publishedAt;
+    }
+
+    public String getChannelId() {
+      return channelId;
+    }
+
+    public String getTitle() {
+      return title;
+    }
+
+    public String getDescription() {
+      return description;
+    }
+
+    public Map<String, Thumbnail> getThumbnails() {
+      return thumbnails;
+    }
+  }
+
+  public static class Thumbnail {
+    @Key
+    private String url;
+
+    @Key
+    private long width;
+
+    @Key
+    private long height;
+
+    public String getUrl() {
+      return url;
+    }
+
+    public long getWidth() {
+      return width;
+    }
+
+    public long getHeight() {
+      return height;
+    }
+  }
+
+  public static ListResponse parseJson(HttpResponse httpResponse) throws IOException {
+    ListResponse listResponse = httpResponse.parseAs(ListResponse.class);
+    if (listResponse.getSearchResults().isEmpty()) {
+      System.out.println("No results found.");
+    } else {
+      for (SearchResult searchResult : listResponse.getSearchResults()) {
+        System.out.println();
+        System.out.println("-----------------------------------------------");
+        System.out.println("Kind: " + searchResult.getKind());
+        System.out.println("Video ID: " + searchResult.getId().getVideoId());
+        System.out.println("Title: " + searchResult.getSnippet().getTitle());
+        System.out.println("Description: " + searchResult.getSnippet().getDescription());
+      }
+    }
+    return listResponse;
+  }
+
+}
\ No newline at end of file
diff --git a/samples/snippets/src/main/resources/youtube-search.json b/samples/snippets/src/main/resources/youtube-search.json
new file mode 100644
index 00000000..a0fc438e
--- /dev/null
+++ b/samples/snippets/src/main/resources/youtube-search.json
@@ -0,0 +1,182 @@
+{
+  "kind": "youtube#searchListResponse",
+  "etag": "XvAmSt9muXVVpoDkmSHjDBBqm48",
+  "nextPageToken": "CAUQAA",
+  "regionCode": "US",
+  "pageInfo": {
+    "totalResults": 1000000,
+    "resultsPerPage": 5
+  },
+  "items": [
+    {
+      "kind": "youtube#searchResult",
+      "etag": "GVJEEWhNeZhHT8jtdV-r370b0AE",
+      "id": {
+        "kind": "youtube#video",
+        "videoId": "e6Tudp5lqt8"
+      },
+      "snippet": {
+        "publishedAt": "2020-06-25T23:18:43Z",
+        "channelId": "UCKwGZZMrhNYKzucCtTPY2Nw",
+        "title": "Title 1",
+        "description": "Description 1",
+        "thumbnails": {
+          "default": {
+            "url": "https://i.ytimg.com/vi/e6Tudp5lqt8/default.jpg",
+            "width": 120,
+            "height": 90
+          },
+          "medium": {
+            "url": "https://i.ytimg.com/vi/e6Tudp5lqt8/mqdefault.jpg",
+            "width": 320,
+            "height": 180
+          },
+          "high": {
+            "url": "https://i.ytimg.com/vi/e6Tudp5lqt8/hqdefault.jpg",
+            "width": 480,
+            "height": 360
+          }
+        },
+        "channelTitle": "Some Channel Title",
+        "liveBroadcastContent": "none",
+        "publishTime": "2020-06-25T23:18:43Z"
+      }
+    },
+    {
+      "kind": "youtube#searchResult",
+      "etag": "abDpn5ZXHCPTAHJUXYDZoDdVGKk",
+      "id": {
+        "kind": "youtube#video",
+        "videoId": "o-NtLpiMpw0"
+      },
+      "snippet": {
+        "publishedAt": "2020-06-25T17:28:52Z",
+        "channelId": "UClljAz6ZKy0XeViKsohdjqA",
+        "title": "Title 2",
+        "description": "Description 2",
+        "thumbnails": {
+          "default": {
+            "url": "https://i.ytimg.com/vi/o-NtLpiMpw0/default.jpg",
+            "width": 120,
+            "height": 90
+          },
+          "medium": {
+            "url": "https://i.ytimg.com/vi/o-NtLpiMpw0/mqdefault.jpg",
+            "width": 320,
+            "height": 180
+          },
+          "high": {
+            "url": "https://i.ytimg.com/vi/o-NtLpiMpw0/hqdefault.jpg",
+            "width": 480,
+            "height": 360
+          }
+        },
+        "channelTitle": "Some Channel Title",
+        "liveBroadcastContent": "none",
+        "publishTime": "2020-06-25T17:28:52Z"
+      }
+    },
+    {
+      "kind": "youtube#searchResult",
+      "etag": "u9pCK3-1ucRi_fZM9VAI22-xekY",
+      "id": {
+        "kind": "youtube#video",
+        "videoId": "TPAahzXZFZo"
+      },
+      "snippet": {
+        "publishedAt": "2020-06-26T15:45:00Z",
+        "channelId": "UCR4Yfr8HAZJd9X24dwuAt1Q",
+        "title": "Title 3",
+        "description": "Description 3",
+        "thumbnails": {
+          "default": {
+            "url": "https://i.ytimg.com/vi/TPAahzXZFZo/default.jpg",
+            "width": 120,
+            "height": 90
+          },
+          "medium": {
+            "url": "https://i.ytimg.com/vi/TPAahzXZFZo/mqdefault.jpg",
+            "width": 320,
+            "height": 180
+          },
+          "high": {
+            "url": "https://i.ytimg.com/vi/TPAahzXZFZo/hqdefault.jpg",
+            "width": 480,
+            "height": 360
+          }
+        },
+        "channelTitle": "Some Channel Title",
+        "liveBroadcastContent": "none",
+        "publishTime": "2020-06-26T15:45:00Z"
+      }
+    },
+    {
+      "kind": "youtube#searchResult",
+      "etag": "9SRI9WYkKwiaA8dLxuQ7Bs5d4TI",
+      "id": {
+        "kind": "youtube#video",
+        "videoId": "gBL-AelsdFk"
+      },
+      "snippet": {
+        "publishedAt": "2020-06-24T15:24:06Z",
+        "channelId": "UCFHZHhZaH7Rc_FOMIzUziJA",
+        "title": "Title 4",
+        "description": "Description 4",
+        "thumbnails": {
+          "default": {
+            "url": "https://i.ytimg.com/vi/gBL-AelsdFk/default.jpg",
+            "width": 120,
+            "height": 90
+          },
+          "medium": {
+            "url": "https://i.ytimg.com/vi/gBL-AelsdFk/mqdefault.jpg",
+            "width": 320,
+            "height": 180
+          },
+          "high": {
+            "url": "https://i.ytimg.com/vi/gBL-AelsdFk/hqdefault.jpg",
+            "width": 480,
+            "height": 360
+          }
+        },
+        "channelTitle": "Some Channel Title",
+        "liveBroadcastContent": "none",
+        "publishTime": "2020-06-24T15:24:06Z"
+      }
+    },
+    {
+      "kind": "youtube#searchResult",
+      "etag": "XQCpyLsFVEHMSpJPLK5hxhFnMks",
+      "id": {
+        "kind": "youtube#video",
+        "videoId": "9ofe8axKjH0"
+      },
+      "snippet": {
+        "publishedAt": "2020-06-26T11:59:32Z",
+        "channelId": "UCtNpbO2MtsVY4qW23WfnxGg",
+        "title": "Title 5",
+        "description": "Description 5",
+        "thumbnails": {
+          "default": {
+            "url": "https://i.ytimg.com/vi/9ofe8axKjH0/default.jpg",
+            "width": 120,
+            "height": 90
+          },
+          "medium": {
+            "url": "https://i.ytimg.com/vi/9ofe8axKjH0/mqdefault.jpg",
+            "width": 320,
+            "height": 180
+          },
+          "high": {
+            "url": "https://i.ytimg.com/vi/9ofe8axKjH0/hqdefault.jpg",
+            "width": 480,
+            "height": 360
+          }
+        },
+        "channelTitle": "Some Channel Title",
+        "liveBroadcastContent": "none",
+        "publishTime": "2020-06-26T11:59:32Z"
+      }
+    }
+  ]
+}
diff --git a/synth.metadata b/synth.metadata
index 630a31ec..4929ab96 100644
--- a/synth.metadata
+++ b/synth.metadata
@@ -4,15 +4,82 @@
       "git": {
         "name": ".",
         "remote": "https://github.com/googleapis/google-http-java-client.git",
-        "sha": "1624d55f9864ff1253321e9bfe715e2f370cc27e"
+        "sha": "fe73acdd345ae3a2d7f214bec0058a6c0a122a7d"
       }
     },
     {
       "git": {
         "name": "synthtool",
         "remote": "https://github.com/googleapis/synthtool.git",
-        "sha": "98c50772ec23295c64cf0d2ddf199ea52961fd4c"
+        "sha": "0762e8ee2ec21cdfc4d82020b985a104feb0453b"
       }
     }
+  ],
+  "generatedFiles": [
+    ".github/CODEOWNERS",
+    ".github/ISSUE_TEMPLATE/bug_report.md",
+    ".github/ISSUE_TEMPLATE/feature_request.md",
+    ".github/ISSUE_TEMPLATE/support_request.md",
+    ".github/PULL_REQUEST_TEMPLATE.md",
+    ".github/readme/synth.py",
+    ".github/release-please.yml",
+    ".github/trusted-contribution.yml",
+    ".github/workflows/auto-release.yaml",
+    ".github/workflows/ci.yaml",
+    ".github/workflows/samples.yaml",
+    ".kokoro/build.bat",
+    ".kokoro/build.sh",
+    ".kokoro/coerce_logs.sh",
+    ".kokoro/common.cfg",
+    ".kokoro/common.sh",
+    ".kokoro/continuous/common.cfg",
+    ".kokoro/continuous/java8.cfg",
+    ".kokoro/continuous/readme.cfg",
+    ".kokoro/dependencies.sh",
+    ".kokoro/linkage-monitor.sh",
+    ".kokoro/nightly/common.cfg",
+    ".kokoro/nightly/integration.cfg",
+    ".kokoro/nightly/java11.cfg",
+    ".kokoro/nightly/java7.cfg",
+    ".kokoro/nightly/java8-osx.cfg",
+    ".kokoro/nightly/java8-win.cfg",
+    ".kokoro/nightly/java8.cfg",
+    ".kokoro/nightly/samples.cfg",
+    ".kokoro/populate-secrets.sh",
+    ".kokoro/presubmit/clirr.cfg",
+    ".kokoro/presubmit/common.cfg",
+    ".kokoro/presubmit/dependencies.cfg",
+    ".kokoro/presubmit/integration.cfg",
+    ".kokoro/presubmit/java11.cfg",
+    ".kokoro/presubmit/java7.cfg",
+    ".kokoro/presubmit/java8-osx.cfg",
+    ".kokoro/presubmit/java8-win.cfg",
+    ".kokoro/presubmit/java8.cfg",
+    ".kokoro/presubmit/linkage-monitor.cfg",
+    ".kokoro/presubmit/lint.cfg",
+    ".kokoro/presubmit/samples.cfg",
+    ".kokoro/readme.sh",
+    ".kokoro/release/bump_snapshot.cfg",
+    ".kokoro/release/common.cfg",
+    ".kokoro/release/common.sh",
+    ".kokoro/release/drop.cfg",
+    ".kokoro/release/drop.sh",
+    ".kokoro/release/promote.cfg",
+    ".kokoro/release/promote.sh",
+    ".kokoro/release/publish_javadoc.cfg",
+    ".kokoro/release/publish_javadoc.sh",
+    ".kokoro/release/snapshot.cfg",
+    ".kokoro/release/snapshot.sh",
+    ".kokoro/release/stage.cfg",
+    ".kokoro/release/stage.sh",
+    ".kokoro/trampoline.sh",
+    "CODE_OF_CONDUCT.md",
+    "CONTRIBUTING.md",
+    "LICENSE",
+    "codecov.yaml",
+    "samples/install-without-bom/pom.xml",
+    "samples/pom.xml",
+    "samples/snapshot/pom.xml",
+    "samples/snippets/pom.xml"
   ]
 }
\ No newline at end of file
diff --git a/synth.py b/synth.py
index 9ed5d748..a22e87e0 100644
--- a/synth.py
+++ b/synth.py
@@ -12,14 +12,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 """This script is used to synthesize generated parts of this library."""
-import synthtool as s
-import synthtool.gcp as gcp
-import logging
 
-logging.basicConfig(level=logging.DEBUG)
-common_templates = gcp.CommonTemplates()
-templates = common_templates.java_library()
-s.copy(templates, excludes=[
+import synthtool.languages.java as java
+
+java.common_templates(excludes=[
     "README.md",
     "java.header",
     "checkstyle.xml",
diff --git a/versions.txt b/versions.txt
index d23765fd..dad7dca8 100644
--- a/versions.txt
+++ b/versions.txt
@@ -1,17 +1,17 @@
 # Format:
 # module:released-version:current-version
 
-google-http-client:1.35.0:1.35.1-SNAPSHOT
-google-http-client-bom:1.35.0:1.35.1-SNAPSHOT
-google-http-client-parent:1.35.0:1.35.1-SNAPSHOT
-google-http-client-android:1.35.0:1.35.1-SNAPSHOT
-google-http-client-android-test:1.35.0:1.35.1-SNAPSHOT
-google-http-client-apache-v2:1.35.0:1.35.1-SNAPSHOT
-google-http-client-appengine:1.35.0:1.35.1-SNAPSHOT
-google-http-client-assembly:1.35.0:1.35.1-SNAPSHOT
-google-http-client-findbugs:1.35.0:1.35.1-SNAPSHOT
-google-http-client-gson:1.35.0:1.35.1-SNAPSHOT
-google-http-client-jackson2:1.35.0:1.35.1-SNAPSHOT
-google-http-client-protobuf:1.35.0:1.35.1-SNAPSHOT
-google-http-client-test:1.35.0:1.35.1-SNAPSHOT
-google-http-client-xml:1.35.0:1.35.1-SNAPSHOT
+google-http-client:1.36.0:1.36.1-SNAPSHOT
+google-http-client-bom:1.36.0:1.36.1-SNAPSHOT
+google-http-client-parent:1.36.0:1.36.1-SNAPSHOT
+google-http-client-android:1.36.0:1.36.1-SNAPSHOT
+google-http-client-android-test:1.36.0:1.36.1-SNAPSHOT
+google-http-client-apache-v2:1.36.0:1.36.1-SNAPSHOT
+google-http-client-appengine:1.36.0:1.36.1-SNAPSHOT
+google-http-client-assembly:1.36.0:1.36.1-SNAPSHOT
+google-http-client-findbugs:1.36.0:1.36.1-SNAPSHOT
+google-http-client-gson:1.36.0:1.36.1-SNAPSHOT
+google-http-client-jackson2:1.36.0:1.36.1-SNAPSHOT
+google-http-client-protobuf:1.36.0:1.36.1-SNAPSHOT
+google-http-client-test:1.36.0:1.36.1-SNAPSHOT
+google-http-client-xml:1.36.0:1.36.1-SNAPSHOT


Test patch:
diff --git a/google-http-client-android-test/pom.xml b/google-http-client-android-test/pom.xml
index 0bbaadcf..4eeddb4b 100644
--- a/google-http-client-android-test/pom.xml
+++ b/google-http-client-android-test/pom.xml
@@ -4,7 +4,7 @@
   <groupId>google-http-client</groupId>
   <artifactId>google-http-client-android-test</artifactId>
   <name>Test project for google-http-client-android.</name>
-  <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-android-test:current} -->
+  <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-android-test:current} -->
   <packaging>apk</packaging>
 
   <build>
@@ -53,7 +53,7 @@
     <dependency>
       <groupId>com.google.http-client</groupId>
       <artifactId>google-http-client-android</artifactId>
-      <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-android:current} -->
+      <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-android:current} -->
       <exclusions>
         <exclusion>
           <artifactId>android</artifactId>
@@ -72,7 +72,7 @@
     <dependency>
       <groupId>com.google.http-client</groupId>
       <artifactId>google-http-client-test</artifactId>
-      <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-test:current} -->
+      <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-test:current} -->
       <exclusions>
         <exclusion>
           <artifactId>junit</artifactId>
diff --git a/google-http-client-test/pom.xml b/google-http-client-test/pom.xml
index 5bc5d32f..3d1a522e 100644
--- a/google-http-client-test/pom.xml
+++ b/google-http-client-test/pom.xml
@@ -4,11 +4,11 @@
   <parent>
     <groupId>com.google.http-client</groupId>
     <artifactId>google-http-client-parent</artifactId>
-    <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
+    <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
     <relativePath>../pom.xml</relativePath>
   </parent>
   <artifactId>google-http-client-test</artifactId>
-  <version>1.35.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-test:current} -->
+  <version>1.36.1-SNAPSHOT</version><!-- {x-version-update:google-http-client-test:current} -->
   <name>Shared classes used for testing of artifacts in the Google HTTP Client Library for Java.</name>
 
   <build>
@@ -38,7 +38,7 @@
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>build-helper-maven-plugin</artifactId>
-        <version>3.1.0</version>
+        <version>3.2.0</version>
         <executions>
           <execution>
             <id>add-test-source</id>
diff --git a/google-http-client/src/main/resources/google-http-client.properties b/google-http-client/src/main/resources/com/google/api/client/http/google-http-client.properties
similarity index 100%
rename from google-http-client/src/main/resources/google-http-client.properties
rename to google-http-client/src/main/resources/com/google/api/client/http/google-http-client.properties
diff --git a/google-http-client/src/test/java/com/google/api/client/http/UrlEncodedContentTest.java b/google-http-client/src/test/java/com/google/api/client/http/UrlEncodedContentTest.java
index f0e0768a..059d9e2c 100644
--- a/google-http-client/src/test/java/com/google/api/client/http/UrlEncodedContentTest.java
+++ b/google-http-client/src/test/java/com/google/api/client/http/UrlEncodedContentTest.java
@@ -33,19 +33,32 @@ import junit.framework.TestCase;
 public class UrlEncodedContentTest extends TestCase {
 
   public void testWriteTo() throws IOException {
-    subtestWriteTo("a=x", ArrayMap.of("a", "x"));
-    subtestWriteTo("noval", ArrayMap.of("noval", ""));
-    subtestWriteTo("multi=a&multi=b&multi=c", ArrayMap.of("multi", Arrays.asList("a", "b", "c")));
-    subtestWriteTo("multi=a&multi=b&multi=c", ArrayMap.of("multi", new String[] {"a", "b", "c"}));
+    subtestWriteTo("a=x", ArrayMap.of("a", "x"), false);
+    subtestWriteTo("noval", ArrayMap.of("noval", ""), false);
+    subtestWriteTo(
+        "multi=a&multi=b&multi=c", ArrayMap.of("multi", Arrays.asList("a", "b", "c")), false);
+    subtestWriteTo(
+        "multi=a&multi=b&multi=c", ArrayMap.of("multi", new String[] {"a", "b", "c"}), false);
     // https://github.com/googleapis/google-http-java-client/issues/202
     final Map<String, String> params = new LinkedHashMap<String, String>();
     params.put("username", "un");
     params.put("password", "password123;{}");
-    subtestWriteTo("username=un&password=password123%3B%7B%7D", params);
+    subtestWriteTo("username=un&password=password123%3B%7B%7D", params, false);
+    subtestWriteTo("additionkey=add%2Btion", ArrayMap.of("additionkey", "add+tion"), false);
+
+    subtestWriteTo("a=x", ArrayMap.of("a", "x"), true);
+    subtestWriteTo("noval", ArrayMap.of("noval", ""), true);
+    subtestWriteTo(
+        "multi=a&multi=b&multi=c", ArrayMap.of("multi", Arrays.asList("a", "b", "c")), true);
+    subtestWriteTo(
+        "multi=a&multi=b&multi=c", ArrayMap.of("multi", new String[] {"a", "b", "c"}), true);
+    subtestWriteTo("username=un&password=password123;%7B%7D", params, true);
+    subtestWriteTo("additionkey=add+tion", ArrayMap.of("additionkey", "add+tion"), true);
   }
 
-  private void subtestWriteTo(String expected, Object data) throws IOException {
-    UrlEncodedContent content = new UrlEncodedContent(data);
+  private void subtestWriteTo(String expected, Object data, boolean useEscapeUriPathEncoding)
+      throws IOException {
+    UrlEncodedContent content = new UrlEncodedContent(data, useEscapeUriPathEncoding);
     ByteArrayOutputStream out = new ByteArrayOutputStream();
     content.writeTo(out);
     assertEquals(expected, out.toString());
diff --git a/samples/snippets/src/test/java/com/example/json/YouTubeSampleTest.java b/samples/snippets/src/test/java/com/example/json/YouTubeSampleTest.java
new file mode 100644
index 00000000..b4bbf6c8
--- /dev/null
+++ b/samples/snippets/src/test/java/com/example/json/YouTubeSampleTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * 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
+ *
+ *    https://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.example.json;
+
+import com.google.api.client.http.HttpRequest;
+import com.google.api.client.http.HttpResponse;
+import com.google.api.client.http.HttpTransport;
+import com.google.api.client.http.LowLevelHttpRequest;
+import com.google.api.client.http.LowLevelHttpResponse;
+import com.google.api.client.json.Json;
+import com.google.api.client.json.JsonObjectParser;
+import com.google.api.client.json.gson.GsonFactory;
+import com.google.api.client.testing.http.HttpTesting;
+import com.google.api.client.testing.http.MockHttpTransport;
+import com.google.api.client.testing.http.MockLowLevelHttpRequest;
+import com.google.api.client.testing.http.MockLowLevelHttpResponse;
+import com.google.common.base.Preconditions;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class YouTubeSampleTest {
+
+  @Test
+  public void testParsing() throws IOException {
+    final InputStream contents = getClass().getClassLoader().getResourceAsStream("youtube-search.json");
+    Preconditions.checkNotNull(contents);
+    HttpTransport transport =
+        new MockHttpTransport() {
+          @Override
+          public LowLevelHttpRequest buildRequest(String method, String url) throws IOException {
+            return new MockLowLevelHttpRequest() {
+              @Override
+              public LowLevelHttpResponse execute() throws IOException {
+                MockLowLevelHttpResponse result = new MockLowLevelHttpResponse();
+                result.setContentType(Json.MEDIA_TYPE);
+                result.setContent(contents);
+                return result;
+              }
+            };
+          }
+        };
+    HttpRequest request =
+        transport.createRequestFactory().buildGetRequest(HttpTesting.SIMPLE_GENERIC_URL);
+    request.setParser(new JsonObjectParser(new GsonFactory()));
+    HttpResponse response = request.execute();
+
+    YouTubeSample.ListResponse listResponse = YouTubeSample.parseJson(response);
+    assertEquals(5, listResponse.getPageInfo().getResultsPerPage());
+    assertEquals(1000000, listResponse.getPageInfo().getTotalResults());
+    assertEquals(5, listResponse.getSearchResults().size());
+    for (YouTubeSample.SearchResult searchResult : listResponse.getSearchResults()) {
+      assertEquals("youtube#searchResult", searchResult.getKind());
+      assertNotNull(searchResult.getId());
+      assertEquals("youtube#video", searchResult.getId().getKind());
+      assertNotNull(searchResult.getId().getVideoId());
+      YouTubeSample.Snippet snippet = searchResult.getSnippet();
+      assertNotNull(snippet);
+      assertNotNull(snippet.getChannelId());
+      assertNotNull(snippet.getDescription());
+      assertNotNull(snippet.getTitle());
+      assertNotNull(snippet.getPublishedAt());
+      Map<String, YouTubeSample.Thumbnail> thumbnails = snippet.getThumbnails();
+      assertNotNull(thumbnails);
+
+      for (Map.Entry<String, YouTubeSample.Thumbnail> entry : thumbnails.entrySet()) {
+        assertNotNull(entry.getKey());
+        YouTubeSample.Thumbnail thumbnail = entry.getValue();
+        assertNotNull(thumbnail);
+        assertNotNull(thumbnail.getUrl());
+        assertNotNull(thumbnail.getWidth());
+        assertNotNull(thumbnail.getHeight());
+      }
+    }
+  }
+}
\ No newline at end of file