Added some initial shell scripts and docker file.
diff --git a/.travis.yml b/.travis.yml
index 9bc4d88..4a29540 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,7 +10,7 @@
 # The Objective C build needs Xcode 7.0 or later.
 osx_image: xcode7.2
 script:
-  - ./travis.sh $CONFIG
+  - ./tools/run_tests/travis.sh $CONFIG
 env:
   - CONFIG=cpp
   - CONFIG=cpp_distcheck
diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile
new file mode 100644
index 0000000..b5e26f9
--- /dev/null
+++ b/tools/docker/Dockerfile
@@ -0,0 +1,57 @@
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Base Dockerfile for gRPC dev images
+FROM debian:latest
+
+# Install Git.
+RUN apt-get update && apt-get install -y \
+  autoconf \
+  autotools-dev \
+  build-essential \
+  bzip2 \
+  curl \
+  gcc \
+  git \
+  libc6 \
+  libc6-dbg \
+  libc6-dev \
+  libgtest-dev \
+  libtool \
+  make \
+  strace \
+  python-dev \
+  python-setuptools \
+  telnet \
+  unzip \
+  wget \
+  zip && apt-get clean
+
+# Define the default command.
+CMD ["bash"]
diff --git a/tools/jenkins/build_and_run_docker.sh b/tools/jenkins/build_and_run_docker.sh
new file mode 100755
index 0000000..e77ffd6
--- /dev/null
+++ b/tools/jenkins/build_and_run_docker.sh
@@ -0,0 +1,78 @@
+#!/bin/bash
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Builds docker image and runs a command under it.
+# You should never need to call this script on your own.
+
+set -ex
+
+cd $(dirname $0)/../..
+git_root=$(pwd)
+cd -
+
+# Inputs
+# 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.
+# $@ - Extra args to pass to docker run
+
+# Use image name based on Dockerfile location checksum
+DOCKER_IMAGE_NAME=$(basename $DOCKERFILE_DIR)_$(sha1sum $DOCKERFILE_DIR/Dockerfile | cut -f1 -d\ )
+
+# Make sure docker image has been built. Should be instantaneous if so.
+docker build -t $DOCKER_IMAGE_NAME $DOCKERFILE_DIR
+
+# Choose random name for docker container
+CONTAINER_NAME="build_and_run_docker_$(uuidgen)"
+
+# Run command inside docker
+docker run \
+  "$@" \
+  -e EXTERNAL_GIT_ROOT="/var/local/jenkins/protobuf" \
+  -e THIS_IS_REALLY_NEEDED='see https://github.com/docker/docker/issues/14203 for why docker is awful' \
+  -v "$git_root:/var/local/jenkins/protobuf:ro" \
+  -w /var/local/git/protobuf \
+  --name=$CONTAINER_NAME \
+  $DOCKER_IMAGE_NAME \
+  bash -l "/var/local/jenkins/protobuf/$DOCKER_RUN_SCRIPT" || FAILED="true"
+
+# Copy output artifacts
+if [ "$OUTPUT_DIR" != "" ]
+then
+  docker cp "$CONTAINER_NAME:/var/local/git/protobuf/$OUTPUT_DIR" "$git_root" || FAILED="true"
+fi
+
+# remove the container, possibly killing it first
+docker rm -f $CONTAINER_NAME || true
+
+if [ "$FAILED" != "" ]
+then
+  exit 1
+fi
diff --git a/tools/jenkins/pull_request.sh b/tools/jenkins/pull_request.sh
new file mode 100755
index 0000000..cb0f407
--- /dev/null
+++ b/tools/jenkins/pull_request.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+
+export DOCKERFILE_DIR=tools/docker
+export DOCKER_RUN_SCRIPT=tools/run_tests/jenkins.sh
+./tools/jenkins/build_and_run_docker.sh
diff --git a/tools/run_tests/jenkins.sh b/tools/run_tests/jenkins.sh
new file mode 100755
index 0000000..34a1682
--- /dev/null
+++ b/tools/run_tests/jenkins.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+MY_DIR="$(dirname "$0")"
+BUILD_DIR=/tmp/protobuf
+
+source $MY_DIR/tests.sh
+
+rm -rf $BUILD_DIR
+mkdir -p $BUILD_DIR
+cd $BUILD_DIR
+git clone /var/local/jenkins/protobuf
+cd protobuf
+build_cpp
diff --git a/travis.sh b/tools/run_tests/tests.sh
old mode 100755
new mode 100644
similarity index 87%
rename from travis.sh
rename to tools/run_tests/tests.sh
index ff5e99d..f1c7e96
--- a/travis.sh
+++ b/tools/run_tests/tests.sh
@@ -1,17 +1,10 @@
-#!/usr/bin/env bash
-
-# Note: travis currently does not support testing more than one language so the
-# .travis.yml cheats and claims to only be cpp.  If they add multiple language
-# support, this should probably get updated to install steps and/or
-# rvm/gemfile/jdk/etc. entries rather than manually doing the work.
-
-# .travis.yml uses matrix.exclude to block the cases where app-get can't be
-# use to install things.
+# This file is not intended to be executed directly.  It is intended to be
+# included in a larger shell script.
 
 # For when some other test needs the C++ main build, including protoc and
 # libprotobuf.
 internal_build_cpp() {
-  if [ $(uname -s) == "Linux" ]; then
+  if [ $(uname -s) == "Linux" && "$TRAVIS" == "true" ]; then
     # Install GCC 4.8 to replace the default GCC 4.6. We need 4.8 for more
     # decent C++ 11 support in order to compile conformance tests.
     sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
@@ -284,31 +277,3 @@
   cd js && npm install && npm test && cd ..
 }
 
