Merge remote-tracking branch 'upstream/master'
diff --git a/.gitignore b/.gitignore
index 0b85d39..a7ca0e2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -145,7 +145,9 @@
 php/ext/google/protobuf/acinclude.m4
 php/ext/google/protobuf/build/
 php/ext/google/protobuf/config.h
+php/ext/google/protobuf/config.h.in~
 php/ext/google/protobuf/config.nice
+php/ext/google/protobuf/configure.ac
 php/ext/google/protobuf/configure.in
 php/ext/google/protobuf/mkinstalldirs
 php/ext/google/protobuf/run-tests.php
diff --git a/BUILD b/BUILD
index eb8077a..253bc3e 100644
--- a/BUILD
+++ b/BUILD
@@ -514,7 +514,6 @@
         "src/google/protobuf/arena_unittest.cc",
         "src/google/protobuf/arenastring_unittest.cc",
         "src/google/protobuf/compiler/annotation_test_util.cc",
-        "src/google/protobuf/compiler/command_line_interface_unittest.cc",
         "src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc",
         "src/google/protobuf/compiler/cpp/cpp_move_unittest.cc",
         "src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc",
@@ -583,7 +582,13 @@
         "src/google/protobuf/util/type_resolver_util_test.cc",
         "src/google/protobuf/well_known_types_unittest.cc",
         "src/google/protobuf/wire_format_unittest.cc",
-    ],
+    ] + select({
+        "//conditions:default" : [
+            # Doesn't pass on Windows with MSVC
+            "src/google/protobuf/compiler/command_line_interface_unittest.cc",
+        ],
+        ":msvc": []
+    }),
     copts = COPTS,
     data = [
         ":test_plugin",
diff --git a/benchmarks/php/PhpBenchmark.php b/benchmarks/php/PhpBenchmark.php
index 9c1132d..7220638 100644
--- a/benchmarks/php/PhpBenchmark.php
+++ b/benchmarks/php/PhpBenchmark.php
@@ -62,7 +62,7 @@
         $t = $this->runBenchmarkWithTimes(1);
         $times = ceil($this->benchmark_time / $t);
         return $this->total_bytes * $times /
-        $this->runBenchmarkWithTimes($times) *
+        ($times == 1 ? $t : $this->runBenchmarkWithTimes($times)) *
         $this->coefficient;
     }
     
diff --git a/benchmarks/python/py_benchmark.py b/benchmarks/python/py_benchmark.py
index ebb1974..40c7af5 100755
--- a/benchmarks/python/py_benchmark.py
+++ b/benchmarks/python/py_benchmark.py
@@ -134,9 +134,10 @@
     t = self.dry_run(test_method_args, setup_method_args);
     if t < 3 :
       reps = int(math.ceil(3 / t)) * self.full_iteration
-    t = timeit.timeit(stmt="%s(%s)" % (self.test_method, test_method_args),
-                      setup=self.full_setup_code(setup_method_args),
-                      number=reps);
+    if reps != self.full_iteration:
+        t = timeit.timeit(stmt="%s(%s)" % (self.test_method, test_method_args),
+                          setup=self.full_setup_code(setup_method_args),
+                          number=reps);
     return self.total_bytes * 1.0 / 2 ** 20 / (1.0 * t / reps)
   
 
diff --git a/benchmarks/util/result_uploader.py b/benchmarks/util/result_uploader.py
index cff2d9d..021cc54 100755
--- a/benchmarks/util/result_uploader.py
+++ b/benchmarks/util/result_uploader.py
@@ -61,12 +61,12 @@
     new_result["timestamp"] = _INITIAL_TIME
     print(labels_string)
  
