diff --git a/path_template.go b/path_template.go
deleted file mode 100644
index 41bda94..0000000
--- a/path_template.go
+++ /dev/null
@@ -1,176 +0,0 @@
-// 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.
-
-package gax
-
-import (
-	"errors"
-	"fmt"
-	"strings"
-)
-
-type matcher interface {
-	match([]string) (int, error)
-	String() string
-}
-
-type segment struct {
-	matcher
-	name string
-}
-
-type labelMatcher string
-
-func (ls labelMatcher) match(segments []string) (int, error) {
-	if len(segments) == 0 {
-		return 0, fmt.Errorf("expected %s but no more segments found", ls)
-	}
-	if segments[0] != string(ls) {
-		return 0, fmt.Errorf("expected %s but got %s", ls, segments[0])
-	}
-	return 1, nil
-}
-
-func (ls labelMatcher) String() string {
-	return string(ls)
-}
-
-type wildcardMatcher int
-
-func (wm wildcardMatcher) match(segments []string) (int, error) {
-	if len(segments) == 0 {
-		return 0, errors.New("no more segments found")
-	}
-	return 1, nil
-}
-
-func (wm wildcardMatcher) String() string {
-	return "*"
-}
-
-type pathWildcardMatcher int
-
-func (pwm pathWildcardMatcher) match(segments []string) (int, error) {
-	length := len(segments) - int(pwm)
-	if length <= 0 {
-		return 0, errors.New("not sufficient segments are supplied for path wildcard")
-	}
-	return length, nil
-}
-
-func (pwm pathWildcardMatcher) String() string {
-	return "**"
-}
-
-type ParseError struct {
-	Pos      int
-	Template string
-	Message  string
-}
-
-func (pe ParseError) Error() string {
-	return fmt.Sprintf("at %d of template '%s', %s", pe.Pos, pe.Template, pe.Message)
-}
-
-// PathTemplate manages the template to build and match with paths used
-// by API services. It holds a template and variable names in it, and
-// it can extract matched patterns from a path string or build a path
-// string from a binding.
-//
-// See http.proto in github.com/googleapis/googleapis/ for the details of
-// the template syntax.
-type PathTemplate struct {
-	segments []segment
-}
-
-// NewPathTemplate parses a path template, and returns a PathTemplate
-// instance if successful.
-func NewPathTemplate(template string) (*PathTemplate, error) {
-	return parsePathTemplate(template)
-}
-
-// MustCompilePathTemplate is like NewPathTemplate but panics if the
-// expression cannot be parsed. It simplifies safe initialization of
-// global variables holding compiled regular expressions.
-func MustCompilePathTemplate(template string) *PathTemplate {
-	pt, err := NewPathTemplate(template)
-	if err != nil {
-		panic(err)
-	}
-	return pt
-}
-
-// Match attempts to match the given path with the template, and returns
-// the mapping of the variable name to the matched pattern string.
-func (pt *PathTemplate) Match(path string) (map[string]string, error) {
-	paths := strings.Split(path, "/")
-	values := map[string]string{}
-	for _, segment := range pt.segments {
-		length, err := segment.match(paths)
-		if err != nil {
-			return nil, err
-		}
-		if segment.name != "" {
-			value := strings.Join(paths[:length], "/")
-			if oldValue, ok := values[segment.name]; ok {
-				values[segment.name] = oldValue + "/" + value
-			} else {
-				values[segment.name] = value
-			}
-		}
-		paths = paths[length:]
-	}
-	if len(paths) != 0 {
-		return nil, fmt.Errorf("Trailing path %s remains after the matching", strings.Join(paths, "/"))
-	}
-	return values, nil
-}
-
-// Render creates a path string from its template and the binding from
-// the variable name to the value.
-func (pt *PathTemplate) Render(binding map[string]string) (string, error) {
-	result := make([]string, 0, len(pt.segments))
-	var lastVariableName string
-	for _, segment := range pt.segments {
-		name := segment.name
-		if lastVariableName != "" && name == lastVariableName {
-			continue
-		}
-		lastVariableName = name
-		if name == "" {
-			result = append(result, segment.String())
-		} else if value, ok := binding[name]; ok {
-			result = append(result, value)
-		} else {
-			return "", fmt.Errorf("%s is not found", name)
-		}
-	}
-	built := strings.Join(result, "/")
-	return built, nil
-}
diff --git a/path_template_parser.go b/path_template_parser.go
deleted file mode 100644
index 79c8e75..0000000
--- a/path_template_parser.go
+++ /dev/null
@@ -1,227 +0,0 @@
-// 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.
-
-package gax
-
-import (
-	"fmt"
-	"io"
-	"strings"
-)
-
-// This parser follows the syntax of path templates, from
-// https://github.com/googleapis/googleapis/blob/master/google/api/http.proto.
-// The differences are that there is no custom verb, we allow the initial slash
-// to be absent, and that we are not strict as
-// https://tools.ietf.org/html/rfc6570 about the characters in identifiers and
-// literals.
-
-type pathTemplateParser struct {
-	r                *strings.Reader
-	runeCount        int             // the number of the current rune in the original string
-	nextVar          int             // the number to use for the next unnamed variable
-	seenName         map[string]bool // names we've seen already
-	seenPathWildcard bool            // have we seen "**" already?
-}
-
-func parsePathTemplate(template string) (pt *PathTemplate, err error) {
-	p := &pathTemplateParser{
-		r:        strings.NewReader(template),
-		seenName: map[string]bool{},
-	}
-
-	// Handle panics with strings like errors.
-	// See pathTemplateParser.error, below.
-	defer func() {
-		if x := recover(); x != nil {
-			errmsg, ok := x.(errString)
-			if !ok {
-				panic(x)
-			}
-			pt = nil
-			err = ParseError{p.runeCount, template, string(errmsg)}
-		}
-	}()
-
-	segs := p.template()
-	// If there is a path wildcard, set its length. We can't do this
-	// until we know how many segments we've got all together.
-	for i, seg := range segs {
-		if _, ok := seg.matcher.(pathWildcardMatcher); ok {
-			segs[i].matcher = pathWildcardMatcher(len(segs) - i - 1)
-			break
-		}
-	}
-	return &PathTemplate{segments: segs}, nil
-
-}
-
-// Used to indicate errors "thrown" by this parser. We don't use string because
-// many parts of the standard library panic with strings.
-type errString string
-
-// Terminates parsing immediately with an error.
-func (p *pathTemplateParser) error(msg string) {
-	panic(errString(msg))
-}
-
-// Template = [ "/" ] Segments
-func (p *pathTemplateParser) template() []segment {
-	var segs []segment
-	if p.consume('/') {
-		// Initial '/' needs an initial empty matcher.
-		segs = append(segs, segment{matcher: labelMatcher("")})
-	}
-	return append(segs, p.segments("")...)
-}
-
-// Segments = Segment { "/" Segment }
-func (p *pathTemplateParser) segments(name string) []segment {
-	var segs []segment
-	for {
-		subsegs := p.segment(name)
-		segs = append(segs, subsegs...)
-		if !p.consume('/') {
-			break
-		}
-	}
-	return segs
-}
-
-// Segment  = "*" | "**" | LITERAL | Variable
-func (p *pathTemplateParser) segment(name string) []segment {
-	if p.consume('*') {
-		if name == "" {
-			name = fmt.Sprintf("$%d", p.nextVar)
-			p.nextVar++
-		}
-		if p.consume('*') {
-			if p.seenPathWildcard {
-				p.error("multiple '**' disallowed")
-			}
-			p.seenPathWildcard = true
-			// We'll change 0 to the right number at the end.
-			return []segment{{name: name, matcher: pathWildcardMatcher(0)}}
-		}
-		return []segment{{name: name, matcher: wildcardMatcher(0)}}
-	}
-	if p.consume('{') {
-		if name != "" {
-			p.error("recursive named bindings are not allowed")
-		}
-		return p.variable()
-	}
-	return []segment{{name: name, matcher: labelMatcher(p.literal())}}
-}
-
-// Variable = "{" FieldPath [ "=" Segments ] "}"
-// "{" is already consumed.
-func (p *pathTemplateParser) variable() []segment {
-	// Simplification: treat FieldPath as LITERAL, instead of IDENT { '.' IDENT }
-	name := p.literal()
-	if p.seenName[name] {
-		p.error(name + " appears multiple times")
-	}
-	p.seenName[name] = true
-	var segs []segment
-	if p.consume('=') {
-		segs = p.segments(name)
-	} else {
-		// "{var}" is equivalent to "{var=*}"
-		segs = []segment{{name: name, matcher: wildcardMatcher(0)}}
-	}
-	if !p.consume('}') {
-		p.error("expected '}'")
-	}
-	return segs
-}
-
-// A literal is any sequence of characters other than a few special ones.
-// The list of stop characters is not quite the same as in the template RFC.
-func (p *pathTemplateParser) literal() string {
-	lit := p.consumeUntil("/*}{=")
-	if lit == "" {
-		p.error("empty literal")
-	}
-	return lit
-}
-
-// Read runes until EOF or one of the runes in stopRunes is encountered.
-// If the latter, unread the stop rune. Return the accumulated runes as a string.
-func (p *pathTemplateParser) consumeUntil(stopRunes string) string {
-	var runes []rune
-	for {
-		r, ok := p.readRune()
-		if !ok {
-			break
-		}
-		if strings.IndexRune(stopRunes, r) >= 0 {
-			p.unreadRune()
-			break
-		}
-		runes = append(runes, r)
-	}
-	return string(runes)
-}
-
-// If the next rune is r, consume it and return true.
-// Otherwise, leave the input unchanged and return false.
-func (p *pathTemplateParser) consume(r rune) bool {
-	rr, ok := p.readRune()
-	if !ok {
-		return false
-	}
-	if r == rr {
-		return true
-	}
-	p.unreadRune()
-	return false
-}
-
-// Read the next rune from the input. Return it.
-// The second return value is false at EOF.
-func (p *pathTemplateParser) readRune() (rune, bool) {
-	r, _, err := p.r.ReadRune()
-	if err == io.EOF {
-		return r, false
-	}
-	if err != nil {
-		p.error(err.Error())
-	}
-	p.runeCount++
-	return r, true
-}
-
-// Put the last rune that was read back on the input.
-func (p *pathTemplateParser) unreadRune() {
-	if err := p.r.UnreadRune(); err != nil {
-		p.error(err.Error())
-	}
-	p.runeCount--
-}
diff --git a/path_template_test.go b/path_template_test.go
deleted file mode 100644
index 49dea47..0000000
--- a/path_template_test.go
+++ /dev/null
@@ -1,211 +0,0 @@
-// 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.
-
-package gax
-
-import "testing"
-
-func TestPathTemplateMatchRender(t *testing.T) {
-	testCases := []struct {
-		message  string
-		template string
-		path     string
-		values   map[string]string
-	}{
-		{
-			"base",
-			"buckets/*/*/objects/*",
-			"buckets/f/o/objects/bar",
-			map[string]string{"$0": "f", "$1": "o", "$2": "bar"},
-		},
-		{
-			"path wildcards",
-			"bar/**/foo/*",
-			"bar/foo/foo/foo/bar",
-			map[string]string{"$0": "foo/foo", "$1": "bar"},
-		},
-		{
-			"named binding",
-			"buckets/{foo}/objects/*",
-			"buckets/foo/objects/bar",
-			map[string]string{"$0": "bar", "foo": "foo"},
-		},
-		{
-			"named binding with colon",
-			"buckets/{foo}/objects/*",
-			"buckets/foo:boo/objects/bar",
-			map[string]string{"$0": "bar", "foo": "foo:boo"},
-		},
-		{
-			"named binding with complex patterns",
-			"buckets/{foo=x/*/y/**}/objects/*",
-			"buckets/x/foo/y/bar/baz/objects/quox",
-			map[string]string{"$0": "quox", "foo": "x/foo/y/bar/baz"},
-		},
-		{
-			"starts with slash",
-			"/foo/*",
-			"/foo/bar",
-			map[string]string{"$0": "bar"},
-		},
-	}
-	for _, testCase := range testCases {
-		pt, err := NewPathTemplate(testCase.template)
-		if err != nil {
-			t.Errorf("[%s] Failed to parse template %s: %v", testCase.message, testCase.template, err)
-			continue
-		}
-		values, err := pt.Match(testCase.path)
-		if err != nil {
-			t.Errorf("[%s] PathTemplate '%s' failed to match with '%s', %v", testCase.message, testCase.template, testCase.path, err)
-			continue
-		}
-		for key, expected := range testCase.values {
-			actual, ok := values[key]
-			if !ok {
-				t.Errorf("[%s] The matched data misses the value for %s", testCase.message, key)
-				continue
-			}
-			delete(values, key)
-			if actual != expected {
-				t.Errorf("[%s] Failed to match: value for '%s' is expected '%s' but is actually '%s'", testCase.message, key, expected, actual)
-			}
-		}
-		if len(values) != 0 {
-			t.Errorf("[%s] The matched data has unexpected keys: %v", testCase.message, values)
-		}
-		built, err := pt.Render(testCase.values)
-		if err != nil || built != testCase.path {
-			t.Errorf("[%s] Built path '%s' is different from the expected '%s', %v", testCase.message, built, testCase.path, err)
-		}
-	}
-}
-
-func TestPathTemplateMatchFailure(t *testing.T) {
-	testCases := []struct {
-		message  string
-		template string
-		path     string
-	}{
-		{
-			"too many paths",
-			"buckets/*/*/objects/*",
-			"buckets/f/o/o/objects/bar",
-		},
-		{
-			"missing last path",
-			"buckets/*/*/objects/*",
-			"buckets/f/o/objects",
-		},
-		{
-			"too many paths at end",
-			"buckets/*/*/objects/*",
-			"buckets/f/o/objects/too/long",
-		},
-	}
-	for _, testCase := range testCases {
-		pt, err := NewPathTemplate(testCase.template)
-		if err != nil {
-			t.Errorf("[%s] Failed to parse path %s: %v", testCase.message, testCase.template, err)
-			continue
-		}
-		if values, err := pt.Match(testCase.path); err == nil {
-			t.Errorf("[%s] PathTemplate %s doesn't expect to match %s, but succeeded somehow. Match result: %v", testCase.message, testCase.template, testCase.path, values)
-
-		}
-	}
-}
-
-func TestPathTemplateRenderTooManyValues(t *testing.T) {
-	// Test cases where Render() succeeds but Match() doesn't return the same map.
-	testCases := []struct {
-		message  string
-		template string
-		values   map[string]string
-		expected string
-	}{
-		{
-			"too many",
-			"bar/*/foo/*",
-			map[string]string{"$0": "_1", "$1": "_2", "$2": "_3"},
-			"bar/_1/foo/_2",
-		},
-	}
-	for _, testCase := range testCases {
-		pt, err := NewPathTemplate(testCase.template)
-		if err != nil {
-			t.Errorf("[%s] Failed to parse template %s (error %v)", testCase.message, testCase.template, err)
-			continue
-		}
-		if result, err := pt.Render(testCase.values); err != nil || result != testCase.expected {
-			t.Errorf("[%s] Failed to build the path (expected '%s' but returned '%s'", testCase.message, testCase.expected, result)
-		}
-	}
-}
-
-func TestPathTemplateParseErrors(t *testing.T) {
-	testCases := []struct {
-		message  string
-		template string
-	}{
-		{
-			"multiple path wildcards",
-			"foo/**/bar/**",
-		},
-		{
-			"recursive named bindings",
-			"foo/{foo=foo/{bar}/baz/*}/baz/*",
-		},
-		{
-			"complicated multiple path wildcards patterns",
-			"foo/{foo=foo/**/bar/*}/baz/**",
-		},
-		{
-			"consective slashes",
-			"foo//bar",
-		},
-		{
-			"invalid variable pattern",
-			"foo/{foo=foo/*/}bar",
-		},
-		{
-			"same name multiple times",
-			"foo/{foo}/bar/{foo}",
-		},
-		{
-			"empty string after '='",
-			"foo/{foo=}/bar",
-		},
-	}
-	for _, testCase := range testCases {
-		if pt, err := NewPathTemplate(testCase.template); err == nil {
-			t.Errorf("[%s] Template '%s' should fail to be parsed, but succeeded and returned %+v", testCase.message, testCase.template, pt)
-		}
-	}
-}