-# -------- main --------
-
-if [ "$#" -ne 1 ]; then
-  echo "
-Usage: $0 { cpp |
-            csharp |
-            java_jdk6 |
-            java_jdk7 |
-            java_oracle7 |
-            javanano_jdk6 |
-            javanano_jdk7 |
-            javanano_oracle7 |
-            objectivec_ios |
-            objectivec_osx |
-            python |
-            python_cpp |
-            ruby_19 |
-            ruby_20 |
-            ruby_21 |
-            ruby_22 |
-            jruby }
-"
-  exit 1
-fi
-
-set -e  # exit immediately on error
-set -x  # display all commands
-eval "build_$1"
diff --git a/tools/run_tests/travis.sh b/tools/run_tests/travis.sh
new file mode 100755
index 0000000..8c87a47
--- /dev/null
+++ b/tools/run_tests/travis.sh
@@ -0,0 +1,42 @@
+#!/usr/bin/env bash
+
+my_dir="$(dirname "$0")"
+
+source $my_dir/tests.sh
+
+# Note: travis currently does not support testing more than one language so the
+# .travis.yml cheats and claims to only be cpp.  If they add multiple language
+# support, this should probably get updated to install steps and/or
+# rvm/gemfile/jdk/etc. entries rather than manually doing the work.
+
+# .travis.yml uses matrix.exclude to block the cases where app-get can't be
+# use to install things.
+
+# -------- main --------
+
+if [ "$#" -ne 1 ]; then
+  echo "
+Usage: $0 { cpp |
+            csharp |
+            java_jdk6 |
+            java_jdk7 |
+            java_oracle7 |
+            javanano_jdk6 |
+            javanano_jdk7 |
+            javanano_oracle7 |
+            objectivec_ios |
+            objectivec_osx |
+            python |
+            python_cpp |
+            ruby_19 |
+            ruby_20 |
+            ruby_21 |
+            ruby_22 |
+            jruby }
+"
+  exit 1
+fi
+
+set -e  # exit immediately on error
+set -x  # display all commands
+eval "build_$1"