-     bq = big_query_utils.create_big_query()
-     row = big_query_utils.make_row(str(uuid.uuid4()), new_result)
-     if not big_query_utils.insert_rows(bq, _PROJECT_ID, _DATASET,
+    bq = big_query_utils.create_big_query()
+    row = big_query_utils.make_row(str(uuid.uuid4()), new_result)
+    if not big_query_utils.insert_rows(bq, _PROJECT_ID, _DATASET,
                                         _TABLE + "$" + _NOW,
                                         [row]):
-       print('Error when uploading result', new_result)
+      print('Error when uploading result', new_result)
 
 
 if __name__ == "__main__":
diff --git a/kokoro/linux/32-bit/build.sh b/kokoro/linux/32-bit/build.sh
index 04383a57..8c0a41e 100755
--- a/kokoro/linux/32-bit/build.sh
+++ b/kokoro/linux/32-bit/build.sh
@@ -10,7 +10,8 @@
 # Change to repo root
 cd $(dirname $0)/../../..
 
-export DOCKERFILE_DIR=kokoro/linux/32-bit
+export DOCKERHUB_ORGANIZATION=protobuftesting
+export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/php_32bit
 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
 export OUTPUT_DIR=testoutput
 export TEST_SET="php_all_32"
diff --git a/kokoro/linux/64-bit/presubmit.cfg b/kokoro/linux/64-bit/presubmit.cfg
deleted file mode 100644
index 3a4faac..0000000
--- a/kokoro/linux/64-bit/presubmit.cfg
+++ /dev/null
@@ -1,11 +0,0 @@
-# Config file for running tests in Kokoro
-
-# Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
-timeout_mins: 120
-
-action {
-  define_artifacts {
-    regex: "**/sponge_log.xml"
-  }
-}
diff --git a/kokoro/linux/benchmark/build.sh b/kokoro/linux/benchmark/build.sh
old mode 100755
new mode 100644
index d832753..bec52b8
--- a/kokoro/linux/benchmark/build.sh
+++ b/kokoro/linux/benchmark/build.sh
@@ -1,108 +1,9 @@
 #!/bin/bash
-#
-# Change to repo root
+
 cd $(dirname $0)/../../..
 
+export DOCKERFILE_DIR=kokoro/linux/64-bit
+export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
 export OUTPUT_DIR=testoutput
-oldpwd=`pwd`
-
-# tcmalloc
-if [ ! -f gperftools/.libs/libtcmalloc.so ]; then
-  git clone https://github.com/gperftools/gperftools.git
-  cd gperftools
-  ./autogen.sh
-  ./configure
-  make -j8
-  cd ..
-fi
-
-# download datasets for benchmark
-cd benchmarks
-./download_data.sh
-datasets=$(for file in $(find . -type f -name "dataset.*.pb" -not -path "./tmp/*"); do echo "$(pwd)/$file"; done | xargs)
-echo $datasets
-cd $oldpwd
-
-# build Python protobuf
-./autogen.sh
-./configure CXXFLAGS="-fPIC -O2"
-make -j8
-cd python
-python setup.py build --cpp_implementation
-pip install . --user
-
-
-# build and run Python benchmark
-cd ../benchmarks
-make python-pure-python-benchmark
-make python-cpp-reflection-benchmark
-make -j8 python-cpp-generated-code-benchmark
-echo "[" > tmp/python_result.json
-echo "benchmarking pure python..."
-./python-pure-python-benchmark --json --behavior_prefix="pure-python-benchmark" $datasets  >> tmp/python_result.json
-echo "," >> "tmp/python_result.json"
-echo "benchmarking python cpp reflection..."
-env LD_PRELOAD="$oldpwd/gperftools/.libs/libtcmalloc.so" LD_LIBRARY_PATH="$oldpwd/src/.libs" ./python-cpp-reflection-benchmark --json --behavior_prefix="cpp-reflection-benchmark" $datasets  >> tmp/python_result.json
-echo "," >> "tmp/python_result.json"
-echo "benchmarking python cpp generated code..."
-env LD_PRELOAD="$oldpwd/gperftools/.libs/libtcmalloc.so" LD_LIBRARY_PATH="$oldpwd/src/.libs" ./python-cpp-generated-code-benchmark --json --behavior_prefix="cpp-generated-code-benchmark" $datasets >> tmp/python_result.json
-echo "]" >> "tmp/python_result.json"
-cd $oldpwd
-
-# build CPP protobuf
-./configure
-make clean && make -j8
-
-# build Java protobuf
-cd java
-mvn package
-cd ..
-
-# build CPP benchmark
-cd benchmarks
-mv tmp/python_result.json . && make clean && make -j8 cpp-benchmark && mv python_result.json tmp
-echo "benchmarking cpp..."
-env LD_PRELOAD="$oldpwd/gperftools/.libs/libtcmalloc.so" ./cpp-benchmark --benchmark_min_time=5.0 --benchmark_out_format=json --benchmark_out="tmp/cpp_result.json" $datasets
-cd $oldpwd
-
-# build go protobuf 
-export PATH="`pwd`/src:$PATH"
-export GOPATH="$HOME/gocode"
-mkdir -p "$GOPATH/src/github.com/google"
-rm -f "$GOPATH/src/github.com/protocolbuffers/protobuf"
-ln -s "`pwd`" "$GOPATH/src/github.com/protocolbuffers/protobuf"
-export PATH="$GOPATH/bin:$PATH"
-go get github.com/golang/protobuf/protoc-gen-go
-
-# build go benchmark
-cd benchmarks
-make go-benchmark
-echo "benchmarking go..."
-./go-benchmark $datasets > tmp/go_result.txt
-
-# build java benchmark
-make java-benchmark
-echo "benchmarking java..."
-./java-benchmark -Cresults.file.options.file="tmp/java_result.json" $datasets
-
-make js-benchmark
-echo "benchmarking js..."
-./js-benchmark $datasets  --json_output=$(pwd)/tmp/node_result.json
-
-make -j8 generate_proto3_data
-proto3_datasets=$(for file in $datasets; do echo $(pwd)/tmp/proto3_data/${file#$(pwd)}; done | xargs)
-echo $proto3_datasets
-
-# build php benchmark
-make -j8 php-benchmark
-echo "benchmarking php..."
-./php-benchmark $proto3_datasets --json --behavior_prefix="php" > tmp/php_result.json
-make -j8 php-c-benchmark
-echo "benchmarking php_c..."
-./php-c-benchmark $proto3_datasets --json --behavior_prefix="php_c" > tmp/php_c_result.json
-
-# upload result to bq
-make python_add_init
-env LD_LIBRARY_PATH="$oldpwd/src/.libs" python -m util.result_uploader -php="../tmp/php_result.json" -php_c="../tmp/php_c_result.json"  \
-	-cpp="../tmp/cpp_result.json" -java="../tmp/java_result.json" -go="../tmp/go_result.txt" -python="../tmp/python_result.json" -node="../tmp/node_result.json"
-cd $oldpwd
+export TEST_SET="benchmark"
+./kokoro/linux/build_and_run_docker.sh
diff --git a/kokoro/linux/benchmark/run.sh b/kokoro/linux/benchmark/run.sh
new file mode 100755
index 0000000..264bdaa
--- /dev/null
+++ b/kokoro/linux/benchmark/run.sh
@@ -0,0 +1,105 @@
+#!/bin/bash
+#
+# Change to repo root
+cd $(dirname $0)/../../..
+
+export OUTPUT_DIR=testoutput
+oldpwd=`pwd`
+
+# tcmalloc
+if [ ! -f gperftools/.libs/libtcmalloc.so ]; then
+  git clone https://github.com/gperftools/gperftools.git
+  cd gperftools
+  ./autogen.sh
+  ./configure
+  make -j8
+  cd ..
+fi
+
+# download datasets for benchmark
+cd benchmarks
+./download_data.sh
+datasets=$(for file in $(find . -type f -name "dataset.*.pb" -not -path "./tmp/*"); do echo "$(pwd)/$file"; done | xargs)
+echo $datasets
+cd $oldpwd
+
+# build Python protobuf
+./autogen.sh
+./configure CXXFLAGS="-fPIC -O2"
+make -j8
+cd python
+python setup.py build --cpp_implementation
+pip install . --user
+
+
+# build and run Python benchmark
+cd ../benchmarks
+make python-pure-python-benchmark
+make python-cpp-reflection-benchmark
+make -j8 python-cpp-generated-code-benchmark
+echo "[" > tmp/python_result.json
+echo "benchmarking pure python..."
+./python-pure-python-benchmark --json --behavior_prefix="pure-python-benchmark" $datasets  >> tmp/python_result.json
+echo "," >> "tmp/python_result.json"
+echo "benchmarking python cpp reflection..."
+env LD_PRELOAD="$oldpwd/gperftools/.libs/libtcmalloc.so" LD_LIBRARY_PATH="$oldpwd/src/.libs" ./python-cpp-reflection-benchmark --json --behavior_prefix="cpp-reflection-benchmark" $datasets  >> tmp/python_result.json
+echo "," >> "tmp/python_result.json"
+echo "benchmarking python cpp generated code..."
+env LD_PRELOAD="$oldpwd/gperftools/.libs/libtcmalloc.so" LD_LIBRARY_PATH="$oldpwd/src/.libs" ./python-cpp-generated-code-benchmark --json --behavior_prefix="cpp-generated-code-benchmark" $datasets >> tmp/python_result.json
+echo "]" >> "tmp/python_result.json"
+cd $oldpwd
+
+# build CPP protobuf
+./configure
+make clean && make -j8
+
+# build Java protobuf
+cd java
+mvn package
+cd ..
+
+# build CPP benchmark
+cd benchmarks
+mv tmp/python_result.json . && make clean && make -j8 cpp-benchmark && mv python_result.json tmp
+echo "benchmarking cpp..."
+env LD_PRELOAD="$oldpwd/gperftools/.libs/libtcmalloc.so" ./cpp-benchmark --benchmark_min_time=5.0 --benchmark_out_format=json --benchmark_out="tmp/cpp_result.json" $datasets
+cd $oldpwd
+
+# build go protobuf 
+export PATH="`pwd`/src:$PATH"
+export GOPATH="$HOME/gocode"
+mkdir -p "$GOPATH/src/github.com/google"
+rm -f "$GOPATH/src/github.com/protocolbuffers/protobuf"
+ln -s "`pwd`" "$GOPATH/src/github.com/protocolbuffers/protobuf"
+export PATH="$GOPATH/bin:$PATH"
+go get github.com/golang/protobuf/protoc-gen-go
+
+# build go benchmark
+cd benchmarks
+make go-benchmark
+echo "benchmarking go..."
+./go-benchmark $datasets > tmp/go_result.txt
+
+# build java benchmark
+make java-benchmark
+echo "benchmarking java..."
+./java-benchmark -Cresults.file.options.file="tmp/java_result.json" $datasets
+
+make js-benchmark
+echo "benchmarking js..."
+./js-benchmark $datasets  --json_output=$(pwd)/tmp/node_result.json
+
+make -j8 generate_proto3_data
+proto3_datasets=$(for file in $datasets; do echo $(pwd)/tmp/proto3_data/${file#$(pwd)}; done | xargs)
+echo $proto3_datasets
+
+# build php benchmark
+make -j8 php-c-benchmark
+echo "benchmarking php_c..."
+./php-c-benchmark $proto3_datasets --json --behavior_prefix="php_c" > tmp/php_c_result.json
+
+# upload result to bq
+make python_add_init
+env LD_LIBRARY_PATH="$oldpwd/src/.libs" python -m util.result_uploader -php_c="../tmp/php_c_result.json"  \
+	-cpp="../tmp/cpp_result.json" -java="../tmp/java_result.json" -go="../tmp/go_result.txt" -python="../tmp/python_result.json" -node="../tmp/node_result.json"
+cd $oldpwd
diff --git a/kokoro/linux/build_and_run_docker.sh b/kokoro/linux/build_and_run_docker.sh
index b81a368..3dc5dbb 100755
--- a/kokoro/linux/build_and_run_docker.sh
+++ b/kokoro/linux/build_and_run_docker.sh
@@ -3,6 +3,8 @@
 # Builds docker image and runs a command under it.
 # This is a generic script that is configured with the following variables:
 #
+# DOCKERHUB_ORGANIZATION - The organization on docker hub storing the
+# Dockerfile.
 # DOCKERFILE_DIR - Directory in which Dockerfile file is located.
 # DOCKER_RUN_SCRIPT - Script to run under docker (relative to protobuf repo root)
 # OUTPUT_DIR - Directory that will be copied from inside docker after finishing.
@@ -15,8 +17,16 @@
 cd -
 
 # Use image name based on Dockerfile sha1
-DOCKERHUB_ORGANIZATION=grpctesting/protobuf
-DOCKER_IMAGE_NAME=${DOCKERHUB_ORGANIZATION}_$(sha1sum $DOCKERFILE_DIR/Dockerfile | cut -f1 -d\ )
+if [ -z "$DOCKERHUB_ORGANIZATION" ]
+then
+  DOCKERHUB_ORGANIZATION=grpctesting/protobuf
+  DOCKER_IMAGE_NAME=${DOCKERHUB_ORGANIZATION}_$(sha1sum $DOCKERFILE_DIR/Dockerfile | cut -f1 -d\ )
+else
+  # TODO(teboring): Remove this when all tests have been migrated to separate
+  # docker images.
+  DOCKERFILE_PREFIX=$(basename $DOCKERFILE_DIR)
+  DOCKER_IMAGE_NAME=${DOCKERHUB_ORGANIZATION}/${DOCKERFILE_PREFIX}_$(sha1sum $DOCKERFILE_DIR/Dockerfile | cut -f1 -d\ )
+fi
 
 # Pull dockerimage from Dockerhub
 docker pull $DOCKER_IMAGE_NAME
diff --git a/kokoro/linux/dockerfile/test/php/Dockerfile b/kokoro/linux/dockerfile/test/php/Dockerfile
index 632d783..276cb73 100644
--- a/kokoro/linux/dockerfile/test/php/Dockerfile
+++ b/kokoro/linux/dockerfile/test/php/Dockerfile
@@ -79,8 +79,8 @@
 
 RUN wget -O phpunit https://phar.phpunit.de/phpunit-4.phar \
   && chmod +x phpunit \
-  && cp phpunit /usr/local/php-5.5 \
-  && mv phpunit /usr/local/php-5.5-zts
+  && cp phpunit /usr/local/php-5.5/bin \
+  && mv phpunit /usr/local/php-5.5-zts/bin
 
 # php 5.6
 RUN cd php-src \
@@ -109,8 +109,8 @@
 
 RUN wget -O phpunit https://phar.phpunit.de/phpunit-5.phar \
   && chmod +x phpunit \
-  && cp phpunit /usr/local/php-5.6 \
-  && mv phpunit /usr/local/php-5.6-zts
+  && cp phpunit /usr/local/php-5.6/bin \
+  && mv phpunit /usr/local/php-5.6-zts/bin
 
 # php 7.0
 RUN cd php-src \
@@ -139,8 +139,8 @@
 
 RUN wget -O phpunit https://phar.phpunit.de/phpunit-6.phar \
   && chmod +x phpunit \
-  && cp phpunit /usr/local/php-7.0 \
-  && mv phpunit /usr/local/php-7.0-zts
+  && cp phpunit /usr/local/php-7.0/bin \
+  && mv phpunit /usr/local/php-7.0-zts/bin
 
 # php 7.1
 RUN cd php-src \
@@ -169,8 +169,8 @@
 
 RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.phar \
   && chmod +x phpunit \
-  && cp phpunit /usr/local/php-7.1 \
-  && mv phpunit /usr/local/php-7.1-zts
+  && cp phpunit /usr/local/php-7.1/bin \
+  && mv phpunit /usr/local/php-7.1-zts/bin
 
 # php 7.2
 RUN cd php-src \
@@ -199,8 +199,8 @@
 
 RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.phar \
   && chmod +x phpunit \
-  && cp phpunit /usr/local/php-7.2 \
-  && mv phpunit /usr/local/php-7.2-zts
+  && cp phpunit /usr/local/php-7.2/bin \
+  && mv phpunit /usr/local/php-7.2-zts/bin
 
 # php 7.3
 RUN cd php-src \
@@ -229,5 +229,10 @@
 
 RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.phar \
   && chmod +x phpunit \
-  && cp phpunit /usr/local/php-7.3 \
-  && mv phpunit /usr/local/php-7.3-zts
+  && cp phpunit /usr/local/php-7.3/bin \
+  && mv phpunit /usr/local/php-7.3-zts/bin
+
+# Install php dependencies
+RUN apt-get clean && apt-get update && apt-get install -y --force-yes \
+  valgrind \
+  && apt-get clean
diff --git a/kokoro/linux/dockerfile/test/php_32bit/Dockerfile b/kokoro/linux/dockerfile/test/php_32bit/Dockerfile
new file mode 100644
index 0000000..f8027c4
--- /dev/null
+++ b/kokoro/linux/dockerfile/test/php_32bit/Dockerfile
@@ -0,0 +1,224 @@
+FROM 32bit/debian:jessie
+
+# Install dependencies.  We start with the basic ones require to build protoc
+# and the C++ build
+RUN apt-get update && apt-get install -y \
+  autoconf \
+  autotools-dev \
+  build-essential \
+  bzip2 \
+  ccache \
+  curl \
+  gcc \
+  git \
+  libc6 \
+  libc6-dbg \
+  libc6-dev \
+  libgtest-dev \
+  libtool \
+  make \
+  parallel \
+  time \
+  wget \
+  && apt-get clean
+
+# Install php dependencies
+RUN apt-get clean && apt-get update && apt-get install -y --force-yes \
+  bison \
+  php5 \
+  libcurl4-openssl-dev \
+  libssl-dev \
+  libxml2-dev \
+  unzip \
+  zlib1g-dev \
+  pkg-config \
+  && apt-get clean
+
+# Install other dependencies
+RUN wget http://ftp.gnu.org/gnu/bison/bison-2.6.4.tar.gz -O /var/local/bison-2.6.4.tar.gz
+RUN cd /var/local \
+  && tar -zxvf bison-2.6.4.tar.gz \
+  && cd /var/local/bison-2.6.4 \
+  && ./configure \
+  && make \
+  && make install
+
+# Install composer
+RUN curl -sS https://getcomposer.org/installer | php
+RUN mv composer.phar /usr/local/bin/composer
+
+# Download php source code
+RUN git clone https://github.com/php/php-src
+
+# php 5.5
+RUN cd php-src \
+  && git checkout PHP-5.5.38 \
+  && ./buildconf --force
+RUN cd php-src \
+  && ./configure \
+  --enable-bcmath \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-5.5 \
+  && make \
+  && make install \
+  && make clean
+RUN cd php-src \
+  && ./configure \
+  --enable-maintainer-zts \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-5.5-zts \
+  && make \
+  && make install \
+  && make clean
+
+RUN wget -O phpunit https://phar.phpunit.de/phpunit-4.phar \
+  && chmod +x phpunit \
+  && cp phpunit /usr/local/php-5.5/bin \
+  && mv phpunit /usr/local/php-5.5-zts/bin
+
+# php 5.6
+RUN cd php-src \
+  && git checkout PHP-5.6.39 \
+  && ./buildconf --force
+RUN cd php-src \
+  && ./configure \
+  --enable-bcmath \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-5.6 \
+  && make \
+  && make install \
+  && make clean
+RUN cd php-src \
+  && ./configure \
+  --enable-maintainer-zts \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-5.6-zts \
+  && make \
+  && make install \
+  && make clean
+
+RUN wget -O phpunit https://phar.phpunit.de/phpunit-5.phar \
+  && chmod +x phpunit \
+  && cp phpunit /usr/local/php-5.6/bin \
+  && mv phpunit /usr/local/php-5.6-zts/bin
+
+# php 7.0
+RUN cd php-src \
+  && git checkout PHP-7.0.33 \
+  && ./buildconf --force
+RUN cd php-src \
+  && ./configure \
+  --enable-bcmath \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-7.0 \
+  && make \
+  && make install \
+  && make clean
+RUN cd php-src \
+  && ./configure \
+  --enable-maintainer-zts \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-7.0-zts \
+  && make \
+  && make install \
+  && make clean
+
+RUN wget -O phpunit https://phar.phpunit.de/phpunit-6.phar \
+  && chmod +x phpunit \
+  && cp phpunit /usr/local/php-7.0/bin \
+  && mv phpunit /usr/local/php-7.0-zts/bin
+
+# php 7.1
+RUN cd php-src \
+  && git checkout PHP-7.1.25 \
+  && ./buildconf --force
+RUN cd php-src \
+  && ./configure \
+  --enable-bcmath \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-7.1 \
+  && make \
+  && make install \
+  && make clean
+RUN cd php-src \
+  && ./configure \
+  --enable-maintainer-zts \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-7.1-zts \
+  && make \
+  && make install \
+  && make clean
+
+RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.phar \
+  && chmod +x phpunit \
+  && cp phpunit /usr/local/php-7.1/bin \
+  && mv phpunit /usr/local/php-7.1-zts/bin
+
+# php 7.2
+RUN cd php-src \
+  && git checkout PHP-7.2.13 \
+  && ./buildconf --force
+RUN cd php-src \
+  && ./configure \
+  --enable-bcmath \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-7.2 \
+  && make \
+  && make install \
+  && make clean
+RUN cd php-src \
+  && ./configure \
+  --enable-maintainer-zts \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-7.2-zts \
+  && make \
+  && make install \
+  && make clean
+
+RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.phar \
+  && chmod +x phpunit \
+  && cp phpunit /usr/local/php-7.2/bin \
+  && mv phpunit /usr/local/php-7.2-zts/bin
+
+# php 7.3
+RUN cd php-src \
+  && git checkout PHP-7.3.0 \
+  && ./buildconf --force
+RUN cd php-src \
+  && ./configure \
+  --enable-bcmath \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-7.3 \
+  && make \
+  && make install \
+  && make clean
+RUN cd php-src \
+  && ./configure \
+  --enable-maintainer-zts \
+  --with-openssl \
+  --with-zlib \
+  --prefix=/usr/local/php-7.3-zts \
+  && make \
+  && make install \
+  && make clean
+
+RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.phar \
+  && chmod +x phpunit \
+  && cp phpunit /usr/local/php-7.3/bin \
+  && mv phpunit /usr/local/php-7.3-zts/bin
+
+# Install php dependencies
+RUN apt-get clean && apt-get update && apt-get install -y --force-yes \
+  valgrind \
+  && apt-get clean
diff --git a/kokoro/linux/dockerfile/test/python_jessie/Dockerfile b/kokoro/linux/dockerfile/test/python_jessie/Dockerfile
new file mode 100644
index 0000000..b5a53a3
--- /dev/null
+++ b/kokoro/linux/dockerfile/test/python_jessie/Dockerfile
@@ -0,0 +1,39 @@
+FROM debian:jessie
+
+# Install dependencies.  We start with the basic ones require to build protoc
+# and the C++ build
+RUN apt-get update && apt-get install -y \
+  autoconf \
+  autotools-dev \
+  build-essential \
+  bzip2 \
+  ccache \
+  curl \
+  gcc \
+  git \
+  libc6 \
+  libc6-dbg \
+  libc6-dev \
+  libgtest-dev \
+  libtool \
+  make \
+  parallel \
+  time \
+  wget \
+  && apt-get clean
+
+# Install python dependencies
+RUN apt-get update && apt-get install -y \
+  python-setuptools \
+  python-all-dev \
+  python3-all-dev \
+  python-pip
+
+# Install Python packages from PyPI
+RUN pip install --upgrade pip==10.0.1
+RUN pip install virtualenv
+RUN pip install six==1.10.0 twisted==17.5.0
+
+# Install pip and virtualenv for Python 3.4
+RUN curl https://bootstrap.pypa.io/get-pip.py | python3.4
+RUN python3.4 -m pip install virtualenv
diff --git a/kokoro/linux/dockerfile/test/python_stretch/Dockerfile b/kokoro/linux/dockerfile/test/python_stretch/Dockerfile
new file mode 100644
index 0000000..1dba530
--- /dev/null
+++ b/kokoro/linux/dockerfile/test/python_stretch/Dockerfile
@@ -0,0 +1,47 @@
+FROM debian:stretch
+
+# Install dependencies.  We start with the basic ones require to build protoc
+# and the C++ build
+RUN apt-get update && apt-get install -y \
+  autoconf \
+  autotools-dev \
+  build-essential \
+  bzip2 \
+  ccache \
+  curl \
+  gcc \
+  git \
+  libc6 \
+  libc6-dbg \
+  libc6-dev \
+  libgtest-dev \
+  libtool \
+  make \
+  parallel \
+  time \
+  wget \
+  && apt-get clean
+
+# Install Python 2.7
+RUN apt-get update && apt-get install -y python2.7 python-all-dev
+RUN curl https://bootstrap.pypa.io/get-pip.py | python2.7
+
+# Install python dependencies
+RUN apt-get update && apt-get install -y \
+  python-setuptools \
+  python-pip
+
+# Add Debian 'testing' repository
+RUN echo 'deb http://ftp.de.debian.org/debian testing main' >> /etc/apt/sources.list
+RUN echo 'APT::Default-Release "stable";' | tee -a /etc/apt/apt.conf.d/00local
+
+# Install Python3
+RUN apt-get update && apt-get -t testing install -y \
+  python3.5 \
+  python3.6 \
+  python3.7 \
+  python3-all-dev
+
+RUN curl https://bootstrap.pypa.io/get-pip.py | python3.5
+RUN curl https://bootstrap.pypa.io/get-pip.py | python3.6
+RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7
diff --git a/kokoro/linux/php_all/build.sh b/kokoro/linux/php_all/build.sh
index e9ab84c..23468a7 100755
--- a/kokoro/linux/php_all/build.sh
+++ b/kokoro/linux/php_all/build.sh
@@ -10,7 +10,8 @@
 # Change to repo root
 cd $(dirname $0)/../../..
 
-export DOCKERFILE_DIR=kokoro/linux/64-bit
+export DOCKERHUB_ORGANIZATION=protobuftesting
+export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/php
 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
 export OUTPUT_DIR=testoutput
 export TEST_SET="php_all"
diff --git a/kokoro/linux/64-bit/build.sh b/kokoro/linux/python27/build.sh
similarity index 73%
copy from kokoro/linux/64-bit/build.sh
copy to kokoro/linux/python27/build.sh
index 48ddbce..8c40ba3 100755
--- a/kokoro/linux/64-bit/build.sh
+++ b/kokoro/linux/python27/build.sh
@@ -10,8 +10,9 @@
 # Change to repo root
 cd $(dirname $0)/../../..
 
-export DOCKERFILE_DIR=kokoro/linux/64-bit
+export DOCKERHUB_ORGANIZATION=protobuftesting
+export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_jessie
 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
 export OUTPUT_DIR=testoutput
-export TEST_SET="csharp java_jdk7 javanano_jdk7 java_oracle7 javanano_oracle7 python python_cpp ruby_all javascript golang php_all"
+export TEST_SET="python27"
 ./kokoro/linux/build_and_run_docker.sh
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python27/continuous.cfg
similarity index 76%
rename from kokoro/linux/64-bit/continuous.cfg
rename to kokoro/linux/python27/continuous.cfg
index 3a4faac..e2fc413 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python27/continuous.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python27/presubmit.cfg
similarity index 76%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python27/presubmit.cfg
index 3a4faac..e2fc413 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python27/presubmit.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/build.sh b/kokoro/linux/python27_cpp/build.sh
similarity index 73%
copy from kokoro/linux/64-bit/build.sh
copy to kokoro/linux/python27_cpp/build.sh
index 48ddbce..2ff09a2 100755
--- a/kokoro/linux/64-bit/build.sh
+++ b/kokoro/linux/python27_cpp/build.sh
@@ -10,8 +10,9 @@
 # Change to repo root
 cd $(dirname $0)/../../..
 
-export DOCKERFILE_DIR=kokoro/linux/64-bit
+export DOCKERHUB_ORGANIZATION=protobuftesting
+export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_jessie
 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
 export OUTPUT_DIR=testoutput
-export TEST_SET="csharp java_jdk7 javanano_jdk7 java_oracle7 javanano_oracle7 python python_cpp ruby_all javascript golang php_all"
+export TEST_SET="python27_cpp"
 ./kokoro/linux/build_and_run_docker.sh
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python27_cpp/continuous.cfg
similarity index 75%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python27_cpp/continuous.cfg
index 3a4faac..b1b0e55 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python27_cpp/continuous.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python27_cpp/presubmit.cfg
similarity index 75%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python27_cpp/presubmit.cfg
index 3a4faac..b1b0e55 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python27_cpp/presubmit.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/build.sh b/kokoro/linux/python33/build.sh
similarity index 73%
copy from kokoro/linux/64-bit/build.sh
copy to kokoro/linux/python33/build.sh
index 48ddbce..84a9acd 100755
--- a/kokoro/linux/64-bit/build.sh
+++ b/kokoro/linux/python33/build.sh
@@ -10,8 +10,9 @@
 # Change to repo root
 cd $(dirname $0)/../../..
 
-export DOCKERFILE_DIR=kokoro/linux/64-bit
+export DOCKERHUB_ORGANIZATION=protobuftesting
+export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_jessie
 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
 export OUTPUT_DIR=testoutput
-export TEST_SET="csharp java_jdk7 javanano_jdk7 java_oracle7 javanano_oracle7 python python_cpp ruby_all javascript golang php_all"
+export TEST_SET="python33"
 ./kokoro/linux/build_and_run_docker.sh
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python33/continuous.cfg
similarity index 76%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python33/continuous.cfg
index 3a4faac..e2fc413 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python33/continuous.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python33/presubmit.cfg
similarity index 76%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python33/presubmit.cfg
index 3a4faac..e2fc413 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python33/presubmit.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/build.sh b/kokoro/linux/python33_cpp/build.sh
similarity index 73%
copy from kokoro/linux/64-bit/build.sh
copy to kokoro/linux/python33_cpp/build.sh
index 48ddbce..ad33e89 100755
--- a/kokoro/linux/64-bit/build.sh
+++ b/kokoro/linux/python33_cpp/build.sh
@@ -10,8 +10,9 @@
 # Change to repo root
 cd $(dirname $0)/../../..
 
-export DOCKERFILE_DIR=kokoro/linux/64-bit
+export DOCKERHUB_ORGANIZATION=protobuftesting
+export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_jessie
 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
 export OUTPUT_DIR=testoutput
-export TEST_SET="csharp java_jdk7 javanano_jdk7 java_oracle7 javanano_oracle7 python python_cpp ruby_all javascript golang php_all"
+export TEST_SET="python33_cpp"
 ./kokoro/linux/build_and_run_docker.sh
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python33_cpp/continuous.cfg
similarity index 75%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python33_cpp/continuous.cfg
index 3a4faac..b1b0e55 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python33_cpp/continuous.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python33_cpp/presubmit.cfg
similarity index 75%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python33_cpp/presubmit.cfg
index 3a4faac..b1b0e55 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python33_cpp/presubmit.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/build.sh b/kokoro/linux/python34/build.sh
similarity index 73%
rename from kokoro/linux/64-bit/build.sh
rename to kokoro/linux/python34/build.sh
index 48ddbce..25dfd5d 100755
--- a/kokoro/linux/64-bit/build.sh
+++ b/kokoro/linux/python34/build.sh
@@ -10,8 +10,9 @@
 # Change to repo root
 cd $(dirname $0)/../../..
 
-export DOCKERFILE_DIR=kokoro/linux/64-bit
+export DOCKERHUB_ORGANIZATION=protobuftesting
+export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_jessie
 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
 export OUTPUT_DIR=testoutput
-export TEST_SET="csharp java_jdk7 javanano_jdk7 java_oracle7 javanano_oracle7 python python_cpp ruby_all javascript golang php_all"
+export TEST_SET="python34"
 ./kokoro/linux/build_and_run_docker.sh
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python34/continuous.cfg
similarity index 76%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python34/continuous.cfg
index 3a4faac..e2fc413 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python34/continuous.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python34/presubmit.cfg
similarity index 76%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python34/presubmit.cfg
index 3a4faac..e2fc413 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python34/presubmit.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/build.sh b/kokoro/linux/python34_cpp/build.sh
similarity index 73%
copy from kokoro/linux/64-bit/build.sh
copy to kokoro/linux/python34_cpp/build.sh
index 48ddbce..e4590ff 100755
--- a/kokoro/linux/64-bit/build.sh
+++ b/kokoro/linux/python34_cpp/build.sh
@@ -10,8 +10,9 @@
 # Change to repo root
 cd $(dirname $0)/../../..
 
-export DOCKERFILE_DIR=kokoro/linux/64-bit
+export DOCKERHUB_ORGANIZATION=protobuftesting
+export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_jessie
 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
 export OUTPUT_DIR=testoutput
-export TEST_SET="csharp java_jdk7 javanano_jdk7 java_oracle7 javanano_oracle7 python python_cpp ruby_all javascript golang php_all"
+export TEST_SET="python34_cpp"
 ./kokoro/linux/build_and_run_docker.sh
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python34_cpp/continuous.cfg
similarity index 75%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python34_cpp/continuous.cfg
index 3a4faac..b1b0e55 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python34_cpp/continuous.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python34_cpp/presubmit.cfg
similarity index 75%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python34_cpp/presubmit.cfg
index 3a4faac..b1b0e55 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python34_cpp/presubmit.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/build.sh b/kokoro/linux/python35/build.sh
similarity index 73%
copy from kokoro/linux/64-bit/build.sh
copy to kokoro/linux/python35/build.sh
index 48ddbce..f978e2a 100755
--- a/kokoro/linux/64-bit/build.sh
+++ b/kokoro/linux/python35/build.sh
@@ -10,8 +10,9 @@
 # Change to repo root
 cd $(dirname $0)/../../..
 
-export DOCKERFILE_DIR=kokoro/linux/64-bit
+export DOCKERHUB_ORGANIZATION=protobuftesting
+export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_stretch
 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
 export OUTPUT_DIR=testoutput
-export TEST_SET="csharp java_jdk7 javanano_jdk7 java_oracle7 javanano_oracle7 python python_cpp ruby_all javascript golang php_all"
+export TEST_SET="python35"
 ./kokoro/linux/build_and_run_docker.sh
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python35/continuous.cfg
similarity index 76%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python35/continuous.cfg
index 3a4faac..e2fc413 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python35/continuous.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python35/presubmit.cfg
similarity index 76%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python35/presubmit.cfg
index 3a4faac..e2fc413 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python35/presubmit.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/build.sh b/kokoro/linux/python35_cpp/build.sh
similarity index 73%
copy from kokoro/linux/64-bit/build.sh
copy to kokoro/linux/python35_cpp/build.sh
index 48ddbce..2a79246 100755
--- a/kokoro/linux/64-bit/build.sh
+++ b/kokoro/linux/python35_cpp/build.sh
@@ -10,8 +10,9 @@
 # Change to repo root
 cd $(dirname $0)/../../..
 
-export DOCKERFILE_DIR=kokoro/linux/64-bit
+export DOCKERHUB_ORGANIZATION=protobuftesting
+export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_stretch
 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
 export OUTPUT_DIR=testoutput
-export TEST_SET="csharp java_jdk7 javanano_jdk7 java_oracle7 javanano_oracle7 python python_cpp ruby_all javascript golang php_all"
+export TEST_SET="python35_cpp"
 ./kokoro/linux/build_and_run_docker.sh
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python35_cpp/continuous.cfg
similarity index 75%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python35_cpp/continuous.cfg
index 3a4faac..b1b0e55 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python35_cpp/continuous.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python35_cpp/presubmit.cfg
similarity index 75%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python35_cpp/presubmit.cfg
index 3a4faac..b1b0e55 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python35_cpp/presubmit.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/build.sh b/kokoro/linux/python36/build.sh
similarity index 73%
copy from kokoro/linux/64-bit/build.sh
copy to kokoro/linux/python36/build.sh
index 48ddbce..633145b 100755
--- a/kokoro/linux/64-bit/build.sh
+++ b/kokoro/linux/python36/build.sh
@@ -10,8 +10,9 @@
 # Change to repo root
 cd $(dirname $0)/../../..
 
-export DOCKERFILE_DIR=kokoro/linux/64-bit
+export DOCKERHUB_ORGANIZATION=protobuftesting
+export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_stretch
 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
 export OUTPUT_DIR=testoutput
-export TEST_SET="csharp java_jdk7 javanano_jdk7 java_oracle7 javanano_oracle7 python python_cpp ruby_all javascript golang php_all"
+export TEST_SET="python36"
 ./kokoro/linux/build_and_run_docker.sh
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python36/continuous.cfg
similarity index 76%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python36/continuous.cfg
index 3a4faac..e2fc413 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python36/continuous.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python36/presubmit.cfg
similarity index 76%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python36/presubmit.cfg
index 3a4faac..e2fc413 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python36/presubmit.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/build.sh b/kokoro/linux/python36_cpp/build.sh
similarity index 73%
copy from kokoro/linux/64-bit/build.sh
copy to kokoro/linux/python36_cpp/build.sh
index 48ddbce..8e120ff 100755
--- a/kokoro/linux/64-bit/build.sh
+++ b/kokoro/linux/python36_cpp/build.sh
@@ -10,8 +10,9 @@
 # Change to repo root
 cd $(dirname $0)/../../..
 
-export DOCKERFILE_DIR=kokoro/linux/64-bit
+export DOCKERHUB_ORGANIZATION=protobuftesting
+export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_stretch
 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
 export OUTPUT_DIR=testoutput
-export TEST_SET="csharp java_jdk7 javanano_jdk7 java_oracle7 javanano_oracle7 python python_cpp ruby_all javascript golang php_all"
+export TEST_SET="python36_cpp"
 ./kokoro/linux/build_and_run_docker.sh
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python36_cpp/continuous.cfg
similarity index 75%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python36_cpp/continuous.cfg
index 3a4faac..b1b0e55 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python36_cpp/continuous.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python36_cpp/presubmit.cfg
similarity index 75%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python36_cpp/presubmit.cfg
index 3a4faac..b1b0e55 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python36_cpp/presubmit.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/build.sh b/kokoro/linux/python37/build.sh
similarity index 73%
copy from kokoro/linux/64-bit/build.sh
copy to kokoro/linux/python37/build.sh
index 48ddbce..554aa09 100755
--- a/kokoro/linux/64-bit/build.sh
+++ b/kokoro/linux/python37/build.sh
@@ -10,8 +10,9 @@
 # Change to repo root
 cd $(dirname $0)/../../..
 
-export DOCKERFILE_DIR=kokoro/linux/64-bit
+export DOCKERHUB_ORGANIZATION=protobuftesting
+export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_stretch
 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
 export OUTPUT_DIR=testoutput
-export TEST_SET="csharp java_jdk7 javanano_jdk7 java_oracle7 javanano_oracle7 python python_cpp ruby_all javascript golang php_all"
+export TEST_SET="python37"
 ./kokoro/linux/build_and_run_docker.sh
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python37/continuous.cfg
similarity index 76%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python37/continuous.cfg
index 3a4faac..e2fc413 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python37/continuous.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python37/presubmit.cfg
similarity index 76%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python37/presubmit.cfg
index 3a4faac..e2fc413 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python37/presubmit.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/build.sh b/kokoro/linux/python37_cpp/build.sh
similarity index 73%
copy from kokoro/linux/64-bit/build.sh
copy to kokoro/linux/python37_cpp/build.sh
index 48ddbce..8fdc8f9 100755
--- a/kokoro/linux/64-bit/build.sh
+++ b/kokoro/linux/python37_cpp/build.sh
@@ -10,8 +10,9 @@
 # Change to repo root
 cd $(dirname $0)/../../..
 
-export DOCKERFILE_DIR=kokoro/linux/64-bit
+export DOCKERHUB_ORGANIZATION=protobuftesting
+export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_stretch
 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
 export OUTPUT_DIR=testoutput
-export TEST_SET="csharp java_jdk7 javanano_jdk7 java_oracle7 javanano_oracle7 python python_cpp ruby_all javascript golang php_all"
+export TEST_SET="python37_cpp"
 ./kokoro/linux/build_and_run_docker.sh
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python37_cpp/continuous.cfg
similarity index 75%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python37_cpp/continuous.cfg
index 3a4faac..b1b0e55 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python37_cpp/continuous.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/kokoro/linux/64-bit/continuous.cfg b/kokoro/linux/python37_cpp/presubmit.cfg
similarity index 75%
copy from kokoro/linux/64-bit/continuous.cfg
copy to kokoro/linux/python37_cpp/presubmit.cfg
index 3a4faac..b1b0e55 100644
--- a/kokoro/linux/64-bit/continuous.cfg
+++ b/kokoro/linux/python37_cpp/presubmit.cfg
@@ -1,7 +1,7 @@
 # Config file for running tests in Kokoro
 
 # Location of the build script in repository
-build_file: "protobuf/kokoro/linux/64-bit/build.sh"
+build_file: "protobuf/kokoro/linux/python_cpp/build.sh"
 timeout_mins: 120
 
 action {
diff --git a/objectivec/GPBDescriptor.m b/objectivec/GPBDescriptor.m
index a349f87..41bf5ad 100644
--- a/objectivec/GPBDescriptor.m
+++ b/objectivec/GPBDescriptor.m
@@ -872,11 +872,10 @@
     if (nameOffsets_ == NULL) return NO;
 
     for (uint32_t i = 0; i < valueCount_; ++i) {
-        int32_t value = values_[i];
-        NSString *valueTextFormatName = [self textFormatNameForValue:value];
+        NSString *valueTextFormatName = [self getEnumTextFormatNameForIndex:i];
         if ([valueTextFormatName isEqual:textFormatName]) {
             if (outValue) {
-                *outValue = value;
+                *outValue = values_[i];
             }
             return YES;
         }
diff --git a/objectivec/Tests/GPBDescriptorTests.m b/objectivec/Tests/GPBDescriptorTests.m
index d47cc30..46c1729 100644
--- a/objectivec/Tests/GPBDescriptorTests.m
+++ b/objectivec/Tests/GPBDescriptorTests.m
@@ -244,7 +244,44 @@
   XCTAssertTrue([descriptor getValue:&value forEnumName:enumName]);
   XCTAssertEqual(value, 2);
   XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:4], @"BAR2");
+}
 
+- (void)testEnumAliasNameCollisions {
+  GPBEnumDescriptor *descriptor = TestEnumObjCNameCollision_EnumDescriptor();
+  NSString *textFormatName;
+  int32_t value;
+
+  XCTAssertEqual(descriptor.enumNameCount, 5U);
+
+  XCTAssertEqualObjects([descriptor getEnumNameForIndex:0], @"TestEnumObjCNameCollision_Foo");
+  textFormatName = [descriptor getEnumTextFormatNameForIndex:0];
+  XCTAssertEqualObjects(textFormatName, @"FOO");
+  XCTAssertTrue([descriptor getValue:&value forEnumTextFormatName:textFormatName]);
+  XCTAssertEqual(value, 1);
+
+  XCTAssertEqualObjects([descriptor getEnumNameForIndex:1], @"TestEnumObjCNameCollision_Foo");
+  textFormatName = [descriptor getEnumTextFormatNameForIndex:1];
+  XCTAssertEqualObjects(textFormatName, @"foo");
+  XCTAssertTrue([descriptor getValue:&value forEnumTextFormatName:textFormatName]);
+  XCTAssertEqual(value, 1);
+
+  XCTAssertEqualObjects([descriptor getEnumNameForIndex:2], @"TestEnumObjCNameCollision_Bar");
+  textFormatName = [descriptor getEnumTextFormatNameForIndex:2];
+  XCTAssertEqualObjects(textFormatName, @"BAR");
+  XCTAssertTrue([descriptor getValue:&value forEnumTextFormatName:textFormatName]);
+  XCTAssertEqual(value, 2);
+
+  XCTAssertEqualObjects([descriptor getEnumNameForIndex:3], @"TestEnumObjCNameCollision_Mumble");
+  textFormatName = [descriptor getEnumTextFormatNameForIndex:3];
+  XCTAssertEqualObjects(textFormatName, @"mumble");
+  XCTAssertTrue([descriptor getValue:&value forEnumTextFormatName:textFormatName]);
+  XCTAssertEqual(value, 2);
+
+  XCTAssertEqualObjects([descriptor getEnumNameForIndex:4], @"TestEnumObjCNameCollision_Mumble");
+  textFormatName = [descriptor getEnumTextFormatNameForIndex:4];
+  XCTAssertEqualObjects(textFormatName, @"MUMBLE");
+  XCTAssertTrue([descriptor getValue:&value forEnumTextFormatName:textFormatName]);
+  XCTAssertEqual(value, 2);
 }
 
 - (void)testEnumValueValidator {
diff --git a/objectivec/Tests/unittest_objc.proto b/objectivec/Tests/unittest_objc.proto
index 1245ebe..91c2139 100644
--- a/objectivec/Tests/unittest_objc.proto
+++ b/objectivec/Tests/unittest_objc.proto
@@ -867,3 +867,18 @@
 message WKTRefereceMessage {
   optional google.protobuf.Any an_any = 1;
 }
+
+// This is in part a compile test, it ensures that when aliases end up with
+// the same ObjC name, we drop them to avoid the duplication names. There
+// is a test to ensure the descriptors are still generated to support
+// reflection and TextFormat.
+enum TestEnumObjCNameCollision {
+  option allow_alias = true;
+
+  FOO = 1;
+  foo = 1;
+
+  BAR = 2;
+  mumble = 2;
+  MUMBLE = 2;
+}
diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c
index 2843321..08a4793 100644
--- a/php/ext/google/protobuf/message.c
+++ b/php/ext/google/protobuf/message.c
@@ -1231,7 +1231,6 @@
 
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Any", Any, any)
-  zend_class_implements(any_type TSRMLS_CC, 1, message_type);
   zend_declare_property_string(any_type, "type_url", strlen("type_url"),
                                "" ,ZEND_ACC_PRIVATE TSRMLS_CC);
   zend_declare_property_string(any_type, "value", strlen("value"),
@@ -1421,7 +1420,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Duration",
                                  Duration, duration)
-  zend_class_implements(duration_type TSRMLS_CC, 1, message_type);
   zend_declare_property_long(duration_type, "seconds", strlen("seconds"),
                              0 ,ZEND_ACC_PRIVATE TSRMLS_CC);
   zend_declare_property_long(duration_type, "nanos", strlen("nanos"),
@@ -1457,7 +1455,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Timestamp",
                                  Timestamp, timestamp)
-  zend_class_implements(timestamp_type TSRMLS_CC, 1, message_type);
   zend_declare_property_long(timestamp_type, "seconds", strlen("seconds"),
                              0 ,ZEND_ACC_PRIVATE TSRMLS_CC);
   zend_declare_property_long(timestamp_type, "nanos", strlen("nanos"),
@@ -1650,7 +1647,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Api",
                                  Api, api)
-  zend_class_implements(api_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(api_type, "name", strlen("name"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
   zend_declare_property_null(api_type, "methods", strlen("methods"),
@@ -1697,7 +1693,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\BoolValue",
                                  BoolValue, bool_value)
-  zend_class_implements(bool_value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(bool_value_type, "value", strlen("value"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -1726,7 +1721,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\BytesValue",
                                  BytesValue, bytes_value)
-  zend_class_implements(bytes_value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(bytes_value_type, "value", strlen("value"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -1755,7 +1749,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\DoubleValue",
                                  DoubleValue, double_value)
-  zend_class_implements(double_value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(double_value_type, "value", strlen("value"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -1792,7 +1785,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Enum",
                                  Enum, enum)
-  zend_class_implements(enum_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(enum_type, "name", strlen("name"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
   zend_declare_property_null(enum_type, "enumvalue", strlen("enumvalue"),
@@ -1837,7 +1829,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\EnumValue",
                                  EnumValue, enum_value)
-  zend_class_implements(enum_value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(enum_value_type, "name", strlen("name"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
   zend_declare_property_null(enum_value_type, "number", strlen("number"),
@@ -1872,7 +1863,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\FieldMask",
                                  FieldMask, field_mask)
-  zend_class_implements(field_mask_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(field_mask_type, "paths", strlen("paths"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -1919,7 +1909,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Field",
                                  Field, field)
-  zend_class_implements(field_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(field_type, "kind", strlen("kind"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
   zend_declare_property_null(field_type, "cardinality", strlen("cardinality"),
@@ -1975,7 +1964,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\FloatValue",
                                  FloatValue, float_value)
-  zend_class_implements(float_value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(float_value_type, "value", strlen("value"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -2002,7 +1990,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\GPBEmpty",
                                  GPBEmpty, empty)
-  zend_class_implements(empty_type TSRMLS_CC, 1, message_type);
 PHP_PROTO_INIT_SUBMSGCLASS_END
 
 PHP_METHOD(GPBEmpty, __construct) {
@@ -2028,7 +2015,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Int32Value",
                                  Int32Value, int32_value)
-  zend_class_implements(int32_value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(int32_value_type, "value", strlen("value"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -2057,7 +2043,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Int64Value",
                                  Int64Value, int64_value)
-  zend_class_implements(int64_value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(int64_value_type, "value", strlen("value"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -2086,7 +2071,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\ListValue",
                                  ListValue, list_value)
-  zend_class_implements(list_value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(list_value_type, "values", strlen("values"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -2127,7 +2111,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Method",
                                  Method, method)
-  zend_class_implements(method_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(method_type, "name", strlen("name"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
   zend_declare_property_null(method_type, "request_type_url", strlen("request_type_url"),
@@ -2176,7 +2159,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Mixin",
                                  Mixin, mixin)
-  zend_class_implements(mixin_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(mixin_type, "name", strlen("name"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
   zend_declare_property_null(mixin_type, "root", strlen("root"),
@@ -2210,7 +2192,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Option",
                                  Option, option)
-  zend_class_implements(option_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(option_type, "name", strlen("name"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
   zend_declare_property_null(option_type, "value", strlen("value"),
@@ -2242,7 +2223,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\SourceContext",
                                  SourceContext, source_context)
-  zend_class_implements(source_context_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(source_context_type, "file_name", strlen("file_name"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -2271,7 +2251,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\StringValue",
                                  StringValue, string_value)
-  zend_class_implements(string_value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(string_value_type, "value", strlen("value"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -2300,7 +2279,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Struct",
                                  Struct, struct)
-  zend_class_implements(struct_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(struct_type, "fields", strlen("fields"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -2339,7 +2317,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Type",
                                  Type, type)
-  zend_class_implements(type_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(type_type, "name", strlen("name"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
   zend_declare_property_null(type_type, "fields", strlen("fields"),
@@ -2383,7 +2360,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\UInt32Value",
                                  UInt32Value, u_int32_value)
-  zend_class_implements(u_int32_value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(u_int32_value_type, "value", strlen("value"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -2412,7 +2388,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\UInt64Value",
                                  UInt64Value, u_int64_value)
-  zend_class_implements(u_int64_value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(u_int64_value_type, "value", strlen("value"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
@@ -2452,7 +2427,6 @@
 // Init class entry.
 PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Value",
                                  Value, value)
-  zend_class_implements(value_type TSRMLS_CC, 1, message_type);
   zend_declare_property_null(value_type, "kind", strlen("kind"),
                              ZEND_ACC_PRIVATE TSRMLS_CC);
 PHP_PROTO_INIT_SUBMSGCLASS_END
diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h
index 0045358..5cbf348 100644
--- a/php/ext/google/protobuf/protobuf.h
+++ b/php/ext/google/protobuf/protobuf.h
@@ -137,7 +137,8 @@
     const char* class_name = CLASSNAME;                                      \
     INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME),            \
                         LOWWERNAME##_methods);                               \
-    LOWWERNAME##_type = zend_register_internal_class(&class_type TSRMLS_CC); \
+    LOWWERNAME##_type = zend_register_internal_class_ex(                     \
+        &class_type, message_type, NULL TSRMLS_CC);                          \
     LOWWERNAME##_type->create_object = message_create;                       \
     zend_do_inheritance(LOWWERNAME##_type, message_type TSRMLS_CC);
 #define PHP_PROTO_INIT_SUBMSGCLASS_END \
@@ -404,7 +405,8 @@
     const char* class_name = CLASSNAME;                                      \
     INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME),            \
                         LOWWERNAME##_methods);                               \
-    LOWWERNAME##_type = zend_register_internal_class(&class_type TSRMLS_CC); \
+    LOWWERNAME##_type = zend_register_internal_class_ex(                     \
+        &class_type, message_type TSRMLS_CC);                                \
     zend_do_inheritance(LOWWERNAME##_type, message_type TSRMLS_CC);
 #define PHP_PROTO_INIT_SUBMSGCLASS_END \
   }
diff --git a/php/ext/google/protobuf/storage.c b/php/ext/google/protobuf/storage.c
index a60fbe3..93a16dd 100644
--- a/php/ext/google/protobuf/storage.c
+++ b/php/ext/google/protobuf/storage.c
@@ -180,7 +180,8 @@
       PHP_PROTO_ZVAL_STRINGL(DEREF(memory, zval*), Z_STRVAL_P(value),
                              Z_STRLEN_P(value), 1);
 #else
-      *(zend_string**)memory = zend_string_dup(Z_STR_P(value), 0);
+      *(zend_string**)memory =
+          zend_string_init(Z_STRVAL_P(value), Z_STRLEN_P(value), 0);
 #endif
       break;
     }
@@ -231,7 +232,8 @@
       PHP_PROTO_ZVAL_STRINGL(DEREF(memory, zval*), Z_STRVAL_P(value),
                              Z_STRLEN_P(value), 1);
 #else
-      *(zend_string**)memory = zend_string_dup(Z_STR_P(value), 0);
+      *(zend_string**)memory =
+          zend_string_init(Z_STRVAL_P(value), Z_STRLEN_P(value), 0);
 #endif
       break;
     }
diff --git a/php/tests/array_test.php b/php/tests/array_test.php
index 36a649e..b008433 100644
--- a/php/tests/array_test.php
+++ b/php/tests/array_test.php
@@ -7,7 +7,7 @@
 use Foo\TestMessage;
 use Foo\TestMessage\Sub;
 
-class RepeatedFieldTest extends PHPUnit_Framework_TestCase
+class RepeatedFieldTest extends \PHPUnit\Framework\TestCase
 {
 
     #########################################################
diff --git a/php/tests/compatibility_test.sh b/php/tests/compatibility_test.sh
index dc8de5d..f4af524 100755
--- a/php/tests/compatibility_test.sh
+++ b/php/tests/compatibility_test.sh
@@ -123,8 +123,12 @@
 sed -i.bak '/php_implementation_test.php/d' phpunit.xml
 sed -i.bak '/generated_phpdoc_test.php/d' phpunit.xml
 sed -i.bak 's/generated_phpdoc_test.php//g' tests/test.sh
+sed -i.bak 's/generated_service_test.php//g' tests/test.sh
 sed -i.bak '/memory_leak_test.php/d' tests/test.sh
 sed -i.bak '/^    public function testTimestamp()$/,/^    }$/d' tests/well_known_test.php
+sed -i.bak 's/PHPUnit_Framework_TestCase/\\PHPUnit\\Framework\\TestCase/g' tests/array_test.php
+sed -i.bak 's/PHPUnit_Framework_TestCase/\\PHPUnit\\Framework\\TestCase/g' tests/map_field_test.php
+sed -i.bak 's/PHPUnit_Framework_TestCase/\\PHPUnit\\Framework\\TestCase/g' tests/test_base.php
 for t in "${tests[@]}"
 do
   remove_error_test tests/$t
diff --git a/php/tests/encode_decode_test.php b/php/tests/encode_decode_test.php
index 8168eeb..06f9a90 100644
--- a/php/tests/encode_decode_test.php
+++ b/php/tests/encode_decode_test.php
@@ -31,6 +31,7 @@
     {
         $m = new TestMessage();
         $m->mergeFromJsonString("{\"optionalInt32\":1}");
+        $this->assertEquals(1, $m->getOptionalInt32());
     }
 
     public function testDecodeTopLevelBoolValue()
@@ -276,6 +277,7 @@
         $to = new TestPackedMessage();
         $to->mergeFromString(TestUtil::getGoldenTestPackedMessage());
         TestUtil::assertTestPackedMessage($to);
+        $this->assertTrue(true);
     }
 
     public function testPackedDecodeUnpacked()
@@ -283,6 +285,7 @@
         $to = new TestPackedMessage();
         $to->mergeFromString(TestUtil::getGoldenTestUnpackedMessage());
         TestUtil::assertTestPackedMessage($to);
+        $this->assertTrue(true);
     }
 
     public function testUnpackedEncode()
@@ -298,6 +301,7 @@
         $to = new TestUnpackedMessage();
         $to->mergeFromString(TestUtil::getGoldenTestPackedMessage());
         TestUtil::assertTestPackedMessage($to);
+        $this->assertTrue(true);
     }
 
     public function testUnpackedDecodeUnpacked()
@@ -305,6 +309,7 @@
         $to = new TestUnpackedMessage();
         $to->mergeFromString(TestUtil::getGoldenTestUnpackedMessage());
         TestUtil::assertTestPackedMessage($to);
+        $this->assertTrue(true);
     }
 
     public function testDecodeInt64()
@@ -361,6 +366,7 @@
         $data = hex2bin('c80501');
         $m = new TestMessage();
         $m->mergeFromString($data);
+        $this->assertTrue(true);
     }
 
     public function testEncodeNegativeInt32()
diff --git a/php/tests/generated_class_test.php b/php/tests/generated_class_test.php
index 96dad22..38c3809 100644
--- a/php/tests/generated_class_test.php
+++ b/php/tests/generated_class_test.php
@@ -260,12 +260,14 @@
     {
         $m = new TestMessage();
         $m->setOptionalNestedEnum(NestedEnum::ZERO);
+        $this->assertTrue(true);
     }
 
     public function testLegacyNestedEnum()
     {
         $m = new TestMessage();
         $m->setOptionalNestedEnum(\Foo\TestMessage_NestedEnum::ZERO);
+        $this->assertTrue(true);
     }
 
     public function testLegacyTypehintWithNestedEnums()
@@ -405,6 +407,7 @@
           $m = new TestMessage();
           $hex = hex2bin("ff");
           $m->setOptionalBytes($hex);
+          $this->assertTrue(true);
       }
 
     #########################################################
@@ -709,6 +712,8 @@
         // test nested messages
         $sub = new NoNamespaceMessage\NestedMessage();
         $n->setNestedMessage($sub);
+
+        $this->assertTrue(true);
     }
 
     public function testEnumWithoutNamespace()
@@ -718,6 +723,7 @@
         $repeatedNoNamespaceEnum = $m->getRepeatedNoNamespaceEnum();
         $repeatedNoNamespaceEnum[] = NoNameSpaceEnum::VALUE_A;
         $m->setRepeatedNoNamespaceEnum($repeatedNoNamespaceEnum);
+        $this->assertTrue(true);
     }
 
     #########################################################
@@ -1262,6 +1268,8 @@
         $m = \Upper_enum_value\NotAllowed::NULL;
         $m = \Upper_enum_value\NotAllowed::VOID;
         $m = \Upper_enum_value\NotAllowed::ITERABLE;
+
+        $this->assertTrue(true);
     }
 
     #########################################################
@@ -1297,6 +1305,7 @@
     {
         $m = new testLowerCaseMessage();
         $n = testLowerCaseEnum::VALUE;
+        $this->assertTrue(true);
     }
 
     #########################################################
@@ -1363,6 +1372,7 @@
         ]);
 
         TestUtil::assertTestMessage($m);
+        $this->assertTrue(true);
     }
 
     #########################################################
diff --git a/php/tests/map_field_test.php b/php/tests/map_field_test.php
index 447bdd9..0260879 100644
--- a/php/tests/map_field_test.php
+++ b/php/tests/map_field_test.php
@@ -7,7 +7,7 @@
 use Foo\TestMessage;
 use Foo\TestMessage\Sub;
 
-class MapFieldTest extends PHPUnit_Framework_TestCase {
+class MapFieldTest extends \PHPUnit\Framework\TestCase {
 
     #########################################################
     # Test int32 field.
diff --git a/php/tests/test_base.php b/php/tests/test_base.php
index 80f603c..27efc87 100644
--- a/php/tests/test_base.php
+++ b/php/tests/test_base.php
@@ -4,7 +4,7 @@
 use Foo\TestEnum;
 use Foo\TestMessage\Sub;
 
-class TestBase extends PHPUnit_Framework_TestCase
+class TestBase extends \PHPUnit\Framework\TestCase
 {
 
     public function setFields(TestMessage $m)
@@ -338,5 +338,6 @@
   // This test is to avoid the warning of no test by php unit.
   public function testNone()
   {
+      $this->assertTrue(true);
   }
 }
diff --git a/php/tests/well_known_test.php b/php/tests/well_known_test.php
index db5d5a7..a16e070 100644
--- a/php/tests/well_known_test.php
+++ b/php/tests/well_known_test.php
@@ -48,6 +48,7 @@
     public function testImportDescriptorProto()
     {
         $msg = new TestImportDescriptorProto();
+        $this->assertTrue(true);
     }
 
     public function testAny()
diff --git a/python/setup.py b/python/setup.py
index e884acb..5f05267 100755
--- a/python/setup.py
+++ b/python/setup.py
@@ -262,6 +262,9 @@
         "Programming Language :: Python :: 3",
         "Programming Language :: Python :: 3.3",
         "Programming Language :: Python :: 3.4",
+        "Programming Language :: Python :: 3.5",
+        "Programming Language :: Python :: 3.6",
+        "Programming Language :: Python :: 3.7",
         ],
       namespace_packages=['google'],
       packages=find_packages(
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum.cc b/src/google/protobuf/compiler/objectivec/objectivec_enum.cc
index 978e985..3b2ca55 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_enum.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_enum.cc
@@ -35,6 +35,7 @@
 #include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/stubs/strutil.h>
+#include <algorithm> // std::find()
 
 namespace google {
 namespace protobuf {
@@ -44,6 +45,17 @@
 EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor)
     : descriptor_(descriptor),
       name_(EnumName(descriptor_)) {
+  // Track the names for the enum values, and if an alias overlaps a base
+  // value, skip making a name for it. Likewise if two alias overlap, the
+  // first one wins.
+  // The one gap in this logic is if two base values overlap, but for that
+  // to happen you have to have "Foo" and "FOO" or "FOO_BAR" and "FooBar",
+  // and if an enum has that, it is already going to be confusing and a
+  // compile error is just fine.
+  // The values are still tracked to support the reflection apis and
+  // TextFormat handing since they are different there.
+  std::set<std::string> value_names;
+
   for (int i = 0; i < descriptor_->value_count(); i++) {
     const EnumValueDescriptor* value = descriptor_->value(i);
     const EnumValueDescriptor* canonical_value =
@@ -51,6 +63,14 @@
 
     if (value == canonical_value) {
       base_values_.push_back(value);
+      value_names.insert(EnumValueName(value));
+    } else {
+      string value_name(EnumValueName(value));
+      if (value_names.find(value_name) != value_names.end()) {
+        alias_values_to_skip_.insert(value);
+      } else {
+        value_names.insert(value_name);
+      }
     }
     all_values_.push_back(value);
   }
@@ -90,6 +110,9 @@
       "name", name_);
   }
   for (int i = 0; i < all_values_.size(); i++) {
+    if (alias_values_to_skip_.find(all_values_[i]) != alias_values_to_skip_.end()) {
+      continue;
+    }
     SourceLocation location;
     if (all_values_[i]->GetSourceLocation(&location)) {
       string comments = BuildCommentsString(location, true).c_str();
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum.h b/src/google/protobuf/compiler/objectivec/objectivec_enum.h
index d9dfc8a..50a6564 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_enum.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_enum.h
@@ -59,6 +59,7 @@
   const EnumDescriptor* descriptor_;
   std::vector<const EnumValueDescriptor*> base_values_;
   std::vector<const EnumValueDescriptor*> all_values_;
+  std::set<const EnumValueDescriptor*> alias_values_to_skip_;
   const string name_;
 };
 
diff --git a/tests.sh b/tests.sh
index 047d579..fdc3600 100755
--- a/tests.sh
+++ b/tests.sh
@@ -220,6 +220,38 @@
   cd ..
 }
 
+build_python_version() {
+  internal_build_cpp
+  cd python
+  envlist=$1
+  tox -e $envlist
+  cd ..
+}
+
+build_python27() {
+  build_python_version py27-python
+}
+
+build_python33() {
+  build_python_version py33-python
+}
+
+build_python34() {
+  build_python_version py34-python
+}
+
+build_python35() {
+  build_python_version py35-python
+}
+
+build_python36() {
+  build_python_version py36-python
+}
+
+build_python37() {
+  build_python_version py37-python
+}
+
 build_python_cpp() {
   internal_build_cpp
   export LD_LIBRARY_PATH=../src/.libs # for Linux
@@ -234,6 +266,40 @@
   cd ..
 }
 
+build_python_cpp_version() {
+  internal_build_cpp
+  export LD_LIBRARY_PATH=../src/.libs # for Linux
+  export DYLD_LIBRARY_PATH=../src/.libs # for OS X
+  cd python
+  envlist=$1
+  tox -e $envlist
+  cd ..
+}
+
+build_python27_cpp() {
+  build_python_cpp_version py27-cpp
+}
+
+build_python33_cpp() {
+  build_python_cpp_version py33-cpp
+}
+
+build_python34_cpp() {
+  build_python_cpp_version py34-cpp
+}
+
+build_python35_cpp() {
+  build_python_cpp_version py35-cpp
+}
+
+build_python36_cpp() {
+  build_python_cpp_version py36-cpp
+}
+
+build_python37_cpp() {
+  build_python_cpp_version py37-cpp
+}
+
 build_python_compatibility() {
   internal_build_cpp
   # Use the unit-tests extraced from 2.5.0 to test the compatibilty.
@@ -302,34 +368,25 @@
 
 use_php() {
   VERSION=$1
-  PHP=`which php`
-  PHP_CONFIG=`which php-config`
-  PHPIZE=`which phpize`
-  ln -sfn "/usr/local/php-${VERSION}/bin/php" $PHP
-  ln -sfn "/usr/local/php-${VERSION}/bin/php-config" $PHP_CONFIG
-  ln -sfn "/usr/local/php-${VERSION}/bin/phpize" $PHPIZE
+  export PATH=/usr/local/php-${VERSION}/bin:$PATH
+  export CPLUS_INCLUDE_PATH=/usr/local/php-${VERSION}/include/php/main:/usr/local/php-${VERSION}/include/php/:$CPLUS_INCLUDE_PATH
+  export C_INCLUDE_PATH=/usr/local/php-${VERSION}/include/php/main:/usr/local/php-${VERSION}/include/php/:$C_INCLUDE_PATH
   generate_php_test_proto
 }
 
 use_php_zts() {
   VERSION=$1
-  PHP=`which php`
-  PHP_CONFIG=`which php-config`
-  PHPIZE=`which phpize`
-  ln -sfn "/usr/local/php-${VERSION}-zts/bin/php" $PHP
-  ln -sfn "/usr/local/php-${VERSION}-zts/bin/php-config" $PHP_CONFIG
-  ln -sfn "/usr/local/php-${VERSION}-zts/bin/phpize" $PHPIZE
+  export PATH=/usr/local/php-${VERSION}-zts/bin:$PATH
+  export CPLUS_INCLUDE_PATH=/usr/local/php-${VERSION}-zts/include/php/main:/usr/local/php-${VERSION}-zts/include/php/:$CPLUS_INCLUDE_PATH
+  export C_INCLUDE_PATH=/usr/local/php-${VERSION}-zts/include/php/main:/usr/local/php-${VERSION}-zts/include/php/:$C_INCLUDE_PATH
   generate_php_test_proto
 }
 
 use_php_bc() {
   VERSION=$1
-  PHP=`which php`
-  PHP_CONFIG=`which php-config`
-  PHPIZE=`which phpize`
-  ln -sfn "/usr/local/php-${VERSION}-bc/bin/php" $PHP
-  ln -sfn "/usr/local/php-${VERSION}-bc/bin/php-config" $PHP_CONFIG
-  ln -sfn "/usr/local/php-${VERSION}-bc/bin/phpize" $PHPIZE
+  export PATH=/usr/local/php-${VERSION}-bc/bin:$PATH
+  export CPLUS_INCLUDE_PATH=/usr/local/php-${VERSION}-bc/include/php/main:/usr/local/php-${VERSION}-bc/include/php/:$CPLUS_INCLUDE_PATH
+  export C_INCLUDE_PATH=/usr/local/php-${VERSION}-bc/include/php/main:/usr/local/php-${VERSION}-bc/include/php/:$C_INCLUDE_PATH
   generate_php_test_proto
 }
 
@@ -338,9 +395,8 @@
 
   pushd php
   rm -rf vendor
-  cp -r /usr/local/vendor-5.5 vendor
-  wget https://phar.phpunit.de/phpunit-4.8.0.phar -O /usr/bin/phpunit
-  phpunit
+  composer update
+  ./vendor/bin/phpunit
   popd
   pushd conformance
   make test_php
@@ -349,7 +405,6 @@
 
 build_php5.5_c() {
   use_php 5.5
-  wget https://phar.phpunit.de/phpunit-4.8.0.phar -O /usr/bin/phpunit
   pushd php/tests
   /bin/bash ./test.sh 5.5
   popd
@@ -361,7 +416,6 @@
 
 build_php5.5_zts_c() {
   use_php_zts 5.5
-  wget https://phar.phpunit.de/phpunit-4.8.0.phar -O /usr/bin/phpunit
   cd php/tests && /bin/bash ./test.sh 5.5-zts && cd ../..
   # TODO(teboring): Add it back
   # pushd conformance
@@ -373,9 +427,8 @@
   use_php 5.6
   pushd php
   rm -rf vendor
-  cp -r /usr/local/vendor-5.6 vendor
-  wget https://phar.phpunit.de/phpunit-5.7.0.phar -O /usr/bin/phpunit
-  phpunit
+  composer update
+  ./vendor/bin/phpunit
   popd
   pushd conformance
   make test_php
@@ -384,7 +437,6 @@
 
 build_php5.6_c() {
   use_php 5.6
-  wget https://phar.phpunit.de/phpunit-5.7.0.phar -O /usr/bin/phpunit
   cd php/tests && /bin/bash ./test.sh 5.6 && cd ../..
   # TODO(teboring): Add it back
   # pushd conformance
@@ -394,7 +446,6 @@
 
 build_php5.6_zts_c() {
   use_php_zts 5.6
-  wget https://phar.phpunit.de/phpunit-5.7.0.phar -O /usr/bin/phpunit
   cd php/tests && /bin/bash ./test.sh 5.6-zts && cd ../..
   # TODO(teboring): Add it back
   # pushd conformance
@@ -431,9 +482,8 @@
   use_php 7.0
   pushd php
   rm -rf vendor
-  cp -r /usr/local/vendor-7.0 vendor
-  wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit
-  phpunit
+  composer update
+  ./vendor/bin/phpunit
   popd
   pushd conformance
   make test_php
@@ -442,7 +492,6 @@
 
 build_php7.0_c() {
   use_php 7.0
-  wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit
   cd php/tests && /bin/bash ./test.sh 7.0 && cd ../..
   # TODO(teboring): Add it back
   # pushd conformance
@@ -452,7 +501,6 @@
 
 build_php7.0_zts_c() {
   use_php_zts 7.0
-  wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit
   cd php/tests && /bin/bash ./test.sh 7.0-zts && cd ../..
   # TODO(teboring): Add it back.
   # pushd conformance
@@ -494,9 +542,8 @@
   use_php 7.1
   pushd php
   rm -rf vendor
-  cp -r /usr/local/vendor-7.1 vendor
-  wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit
-  phpunit
+  composer update
+  ./vendor/bin/phpunit
   popd
   pushd conformance
   make test_php
@@ -506,7 +553,6 @@
 build_php7.1_c() {
   ENABLE_CONFORMANCE_TEST=$1
   use_php 7.1
-  wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit
   cd php/tests && /bin/bash ./test.sh 7.1 && cd ../..
   if [ "$ENABLE_CONFORMANCE_TEST" = "true" ]
   then
@@ -518,7 +564,6 @@
 
 build_php7.1_zts_c() {
   use_php_zts 7.1
-  wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit
   cd php/tests && /bin/bash ./test.sh 7.1-zts && cd ../..
   pushd conformance
   # make test_php_c
@@ -545,6 +590,11 @@
   build_php_compatibility
 }
 
+build_benchmark() {
+  use_php 7.1
+  cd kokoro/linux/benchmark && ./run.sh
+}
+
 # -------- main --------
 
 if [ "$#" -ne 1 ]; then
@@ -577,7 +627,8 @@
             php_compatibility |
             php7.1   |
             php7.1_c |
-            php_all)
+            php_all |
+			benchmark)
 "
   exit 1
 fi