Преглед изворни кода

Merge pull request #48 from zricethezav/develop

Develop
Zachary Rice пре 8 година
родитељ
комит
27ab66827d
100 измењених фајлова са 34686 додато и 206 уклоњено
  1. 26 0
      CHANGELOG.md
  2. 65 0
      Gopkg.lock
  3. 42 0
      Gopkg.toml
  4. 65 25
      README.md
  5. 26 8
      checks.go
  6. 15 8
      checks_test.go
  7. 123 59
      leaks.go
  8. 0 54
      leaks_test.go
  9. 173 49
      main.go
  10. 21 3
      options.go
  11. 3 0
      vendor/github.com/golang/protobuf/AUTHORS
  12. 3 0
      vendor/github.com/golang/protobuf/CONTRIBUTORS
  13. 31 0
      vendor/github.com/golang/protobuf/LICENSE
  14. 43 0
      vendor/github.com/golang/protobuf/proto/Makefile
  15. 229 0
      vendor/github.com/golang/protobuf/proto/clone.go
  16. 970 0
      vendor/github.com/golang/protobuf/proto/decode.go
  17. 151 0
      vendor/github.com/golang/protobuf/proto/discard.go
  18. 1362 0
      vendor/github.com/golang/protobuf/proto/encode.go
  19. 300 0
      vendor/github.com/golang/protobuf/proto/equal.go
  20. 587 0
      vendor/github.com/golang/protobuf/proto/extensions.go
  21. 897 0
      vendor/github.com/golang/protobuf/proto/lib.go
  22. 311 0
      vendor/github.com/golang/protobuf/proto/message_set.go
  23. 484 0
      vendor/github.com/golang/protobuf/proto/pointer_reflect.go
  24. 270 0
      vendor/github.com/golang/protobuf/proto/pointer_unsafe.go
  25. 872 0
      vendor/github.com/golang/protobuf/proto/properties.go
  26. 854 0
      vendor/github.com/golang/protobuf/proto/text.go
  27. 895 0
      vendor/github.com/golang/protobuf/proto/text_parser.go
  28. 171 0
      vendor/github.com/google/go-github/AUTHORS
  29. 341 0
      vendor/github.com/google/go-github/LICENSE
  30. 69 0
      vendor/github.com/google/go-github/github/activity.go
  31. 324 0
      vendor/github.com/google/go-github/github/activity_events.go
  32. 223 0
      vendor/github.com/google/go-github/github/activity_notifications.go
  33. 135 0
      vendor/github.com/google/go-github/github/activity_star.go
  34. 146 0
      vendor/github.com/google/go-github/github/activity_watching.go
  35. 101 0
      vendor/github.com/google/go-github/github/admin.go
  36. 171 0
      vendor/github.com/google/go-github/github/admin_stats.go
  37. 169 0
      vendor/github.com/google/go-github/github/apps.go
  38. 114 0
      vendor/github.com/google/go-github/github/apps_installation.go
  39. 180 0
      vendor/github.com/google/go-github/github/apps_marketplace.go
  40. 435 0
      vendor/github.com/google/go-github/github/authorizations.go
  41. 191 0
      vendor/github.com/google/go-github/github/doc.go
  42. 748 0
      vendor/github.com/google/go-github/github/event_types.go
  43. 332 0
      vendor/github.com/google/go-github/github/gen-accessors.go
  44. 388 0
      vendor/github.com/google/go-github/github/gists.go
  45. 119 0
      vendor/github.com/google/go-github/github/gists_comments.go
  46. 12 0
      vendor/github.com/google/go-github/github/git.go
  47. 57 0
      vendor/github.com/google/go-github/github/git_blobs.go
  48. 139 0
      vendor/github.com/google/go-github/github/git_commits.go
  49. 233 0
      vendor/github.com/google/go-github/github/git_refs.go
  50. 84 0
      vendor/github.com/google/go-github/github/git_tags.go
  51. 93 0
      vendor/github.com/google/go-github/github/git_trees.go
  52. 10429 0
      vendor/github.com/google/go-github/github/github-accessors.go
  53. 980 0
      vendor/github.com/google/go-github/github/github.go
  54. 64 0
      vendor/github.com/google/go-github/github/gitignore.go
  55. 330 0
      vendor/github.com/google/go-github/github/issues.go
  56. 85 0
      vendor/github.com/google/go-github/github/issues_assignees.go
  57. 148 0
      vendor/github.com/google/go-github/github/issues_comments.go
  58. 151 0
      vendor/github.com/google/go-github/github/issues_events.go
  59. 251 0
      vendor/github.com/google/go-github/github/issues_labels.go
  60. 160 0
      vendor/github.com/google/go-github/github/issues_milestones.go
  61. 149 0
      vendor/github.com/google/go-github/github/issues_timeline.go
  62. 103 0
      vendor/github.com/google/go-github/github/licenses.go
  63. 245 0
      vendor/github.com/google/go-github/github/messages.go
  64. 224 0
      vendor/github.com/google/go-github/github/migrations.go
  65. 329 0
      vendor/github.com/google/go-github/github/migrations_source_import.go
  66. 253 0
      vendor/github.com/google/go-github/github/misc.go
  67. 209 0
      vendor/github.com/google/go-github/github/orgs.go
  68. 107 0
      vendor/github.com/google/go-github/github/orgs_hooks.go
  69. 299 0
      vendor/github.com/google/go-github/github/orgs_members.go
  70. 81 0
      vendor/github.com/google/go-github/github/orgs_outside_collaborators.go
  71. 60 0
      vendor/github.com/google/go-github/github/orgs_projects.go
  72. 512 0
      vendor/github.com/google/go-github/github/orgs_teams.go
  73. 91 0
      vendor/github.com/google/go-github/github/orgs_users_blocking.go
  74. 431 0
      vendor/github.com/google/go-github/github/projects.go
  75. 371 0
      vendor/github.com/google/go-github/github/pulls.go
  76. 157 0
      vendor/github.com/google/go-github/github/pulls_comments.go
  77. 88 0
      vendor/github.com/google/go-github/github/pulls_reviewers.go
  78. 236 0
      vendor/github.com/google/go-github/github/pulls_reviews.go
  79. 273 0
      vendor/github.com/google/go-github/github/reactions.go
  80. 1076 0
      vendor/github.com/google/go-github/github/repos.go
  81. 140 0
      vendor/github.com/google/go-github/github/repos_collaborators.go
  82. 161 0
      vendor/github.com/google/go-github/github/repos_comments.go
  83. 237 0
      vendor/github.com/google/go-github/github/repos_commits.go
  84. 57 0
      vendor/github.com/google/go-github/github/repos_community_health.go
  85. 266 0
      vendor/github.com/google/go-github/github/repos_contents.go
  86. 237 0
      vendor/github.com/google/go-github/github/repos_deployments.go
  87. 85 0
      vendor/github.com/google/go-github/github/repos_forks.go
  88. 192 0
      vendor/github.com/google/go-github/github/repos_hooks.go
  89. 98 0
      vendor/github.com/google/go-github/github/repos_invitations.go
  90. 111 0
      vendor/github.com/google/go-github/github/repos_keys.go
  91. 38 0
      vendor/github.com/google/go-github/github/repos_merging.go
  92. 143 0
      vendor/github.com/google/go-github/github/repos_pages.go
  93. 69 0
      vendor/github.com/google/go-github/github/repos_projects.go
  94. 327 0
      vendor/github.com/google/go-github/github/repos_releases.go
  95. 226 0
      vendor/github.com/google/go-github/github/repos_stats.go
  96. 129 0
      vendor/github.com/google/go-github/github/repos_statuses.go
  97. 141 0
      vendor/github.com/google/go-github/github/repos_traffic.go
  98. 210 0
      vendor/github.com/google/go-github/github/search.go
  99. 93 0
      vendor/github.com/google/go-github/github/strings.go
  100. 41 0
      vendor/github.com/google/go-github/github/timestamp.go

+ 26 - 0
CHANGELOG.md

@@ -0,0 +1,26 @@
+CHANGELOG
+=========
+
+0.2.0
+-----
+Version 0.2.0 of Gitleaks is the first version update since this got relatively popular. Based on the issues raised it seems that folks want better support for integration into their pipelines. I hear ya. This is what this update tries to provide. So... what are the changes?
+
+* Additionally regex checking
+* $HOME/.gitleaks/ directory for clones and reports
+* Clone into temp dir option
+* Persistent repos for Orgs and Users (no more re-cloning)
+* Pagination for Org/User list... no more partial repo lists
+* Since commit option
+* Updated README
+* Multi-staged Docker build
+* Travis CI
+
+
+0.1.0
+-----
+
+Version 0.1.0 of Gitleaks demonstrates:
+
+* full git history search
+* regex/entropy checks
+* report generation

+ 65 - 0
Gopkg.lock

@@ -0,0 +1,65 @@
+# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
+
+
+[[projects]]
+  name = "github.com/golang/protobuf"
+  packages = ["proto"]
+  revision = "925541529c1fa6821df4e44ce2723319eb2be768"
+  version = "v1.0.0"
+
+[[projects]]
+  name = "github.com/google/go-github"
+  packages = ["github"]
+  revision = "e48060a28fac52d0f1cb758bc8b87c07bac4a87d"
+  version = "v15.0.0"
+
+[[projects]]
+  branch = "master"
+  name = "github.com/google/go-querystring"
+  packages = ["query"]
+  revision = "53e6ce116135b80d037921a7fdd5138cf32d7a8a"
+
+[[projects]]
+  branch = "master"
+  name = "github.com/mitchellh/go-homedir"
+  packages = ["."]
+  revision = "b8bc1bf767474819792c23f32d8286a45736f1c6"
+
+[[projects]]
+  branch = "master"
+  name = "golang.org/x/net"
+  packages = [
+    "context",
+    "context/ctxhttp"
+  ]
+  revision = "cbe0f9307d0156177f9dd5dc85da1a31abc5f2fb"
+
+[[projects]]
+  branch = "master"
+  name = "golang.org/x/oauth2"
+  packages = [
+    ".",
+    "internal"
+  ]
+  revision = "543e37812f10c46c622c9575afd7ad22f22a12ba"
+
+[[projects]]
+  name = "google.golang.org/appengine"
+  packages = [
+    "internal",
+    "internal/base",
+    "internal/datastore",
+    "internal/log",
+    "internal/remote_api",
+    "internal/urlfetch",
+    "urlfetch"
+  ]
+  revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a"
+  version = "v1.0.0"
+
+[solve-meta]
+  analyzer-name = "dep"
+  analyzer-version = 1
+  inputs-digest = "7333248555a2c0448201b30ce445c31106919113c141e5b6436580e21151d851"
+  solver-name = "gps-cdcl"
+  solver-version = 1

+ 42 - 0
Gopkg.toml

@@ -0,0 +1,42 @@
+# Gopkg.toml example
+#
+# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
+# for detailed Gopkg.toml documentation.
+#
+# required = ["github.com/user/thing/cmd/thing"]
+# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
+#
+# [[constraint]]
+#   name = "github.com/user/project"
+#   version = "1.0.0"
+#
+# [[constraint]]
+#   name = "github.com/user/project2"
+#   branch = "dev"
+#   source = "github.com/myfork/project2"
+#
+# [[override]]
+#   name = "github.com/x/y"
+#   version = "2.4.0"
+#
+# [prune]
+#   non-go = false
+#   go-tests = true
+#   unused-packages = true
+
+
+[[constraint]]
+  name = "github.com/google/go-github"
+  version = "15.0.0"
+
+[[constraint]]
+  branch = "master"
+  name = "github.com/mitchellh/go-homedir"
+
+[[constraint]]
+  branch = "master"
+  name = "golang.org/x/oauth2"
+
+[prune]
+  go-tests = true
+  unused-packages = true

+ 65 - 25
README.md

@@ -5,11 +5,6 @@
 
 ## Check git repos for secrets and keys
 
-### Features
-
-* Search all commits on all branches in topological order
-* Regex/Entropy checks
-
 #### Installing
 
 ```bash
@@ -24,34 +19,80 @@ go get -u github.com/zricethezav/gitleaks
 ./gitleaks {git url}
 ```
 
-This example will clone the target `{git url}` and run a diff on all commits. A report will be outputted to `{repo_name}_leaks.json`
-Gitleaks scans all lines of all commits and checks if there are any regular expression matches. The regexs are defined in `main.go`. Work largely based on  [https://people.eecs.berkeley.edu/~rohanpadhye/files/key_leaks-msr15.pdf](https://people.eecs.berkeley.edu/~rohanpadhye/files/key_leaks-msr15.pdf) and regexes from https://github.com/dxa4481/truffleHog and https://github.com/anshumanbh/git-all-secrets.
-
-##### gitLeaks User
-```bash
-./gitleaks -u {user git url}
+Gitleaks will clone the target `<git url>` to `$HOME/.gitleaks/clones/<repo name>` and run a regex check against all diffs of all commits on all remotes in topological order. If any leaks are found gitleaks will output the leak in json, Ex:
 ```
-##### gitLeaks Org
+{
+   "line": "-const AWS_KEY = \"AKIALALEMEL33243OLIAE\"",
+   "commit": "eaeffdc65b4c73ccb67e75d96bd8743be2c85973",
+   "string": "AKIALALEMEL33243OLIA",
+   "reason": "AWS",
+   "commitMsg": "remove fake key",
+   "time": "2018-02-04 19:43:28 -0600",
+   "author": "Zachary Rice",
+   "file": "main.go",
+   "repoURL": "https://github.com/zricethezav/gronit"
+}
+``` 
+Gitleaks will not re-clone repos unless the temporary flag is set (see Options section), instead gitleaks will `fetch` all new changes before the scan. This works for users and organization repos as well. Regex's for the scan are defined in `main.go`, feel free to open a PR and contribute if you have additional regex you want included. Work largely based on  [https://people.eecs.berkeley.edu/~rohanpadhye/files/key_leaks-msr15.pdf](https://people.eecs.berkeley.edu/~rohanpadhye/files/key_leaks-msr15.pdf) and regexes from https://github.com/dxa4481/truffleHog and https://github.com/anshumanbh/git-all-secrets.
+
+#### Example with Report
 ```bash
-./gitleaks -o {org git url}
+gitleaks --json https://github.com/zricethezav/gronit
+```
+This will run gitleaks on one of my projects, gronit and create the following structure in `$HOME/.gitleaks`:
 ```
+.
+├── clones
+│   └── zricethezav
+│       └── gronit
+│           ├── README.md
+│           ├── main.go
+│           ├── options.go
+│           ├── server.go
+│           └── utils.go
+└── report
+    └── zricethezav
+        └── gronit_leaks.json
+```
+The clones directory contains the repo owner (me) and any repos gitleaks has scanned. Next time we run gitleaks on gronit again we will `fetch` gronit rather than `clone`. Reports are written out to `$HOME/.gitleaks/report/<owner>/<repo>_leaks.json`
 
-#### Help
+#### Options
 ```
 usage: gitleaks [options] <url>
 
 Options:
- -c                     Concurrency factor (default is 10)
- -u --user              Git user url
- -r --repo              Git repo url
- -o --org               Git organization url
- -s --since             Scan until this commit (SHA)
- -b --b64Entropy        Base64 entropy cutoff (default is 70)
- -x --hexEntropy        Hex entropy cutoff (default is 40)
- -e --entropy           Enable entropy
- --strict               Enables stopwords
- -h --help              Display this message
+ -c --concurrency 	Upper bound on concurrent diffs
+ -u --user 		    Git user url
+ -r --repo 		    Git repo url
+ -o --org 		    Git organization url
+ -s --since 		Commit to stop at
+ -b --b64Entropy 	Base64 entropy cutoff (default is 70)
+ -x --hexEntropy  	Hex entropy cutoff (default is 40)
+ -e --entropy		Enable entropy		
+ -j --json 		    Output gitleaks report
+ --token    		Github API token
+ --strict 		    Enables stopwords
+ -h --help 		    Display this message
+
 ```
+
+##### Options Explained
+
+| Option | Explanation |
+| ------------- | ------------- |
+| -c --concurrency | Set the limit on the number of concurrent diffs. If unbounded, your system would throw a `too many open files` error. Tweak `ulimit` for quicker scans at your own risk. Ex: `gitleaks -c 100 <repo_url>` |
+| -u --user | Target git user. Reports and clones are dumped to `$HOME/.gitleaks/clones/<user>/<user_repos>` and `$HOME/.gitleaks/reports/<user>/<gitleaks_reports>`. Ex: `gitleaks -u <user_git_url>`.
+| -o --org | Target git organization. Reports and clones are dumped to `$HOME/.gitleaks/clones/<org>/<org_repos>` and `$HOME/.gitleaks/reports/<org>/<gitleaks_reports>`. Ex: `gitleaks -o <org_git_url>`
+| -r --repo | Default behavior is to have gitleaks target a specific repo, so this option is unecessary, but... Target git repo. Reports and clones are dumped to `$HOME/.gitleaks/clones/<owner>/<repos>` and `$HOME/.gitleaks/reports/<owner>/<gitleaks_reports>`
+| -s --since  | Since argument accepts a commit hash and will scan the repo history up to and including this hash. Ex: `gitleaks -s <HASH> <repo_url>`
+| -b --b64Entropy | Entropy cutoff for base 64 characters. Ex: `gitleaks -e -b 70 <repo_url>` |
+| -x --hexEntropy | Entropy cutoff for hex characters. Ex: `gitleaks -e -x 70 <repo_url>` |
+| -e --entroy | Enable entropy checks. Ex: `gitleaks -e <repo_url>` |
+| -j --json | Enable report generation. Ex: `gitleaks --json <repo_url>` | 
+| -t --temporary | Cloned repos will be cloned into a temp directory and removed after gitleaks exits. Ex: `gitleaks -t <repo_url>` |
+| --token | NOTE: you should use env var `GITHUB_TOKEN` instead of this flag. Github API token needed for scanning private repos and pagination on repo fetching from github's api. |
+| -- strict | Enable stopwords. Ex: `gitleaks --strict <repo_url>` |
+
 NOTE: your mileage may vary so if you aren't getting the results you expected try updating the regexes to fit your needs or try tweaking the entropy cutoffs and stopwords. Entropy cutoff for base64 alphabets seemed to give good results around 70 and hex alphabets seemed to give good results around 40. Entropy is calculated using [Shannon entropy](http://www.bearcave.com/misl/misl_tech/wavelets/compression/shannon.html).
 
 
@@ -69,4 +110,3 @@ docker build -t gitleaks .
 docker run --rm --name=gitleaks gitleaks https://github.com/zricethezav/gitleaks
 ```
 
-

+ 26 - 8
checks.go

@@ -1,32 +1,50 @@
 package main
 
 import (
+	_ "fmt"
 	"math"
 	"strings"
 )
 
+// TODO LOCAL REPO!!!!
+
 // checks Regex and if enabled, entropy and stopwords
-func doChecks(diff string, commit string) []LeakElem {
-	var match string
-	var leaks []LeakElem
-	var leak LeakElem
+func doChecks(diff string, commit Commit, opts *Options, repo RepoDesc) []LeakElem {
+	var (
+		match string
+		leaks []LeakElem
+		leak  LeakElem
+	)
+
 	lines := strings.Split(diff, "\n")
+	file := "unable to determine file"
 	for _, line := range lines {
+		if strings.Contains(line, "diff --git a") {
+			idx := fileDiffRegex.FindStringIndex(line)
+			if len(idx) == 2 {
+				file = line[idx[1]:]
+			}
+		}
+
 		for leakType, re := range regexes {
 			match = re.FindString(line)
 			if len(match) == 0 ||
 				(opts.Strict && containsStopWords(line)) ||
-				(opts.Entropy && !checkShannonEntropy(line)) {
+				(opts.Entropy && !checkShannonEntropy(line, opts)) {
 				continue
 			}
 
 			leak = LeakElem{
 				Line:     line,
-				Commit:   commit,
+				Commit:   commit.Hash,
 				Offender: match,
 				Reason:   leakType,
+				Msg:      commit.Msg,
+				Time:     commit.Time,
+				Author:   commit.Author,
+				File:     file,
+				RepoURL:  repo.url,
 			}
-
 			leaks = append(leaks, leak)
 		}
 	}
@@ -35,7 +53,7 @@ func doChecks(diff string, commit string) []LeakElem {
 }
 
 // checkShannonEntropy checks entropy of target
-func checkShannonEntropy(target string) bool {
+func checkShannonEntropy(target string, opts *Options) bool {
 	var (
 		sum             float64
 		targetBase64Len int

+ 15 - 8
checks_test.go

@@ -4,24 +4,25 @@ import (
 	"testing"
 )
 
-func init() {
-	opts = &Options{
+func TestCheckRegex(t *testing.T) {
+	var results []LeakElem
+	opts := &Options{
 		Concurrency:      10,
 		B64EntropyCutoff: 70,
 		HexEntropyCutoff: 40,
 		Entropy:          false,
 	}
-}
-
-func TestCheckRegex(t *testing.T) {
-	var results []LeakElem
+	repo := RepoDesc{
+		url: "someurl",
+	}
+	commit := Commit{}
 	checks := map[string]int{
 		"aws=\"AKIALALEMEL33243OLIAE": 1,
 		"aws\"afewafewafewafewaf\"":   0,
 	}
 
 	for k, v := range checks {
-		results = doChecks(k, "commit")
+		results = doChecks(k, commit, opts, repo)
 		if v != len(results) {
 			t.Errorf("regexCheck failed on string %s", k)
 		}
@@ -30,6 +31,12 @@ func TestCheckRegex(t *testing.T) {
 
 func TestEntropy(t *testing.T) {
 	var enoughEntropy bool
+	opts := &Options{
+		Concurrency:      10,
+		B64EntropyCutoff: 70,
+		HexEntropyCutoff: 40,
+		Entropy:          false,
+	}
 	checks := map[string]bool{
 		"reddit_api_secret = settings./.http}":           false,
 		"heroku_client_secret = simple":                  false,
@@ -37,7 +44,7 @@ func TestEntropy(t *testing.T) {
 		"aws_secret= \"AKIAIMNOJVGFDXXFE4OA\"":           true,
 	}
 	for k, v := range checks {
-		enoughEntropy = checkShannonEntropy(k)
+		enoughEntropy = checkShannonEntropy(k, opts)
 		if v != enoughEntropy {
 			t.Errorf("checkEntropy failed for %s. Expected %t, got %t", k, v, enoughEntropy)
 		}

+ 123 - 59
leaks.go

@@ -9,6 +9,7 @@ import (
 	"os"
 	"os/exec"
 	"os/signal"
+	"path/filepath"
 	"strings"
 	"sync"
 	"syscall"
@@ -20,66 +21,106 @@ type LeakElem struct {
 	Commit   string `json:"commit"`
 	Offender string `json:"string"`
 	Reason   string `json:"reason"`
+	Msg      string `json:"commitMsg"`
+	Time     string `json:"time"`
+	Author   string `json:"author"`
+	File     string `json:"file"`
+	RepoURL  string `json:"repoURL"`
 }
 
-// start clones and determines if there are any leaks
-func start(opts *Options) {
-	c := make(chan os.Signal, 2)
-	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
+type Commit struct {
+	Hash   string
+	Author string
+	Time   string
+	Msg    string
+}
 
-	fmt.Printf("Cloning \x1b[37;1m%s\x1b[0m...\n", opts.RepoURL)
-	err := exec.Command("git", "clone", opts.RepoURL).Run()
-	if err != nil {
-		log.Printf("failed to clone repo %v", err)
-		return
+func rmTmp(owner *Owner) {
+	if _, err := os.Stat(owner.path); err == nil {
+		err := os.RemoveAll(owner.path)
+		log.Printf("\nCleaning up tmp repos in %s\n", owner.path)
+		if err != nil {
+			log.Printf("failed to properly remove tmp gitleaks dir: %v", err)
+		}
 	}
-	fmt.Printf("Evaluating \x1b[37;1m%s\x1b[0m...\n", opts.RepoURL)
-	repoName := getLocalRepoName(opts.RepoURL)
-	if err = os.Chdir(repoName); err != nil {
-		log.Fatal(err)
+	os.Exit(1)
+}
+
+// start
+func start(repos []RepoDesc, owner *Owner, opts *Options) {
+	var report []LeakElem
+	if opts.Tmp {
+		defer rmTmp(owner)
 	}
+
+	// interrupt handling
+	c := make(chan os.Signal, 2)
+	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
 	go func() {
 		<-c
-		cleanup(repoName)
+		if opts.Tmp {
+			rmTmp(owner)
+		}
 		os.Exit(1)
 	}()
 
-	report := getLeaks(repoName, opts)
-	if len(report) == 0 {
-		fmt.Printf("No Leaks detected for \x1b[35;2m%s\x1b[0m...\n\n", opts.RepoURL)
-	}
-	cleanup(repoName)
-	reportJSON, _ := json.MarshalIndent(report, "", "\t")
-	err = ioutil.WriteFile(fmt.Sprintf("%s_leaks.json", repoName), reportJSON, 0644)
-	if err != nil {
-		log.Fatalf("Can't write to file: %s", err)
-	}
-}
+	// run checks on repos
+	for _, repo := range repos {
+		dotGitPath := filepath.Join(repo.path, ".git")
+		if _, err := os.Stat(dotGitPath); err == nil {
+			if err := os.Chdir(fmt.Sprintf(repo.path)); err != nil {
+				log.Fatal(err)
+			}
+			// use pre-cloned repo
+			fmt.Printf("Checking \x1b[37;1m%s\x1b[0m...\n", repo.url)
+			err := exec.Command("git", "fetch").Run()
+			if err != nil {
+				log.Printf("failed to fetch repo %v", err)
+				return
+			}
+			report = getLeaks(repo, owner, opts)
+		} else {
+			// no repo present, clone it
+			if err := os.Chdir(fmt.Sprintf(owner.path)); err != nil {
+				log.Fatal(err)
+			}
+			fmt.Printf("Cloning \x1b[37;1m%s\x1b[0m...\n", repo.url)
+			err := exec.Command("git", "clone", repo.url).Run()
+			if err != nil {
+				fmt.Printf("failed to clone repo %v", err)
+				return
+			}
+			report = getLeaks(repo, owner, opts)
+		}
 
-// getLocalRepoName generates the name of the local clone folder based on the given URL
-func getLocalRepoName(url string) string {
-	splitSlashes := strings.Split(url, "/")
-	name := splitSlashes[len(splitSlashes)-1]
-	name = strings.TrimSuffix(name, ".git")
-	splitColons := strings.Split(name, ":")
-	name = splitColons[len(splitColons)-1]
+		if len(report) == 0 {
+			fmt.Printf("No Leaks detected for \x1b[35;2m%s\x1b[0m...\n\n", repo.url)
+		}
 
-	return name
+		if opts.EnableJSON {
+			outputGitLeaksReport(report, repo, opts)
+		}
+	}
 }
 
-// cleanup deletes the repo
-func cleanup(repoName string) {
-	if err := os.Chdir(appRoot); err != nil {
-		log.Fatalf("failed cleaning up repo. Does the repo exist? %v", err)
+// outputGitLeaksReport
+func outputGitLeaksReport(report []LeakElem, repo RepoDesc, opts *Options) {
+	reportJSON, _ := json.MarshalIndent(report, "", "\t")
+	if _, err := os.Stat(repo.owner.reportPath); os.IsNotExist(err) {
+		os.Mkdir(repo.owner.reportPath, os.ModePerm)
 	}
-	err := exec.Command("rm", "-rf", repoName).Run()
+
+	reportFileName := fmt.Sprintf("%s_leaks.json", repo.name)
+	reportFile := filepath.Join(repo.owner.reportPath, reportFileName)
+	err := ioutil.WriteFile(reportFile, reportJSON, 0644)
 	if err != nil {
-		log.Fatal(err)
+		log.Fatalf("Can't write to file: %s", err)
 	}
+	fmt.Printf("Report written to %s\n", reportFile)
 }
 
 // getLeaks will attempt to find gitleaks
-func getLeaks(repoName string, opts *Options) []LeakElem {
+func getLeaks(repo RepoDesc, owner *Owner, opts *Options) []LeakElem {
 	var (
 		out               []byte
 		err               error
@@ -102,43 +143,48 @@ func getLeaks(repoName string, opts *Options) []LeakElem {
 		}
 	}(&commitWG, &gitLeakReceiverWG)
 
-	out, err = exec.Command("git", "rev-list", "--all", "--remotes", "--topo-order").Output()
+	if err := os.Chdir(fmt.Sprintf(repo.path)); err != nil {
+		log.Fatal(err)
+	}
+
+	gitFormat := "--format=%H%n%an%n%s%n%ci"
+	out, err = exec.Command("git", "rev-list", "--all",
+		"--remotes", "--topo-order", gitFormat).Output()
 	if err != nil {
 		log.Fatalf("error retrieving commits%v\n", err)
 	}
 
-	commits := bytes.Split(out, []byte("\n"))
-	for _, currCommitB := range commits {
-		currCommit := string(currCommitB)
-		if currCommit == "" {
+	revListLines := bytes.Split(out, []byte("\n"))
+	commits := parseFormattedRevList(revListLines)
+
+	for _, commit := range commits {
+		if commit.Hash == "" {
 			continue
 		}
-		if currCommit == opts.SinceCommit {
-			break
-		}
 
 		commitWG.Add(1)
-		go func(currCommit string, repoName string, commitWG *sync.WaitGroup,
-			gitLeakReceiverWG *sync.WaitGroup) {
-
+		go func(currCommit Commit, repoName string, commitWG *sync.WaitGroup,
+			gitLeakReceiverWG *sync.WaitGroup, opts *Options) {
 			defer commitWG.Done()
-
-			if err := os.Chdir(fmt.Sprintf("%s/%s", appRoot, repoName)); err != nil {
+			if err := os.Chdir(fmt.Sprintf(repo.path)); err != nil {
 				log.Fatal(err)
 			}
 
-			commitCmp := fmt.Sprintf("%s^!", currCommit)
+			commitCmp := fmt.Sprintf("%s^!", currCommit.Hash)
 			semaphoreChan <- struct{}{}
 			out, err := exec.Command("git", "diff", commitCmp).Output()
 			<-semaphoreChan
 
 			if err != nil {
-				fmt.Printf("error retrieving diff for commit %s try turning concurrency factor down %v\n", currCommit, err)
-				cleanup(repoName)
-				return
+				if strings.Contains(err.Error(), "too many files open") {
+					log.Printf("error retrieving diff for commit %s. Try turning concurrency down. %v\n", currCommit, err)
+				}
+				if opts.Tmp {
+					rmTmp(owner)
+				}
 			}
 
-			leaks := doChecks(string(out), currCommit)
+			leaks := doChecks(string(out), currCommit, opts, repo)
 			if len(leaks) == 0 {
 				return
 			}
@@ -147,10 +193,28 @@ func getLeaks(repoName string, opts *Options) []LeakElem {
 				gitLeaks <- leak
 			}
 
-		}(currCommit, repoName, &commitWG, &gitLeakReceiverWG)
+		}(commit, repo.name, &commitWG, &gitLeakReceiverWG, opts)
+
+		if commit.Hash == opts.SinceCommit {
+			break
+		}
 	}
 
 	commitWG.Wait()
 	gitLeakReceiverWG.Wait()
 	return report
 }
+
+func parseFormattedRevList(revList [][]byte) []Commit {
+	var commits []Commit
+	for i := 0; i < len(revList)-1; i = i + 5 {
+		commit := Commit{
+			Hash:   string(revList[i+1]),
+			Author: string(revList[i+2]),
+			Msg:    string(revList[i+3]),
+			Time:   string(revList[i+4]),
+		}
+		commits = append(commits, commit)
+	}
+	return commits
+}

+ 0 - 54
leaks_test.go

@@ -1,54 +0,0 @@
-package main
-
-import "testing"
-
-func TestGetLocalRepoName(t *testing.T) {
-	cases := []struct {
-		name     string
-		input    string
-		expected string
-	}{
-		{
-			"Usual github url",
-			"https://github.com/usual/url",
-			"url",
-		},
-		{
-			"Usual github url with .git suffix",
-			"https://github.com/usual/url.git",
-			"url",
-		},
-		{
-			"personal git url",
-			"git@github.com:url.git",
-			"url",
-		},
-		{
-			"personal git url in sub folder",
-			"git@github.com:sub/url.git",
-			"url",
-		},
-		{
-			"ssh git url with port",
-			"ssh://git@github.com:2222/sub/url.git",
-			"url",
-		},
-		{
-			"local git in sub folder",
-			"local/url.git",
-			"url",
-		},
-		{
-			"local git in same folder",
-			"url.git",
-			"url",
-		},
-	}
-
-	for _, c := range cases {
-		actual := getLocalRepoName(c.input)
-		if actual != c.expected {
-			t.Errorf("'%s' failed. Input: '%s'; Expected: '%s'; Got: '%s'", c.input, c.name, c.expected, actual)
-		}
-	}
-}

+ 173 - 49
main.go

@@ -1,39 +1,48 @@
 package main
 
 import (
-	"encoding/json"
-	"fmt"
+	"context"
+	"github.com/google/go-github/github"
+	"github.com/mitchellh/go-homedir"
+	"golang.org/x/oauth2"
+	"io/ioutil"
 	"log"
 	"net/http"
 	"os"
+	"path"
+	"path/filepath"
 	"regexp"
 	"strings"
 )
 
 var (
-	appRoot     string
-	regexes     map[string]*regexp.Regexp
-	stopWords   []string
-	base64Chars string
-	hexChars    string
-	opts        *Options
-	assignRegex *regexp.Regexp
+	regexes            map[string]*regexp.Regexp
+	stopWords          []string
+	base64Chars        string
+	hexChars           string
+	assignRegex        *regexp.Regexp
+	fileDiffRegex      *regexp.Regexp
+	gitLeaksPath       string
+	gitLeaksClonePath  string
+	gitLeaksReportPath string
 )
 
-// RepoElem used for parsing json from github api
-type RepoElem struct {
-	RepoURL string `json:"html_url"`
+type RepoDesc struct {
+	name  string
+	url   string
+	path  string
+	owner *Owner
 }
 
-func init() {
-	var (
-		err error
-	)
+type Owner struct {
+	name        string
+	url         string
+	accountType string
+	path        string
+	reportPath  string
+}
 
-	appRoot, err = os.Getwd()
-	if err != nil {
-		log.Fatalf("Can't get working dir: %s", err)
-	}
+func init() {
 	base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
 	hexChars = "1234567890abcdefABCDEF"
 
@@ -53,46 +62,161 @@ func init() {
 		// "Custom": regexp.MustCompile(".*")
 	}
 	assignRegex = regexp.MustCompile(`(=|:|:=|<-)`)
+	fileDiffRegex = regexp.MustCompile("diff --git a.+b/")
+	homeDir, err := homedir.Dir()
+	if err != nil {
+		log.Fatal("Cant find home dir")
+	}
+
+	gitLeaksPath = filepath.Join(homeDir, ".gitleaks")
+	if _, err := os.Stat(gitLeaksPath); os.IsNotExist(err) {
+		os.Mkdir(gitLeaksPath, os.ModePerm)
+	}
+	gitLeaksClonePath = filepath.Join(gitLeaksPath, "clones")
+	if _, err := os.Stat(gitLeaksClonePath); os.IsNotExist(err) {
+		os.Mkdir(gitLeaksClonePath, os.ModePerm)
+	}
+	gitLeaksReportPath = filepath.Join(gitLeaksPath, "report")
+	if _, err := os.Stat(gitLeaksReportPath); os.IsNotExist(err) {
+		os.Mkdir(gitLeaksReportPath, os.ModePerm)
+	}
 }
 
-func main() {
-	args := os.Args[1:]
-	opts = parseOptions(args)
+// getOwner
+func getOwner(opts *Options) *Owner {
+	var owner Owner
 	if opts.RepoURL != "" {
-		start(opts)
-	} else if opts.UserURL != "" || opts.OrgURL != "" {
-		repoList := repoScan(opts)
-		for _, repo := range repoList {
-			opts.RepoURL = repo.RepoURL
-			start(opts)
+		splitSlashes := strings.Split(opts.RepoURL, "/")
+		owner = Owner{
+			name:        splitSlashes[len(splitSlashes)-2],
+			url:         opts.RepoURL,
+			accountType: "users",
+		}
+
+	} else if opts.UserURL != "" {
+		_, ownerName := path.Split(opts.UserURL)
+		owner = Owner{
+			name:        ownerName,
+			url:         opts.UserURL,
+			accountType: "user",
+		}
+	} else if opts.OrgURL != "" {
+		_, ownerName := path.Split(opts.OrgURL)
+		owner = Owner{
+			name:        ownerName,
+			url:         opts.OrgURL,
+			accountType: "org",
 		}
 	}
+
+	if opts.Tmp {
+		dir, err := ioutil.TempDir("", owner.name)
+		if err != nil {
+			log.Fatal("Cant make temp dir")
+		}
+		owner.path = dir
+	} else {
+		owner.path = filepath.Join(gitLeaksClonePath, owner.name)
+		if _, err := os.Stat(owner.path); os.IsNotExist(err) {
+			os.Mkdir(owner.path, os.ModePerm)
+		}
+	}
+	owner.reportPath = filepath.Join(gitLeaksPath, "report", owner.name)
+	return &owner
 }
 
-// repoScan attempts to parse all repo urls from an organization or user
-func repoScan(opts *Options) []RepoElem {
+// getRepos
+func getRepos(opts *Options, owner *Owner) []RepoDesc {
 	var (
-		targetURL  string
-		target     string
-		targetType string
-		repoList   []RepoElem
+		allRepos  []*github.Repository
+		repos     []*github.Repository
+		repoDescs []RepoDesc
+		resp      *github.Response
+		ctx       = context.Background()
+		err       error
 	)
+	if opts.RepoURL != "" {
+		_, repoName := path.Split(opts.RepoURL)
+		if strings.HasSuffix(repoName, ".git") {
+			repoName = repoName[:len(repoName)-4]
+		}
+		ownerPath := filepath.Join(owner.path, repoName)
+		repo := RepoDesc{
+			name:  repoName,
+			url:   opts.RepoURL,
+			owner: owner,
+			path:  ownerPath}
+		repoDescs = append(repoDescs, repo)
+		return repoDescs
+	}
 
-	if opts.UserURL != "" {
-		targetURL = opts.UserURL
-		targetType = "users"
-	} else {
-		targetURL = opts.OrgURL
-		targetType = "orgs"
+	tokenClient := getAccessToken(opts)
+	gitClient := github.NewClient(tokenClient)
+
+	// TODO include fork check
+	orgOpt := &github.RepositoryListByOrgOptions{
+		ListOptions: github.ListOptions{PerPage: 10},
+	}
+	userOpt := &github.RepositoryListOptions{
+		ListOptions: github.ListOptions{PerPage: 10},
 	}
-	splitTargetURL := strings.Split(targetURL, "/")
-	target = splitTargetURL[len(splitTargetURL)-1]
 
-	resp, err := http.Get(fmt.Sprintf("https://api.github.com/%s/%s/repos", targetType, target))
-	if err != nil {
-		log.Fatal(err)
+	for {
+		if opts.UserURL != "" {
+			repos, resp, err = gitClient.Repositories.List(
+				ctx, owner.name, userOpt)
+		} else if opts.OrgURL != "" {
+			repos, resp, err = gitClient.Repositories.ListByOrg(
+				ctx, owner.name, orgOpt)
+		}
+		allRepos = append(allRepos, repos...)
+		if resp.NextPage == 0 || err != nil {
+			break
+		}
+
+		for _, repo := range repos {
+			repoPath := filepath.Join(owner.path, *repo.Name)
+			repoDescs = append(repoDescs,
+				RepoDesc{
+					name:  *repo.Name,
+					url:   *repo.CloneURL,
+					owner: owner,
+					path:  repoPath})
+		}
+
+		orgOpt.Page = resp.NextPage
+		userOpt.Page = resp.NextPage
 	}
-	defer resp.Body.Close()
-	json.NewDecoder(resp.Body).Decode(&repoList)
-	return repoList
+
+	return repoDescs
+}
+
+// getAccessToken checks
+// 1. option
+// 2. env var
+// TODO. $HOME/.gitleaks/.creds
+func getAccessToken(opts *Options) *http.Client {
+	var token string
+	if opts.Token != "" {
+		token = opts.Token
+	} else {
+		token = os.Getenv("GITHUB_TOKEN")
+	}
+	if token == "" {
+		return nil
+	}
+
+	tokenService := oauth2.StaticTokenSource(
+		&oauth2.Token{AccessToken: token},
+	)
+	tokenClient := oauth2.NewClient(context.Background(), tokenService)
+	return tokenClient
+}
+
+func main() {
+	args := os.Args[1:]
+	opts := parseOptions(args)
+	owner := getOwner(opts)
+	repos := getRepos(opts, owner)
+	start(repos, owner, opts)
 }

+ 21 - 3
options.go

@@ -9,7 +9,7 @@ import (
 const usage = `usage: gitleaks [options] <url>
 
 Options:
- -c 			Concurrency factor (default is 10)
+ -c --concurrency 	Upper bound on concurrent diffs
  -u --user 		Git user url
  -r --repo 		Git repo url
  -o --org 		Git organization url
@@ -17,7 +17,9 @@ Options:
  -b --b64Entropy 	Base64 entropy cutoff (default is 70)
  -x --hexEntropy  	Hex entropy cutoff (default is 40)
  -e --entropy		Enable entropy		
+ -j --json 		Output gitleaks report
  -h --help 		Display this message
+ --token    		Github API token
  --strict 		Enables stopwords
 `
 
@@ -32,6 +34,12 @@ type Options struct {
 	Strict           bool
 	Entropy          bool
 	SinceCommit      string
+	Persist          bool
+	IncludeForks     bool
+	Tmp              bool
+	EnableJSON       bool
+	Token            string
+	Verbose          bool
 }
 
 // help prints the usage string and exits
@@ -72,7 +80,6 @@ func parseOptions(args []string) *Options {
 		Concurrency:      10,
 		B64EntropyCutoff: 70,
 		HexEntropyCutoff: 40,
-		Entropy:          false,
 	}
 
 	if len(args) == 0 {
@@ -92,7 +99,7 @@ func parseOptions(args []string) *Options {
 			opts.HexEntropyCutoff = optionsNextInt(args, &i)
 		case "-e", "--entropy":
 			opts.Entropy = true
-		case "-c":
+		case "-c", "--concurrency":
 			opts.Concurrency = optionsNextInt(args, &i)
 		case "-o", "--org":
 			opts.OrgURL = optionsNextString(args, &i)
@@ -100,6 +107,12 @@ func parseOptions(args []string) *Options {
 			opts.UserURL = optionsNextString(args, &i)
 		case "-r", "--repo":
 			opts.RepoURL = optionsNextString(args, &i)
+		case "-t", "--temporary":
+			opts.Tmp = true
+		case "--token":
+			opts.Token = optionsNextString(args, &i)
+		case "-j", "--json":
+			opts.EnableJSON = true
 		case "-h", "--help":
 			help()
 			return nil
@@ -114,5 +127,10 @@ func parseOptions(args []string) *Options {
 		}
 	}
 
+	// "guards"
+	if opts.Tmp && opts.EnableJSON {
+		fmt.Println("Report generation with temporary clones not supported")
+	}
+
 	return opts
 }

+ 3 - 0
vendor/github.com/golang/protobuf/AUTHORS

@@ -0,0 +1,3 @@
+# This source code refers to The Go Authors for copyright purposes.
+# The master list of authors is in the main Go distribution,
+# visible at http://tip.golang.org/AUTHORS.

+ 3 - 0
vendor/github.com/golang/protobuf/CONTRIBUTORS

@@ -0,0 +1,3 @@
+# This source code was written by the Go contributors.
+# The master list of contributors is in the main Go distribution,
+# visible at http://tip.golang.org/CONTRIBUTORS.

+ 31 - 0
vendor/github.com/golang/protobuf/LICENSE

@@ -0,0 +1,31 @@
+Go support for Protocol Buffers - Google's data interchange format
+
+Copyright 2010 The Go Authors.  All rights reserved.
+https://github.com/golang/protobuf
+
+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.
+

+ 43 - 0
vendor/github.com/golang/protobuf/proto/Makefile

@@ -0,0 +1,43 @@
+# Go support for Protocol Buffers - Google's data interchange format
+#
+# Copyright 2010 The Go Authors.  All rights reserved.
+# https://github.com/golang/protobuf
+#
+# 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.
+
+install:
+	go install
+
+test: install generate-test-pbs
+	go test
+
+
+generate-test-pbs:
+	make install
+	make -C testdata
+	protoc --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata,Mgoogle/protobuf/any.proto=github.com/golang/protobuf/ptypes/any:. proto3_proto/proto3.proto
+	make

+ 229 - 0
vendor/github.com/golang/protobuf/proto/clone.go

@@ -0,0 +1,229 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2011 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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.
+
+// Protocol buffer deep copy and merge.
+// TODO: RawMessage.
+
+package proto
+
+import (
+	"log"
+	"reflect"
+	"strings"
+)
+
+// Clone returns a deep copy of a protocol buffer.
+func Clone(pb Message) Message {
+	in := reflect.ValueOf(pb)
+	if in.IsNil() {
+		return pb
+	}
+
+	out := reflect.New(in.Type().Elem())
+	// out is empty so a merge is a deep copy.
+	mergeStruct(out.Elem(), in.Elem())
+	return out.Interface().(Message)
+}
+
+// Merge merges src into dst.
+// Required and optional fields that are set in src will be set to that value in dst.
+// Elements of repeated fields will be appended.
+// Merge panics if src and dst are not the same type, or if dst is nil.
+func Merge(dst, src Message) {
+	in := reflect.ValueOf(src)
+	out := reflect.ValueOf(dst)
+	if out.IsNil() {
+		panic("proto: nil destination")
+	}
+	if in.Type() != out.Type() {
+		// Explicit test prior to mergeStruct so that mistyped nils will fail
+		panic("proto: type mismatch")
+	}
+	if in.IsNil() {
+		// Merging nil into non-nil is a quiet no-op
+		return
+	}
+	mergeStruct(out.Elem(), in.Elem())
+}
+
+func mergeStruct(out, in reflect.Value) {
+	sprop := GetProperties(in.Type())
+	for i := 0; i < in.NumField(); i++ {
+		f := in.Type().Field(i)
+		if strings.HasPrefix(f.Name, "XXX_") {
+			continue
+		}
+		mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i])
+	}
+
+	if emIn, ok := extendable(in.Addr().Interface()); ok {
+		emOut, _ := extendable(out.Addr().Interface())
+		mIn, muIn := emIn.extensionsRead()
+		if mIn != nil {
+			mOut := emOut.extensionsWrite()
+			muIn.Lock()
+			mergeExtension(mOut, mIn)
+			muIn.Unlock()
+		}
+	}
+
+	uf := in.FieldByName("XXX_unrecognized")
+	if !uf.IsValid() {
+		return
+	}
+	uin := uf.Bytes()
+	if len(uin) > 0 {
+		out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...))
+	}
+}
+
+// mergeAny performs a merge between two values of the same type.
+// viaPtr indicates whether the values were indirected through a pointer (implying proto2).
+// prop is set if this is a struct field (it may be nil).
+func mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) {
+	if in.Type() == protoMessageType {
+		if !in.IsNil() {
+			if out.IsNil() {
+				out.Set(reflect.ValueOf(Clone(in.Interface().(Message))))
+			} else {
+				Merge(out.Interface().(Message), in.Interface().(Message))
+			}
+		}
+		return
+	}
+	switch in.Kind() {
+	case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
+		reflect.String, reflect.Uint32, reflect.Uint64:
+		if !viaPtr && isProto3Zero(in) {
+			return
+		}
+		out.Set(in)
+	case reflect.Interface:
+		// Probably a oneof field; copy non-nil values.
+		if in.IsNil() {
+			return
+		}
+		// Allocate destination if it is not set, or set to a different type.
+		// Otherwise we will merge as normal.
+		if out.IsNil() || out.Elem().Type() != in.Elem().Type() {
+			out.Set(reflect.New(in.Elem().Elem().Type())) // interface -> *T -> T -> new(T)
+		}
+		mergeAny(out.Elem(), in.Elem(), false, nil)
+	case reflect.Map:
+		if in.Len() == 0 {
+			return
+		}
+		if out.IsNil() {
+			out.Set(reflect.MakeMap(in.Type()))
+		}
+		// For maps with value types of *T or []byte we need to deep copy each value.
+		elemKind := in.Type().Elem().Kind()
+		for _, key := range in.MapKeys() {
+			var val reflect.Value
+			switch elemKind {
+			case reflect.Ptr:
+				val = reflect.New(in.Type().Elem().Elem())
+				mergeAny(val, in.MapIndex(key), false, nil)
+			case reflect.Slice:
+				val = in.MapIndex(key)
+				val = reflect.ValueOf(append([]byte{}, val.Bytes()...))
+			default:
+				val = in.MapIndex(key)
+			}
+			out.SetMapIndex(key, val)
+		}
+	case reflect.Ptr:
+		if in.IsNil() {
+			return
+		}
+		if out.IsNil() {
+			out.Set(reflect.New(in.Elem().Type()))
+		}
+		mergeAny(out.Elem(), in.Elem(), true, nil)
+	case reflect.Slice:
+		if in.IsNil() {
+			return
+		}
+		if in.Type().Elem().Kind() == reflect.Uint8 {
+			// []byte is a scalar bytes field, not a repeated field.
+
+			// Edge case: if this is in a proto3 message, a zero length
+			// bytes field is considered the zero value, and should not
+			// be merged.
+			if prop != nil && prop.proto3 && in.Len() == 0 {
+				return
+			}
+
+			// Make a deep copy.
+			// Append to []byte{} instead of []byte(nil) so that we never end up
+			// with a nil result.
+			out.SetBytes(append([]byte{}, in.Bytes()...))
+			return
+		}
+		n := in.Len()
+		if out.IsNil() {
+			out.Set(reflect.MakeSlice(in.Type(), 0, n))
+		}
+		switch in.Type().Elem().Kind() {
+		case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
+			reflect.String, reflect.Uint32, reflect.Uint64:
+			out.Set(reflect.AppendSlice(out, in))
+		default:
+			for i := 0; i < n; i++ {
+				x := reflect.Indirect(reflect.New(in.Type().Elem()))
+				mergeAny(x, in.Index(i), false, nil)
+				out.Set(reflect.Append(out, x))
+			}
+		}
+	case reflect.Struct:
+		mergeStruct(out, in)
+	default:
+		// unknown type, so not a protocol buffer
+		log.Printf("proto: don't know how to copy %v", in)
+	}
+}
+
+func mergeExtension(out, in map[int32]Extension) {
+	for extNum, eIn := range in {
+		eOut := Extension{desc: eIn.desc}
+		if eIn.value != nil {
+			v := reflect.New(reflect.TypeOf(eIn.value)).Elem()
+			mergeAny(v, reflect.ValueOf(eIn.value), false, nil)
+			eOut.value = v.Interface()
+		}
+		if eIn.enc != nil {
+			eOut.enc = make([]byte, len(eIn.enc))
+			copy(eOut.enc, eIn.enc)
+		}
+
+		out[extNum] = eOut
+	}
+}

+ 970 - 0
vendor/github.com/golang/protobuf/proto/decode.go

@@ -0,0 +1,970 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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 proto
+
+/*
+ * Routines for decoding protocol buffer data to construct in-memory representations.
+ */
+
+import (
+	"errors"
+	"fmt"
+	"io"
+	"os"
+	"reflect"
+)
+
+// errOverflow is returned when an integer is too large to be represented.
+var errOverflow = errors.New("proto: integer overflow")
+
+// ErrInternalBadWireType is returned by generated code when an incorrect
+// wire type is encountered. It does not get returned to user code.
+var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof")
+
+// The fundamental decoders that interpret bytes on the wire.
+// Those that take integer types all return uint64 and are
+// therefore of type valueDecoder.
+
+// DecodeVarint reads a varint-encoded integer from the slice.
+// It returns the integer and the number of bytes consumed, or
+// zero if there is not enough.
+// This is the format for the
+// int32, int64, uint32, uint64, bool, and enum
+// protocol buffer types.
+func DecodeVarint(buf []byte) (x uint64, n int) {
+	for shift := uint(0); shift < 64; shift += 7 {
+		if n >= len(buf) {
+			return 0, 0
+		}
+		b := uint64(buf[n])
+		n++
+		x |= (b & 0x7F) << shift
+		if (b & 0x80) == 0 {
+			return x, n
+		}
+	}
+
+	// The number is too large to represent in a 64-bit value.
+	return 0, 0
+}
+
+func (p *Buffer) decodeVarintSlow() (x uint64, err error) {
+	i := p.index
+	l := len(p.buf)
+
+	for shift := uint(0); shift < 64; shift += 7 {
+		if i >= l {
+			err = io.ErrUnexpectedEOF
+			return
+		}
+		b := p.buf[i]
+		i++
+		x |= (uint64(b) & 0x7F) << shift
+		if b < 0x80 {
+			p.index = i
+			return
+		}
+	}
+
+	// The number is too large to represent in a 64-bit value.
+	err = errOverflow
+	return
+}
+
+// DecodeVarint reads a varint-encoded integer from the Buffer.
+// This is the format for the
+// int32, int64, uint32, uint64, bool, and enum
+// protocol buffer types.
+func (p *Buffer) DecodeVarint() (x uint64, err error) {
+	i := p.index
+	buf := p.buf
+
+	if i >= len(buf) {
+		return 0, io.ErrUnexpectedEOF
+	} else if buf[i] < 0x80 {
+		p.index++
+		return uint64(buf[i]), nil
+	} else if len(buf)-i < 10 {
+		return p.decodeVarintSlow()
+	}
+
+	var b uint64
+	// we already checked the first byte
+	x = uint64(buf[i]) - 0x80
+	i++
+
+	b = uint64(buf[i])
+	i++
+	x += b << 7
+	if b&0x80 == 0 {
+		goto done
+	}
+	x -= 0x80 << 7
+
+	b = uint64(buf[i])
+	i++
+	x += b << 14
+	if b&0x80 == 0 {
+		goto done
+	}
+	x -= 0x80 << 14
+
+	b = uint64(buf[i])
+	i++
+	x += b << 21
+	if b&0x80 == 0 {
+		goto done
+	}
+	x -= 0x80 << 21
+
+	b = uint64(buf[i])
+	i++
+	x += b << 28
+	if b&0x80 == 0 {
+		goto done
+	}
+	x -= 0x80 << 28
+
+	b = uint64(buf[i])
+	i++
+	x += b << 35
+	if b&0x80 == 0 {
+		goto done
+	}
+	x -= 0x80 << 35
+
+	b = uint64(buf[i])
+	i++
+	x += b << 42
+	if b&0x80 == 0 {
+		goto done
+	}
+	x -= 0x80 << 42
+
+	b = uint64(buf[i])
+	i++
+	x += b << 49
+	if b&0x80 == 0 {
+		goto done
+	}
+	x -= 0x80 << 49
+
+	b = uint64(buf[i])
+	i++
+	x += b << 56
+	if b&0x80 == 0 {
+		goto done
+	}
+	x -= 0x80 << 56
+
+	b = uint64(buf[i])
+	i++
+	x += b << 63
+	if b&0x80 == 0 {
+		goto done
+	}
+	// x -= 0x80 << 63 // Always zero.
+
+	return 0, errOverflow
+
+done:
+	p.index = i
+	return x, nil
+}
+
+// DecodeFixed64 reads a 64-bit integer from the Buffer.
+// This is the format for the
+// fixed64, sfixed64, and double protocol buffer types.
+func (p *Buffer) DecodeFixed64() (x uint64, err error) {
+	// x, err already 0
+	i := p.index + 8
+	if i < 0 || i > len(p.buf) {
+		err = io.ErrUnexpectedEOF
+		return
+	}
+	p.index = i
+
+	x = uint64(p.buf[i-8])
+	x |= uint64(p.buf[i-7]) << 8
+	x |= uint64(p.buf[i-6]) << 16
+	x |= uint64(p.buf[i-5]) << 24
+	x |= uint64(p.buf[i-4]) << 32
+	x |= uint64(p.buf[i-3]) << 40
+	x |= uint64(p.buf[i-2]) << 48
+	x |= uint64(p.buf[i-1]) << 56
+	return
+}
+
+// DecodeFixed32 reads a 32-bit integer from the Buffer.
+// This is the format for the
+// fixed32, sfixed32, and float protocol buffer types.
+func (p *Buffer) DecodeFixed32() (x uint64, err error) {
+	// x, err already 0
+	i := p.index + 4
+	if i < 0 || i > len(p.buf) {
+		err = io.ErrUnexpectedEOF
+		return
+	}
+	p.index = i
+
+	x = uint64(p.buf[i-4])
+	x |= uint64(p.buf[i-3]) << 8
+	x |= uint64(p.buf[i-2]) << 16
+	x |= uint64(p.buf[i-1]) << 24
+	return
+}
+
+// DecodeZigzag64 reads a zigzag-encoded 64-bit integer
+// from the Buffer.
+// This is the format used for the sint64 protocol buffer type.
+func (p *Buffer) DecodeZigzag64() (x uint64, err error) {
+	x, err = p.DecodeVarint()
+	if err != nil {
+		return
+	}
+	x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63)
+	return
+}
+
+// DecodeZigzag32 reads a zigzag-encoded 32-bit integer
+// from  the Buffer.
+// This is the format used for the sint32 protocol buffer type.
+func (p *Buffer) DecodeZigzag32() (x uint64, err error) {
+	x, err = p.DecodeVarint()
+	if err != nil {
+		return
+	}
+	x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31))
+	return
+}
+
+// These are not ValueDecoders: they produce an array of bytes or a string.
+// bytes, embedded messages
+
+// DecodeRawBytes reads a count-delimited byte buffer from the Buffer.
+// This is the format used for the bytes protocol buffer
+// type and for embedded messages.
+func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) {
+	n, err := p.DecodeVarint()
+	if err != nil {
+		return nil, err
+	}
+
+	nb := int(n)
+	if nb < 0 {
+		return nil, fmt.Errorf("proto: bad byte length %d", nb)
+	}
+	end := p.index + nb
+	if end < p.index || end > len(p.buf) {
+		return nil, io.ErrUnexpectedEOF
+	}
+
+	if !alloc {
+		// todo: check if can get more uses of alloc=false
+		buf = p.buf[p.index:end]
+		p.index += nb
+		return
+	}
+
+	buf = make([]byte, nb)
+	copy(buf, p.buf[p.index:])
+	p.index += nb
+	return
+}
+
+// DecodeStringBytes reads an encoded string from the Buffer.
+// This is the format used for the proto2 string type.
+func (p *Buffer) DecodeStringBytes() (s string, err error) {
+	buf, err := p.DecodeRawBytes(false)
+	if err != nil {
+		return
+	}
+	return string(buf), nil
+}
+
+// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
+// If the protocol buffer has extensions, and the field matches, add it as an extension.
+// Otherwise, if the XXX_unrecognized field exists, append the skipped data there.
+func (o *Buffer) skipAndSave(t reflect.Type, tag, wire int, base structPointer, unrecField field) error {
+	oi := o.index
+
+	err := o.skip(t, tag, wire)
+	if err != nil {
+		return err
+	}
+
+	if !unrecField.IsValid() {
+		return nil
+	}
+
+	ptr := structPointer_Bytes(base, unrecField)
+
+	// Add the skipped field to struct field
+	obuf := o.buf
+
+	o.buf = *ptr
+	o.EncodeVarint(uint64(tag<<3 | wire))
+	*ptr = append(o.buf, obuf[oi:o.index]...)
+
+	o.buf = obuf
+
+	return nil
+}
+
+// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
+func (o *Buffer) skip(t reflect.Type, tag, wire int) error {
+
+	var u uint64
+	var err error
+
+	switch wire {
+	case WireVarint:
+		_, err = o.DecodeVarint()
+	case WireFixed64:
+		_, err = o.DecodeFixed64()
+	case WireBytes:
+		_, err = o.DecodeRawBytes(false)
+	case WireFixed32:
+		_, err = o.DecodeFixed32()
+	case WireStartGroup:
+		for {
+			u, err = o.DecodeVarint()
+			if err != nil {
+				break
+			}
+			fwire := int(u & 0x7)
+			if fwire == WireEndGroup {
+				break
+			}
+			ftag := int(u >> 3)
+			err = o.skip(t, ftag, fwire)
+			if err != nil {
+				break
+			}
+		}
+	default:
+		err = fmt.Errorf("proto: can't skip unknown wire type %d for %s", wire, t)
+	}
+	return err
+}
+
+// Unmarshaler is the interface representing objects that can
+// unmarshal themselves.  The method should reset the receiver before
+// decoding starts.  The argument points to data that may be
+// overwritten, so implementations should not keep references to the
+// buffer.
+type Unmarshaler interface {
+	Unmarshal([]byte) error
+}
+
+// Unmarshal parses the protocol buffer representation in buf and places the
+// decoded result in pb.  If the struct underlying pb does not match
+// the data in buf, the results can be unpredictable.
+//
+// Unmarshal resets pb before starting to unmarshal, so any
+// existing data in pb is always removed. Use UnmarshalMerge
+// to preserve and append to existing data.
+func Unmarshal(buf []byte, pb Message) error {
+	pb.Reset()
+	return UnmarshalMerge(buf, pb)
+}
+
+// UnmarshalMerge parses the protocol buffer representation in buf and
+// writes the decoded result to pb.  If the struct underlying pb does not match
+// the data in buf, the results can be unpredictable.
+//
+// UnmarshalMerge merges into existing data in pb.
+// Most code should use Unmarshal instead.
+func UnmarshalMerge(buf []byte, pb Message) error {
+	// If the object can unmarshal itself, let it.
+	if u, ok := pb.(Unmarshaler); ok {
+		return u.Unmarshal(buf)
+	}
+	return NewBuffer(buf).Unmarshal(pb)
+}
+
+// DecodeMessage reads a count-delimited message from the Buffer.
+func (p *Buffer) DecodeMessage(pb Message) error {
+	enc, err := p.DecodeRawBytes(false)
+	if err != nil {
+		return err
+	}
+	return NewBuffer(enc).Unmarshal(pb)
+}
+
+// DecodeGroup reads a tag-delimited group from the Buffer.
+func (p *Buffer) DecodeGroup(pb Message) error {
+	typ, base, err := getbase(pb)
+	if err != nil {
+		return err
+	}
+	return p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), true, base)
+}
+
+// Unmarshal parses the protocol buffer representation in the
+// Buffer and places the decoded result in pb.  If the struct
+// underlying pb does not match the data in the buffer, the results can be
+// unpredictable.
+//
+// Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal.
+func (p *Buffer) Unmarshal(pb Message) error {
+	// If the object can unmarshal itself, let it.
+	if u, ok := pb.(Unmarshaler); ok {
+		err := u.Unmarshal(p.buf[p.index:])
+		p.index = len(p.buf)
+		return err
+	}
+
+	typ, base, err := getbase(pb)
+	if err != nil {
+		return err
+	}
+
+	err = p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), false, base)
+
+	if collectStats {
+		stats.Decode++
+	}
+
+	return err
+}
+
+// unmarshalType does the work of unmarshaling a structure.
+func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group bool, base structPointer) error {
+	var state errorState
+	required, reqFields := prop.reqCount, uint64(0)
+
+	var err error
+	for err == nil && o.index < len(o.buf) {
+		oi := o.index
+		var u uint64
+		u, err = o.DecodeVarint()
+		if err != nil {
+			break
+		}
+		wire := int(u & 0x7)
+		if wire == WireEndGroup {
+			if is_group {
+				if required > 0 {
+					// Not enough information to determine the exact field.
+					// (See below.)
+					return &RequiredNotSetError{"{Unknown}"}
+				}
+				return nil // input is satisfied
+			}
+			return fmt.Errorf("proto: %s: wiretype end group for non-group", st)
+		}
+		tag := int(u >> 3)
+		if tag <= 0 {
+			return fmt.Errorf("proto: %s: illegal tag %d (wire type %d)", st, tag, wire)
+		}
+		fieldnum, ok := prop.decoderTags.get(tag)
+		if !ok {
+			// Maybe it's an extension?
+			if prop.extendable {
+				if e, _ := extendable(structPointer_Interface(base, st)); isExtensionField(e, int32(tag)) {
+					if err = o.skip(st, tag, wire); err == nil {
+						extmap := e.extensionsWrite()
+						ext := extmap[int32(tag)] // may be missing
+						ext.enc = append(ext.enc, o.buf[oi:o.index]...)
+						extmap[int32(tag)] = ext
+					}
+					continue
+				}
+			}
+			// Maybe it's a oneof?
+			if prop.oneofUnmarshaler != nil {
+				m := structPointer_Interface(base, st).(Message)
+				// First return value indicates whether tag is a oneof field.
+				ok, err = prop.oneofUnmarshaler(m, tag, wire, o)
+				if err == ErrInternalBadWireType {
+					// Map the error to something more descriptive.
+					// Do the formatting here to save generated code space.
+					err = fmt.Errorf("bad wiretype for oneof field in %T", m)
+				}
+				if ok {
+					continue
+				}
+			}
+			err = o.skipAndSave(st, tag, wire, base, prop.unrecField)
+			continue
+		}
+		p := prop.Prop[fieldnum]
+
+		if p.dec == nil {
+			fmt.Fprintf(os.Stderr, "proto: no protobuf decoder for %s.%s\n", st, st.Field(fieldnum).Name)
+			continue
+		}
+		dec := p.dec
+		if wire != WireStartGroup && wire != p.WireType {
+			if wire == WireBytes && p.packedDec != nil {
+				// a packable field
+				dec = p.packedDec
+			} else {
+				err = fmt.Errorf("proto: bad wiretype for field %s.%s: got wiretype %d, want %d", st, st.Field(fieldnum).Name, wire, p.WireType)
+				continue
+			}
+		}
+		decErr := dec(o, p, base)
+		if decErr != nil && !state.shouldContinue(decErr, p) {
+			err = decErr
+		}
+		if err == nil && p.Required {
+			// Successfully decoded a required field.
+			if tag <= 64 {
+				// use bitmap for fields 1-64 to catch field reuse.
+				var mask uint64 = 1 << uint64(tag-1)
+				if reqFields&mask == 0 {
+					// new required field
+					reqFields |= mask
+					required--
+				}
+			} else {
+				// This is imprecise. It can be fooled by a required field
+				// with a tag > 64 that is encoded twice; that's very rare.
+				// A fully correct implementation would require allocating
+				// a data structure, which we would like to avoid.
+				required--
+			}
+		}
+	}
+	if err == nil {
+		if is_group {
+			return io.ErrUnexpectedEOF
+		}
+		if state.err != nil {
+			return state.err
+		}
+		if required > 0 {
+			// Not enough information to determine the exact field. If we use extra
+			// CPU, we could determine the field only if the missing required field
+			// has a tag <= 64 and we check reqFields.
+			return &RequiredNotSetError{"{Unknown}"}
+		}
+	}
+	return err
+}
+
+// Individual type decoders
+// For each,
+//	u is the decoded value,
+//	v is a pointer to the field (pointer) in the struct
+
+// Sizes of the pools to allocate inside the Buffer.
+// The goal is modest amortization and allocation
+// on at least 16-byte boundaries.
+const (
+	boolPoolSize   = 16
+	uint32PoolSize = 8
+	uint64PoolSize = 4
+)
+
+// Decode a bool.
+func (o *Buffer) dec_bool(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	if len(o.bools) == 0 {
+		o.bools = make([]bool, boolPoolSize)
+	}
+	o.bools[0] = u != 0
+	*structPointer_Bool(base, p.field) = &o.bools[0]
+	o.bools = o.bools[1:]
+	return nil
+}
+
+func (o *Buffer) dec_proto3_bool(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	*structPointer_BoolVal(base, p.field) = u != 0
+	return nil
+}
+
+// Decode an int32.
+func (o *Buffer) dec_int32(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	word32_Set(structPointer_Word32(base, p.field), o, uint32(u))
+	return nil
+}
+
+func (o *Buffer) dec_proto3_int32(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	word32Val_Set(structPointer_Word32Val(base, p.field), uint32(u))
+	return nil
+}
+
+// Decode an int64.
+func (o *Buffer) dec_int64(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	word64_Set(structPointer_Word64(base, p.field), o, u)
+	return nil
+}
+
+func (o *Buffer) dec_proto3_int64(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	word64Val_Set(structPointer_Word64Val(base, p.field), o, u)
+	return nil
+}
+
+// Decode a string.
+func (o *Buffer) dec_string(p *Properties, base structPointer) error {
+	s, err := o.DecodeStringBytes()
+	if err != nil {
+		return err
+	}
+	*structPointer_String(base, p.field) = &s
+	return nil
+}
+
+func (o *Buffer) dec_proto3_string(p *Properties, base structPointer) error {
+	s, err := o.DecodeStringBytes()
+	if err != nil {
+		return err
+	}
+	*structPointer_StringVal(base, p.field) = s
+	return nil
+}
+
+// Decode a slice of bytes ([]byte).
+func (o *Buffer) dec_slice_byte(p *Properties, base structPointer) error {
+	b, err := o.DecodeRawBytes(true)
+	if err != nil {
+		return err
+	}
+	*structPointer_Bytes(base, p.field) = b
+	return nil
+}
+
+// Decode a slice of bools ([]bool).
+func (o *Buffer) dec_slice_bool(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	v := structPointer_BoolSlice(base, p.field)
+	*v = append(*v, u != 0)
+	return nil
+}
+
+// Decode a slice of bools ([]bool) in packed format.
+func (o *Buffer) dec_slice_packed_bool(p *Properties, base structPointer) error {
+	v := structPointer_BoolSlice(base, p.field)
+
+	nn, err := o.DecodeVarint()
+	if err != nil {
+		return err
+	}
+	nb := int(nn) // number of bytes of encoded bools
+	fin := o.index + nb
+	if fin < o.index {
+		return errOverflow
+	}
+
+	y := *v
+	for o.index < fin {
+		u, err := p.valDec(o)
+		if err != nil {
+			return err
+		}
+		y = append(y, u != 0)
+	}
+
+	*v = y
+	return nil
+}
+
+// Decode a slice of int32s ([]int32).
+func (o *Buffer) dec_slice_int32(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	structPointer_Word32Slice(base, p.field).Append(uint32(u))
+	return nil
+}
+
+// Decode a slice of int32s ([]int32) in packed format.
+func (o *Buffer) dec_slice_packed_int32(p *Properties, base structPointer) error {
+	v := structPointer_Word32Slice(base, p.field)
+
+	nn, err := o.DecodeVarint()
+	if err != nil {
+		return err
+	}
+	nb := int(nn) // number of bytes of encoded int32s
+
+	fin := o.index + nb
+	if fin < o.index {
+		return errOverflow
+	}
+	for o.index < fin {
+		u, err := p.valDec(o)
+		if err != nil {
+			return err
+		}
+		v.Append(uint32(u))
+	}
+	return nil
+}
+
+// Decode a slice of int64s ([]int64).
+func (o *Buffer) dec_slice_int64(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+
+	structPointer_Word64Slice(base, p.field).Append(u)
+	return nil
+}
+
+// Decode a slice of int64s ([]int64) in packed format.
+func (o *Buffer) dec_slice_packed_int64(p *Properties, base structPointer) error {
+	v := structPointer_Word64Slice(base, p.field)
+
+	nn, err := o.DecodeVarint()
+	if err != nil {
+		return err
+	}
+	nb := int(nn) // number of bytes of encoded int64s
+
+	fin := o.index + nb
+	if fin < o.index {
+		return errOverflow
+	}
+	for o.index < fin {
+		u, err := p.valDec(o)
+		if err != nil {
+			return err
+		}
+		v.Append(u)
+	}
+	return nil
+}
+
+// Decode a slice of strings ([]string).
+func (o *Buffer) dec_slice_string(p *Properties, base structPointer) error {
+	s, err := o.DecodeStringBytes()
+	if err != nil {
+		return err
+	}
+	v := structPointer_StringSlice(base, p.field)
+	*v = append(*v, s)
+	return nil
+}
+
+// Decode a slice of slice of bytes ([][]byte).
+func (o *Buffer) dec_slice_slice_byte(p *Properties, base structPointer) error {
+	b, err := o.DecodeRawBytes(true)
+	if err != nil {
+		return err
+	}
+	v := structPointer_BytesSlice(base, p.field)
+	*v = append(*v, b)
+	return nil
+}
+
+// Decode a map field.
+func (o *Buffer) dec_new_map(p *Properties, base structPointer) error {
+	raw, err := o.DecodeRawBytes(false)
+	if err != nil {
+		return err
+	}
+	oi := o.index       // index at the end of this map entry
+	o.index -= len(raw) // move buffer back to start of map entry
+
+	mptr := structPointer_NewAt(base, p.field, p.mtype) // *map[K]V
+	if mptr.Elem().IsNil() {
+		mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem()))
+	}
+	v := mptr.Elem() // map[K]V
+
+	// Prepare addressable doubly-indirect placeholders for the key and value types.
+	// See enc_new_map for why.
+	keyptr := reflect.New(reflect.PtrTo(p.mtype.Key())).Elem() // addressable *K
+	keybase := toStructPointer(keyptr.Addr())                  // **K
+
+	var valbase structPointer
+	var valptr reflect.Value
+	switch p.mtype.Elem().Kind() {
+	case reflect.Slice:
+		// []byte
+		var dummy []byte
+		valptr = reflect.ValueOf(&dummy)  // *[]byte
+		valbase = toStructPointer(valptr) // *[]byte
+	case reflect.Ptr:
+		// message; valptr is **Msg; need to allocate the intermediate pointer
+		valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
+		valptr.Set(reflect.New(valptr.Type().Elem()))
+		valbase = toStructPointer(valptr)
+	default:
+		// everything else
+		valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
+		valbase = toStructPointer(valptr.Addr())                   // **V
+	}
+
+	// Decode.
+	// This parses a restricted wire format, namely the encoding of a message
+	// with two fields. See enc_new_map for the format.
+	for o.index < oi {
+		// tagcode for key and value properties are always a single byte
+		// because they have tags 1 and 2.
+		tagcode := o.buf[o.index]
+		o.index++
+		switch tagcode {
+		case p.mkeyprop.tagcode[0]:
+			if err := p.mkeyprop.dec(o, p.mkeyprop, keybase); err != nil {
+				return err
+			}
+		case p.mvalprop.tagcode[0]:
+			if err := p.mvalprop.dec(o, p.mvalprop, valbase); err != nil {
+				return err
+			}
+		default:
+			// TODO: Should we silently skip this instead?
+			return fmt.Errorf("proto: bad map data tag %d", raw[0])
+		}
+	}
+	keyelem, valelem := keyptr.Elem(), valptr.Elem()
+	if !keyelem.IsValid() {
+		keyelem = reflect.Zero(p.mtype.Key())
+	}
+	if !valelem.IsValid() {
+		valelem = reflect.Zero(p.mtype.Elem())
+	}
+
+	v.SetMapIndex(keyelem, valelem)
+	return nil
+}
+
+// Decode a group.
+func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error {
+	bas := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(bas) {
+		// allocate new nested message
+		bas = toStructPointer(reflect.New(p.stype))
+		structPointer_SetStructPointer(base, p.field, bas)
+	}
+	return o.unmarshalType(p.stype, p.sprop, true, bas)
+}
+
+// Decode an embedded message.
+func (o *Buffer) dec_struct_message(p *Properties, base structPointer) (err error) {
+	raw, e := o.DecodeRawBytes(false)
+	if e != nil {
+		return e
+	}
+
+	bas := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(bas) {
+		// allocate new nested message
+		bas = toStructPointer(reflect.New(p.stype))
+		structPointer_SetStructPointer(base, p.field, bas)
+	}
+
+	// If the object can unmarshal itself, let it.
+	if p.isUnmarshaler {
+		iv := structPointer_Interface(bas, p.stype)
+		return iv.(Unmarshaler).Unmarshal(raw)
+	}
+
+	obuf := o.buf
+	oi := o.index
+	o.buf = raw
+	o.index = 0
+
+	err = o.unmarshalType(p.stype, p.sprop, false, bas)
+	o.buf = obuf
+	o.index = oi
+
+	return err
+}
+
+// Decode a slice of embedded messages.
+func (o *Buffer) dec_slice_struct_message(p *Properties, base structPointer) error {
+	return o.dec_slice_struct(p, false, base)
+}
+
+// Decode a slice of embedded groups.
+func (o *Buffer) dec_slice_struct_group(p *Properties, base structPointer) error {
+	return o.dec_slice_struct(p, true, base)
+}
+
+// Decode a slice of structs ([]*struct).
+func (o *Buffer) dec_slice_struct(p *Properties, is_group bool, base structPointer) error {
+	v := reflect.New(p.stype)
+	bas := toStructPointer(v)
+	structPointer_StructPointerSlice(base, p.field).Append(bas)
+
+	if is_group {
+		err := o.unmarshalType(p.stype, p.sprop, is_group, bas)
+		return err
+	}
+
+	raw, err := o.DecodeRawBytes(false)
+	if err != nil {
+		return err
+	}
+
+	// If the object can unmarshal itself, let it.
+	if p.isUnmarshaler {
+		iv := v.Interface()
+		return iv.(Unmarshaler).Unmarshal(raw)
+	}
+
+	obuf := o.buf
+	oi := o.index
+	o.buf = raw
+	o.index = 0
+
+	err = o.unmarshalType(p.stype, p.sprop, is_group, bas)
+
+	o.buf = obuf
+	o.index = oi
+
+	return err
+}

+ 151 - 0
vendor/github.com/golang/protobuf/proto/discard.go

@@ -0,0 +1,151 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2017 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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 proto
+
+import (
+	"fmt"
+	"reflect"
+	"strings"
+)
+
+// DiscardUnknown recursively discards all unknown fields from this message
+// and all embedded messages.
+//
+// When unmarshaling a message with unrecognized fields, the tags and values
+// of such fields are preserved in the Message. This allows a later call to
+// marshal to be able to produce a message that continues to have those
+// unrecognized fields. To avoid this, DiscardUnknown is used to
+// explicitly clear the unknown fields after unmarshaling.
+//
+// For proto2 messages, the unknown fields of message extensions are only
+// discarded from messages that have been accessed via GetExtension.
+func DiscardUnknown(m Message) {
+	discardLegacy(m)
+}
+
+func discardLegacy(m Message) {
+	v := reflect.ValueOf(m)
+	if v.Kind() != reflect.Ptr || v.IsNil() {
+		return
+	}
+	v = v.Elem()
+	if v.Kind() != reflect.Struct {
+		return
+	}
+	t := v.Type()
+
+	for i := 0; i < v.NumField(); i++ {
+		f := t.Field(i)
+		if strings.HasPrefix(f.Name, "XXX_") {
+			continue
+		}
+		vf := v.Field(i)
+		tf := f.Type
+
+		// Unwrap tf to get its most basic type.
+		var isPointer, isSlice bool
+		if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 {
+			isSlice = true
+			tf = tf.Elem()
+		}
+		if tf.Kind() == reflect.Ptr {
+			isPointer = true
+			tf = tf.Elem()
+		}
+		if isPointer && isSlice && tf.Kind() != reflect.Struct {
+			panic(fmt.Sprintf("%T.%s cannot be a slice of pointers to primitive types", m, f.Name))
+		}
+
+		switch tf.Kind() {
+		case reflect.Struct:
+			switch {
+			case !isPointer:
+				panic(fmt.Sprintf("%T.%s cannot be a direct struct value", m, f.Name))
+			case isSlice: // E.g., []*pb.T
+				for j := 0; j < vf.Len(); j++ {
+					discardLegacy(vf.Index(j).Interface().(Message))
+				}
+			default: // E.g., *pb.T
+				discardLegacy(vf.Interface().(Message))
+			}
+		case reflect.Map:
+			switch {
+			case isPointer || isSlice:
+				panic(fmt.Sprintf("%T.%s cannot be a pointer to a map or a slice of map values", m, f.Name))
+			default: // E.g., map[K]V
+				tv := vf.Type().Elem()
+				if tv.Kind() == reflect.Ptr && tv.Implements(protoMessageType) { // Proto struct (e.g., *T)
+					for _, key := range vf.MapKeys() {
+						val := vf.MapIndex(key)
+						discardLegacy(val.Interface().(Message))
+					}
+				}
+			}
+		case reflect.Interface:
+			// Must be oneof field.
+			switch {
+			case isPointer || isSlice:
+				panic(fmt.Sprintf("%T.%s cannot be a pointer to a interface or a slice of interface values", m, f.Name))
+			default: // E.g., test_proto.isCommunique_Union interface
+				if !vf.IsNil() && f.Tag.Get("protobuf_oneof") != "" {
+					vf = vf.Elem() // E.g., *test_proto.Communique_Msg
+					if !vf.IsNil() {
+						vf = vf.Elem()   // E.g., test_proto.Communique_Msg
+						vf = vf.Field(0) // E.g., Proto struct (e.g., *T) or primitive value
+						if vf.Kind() == reflect.Ptr {
+							discardLegacy(vf.Interface().(Message))
+						}
+					}
+				}
+			}
+		}
+	}
+
+	if vf := v.FieldByName("XXX_unrecognized"); vf.IsValid() {
+		if vf.Type() != reflect.TypeOf([]byte{}) {
+			panic("expected XXX_unrecognized to be of type []byte")
+		}
+		vf.Set(reflect.ValueOf([]byte(nil)))
+	}
+
+	// For proto2 messages, only discard unknown fields in message extensions
+	// that have been accessed via GetExtension.
+	if em, ok := extendable(m); ok {
+		// Ignore lock since discardLegacy is not concurrency safe.
+		emm, _ := em.extensionsRead()
+		for _, mx := range emm {
+			if m, ok := mx.value.(Message); ok {
+				discardLegacy(m)
+			}
+		}
+	}
+}

+ 1362 - 0
vendor/github.com/golang/protobuf/proto/encode.go

@@ -0,0 +1,1362 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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 proto
+
+/*
+ * Routines for encoding data into the wire format for protocol buffers.
+ */
+
+import (
+	"errors"
+	"fmt"
+	"reflect"
+	"sort"
+)
+
+// RequiredNotSetError is the error returned if Marshal is called with
+// a protocol buffer struct whose required fields have not
+// all been initialized. It is also the error returned if Unmarshal is
+// called with an encoded protocol buffer that does not include all the
+// required fields.
+//
+// When printed, RequiredNotSetError reports the first unset required field in a
+// message. If the field cannot be precisely determined, it is reported as
+// "{Unknown}".
+type RequiredNotSetError struct {
+	field string
+}
+
+func (e *RequiredNotSetError) Error() string {
+	return fmt.Sprintf("proto: required field %q not set", e.field)
+}
+
+var (
+	// errRepeatedHasNil is the error returned if Marshal is called with
+	// a struct with a repeated field containing a nil element.
+	errRepeatedHasNil = errors.New("proto: repeated field has nil element")
+
+	// errOneofHasNil is the error returned if Marshal is called with
+	// a struct with a oneof field containing a nil element.
+	errOneofHasNil = errors.New("proto: oneof field has nil value")
+
+	// ErrNil is the error returned if Marshal is called with nil.
+	ErrNil = errors.New("proto: Marshal called with nil")
+
+	// ErrTooLarge is the error returned if Marshal is called with a
+	// message that encodes to >2GB.
+	ErrTooLarge = errors.New("proto: message encodes to over 2 GB")
+)
+
+// The fundamental encoders that put bytes on the wire.
+// Those that take integer types all accept uint64 and are
+// therefore of type valueEncoder.
+
+const maxVarintBytes = 10 // maximum length of a varint
+
+// maxMarshalSize is the largest allowed size of an encoded protobuf,
+// since C++ and Java use signed int32s for the size.
+const maxMarshalSize = 1<<31 - 1
+
+// EncodeVarint returns the varint encoding of x.
+// This is the format for the
+// int32, int64, uint32, uint64, bool, and enum
+// protocol buffer types.
+// Not used by the package itself, but helpful to clients
+// wishing to use the same encoding.
+func EncodeVarint(x uint64) []byte {
+	var buf [maxVarintBytes]byte
+	var n int
+	for n = 0; x > 127; n++ {
+		buf[n] = 0x80 | uint8(x&0x7F)
+		x >>= 7
+	}
+	buf[n] = uint8(x)
+	n++
+	return buf[0:n]
+}
+
+// EncodeVarint writes a varint-encoded integer to the Buffer.
+// This is the format for the
+// int32, int64, uint32, uint64, bool, and enum
+// protocol buffer types.
+func (p *Buffer) EncodeVarint(x uint64) error {
+	for x >= 1<<7 {
+		p.buf = append(p.buf, uint8(x&0x7f|0x80))
+		x >>= 7
+	}
+	p.buf = append(p.buf, uint8(x))
+	return nil
+}
+
+// SizeVarint returns the varint encoding size of an integer.
+func SizeVarint(x uint64) int {
+	return sizeVarint(x)
+}
+
+func sizeVarint(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+
+// EncodeFixed64 writes a 64-bit integer to the Buffer.
+// This is the format for the
+// fixed64, sfixed64, and double protocol buffer types.
+func (p *Buffer) EncodeFixed64(x uint64) error {
+	p.buf = append(p.buf,
+		uint8(x),
+		uint8(x>>8),
+		uint8(x>>16),
+		uint8(x>>24),
+		uint8(x>>32),
+		uint8(x>>40),
+		uint8(x>>48),
+		uint8(x>>56))
+	return nil
+}
+
+func sizeFixed64(x uint64) int {
+	return 8
+}
+
+// EncodeFixed32 writes a 32-bit integer to the Buffer.
+// This is the format for the
+// fixed32, sfixed32, and float protocol buffer types.
+func (p *Buffer) EncodeFixed32(x uint64) error {
+	p.buf = append(p.buf,
+		uint8(x),
+		uint8(x>>8),
+		uint8(x>>16),
+		uint8(x>>24))
+	return nil
+}
+
+func sizeFixed32(x uint64) int {
+	return 4
+}
+
+// EncodeZigzag64 writes a zigzag-encoded 64-bit integer
+// to the Buffer.
+// This is the format used for the sint64 protocol buffer type.
+func (p *Buffer) EncodeZigzag64(x uint64) error {
+	// use signed number to get arithmetic right shift.
+	return p.EncodeVarint((x << 1) ^ uint64((int64(x) >> 63)))
+}
+
+func sizeZigzag64(x uint64) int {
+	return sizeVarint((x << 1) ^ uint64((int64(x) >> 63)))
+}
+
+// EncodeZigzag32 writes a zigzag-encoded 32-bit integer
+// to the Buffer.
+// This is the format used for the sint32 protocol buffer type.
+func (p *Buffer) EncodeZigzag32(x uint64) error {
+	// use signed number to get arithmetic right shift.
+	return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
+}
+
+func sizeZigzag32(x uint64) int {
+	return sizeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
+}
+
+// EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
+// This is the format used for the bytes protocol buffer
+// type and for embedded messages.
+func (p *Buffer) EncodeRawBytes(b []byte) error {
+	p.EncodeVarint(uint64(len(b)))
+	p.buf = append(p.buf, b...)
+	return nil
+}
+
+func sizeRawBytes(b []byte) int {
+	return sizeVarint(uint64(len(b))) +
+		len(b)
+}
+
+// EncodeStringBytes writes an encoded string to the Buffer.
+// This is the format used for the proto2 string type.
+func (p *Buffer) EncodeStringBytes(s string) error {
+	p.EncodeVarint(uint64(len(s)))
+	p.buf = append(p.buf, s...)
+	return nil
+}
+
+func sizeStringBytes(s string) int {
+	return sizeVarint(uint64(len(s))) +
+		len(s)
+}
+
+// Marshaler is the interface representing objects that can marshal themselves.
+type Marshaler interface {
+	Marshal() ([]byte, error)
+}
+
+// Marshal takes the protocol buffer
+// and encodes it into the wire format, returning the data.
+func Marshal(pb Message) ([]byte, error) {
+	// Can the object marshal itself?
+	if m, ok := pb.(Marshaler); ok {
+		return m.Marshal()
+	}
+	p := NewBuffer(nil)
+	err := p.Marshal(pb)
+	if p.buf == nil && err == nil {
+		// Return a non-nil slice on success.
+		return []byte{}, nil
+	}
+	return p.buf, err
+}
+
+// EncodeMessage writes the protocol buffer to the Buffer,
+// prefixed by a varint-encoded length.
+func (p *Buffer) EncodeMessage(pb Message) error {
+	t, base, err := getbase(pb)
+	if structPointer_IsNil(base) {
+		return ErrNil
+	}
+	if err == nil {
+		var state errorState
+		err = p.enc_len_struct(GetProperties(t.Elem()), base, &state)
+	}
+	return err
+}
+
+// Marshal takes the protocol buffer
+// and encodes it into the wire format, writing the result to the
+// Buffer.
+func (p *Buffer) Marshal(pb Message) error {
+	// Can the object marshal itself?
+	if m, ok := pb.(Marshaler); ok {
+		data, err := m.Marshal()
+		p.buf = append(p.buf, data...)
+		return err
+	}
+
+	t, base, err := getbase(pb)
+	if structPointer_IsNil(base) {
+		return ErrNil
+	}
+	if err == nil {
+		err = p.enc_struct(GetProperties(t.Elem()), base)
+	}
+
+	if collectStats {
+		(stats).Encode++ // Parens are to work around a goimports bug.
+	}
+
+	if len(p.buf) > maxMarshalSize {
+		return ErrTooLarge
+	}
+	return err
+}
+
+// Size returns the encoded size of a protocol buffer.
+func Size(pb Message) (n int) {
+	// Can the object marshal itself?  If so, Size is slow.
+	// TODO: add Size to Marshaler, or add a Sizer interface.
+	if m, ok := pb.(Marshaler); ok {
+		b, _ := m.Marshal()
+		return len(b)
+	}
+
+	t, base, err := getbase(pb)
+	if structPointer_IsNil(base) {
+		return 0
+	}
+	if err == nil {
+		n = size_struct(GetProperties(t.Elem()), base)
+	}
+
+	if collectStats {
+		(stats).Size++ // Parens are to work around a goimports bug.
+	}
+
+	return
+}
+
+// Individual type encoders.
+
+// Encode a bool.
+func (o *Buffer) enc_bool(p *Properties, base structPointer) error {
+	v := *structPointer_Bool(base, p.field)
+	if v == nil {
+		return ErrNil
+	}
+	x := 0
+	if *v {
+		x = 1
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, uint64(x))
+	return nil
+}
+
+func (o *Buffer) enc_proto3_bool(p *Properties, base structPointer) error {
+	v := *structPointer_BoolVal(base, p.field)
+	if !v {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, 1)
+	return nil
+}
+
+func size_bool(p *Properties, base structPointer) int {
+	v := *structPointer_Bool(base, p.field)
+	if v == nil {
+		return 0
+	}
+	return len(p.tagcode) + 1 // each bool takes exactly one byte
+}
+
+func size_proto3_bool(p *Properties, base structPointer) int {
+	v := *structPointer_BoolVal(base, p.field)
+	if !v && !p.oneof {
+		return 0
+	}
+	return len(p.tagcode) + 1 // each bool takes exactly one byte
+}
+
+// Encode an int32.
+func (o *Buffer) enc_int32(p *Properties, base structPointer) error {
+	v := structPointer_Word32(base, p.field)
+	if word32_IsNil(v) {
+		return ErrNil
+	}
+	x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, uint64(x))
+	return nil
+}
+
+func (o *Buffer) enc_proto3_int32(p *Properties, base structPointer) error {
+	v := structPointer_Word32Val(base, p.field)
+	x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
+	if x == 0 {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, uint64(x))
+	return nil
+}
+
+func size_int32(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word32(base, p.field)
+	if word32_IsNil(v) {
+		return 0
+	}
+	x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range
+	n += len(p.tagcode)
+	n += p.valSize(uint64(x))
+	return
+}
+
+func size_proto3_int32(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word32Val(base, p.field)
+	x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
+	if x == 0 && !p.oneof {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += p.valSize(uint64(x))
+	return
+}
+
+// Encode a uint32.
+// Exactly the same as int32, except for no sign extension.
+func (o *Buffer) enc_uint32(p *Properties, base structPointer) error {
+	v := structPointer_Word32(base, p.field)
+	if word32_IsNil(v) {
+		return ErrNil
+	}
+	x := word32_Get(v)
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, uint64(x))
+	return nil
+}
+
+func (o *Buffer) enc_proto3_uint32(p *Properties, base structPointer) error {
+	v := structPointer_Word32Val(base, p.field)
+	x := word32Val_Get(v)
+	if x == 0 {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, uint64(x))
+	return nil
+}
+
+func size_uint32(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word32(base, p.field)
+	if word32_IsNil(v) {
+		return 0
+	}
+	x := word32_Get(v)
+	n += len(p.tagcode)
+	n += p.valSize(uint64(x))
+	return
+}
+
+func size_proto3_uint32(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word32Val(base, p.field)
+	x := word32Val_Get(v)
+	if x == 0 && !p.oneof {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += p.valSize(uint64(x))
+	return
+}
+
+// Encode an int64.
+func (o *Buffer) enc_int64(p *Properties, base structPointer) error {
+	v := structPointer_Word64(base, p.field)
+	if word64_IsNil(v) {
+		return ErrNil
+	}
+	x := word64_Get(v)
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, x)
+	return nil
+}
+
+func (o *Buffer) enc_proto3_int64(p *Properties, base structPointer) error {
+	v := structPointer_Word64Val(base, p.field)
+	x := word64Val_Get(v)
+	if x == 0 {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, x)
+	return nil
+}
+
+func size_int64(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word64(base, p.field)
+	if word64_IsNil(v) {
+		return 0
+	}
+	x := word64_Get(v)
+	n += len(p.tagcode)
+	n += p.valSize(x)
+	return
+}
+
+func size_proto3_int64(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word64Val(base, p.field)
+	x := word64Val_Get(v)
+	if x == 0 && !p.oneof {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += p.valSize(x)
+	return
+}
+
+// Encode a string.
+func (o *Buffer) enc_string(p *Properties, base structPointer) error {
+	v := *structPointer_String(base, p.field)
+	if v == nil {
+		return ErrNil
+	}
+	x := *v
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeStringBytes(x)
+	return nil
+}
+
+func (o *Buffer) enc_proto3_string(p *Properties, base structPointer) error {
+	v := *structPointer_StringVal(base, p.field)
+	if v == "" {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeStringBytes(v)
+	return nil
+}
+
+func size_string(p *Properties, base structPointer) (n int) {
+	v := *structPointer_String(base, p.field)
+	if v == nil {
+		return 0
+	}
+	x := *v
+	n += len(p.tagcode)
+	n += sizeStringBytes(x)
+	return
+}
+
+func size_proto3_string(p *Properties, base structPointer) (n int) {
+	v := *structPointer_StringVal(base, p.field)
+	if v == "" && !p.oneof {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += sizeStringBytes(v)
+	return
+}
+
+// All protocol buffer fields are nillable, but be careful.
+func isNil(v reflect.Value) bool {
+	switch v.Kind() {
+	case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
+		return v.IsNil()
+	}
+	return false
+}
+
+// Encode a message struct.
+func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error {
+	var state errorState
+	structp := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(structp) {
+		return ErrNil
+	}
+
+	// Can the object marshal itself?
+	if p.isMarshaler {
+		m := structPointer_Interface(structp, p.stype).(Marshaler)
+		data, err := m.Marshal()
+		if err != nil && !state.shouldContinue(err, nil) {
+			return err
+		}
+		o.buf = append(o.buf, p.tagcode...)
+		o.EncodeRawBytes(data)
+		return state.err
+	}
+
+	o.buf = append(o.buf, p.tagcode...)
+	return o.enc_len_struct(p.sprop, structp, &state)
+}
+
+func size_struct_message(p *Properties, base structPointer) int {
+	structp := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(structp) {
+		return 0
+	}
+
+	// Can the object marshal itself?
+	if p.isMarshaler {
+		m := structPointer_Interface(structp, p.stype).(Marshaler)
+		data, _ := m.Marshal()
+		n0 := len(p.tagcode)
+		n1 := sizeRawBytes(data)
+		return n0 + n1
+	}
+
+	n0 := len(p.tagcode)
+	n1 := size_struct(p.sprop, structp)
+	n2 := sizeVarint(uint64(n1)) // size of encoded length
+	return n0 + n1 + n2
+}
+
+// Encode a group struct.
+func (o *Buffer) enc_struct_group(p *Properties, base structPointer) error {
+	var state errorState
+	b := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(b) {
+		return ErrNil
+	}
+
+	o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
+	err := o.enc_struct(p.sprop, b)
+	if err != nil && !state.shouldContinue(err, nil) {
+		return err
+	}
+	o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
+	return state.err
+}
+
+func size_struct_group(p *Properties, base structPointer) (n int) {
+	b := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(b) {
+		return 0
+	}
+
+	n += sizeVarint(uint64((p.Tag << 3) | WireStartGroup))
+	n += size_struct(p.sprop, b)
+	n += sizeVarint(uint64((p.Tag << 3) | WireEndGroup))
+	return
+}
+
+// Encode a slice of bools ([]bool).
+func (o *Buffer) enc_slice_bool(p *Properties, base structPointer) error {
+	s := *structPointer_BoolSlice(base, p.field)
+	l := len(s)
+	if l == 0 {
+		return ErrNil
+	}
+	for _, x := range s {
+		o.buf = append(o.buf, p.tagcode...)
+		v := uint64(0)
+		if x {
+			v = 1
+		}
+		p.valEnc(o, v)
+	}
+	return nil
+}
+
+func size_slice_bool(p *Properties, base structPointer) int {
+	s := *structPointer_BoolSlice(base, p.field)
+	l := len(s)
+	if l == 0 {
+		return 0
+	}
+	return l * (len(p.tagcode) + 1) // each bool takes exactly one byte
+}
+
+// Encode a slice of bools ([]bool) in packed format.
+func (o *Buffer) enc_slice_packed_bool(p *Properties, base structPointer) error {
+	s := *structPointer_BoolSlice(base, p.field)
+	l := len(s)
+	if l == 0 {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeVarint(uint64(l)) // each bool takes exactly one byte
+	for _, x := range s {
+		v := uint64(0)
+		if x {
+			v = 1
+		}
+		p.valEnc(o, v)
+	}
+	return nil
+}
+
+func size_slice_packed_bool(p *Properties, base structPointer) (n int) {
+	s := *structPointer_BoolSlice(base, p.field)
+	l := len(s)
+	if l == 0 {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += sizeVarint(uint64(l))
+	n += l // each bool takes exactly one byte
+	return
+}
+
+// Encode a slice of bytes ([]byte).
+func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error {
+	s := *structPointer_Bytes(base, p.field)
+	if s == nil {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeRawBytes(s)
+	return nil
+}
+
+func (o *Buffer) enc_proto3_slice_byte(p *Properties, base structPointer) error {
+	s := *structPointer_Bytes(base, p.field)
+	if len(s) == 0 {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeRawBytes(s)
+	return nil
+}
+
+func size_slice_byte(p *Properties, base structPointer) (n int) {
+	s := *structPointer_Bytes(base, p.field)
+	if s == nil && !p.oneof {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += sizeRawBytes(s)
+	return
+}
+
+func size_proto3_slice_byte(p *Properties, base structPointer) (n int) {
+	s := *structPointer_Bytes(base, p.field)
+	if len(s) == 0 && !p.oneof {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += sizeRawBytes(s)
+	return
+}
+
+// Encode a slice of int32s ([]int32).
+func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	for i := 0; i < l; i++ {
+		o.buf = append(o.buf, p.tagcode...)
+		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+		p.valEnc(o, uint64(x))
+	}
+	return nil
+}
+
+func size_slice_int32(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	for i := 0; i < l; i++ {
+		n += len(p.tagcode)
+		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+		n += p.valSize(uint64(x))
+	}
+	return
+}
+
+// Encode a slice of int32s ([]int32) in packed format.
+func (o *Buffer) enc_slice_packed_int32(p *Properties, base structPointer) error {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	// TODO: Reuse a Buffer.
+	buf := NewBuffer(nil)
+	for i := 0; i < l; i++ {
+		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+		p.valEnc(buf, uint64(x))
+	}
+
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeVarint(uint64(len(buf.buf)))
+	o.buf = append(o.buf, buf.buf...)
+	return nil
+}
+
+func size_slice_packed_int32(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	var bufSize int
+	for i := 0; i < l; i++ {
+		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+		bufSize += p.valSize(uint64(x))
+	}
+
+	n += len(p.tagcode)
+	n += sizeVarint(uint64(bufSize))
+	n += bufSize
+	return
+}
+
+// Encode a slice of uint32s ([]uint32).
+// Exactly the same as int32, except for no sign extension.
+func (o *Buffer) enc_slice_uint32(p *Properties, base structPointer) error {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	for i := 0; i < l; i++ {
+		o.buf = append(o.buf, p.tagcode...)
+		x := s.Index(i)
+		p.valEnc(o, uint64(x))
+	}
+	return nil
+}
+
+func size_slice_uint32(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	for i := 0; i < l; i++ {
+		n += len(p.tagcode)
+		x := s.Index(i)
+		n += p.valSize(uint64(x))
+	}
+	return
+}
+
+// Encode a slice of uint32s ([]uint32) in packed format.
+// Exactly the same as int32, except for no sign extension.
+func (o *Buffer) enc_slice_packed_uint32(p *Properties, base structPointer) error {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	// TODO: Reuse a Buffer.
+	buf := NewBuffer(nil)
+	for i := 0; i < l; i++ {
+		p.valEnc(buf, uint64(s.Index(i)))
+	}
+
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeVarint(uint64(len(buf.buf)))
+	o.buf = append(o.buf, buf.buf...)
+	return nil
+}
+
+func size_slice_packed_uint32(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	var bufSize int
+	for i := 0; i < l; i++ {
+		bufSize += p.valSize(uint64(s.Index(i)))
+	}
+
+	n += len(p.tagcode)
+	n += sizeVarint(uint64(bufSize))
+	n += bufSize
+	return
+}
+
+// Encode a slice of int64s ([]int64).
+func (o *Buffer) enc_slice_int64(p *Properties, base structPointer) error {
+	s := structPointer_Word64Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	for i := 0; i < l; i++ {
+		o.buf = append(o.buf, p.tagcode...)
+		p.valEnc(o, s.Index(i))
+	}
+	return nil
+}
+
+func size_slice_int64(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word64Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	for i := 0; i < l; i++ {
+		n += len(p.tagcode)
+		n += p.valSize(s.Index(i))
+	}
+	return
+}
+
+// Encode a slice of int64s ([]int64) in packed format.
+func (o *Buffer) enc_slice_packed_int64(p *Properties, base structPointer) error {
+	s := structPointer_Word64Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	// TODO: Reuse a Buffer.
+	buf := NewBuffer(nil)
+	for i := 0; i < l; i++ {
+		p.valEnc(buf, s.Index(i))
+	}
+
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeVarint(uint64(len(buf.buf)))
+	o.buf = append(o.buf, buf.buf...)
+	return nil
+}
+
+func size_slice_packed_int64(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word64Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	var bufSize int
+	for i := 0; i < l; i++ {
+		bufSize += p.valSize(s.Index(i))
+	}
+
+	n += len(p.tagcode)
+	n += sizeVarint(uint64(bufSize))
+	n += bufSize
+	return
+}
+
+// Encode a slice of slice of bytes ([][]byte).
+func (o *Buffer) enc_slice_slice_byte(p *Properties, base structPointer) error {
+	ss := *structPointer_BytesSlice(base, p.field)
+	l := len(ss)
+	if l == 0 {
+		return ErrNil
+	}
+	for i := 0; i < l; i++ {
+		o.buf = append(o.buf, p.tagcode...)
+		o.EncodeRawBytes(ss[i])
+	}
+	return nil
+}
+
+func size_slice_slice_byte(p *Properties, base structPointer) (n int) {
+	ss := *structPointer_BytesSlice(base, p.field)
+	l := len(ss)
+	if l == 0 {
+		return 0
+	}
+	n += l * len(p.tagcode)
+	for i := 0; i < l; i++ {
+		n += sizeRawBytes(ss[i])
+	}
+	return
+}
+
+// Encode a slice of strings ([]string).
+func (o *Buffer) enc_slice_string(p *Properties, base structPointer) error {
+	ss := *structPointer_StringSlice(base, p.field)
+	l := len(ss)
+	for i := 0; i < l; i++ {
+		o.buf = append(o.buf, p.tagcode...)
+		o.EncodeStringBytes(ss[i])
+	}
+	return nil
+}
+
+func size_slice_string(p *Properties, base structPointer) (n int) {
+	ss := *structPointer_StringSlice(base, p.field)
+	l := len(ss)
+	n += l * len(p.tagcode)
+	for i := 0; i < l; i++ {
+		n += sizeStringBytes(ss[i])
+	}
+	return
+}
+
+// Encode a slice of message structs ([]*struct).
+func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) error {
+	var state errorState
+	s := structPointer_StructPointerSlice(base, p.field)
+	l := s.Len()
+
+	for i := 0; i < l; i++ {
+		structp := s.Index(i)
+		if structPointer_IsNil(structp) {
+			return errRepeatedHasNil
+		}
+
+		// Can the object marshal itself?
+		if p.isMarshaler {
+			m := structPointer_Interface(structp, p.stype).(Marshaler)
+			data, err := m.Marshal()
+			if err != nil && !state.shouldContinue(err, nil) {
+				return err
+			}
+			o.buf = append(o.buf, p.tagcode...)
+			o.EncodeRawBytes(data)
+			continue
+		}
+
+		o.buf = append(o.buf, p.tagcode...)
+		err := o.enc_len_struct(p.sprop, structp, &state)
+		if err != nil && !state.shouldContinue(err, nil) {
+			if err == ErrNil {
+				return errRepeatedHasNil
+			}
+			return err
+		}
+	}
+	return state.err
+}
+
+func size_slice_struct_message(p *Properties, base structPointer) (n int) {
+	s := structPointer_StructPointerSlice(base, p.field)
+	l := s.Len()
+	n += l * len(p.tagcode)
+	for i := 0; i < l; i++ {
+		structp := s.Index(i)
+		if structPointer_IsNil(structp) {
+			return // return the size up to this point
+		}
+
+		// Can the object marshal itself?
+		if p.isMarshaler {
+			m := structPointer_Interface(structp, p.stype).(Marshaler)
+			data, _ := m.Marshal()
+			n += sizeRawBytes(data)
+			continue
+		}
+
+		n0 := size_struct(p.sprop, structp)
+		n1 := sizeVarint(uint64(n0)) // size of encoded length
+		n += n0 + n1
+	}
+	return
+}
+
+// Encode a slice of group structs ([]*struct).
+func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error {
+	var state errorState
+	s := structPointer_StructPointerSlice(base, p.field)
+	l := s.Len()
+
+	for i := 0; i < l; i++ {
+		b := s.Index(i)
+		if structPointer_IsNil(b) {
+			return errRepeatedHasNil
+		}
+
+		o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
+
+		err := o.enc_struct(p.sprop, b)
+
+		if err != nil && !state.shouldContinue(err, nil) {
+			if err == ErrNil {
+				return errRepeatedHasNil
+			}
+			return err
+		}
+
+		o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
+	}
+	return state.err
+}
+
+func size_slice_struct_group(p *Properties, base structPointer) (n int) {
+	s := structPointer_StructPointerSlice(base, p.field)
+	l := s.Len()
+
+	n += l * sizeVarint(uint64((p.Tag<<3)|WireStartGroup))
+	n += l * sizeVarint(uint64((p.Tag<<3)|WireEndGroup))
+	for i := 0; i < l; i++ {
+		b := s.Index(i)
+		if structPointer_IsNil(b) {
+			return // return size up to this point
+		}
+
+		n += size_struct(p.sprop, b)
+	}
+	return
+}
+
+// Encode an extension map.
+func (o *Buffer) enc_map(p *Properties, base structPointer) error {
+	exts := structPointer_ExtMap(base, p.field)
+	if err := encodeExtensionsMap(*exts); err != nil {
+		return err
+	}
+
+	return o.enc_map_body(*exts)
+}
+
+func (o *Buffer) enc_exts(p *Properties, base structPointer) error {
+	exts := structPointer_Extensions(base, p.field)
+
+	v, mu := exts.extensionsRead()
+	if v == nil {
+		return nil
+	}
+
+	mu.Lock()
+	defer mu.Unlock()
+	if err := encodeExtensionsMap(v); err != nil {
+		return err
+	}
+
+	return o.enc_map_body(v)
+}
+
+func (o *Buffer) enc_map_body(v map[int32]Extension) error {
+	// Fast-path for common cases: zero or one extensions.
+	if len(v) <= 1 {
+		for _, e := range v {
+			o.buf = append(o.buf, e.enc...)
+		}
+		return nil
+	}
+
+	// Sort keys to provide a deterministic encoding.
+	keys := make([]int, 0, len(v))
+	for k := range v {
+		keys = append(keys, int(k))
+	}
+	sort.Ints(keys)
+
+	for _, k := range keys {
+		o.buf = append(o.buf, v[int32(k)].enc...)
+	}
+	return nil
+}
+
+func size_map(p *Properties, base structPointer) int {
+	v := structPointer_ExtMap(base, p.field)
+	return extensionsMapSize(*v)
+}
+
+func size_exts(p *Properties, base structPointer) int {
+	v := structPointer_Extensions(base, p.field)
+	return extensionsSize(v)
+}
+
+// Encode a map field.
+func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
+	var state errorState // XXX: or do we need to plumb this through?
+
+	/*
+		A map defined as
+			map<key_type, value_type> map_field = N;
+		is encoded in the same way as
+			message MapFieldEntry {
+				key_type key = 1;
+				value_type value = 2;
+			}
+			repeated MapFieldEntry map_field = N;
+	*/
+
+	v := structPointer_NewAt(base, p.field, p.mtype).Elem() // map[K]V
+	if v.Len() == 0 {
+		return nil
+	}
+
+	keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
+
+	enc := func() error {
+		if err := p.mkeyprop.enc(o, p.mkeyprop, keybase); err != nil {
+			return err
+		}
+		if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil && err != ErrNil {
+			return err
+		}
+		return nil
+	}
+
+	// Don't sort map keys. It is not required by the spec, and C++ doesn't do it.
+	for _, key := range v.MapKeys() {
+		val := v.MapIndex(key)
+
+		keycopy.Set(key)
+		valcopy.Set(val)
+
+		o.buf = append(o.buf, p.tagcode...)
+		if err := o.enc_len_thing(enc, &state); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func size_new_map(p *Properties, base structPointer) int {
+	v := structPointer_NewAt(base, p.field, p.mtype).Elem() // map[K]V
+
+	keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
+
+	n := 0
+	for _, key := range v.MapKeys() {
+		val := v.MapIndex(key)
+		keycopy.Set(key)
+		valcopy.Set(val)
+
+		// Tag codes for key and val are the responsibility of the sub-sizer.
+		keysize := p.mkeyprop.size(p.mkeyprop, keybase)
+		valsize := p.mvalprop.size(p.mvalprop, valbase)
+		entry := keysize + valsize
+		// Add on tag code and length of map entry itself.
+		n += len(p.tagcode) + sizeVarint(uint64(entry)) + entry
+	}
+	return n
+}
+
+// mapEncodeScratch returns a new reflect.Value matching the map's value type,
+// and a structPointer suitable for passing to an encoder or sizer.
+func mapEncodeScratch(mapType reflect.Type) (keycopy, valcopy reflect.Value, keybase, valbase structPointer) {
+	// Prepare addressable doubly-indirect placeholders for the key and value types.
+	// This is needed because the element-type encoders expect **T, but the map iteration produces T.
+
+	keycopy = reflect.New(mapType.Key()).Elem()                 // addressable K
+	keyptr := reflect.New(reflect.PtrTo(keycopy.Type())).Elem() // addressable *K
+	keyptr.Set(keycopy.Addr())                                  //
+	keybase = toStructPointer(keyptr.Addr())                    // **K
+
+	// Value types are more varied and require special handling.
+	switch mapType.Elem().Kind() {
+	case reflect.Slice:
+		// []byte
+		var dummy []byte
+		valcopy = reflect.ValueOf(&dummy).Elem() // addressable []byte
+		valbase = toStructPointer(valcopy.Addr())
+	case reflect.Ptr:
+		// message; the generated field type is map[K]*Msg (so V is *Msg),
+		// so we only need one level of indirection.
+		valcopy = reflect.New(mapType.Elem()).Elem() // addressable V
+		valbase = toStructPointer(valcopy.Addr())
+	default:
+		// everything else
+		valcopy = reflect.New(mapType.Elem()).Elem()                // addressable V
+		valptr := reflect.New(reflect.PtrTo(valcopy.Type())).Elem() // addressable *V
+		valptr.Set(valcopy.Addr())                                  //
+		valbase = toStructPointer(valptr.Addr())                    // **V
+	}
+	return
+}
+
+// Encode a struct.
+func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
+	var state errorState
+	// Encode fields in tag order so that decoders may use optimizations
+	// that depend on the ordering.
+	// https://developers.google.com/protocol-buffers/docs/encoding#order
+	for _, i := range prop.order {
+		p := prop.Prop[i]
+		if p.enc != nil {
+			err := p.enc(o, p, base)
+			if err != nil {
+				if err == ErrNil {
+					if p.Required && state.err == nil {
+						state.err = &RequiredNotSetError{p.Name}
+					}
+				} else if err == errRepeatedHasNil {
+					// Give more context to nil values in repeated fields.
+					return errors.New("repeated field " + p.OrigName + " has nil element")
+				} else if !state.shouldContinue(err, p) {
+					return err
+				}
+			}
+			if len(o.buf) > maxMarshalSize {
+				return ErrTooLarge
+			}
+		}
+	}
+
+	// Do oneof fields.
+	if prop.oneofMarshaler != nil {
+		m := structPointer_Interface(base, prop.stype).(Message)
+		if err := prop.oneofMarshaler(m, o); err == ErrNil {
+			return errOneofHasNil
+		} else if err != nil {
+			return err
+		}
+	}
+
+	// Add unrecognized fields at the end.
+	if prop.unrecField.IsValid() {
+		v := *structPointer_Bytes(base, prop.unrecField)
+		if len(o.buf)+len(v) > maxMarshalSize {
+			return ErrTooLarge
+		}
+		if len(v) > 0 {
+			o.buf = append(o.buf, v...)
+		}
+	}
+
+	return state.err
+}
+
+func size_struct(prop *StructProperties, base structPointer) (n int) {
+	for _, i := range prop.order {
+		p := prop.Prop[i]
+		if p.size != nil {
+			n += p.size(p, base)
+		}
+	}
+
+	// Add unrecognized fields at the end.
+	if prop.unrecField.IsValid() {
+		v := *structPointer_Bytes(base, prop.unrecField)
+		n += len(v)
+	}
+
+	// Factor in any oneof fields.
+	if prop.oneofSizer != nil {
+		m := structPointer_Interface(base, prop.stype).(Message)
+		n += prop.oneofSizer(m)
+	}
+
+	return
+}
+
+var zeroes [20]byte // longer than any conceivable sizeVarint
+
+// Encode a struct, preceded by its encoded length (as a varint).
+func (o *Buffer) enc_len_struct(prop *StructProperties, base structPointer, state *errorState) error {
+	return o.enc_len_thing(func() error { return o.enc_struct(prop, base) }, state)
+}
+
+// Encode something, preceded by its encoded length (as a varint).
+func (o *Buffer) enc_len_thing(enc func() error, state *errorState) error {
+	iLen := len(o.buf)
+	o.buf = append(o.buf, 0, 0, 0, 0) // reserve four bytes for length
+	iMsg := len(o.buf)
+	err := enc()
+	if err != nil && !state.shouldContinue(err, nil) {
+		return err
+	}
+	lMsg := len(o.buf) - iMsg
+	lLen := sizeVarint(uint64(lMsg))
+	switch x := lLen - (iMsg - iLen); {
+	case x > 0: // actual length is x bytes larger than the space we reserved
+		// Move msg x bytes right.
+		o.buf = append(o.buf, zeroes[:x]...)
+		copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
+	case x < 0: // actual length is x bytes smaller than the space we reserved
+		// Move msg x bytes left.
+		copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
+		o.buf = o.buf[:len(o.buf)+x] // x is negative
+	}
+	// Encode the length in the reserved space.
+	o.buf = o.buf[:iLen]
+	o.EncodeVarint(uint64(lMsg))
+	o.buf = o.buf[:len(o.buf)+lMsg]
+	return state.err
+}
+
+// errorState maintains the first error that occurs and updates that error
+// with additional context.
+type errorState struct {
+	err error
+}
+
+// shouldContinue reports whether encoding should continue upon encountering the
+// given error. If the error is RequiredNotSetError, shouldContinue returns true
+// and, if this is the first appearance of that error, remembers it for future
+// reporting.
+//
+// If prop is not nil, it may update any error with additional context about the
+// field with the error.
+func (s *errorState) shouldContinue(err error, prop *Properties) bool {
+	// Ignore unset required fields.
+	reqNotSet, ok := err.(*RequiredNotSetError)
+	if !ok {
+		return false
+	}
+	if s.err == nil {
+		if prop != nil {
+			err = &RequiredNotSetError{prop.Name + "." + reqNotSet.field}
+		}
+		s.err = err
+	}
+	return true
+}

+ 300 - 0
vendor/github.com/golang/protobuf/proto/equal.go

@@ -0,0 +1,300 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2011 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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.
+
+// Protocol buffer comparison.
+
+package proto
+
+import (
+	"bytes"
+	"log"
+	"reflect"
+	"strings"
+)
+
+/*
+Equal returns true iff protocol buffers a and b are equal.
+The arguments must both be pointers to protocol buffer structs.
+
+Equality is defined in this way:
+  - Two messages are equal iff they are the same type,
+    corresponding fields are equal, unknown field sets
+    are equal, and extensions sets are equal.
+  - Two set scalar fields are equal iff their values are equal.
+    If the fields are of a floating-point type, remember that
+    NaN != x for all x, including NaN. If the message is defined
+    in a proto3 .proto file, fields are not "set"; specifically,
+    zero length proto3 "bytes" fields are equal (nil == {}).
+  - Two repeated fields are equal iff their lengths are the same,
+    and their corresponding elements are equal. Note a "bytes" field,
+    although represented by []byte, is not a repeated field and the
+    rule for the scalar fields described above applies.
+  - Two unset fields are equal.
+  - Two unknown field sets are equal if their current
+    encoded state is equal.
+  - Two extension sets are equal iff they have corresponding
+    elements that are pairwise equal.
+  - Two map fields are equal iff their lengths are the same,
+    and they contain the same set of elements. Zero-length map
+    fields are equal.
+  - Every other combination of things are not equal.
+
+The return value is undefined if a and b are not protocol buffers.
+*/
+func Equal(a, b Message) bool {
+	if a == nil || b == nil {
+		return a == b
+	}
+	v1, v2 := reflect.ValueOf(a), reflect.ValueOf(b)
+	if v1.Type() != v2.Type() {
+		return false
+	}
+	if v1.Kind() == reflect.Ptr {
+		if v1.IsNil() {
+			return v2.IsNil()
+		}
+		if v2.IsNil() {
+			return false
+		}
+		v1, v2 = v1.Elem(), v2.Elem()
+	}
+	if v1.Kind() != reflect.Struct {
+		return false
+	}
+	return equalStruct(v1, v2)
+}
+
+// v1 and v2 are known to have the same type.
+func equalStruct(v1, v2 reflect.Value) bool {
+	sprop := GetProperties(v1.Type())
+	for i := 0; i < v1.NumField(); i++ {
+		f := v1.Type().Field(i)
+		if strings.HasPrefix(f.Name, "XXX_") {
+			continue
+		}
+		f1, f2 := v1.Field(i), v2.Field(i)
+		if f.Type.Kind() == reflect.Ptr {
+			if n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 {
+				// both unset
+				continue
+			} else if n1 != n2 {
+				// set/unset mismatch
+				return false
+			}
+			b1, ok := f1.Interface().(raw)
+			if ok {
+				b2 := f2.Interface().(raw)
+				// RawMessage
+				if !bytes.Equal(b1.Bytes(), b2.Bytes()) {
+					return false
+				}
+				continue
+			}
+			f1, f2 = f1.Elem(), f2.Elem()
+		}
+		if !equalAny(f1, f2, sprop.Prop[i]) {
+			return false
+		}
+	}
+
+	if em1 := v1.FieldByName("XXX_InternalExtensions"); em1.IsValid() {
+		em2 := v2.FieldByName("XXX_InternalExtensions")
+		if !equalExtensions(v1.Type(), em1.Interface().(XXX_InternalExtensions), em2.Interface().(XXX_InternalExtensions)) {
+			return false
+		}
+	}
+
+	if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() {
+		em2 := v2.FieldByName("XXX_extensions")
+		if !equalExtMap(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) {
+			return false
+		}
+	}
+
+	uf := v1.FieldByName("XXX_unrecognized")
+	if !uf.IsValid() {
+		return true
+	}
+
+	u1 := uf.Bytes()
+	u2 := v2.FieldByName("XXX_unrecognized").Bytes()
+	if !bytes.Equal(u1, u2) {
+		return false
+	}
+
+	return true
+}
+
+// v1 and v2 are known to have the same type.
+// prop may be nil.
+func equalAny(v1, v2 reflect.Value, prop *Properties) bool {
+	if v1.Type() == protoMessageType {
+		m1, _ := v1.Interface().(Message)
+		m2, _ := v2.Interface().(Message)
+		return Equal(m1, m2)
+	}
+	switch v1.Kind() {
+	case reflect.Bool:
+		return v1.Bool() == v2.Bool()
+	case reflect.Float32, reflect.Float64:
+		return v1.Float() == v2.Float()
+	case reflect.Int32, reflect.Int64:
+		return v1.Int() == v2.Int()
+	case reflect.Interface:
+		// Probably a oneof field; compare the inner values.
+		n1, n2 := v1.IsNil(), v2.IsNil()
+		if n1 || n2 {
+			return n1 == n2
+		}
+		e1, e2 := v1.Elem(), v2.Elem()
+		if e1.Type() != e2.Type() {
+			return false
+		}
+		return equalAny(e1, e2, nil)
+	case reflect.Map:
+		if v1.Len() != v2.Len() {
+			return false
+		}
+		for _, key := range v1.MapKeys() {
+			val2 := v2.MapIndex(key)
+			if !val2.IsValid() {
+				// This key was not found in the second map.
+				return false
+			}
+			if !equalAny(v1.MapIndex(key), val2, nil) {
+				return false
+			}
+		}
+		return true
+	case reflect.Ptr:
+		// Maps may have nil values in them, so check for nil.
+		if v1.IsNil() && v2.IsNil() {
+			return true
+		}
+		if v1.IsNil() != v2.IsNil() {
+			return false
+		}
+		return equalAny(v1.Elem(), v2.Elem(), prop)
+	case reflect.Slice:
+		if v1.Type().Elem().Kind() == reflect.Uint8 {
+			// short circuit: []byte
+
+			// Edge case: if this is in a proto3 message, a zero length
+			// bytes field is considered the zero value.
+			if prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 {
+				return true
+			}
+			if v1.IsNil() != v2.IsNil() {
+				return false
+			}
+			return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte))
+		}
+
+		if v1.Len() != v2.Len() {
+			return false
+		}
+		for i := 0; i < v1.Len(); i++ {
+			if !equalAny(v1.Index(i), v2.Index(i), prop) {
+				return false
+			}
+		}
+		return true
+	case reflect.String:
+		return v1.Interface().(string) == v2.Interface().(string)
+	case reflect.Struct:
+		return equalStruct(v1, v2)
+	case reflect.Uint32, reflect.Uint64:
+		return v1.Uint() == v2.Uint()
+	}
+
+	// unknown type, so not a protocol buffer
+	log.Printf("proto: don't know how to compare %v", v1)
+	return false
+}
+
+// base is the struct type that the extensions are based on.
+// x1 and x2 are InternalExtensions.
+func equalExtensions(base reflect.Type, x1, x2 XXX_InternalExtensions) bool {
+	em1, _ := x1.extensionsRead()
+	em2, _ := x2.extensionsRead()
+	return equalExtMap(base, em1, em2)
+}
+
+func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool {
+	if len(em1) != len(em2) {
+		return false
+	}
+
+	for extNum, e1 := range em1 {
+		e2, ok := em2[extNum]
+		if !ok {
+			return false
+		}
+
+		m1, m2 := e1.value, e2.value
+
+		if m1 != nil && m2 != nil {
+			// Both are unencoded.
+			if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) {
+				return false
+			}
+			continue
+		}
+
+		// At least one is encoded. To do a semantically correct comparison
+		// we need to unmarshal them first.
+		var desc *ExtensionDesc
+		if m := extensionMaps[base]; m != nil {
+			desc = m[extNum]
+		}
+		if desc == nil {
+			log.Printf("proto: don't know how to compare extension %d of %v", extNum, base)
+			continue
+		}
+		var err error
+		if m1 == nil {
+			m1, err = decodeExtension(e1.enc, desc)
+		}
+		if m2 == nil && err == nil {
+			m2, err = decodeExtension(e2.enc, desc)
+		}
+		if err != nil {
+			// The encoded form is invalid.
+			log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err)
+			return false
+		}
+		if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) {
+			return false
+		}
+	}
+
+	return true
+}

+ 587 - 0
vendor/github.com/golang/protobuf/proto/extensions.go

@@ -0,0 +1,587 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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 proto
+
+/*
+ * Types and routines for supporting protocol buffer extensions.
+ */
+
+import (
+	"errors"
+	"fmt"
+	"reflect"
+	"strconv"
+	"sync"
+)
+
+// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message.
+var ErrMissingExtension = errors.New("proto: missing extension")
+
+// ExtensionRange represents a range of message extensions for a protocol buffer.
+// Used in code generated by the protocol compiler.
+type ExtensionRange struct {
+	Start, End int32 // both inclusive
+}
+
+// extendableProto is an interface implemented by any protocol buffer generated by the current
+// proto compiler that may be extended.
+type extendableProto interface {
+	Message
+	ExtensionRangeArray() []ExtensionRange
+	extensionsWrite() map[int32]Extension
+	extensionsRead() (map[int32]Extension, sync.Locker)
+}
+
+// extendableProtoV1 is an interface implemented by a protocol buffer generated by the previous
+// version of the proto compiler that may be extended.
+type extendableProtoV1 interface {
+	Message
+	ExtensionRangeArray() []ExtensionRange
+	ExtensionMap() map[int32]Extension
+}
+
+// extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto.
+type extensionAdapter struct {
+	extendableProtoV1
+}
+
+func (e extensionAdapter) extensionsWrite() map[int32]Extension {
+	return e.ExtensionMap()
+}
+
+func (e extensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) {
+	return e.ExtensionMap(), notLocker{}
+}
+
+// notLocker is a sync.Locker whose Lock and Unlock methods are nops.
+type notLocker struct{}
+
+func (n notLocker) Lock()   {}
+func (n notLocker) Unlock() {}
+
+// extendable returns the extendableProto interface for the given generated proto message.
+// If the proto message has the old extension format, it returns a wrapper that implements
+// the extendableProto interface.
+func extendable(p interface{}) (extendableProto, bool) {
+	if ep, ok := p.(extendableProto); ok {
+		return ep, ok
+	}
+	if ep, ok := p.(extendableProtoV1); ok {
+		return extensionAdapter{ep}, ok
+	}
+	return nil, false
+}
+
+// XXX_InternalExtensions is an internal representation of proto extensions.
+//
+// Each generated message struct type embeds an anonymous XXX_InternalExtensions field,
+// thus gaining the unexported 'extensions' method, which can be called only from the proto package.
+//
+// The methods of XXX_InternalExtensions are not concurrency safe in general,
+// but calls to logically read-only methods such as has and get may be executed concurrently.
+type XXX_InternalExtensions struct {
+	// The struct must be indirect so that if a user inadvertently copies a
+	// generated message and its embedded XXX_InternalExtensions, they
+	// avoid the mayhem of a copied mutex.
+	//
+	// The mutex serializes all logically read-only operations to p.extensionMap.
+	// It is up to the client to ensure that write operations to p.extensionMap are
+	// mutually exclusive with other accesses.
+	p *struct {
+		mu           sync.Mutex
+		extensionMap map[int32]Extension
+	}
+}
+
+// extensionsWrite returns the extension map, creating it on first use.
+func (e *XXX_InternalExtensions) extensionsWrite() map[int32]Extension {
+	if e.p == nil {
+		e.p = new(struct {
+			mu           sync.Mutex
+			extensionMap map[int32]Extension
+		})
+		e.p.extensionMap = make(map[int32]Extension)
+	}
+	return e.p.extensionMap
+}
+
+// extensionsRead returns the extensions map for read-only use.  It may be nil.
+// The caller must hold the returned mutex's lock when accessing Elements within the map.
+func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Locker) {
+	if e.p == nil {
+		return nil, nil
+	}
+	return e.p.extensionMap, &e.p.mu
+}
+
+var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem()
+var extendableProtoV1Type = reflect.TypeOf((*extendableProtoV1)(nil)).Elem()
+
+// ExtensionDesc represents an extension specification.
+// Used in generated code from the protocol compiler.
+type ExtensionDesc struct {
+	ExtendedType  Message     // nil pointer to the type that is being extended
+	ExtensionType interface{} // nil pointer to the extension type
+	Field         int32       // field number
+	Name          string      // fully-qualified name of extension, for text formatting
+	Tag           string      // protobuf tag style
+	Filename      string      // name of the file in which the extension is defined
+}
+
+func (ed *ExtensionDesc) repeated() bool {
+	t := reflect.TypeOf(ed.ExtensionType)
+	return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
+}
+
+// Extension represents an extension in a message.
+type Extension struct {
+	// When an extension is stored in a message using SetExtension
+	// only desc and value are set. When the message is marshaled
+	// enc will be set to the encoded form of the message.
+	//
+	// When a message is unmarshaled and contains extensions, each
+	// extension will have only enc set. When such an extension is
+	// accessed using GetExtension (or GetExtensions) desc and value
+	// will be set.
+	desc  *ExtensionDesc
+	value interface{}
+	enc   []byte
+}
+
+// SetRawExtension is for testing only.
+func SetRawExtension(base Message, id int32, b []byte) {
+	epb, ok := extendable(base)
+	if !ok {
+		return
+	}
+	extmap := epb.extensionsWrite()
+	extmap[id] = Extension{enc: b}
+}
+
+// isExtensionField returns true iff the given field number is in an extension range.
+func isExtensionField(pb extendableProto, field int32) bool {
+	for _, er := range pb.ExtensionRangeArray() {
+		if er.Start <= field && field <= er.End {
+			return true
+		}
+	}
+	return false
+}
+
+// checkExtensionTypes checks that the given extension is valid for pb.
+func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error {
+	var pbi interface{} = pb
+	// Check the extended type.
+	if ea, ok := pbi.(extensionAdapter); ok {
+		pbi = ea.extendableProtoV1
+	}
+	if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b {
+		return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String())
+	}
+	// Check the range.
+	if !isExtensionField(pb, extension.Field) {
+		return errors.New("proto: bad extension number; not in declared ranges")
+	}
+	return nil
+}
+
+// extPropKey is sufficient to uniquely identify an extension.
+type extPropKey struct {
+	base  reflect.Type
+	field int32
+}
+
+var extProp = struct {
+	sync.RWMutex
+	m map[extPropKey]*Properties
+}{
+	m: make(map[extPropKey]*Properties),
+}
+
+func extensionProperties(ed *ExtensionDesc) *Properties {
+	key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field}
+
+	extProp.RLock()
+	if prop, ok := extProp.m[key]; ok {
+		extProp.RUnlock()
+		return prop
+	}
+	extProp.RUnlock()
+
+	extProp.Lock()
+	defer extProp.Unlock()
+	// Check again.
+	if prop, ok := extProp.m[key]; ok {
+		return prop
+	}
+
+	prop := new(Properties)
+	prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil)
+	extProp.m[key] = prop
+	return prop
+}
+
+// encode encodes any unmarshaled (unencoded) extensions in e.
+func encodeExtensions(e *XXX_InternalExtensions) error {
+	m, mu := e.extensionsRead()
+	if m == nil {
+		return nil // fast path
+	}
+	mu.Lock()
+	defer mu.Unlock()
+	return encodeExtensionsMap(m)
+}
+
+// encode encodes any unmarshaled (unencoded) extensions in e.
+func encodeExtensionsMap(m map[int32]Extension) error {
+	for k, e := range m {
+		if e.value == nil || e.desc == nil {
+			// Extension is only in its encoded form.
+			continue
+		}
+
+		// We don't skip extensions that have an encoded form set,
+		// because the extension value may have been mutated after
+		// the last time this function was called.
+
+		et := reflect.TypeOf(e.desc.ExtensionType)
+		props := extensionProperties(e.desc)
+
+		p := NewBuffer(nil)
+		// If e.value has type T, the encoder expects a *struct{ X T }.
+		// Pass a *T with a zero field and hope it all works out.
+		x := reflect.New(et)
+		x.Elem().Set(reflect.ValueOf(e.value))
+		if err := props.enc(p, props, toStructPointer(x)); err != nil {
+			return err
+		}
+		e.enc = p.buf
+		m[k] = e
+	}
+	return nil
+}
+
+func extensionsSize(e *XXX_InternalExtensions) (n int) {
+	m, mu := e.extensionsRead()
+	if m == nil {
+		return 0
+	}
+	mu.Lock()
+	defer mu.Unlock()
+	return extensionsMapSize(m)
+}
+
+func extensionsMapSize(m map[int32]Extension) (n int) {
+	for _, e := range m {
+		if e.value == nil || e.desc == nil {
+			// Extension is only in its encoded form.
+			n += len(e.enc)
+			continue
+		}
+
+		// We don't skip extensions that have an encoded form set,
+		// because the extension value may have been mutated after
+		// the last time this function was called.
+
+		et := reflect.TypeOf(e.desc.ExtensionType)
+		props := extensionProperties(e.desc)
+
+		// If e.value has type T, the encoder expects a *struct{ X T }.
+		// Pass a *T with a zero field and hope it all works out.
+		x := reflect.New(et)
+		x.Elem().Set(reflect.ValueOf(e.value))
+		n += props.size(props, toStructPointer(x))
+	}
+	return
+}
+
+// HasExtension returns whether the given extension is present in pb.
+func HasExtension(pb Message, extension *ExtensionDesc) bool {
+	// TODO: Check types, field numbers, etc.?
+	epb, ok := extendable(pb)
+	if !ok {
+		return false
+	}
+	extmap, mu := epb.extensionsRead()
+	if extmap == nil {
+		return false
+	}
+	mu.Lock()
+	_, ok = extmap[extension.Field]
+	mu.Unlock()
+	return ok
+}
+
+// ClearExtension removes the given extension from pb.
+func ClearExtension(pb Message, extension *ExtensionDesc) {
+	epb, ok := extendable(pb)
+	if !ok {
+		return
+	}
+	// TODO: Check types, field numbers, etc.?
+	extmap := epb.extensionsWrite()
+	delete(extmap, extension.Field)
+}
+
+// GetExtension parses and returns the given extension of pb.
+// If the extension is not present and has no default value it returns ErrMissingExtension.
+func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
+	epb, ok := extendable(pb)
+	if !ok {
+		return nil, errors.New("proto: not an extendable proto")
+	}
+
+	if err := checkExtensionTypes(epb, extension); err != nil {
+		return nil, err
+	}
+
+	emap, mu := epb.extensionsRead()
+	if emap == nil {
+		return defaultExtensionValue(extension)
+	}
+	mu.Lock()
+	defer mu.Unlock()
+	e, ok := emap[extension.Field]
+	if !ok {
+		// defaultExtensionValue returns the default value or
+		// ErrMissingExtension if there is no default.
+		return defaultExtensionValue(extension)
+	}
+
+	if e.value != nil {
+		// Already decoded. Check the descriptor, though.
+		if e.desc != extension {
+			// This shouldn't happen. If it does, it means that
+			// GetExtension was called twice with two different
+			// descriptors with the same field number.
+			return nil, errors.New("proto: descriptor conflict")
+		}
+		return e.value, nil
+	}
+
+	v, err := decodeExtension(e.enc, extension)
+	if err != nil {
+		return nil, err
+	}
+
+	// Remember the decoded version and drop the encoded version.
+	// That way it is safe to mutate what we return.
+	e.value = v
+	e.desc = extension
+	e.enc = nil
+	emap[extension.Field] = e
+	return e.value, nil
+}
+
+// defaultExtensionValue returns the default value for extension.
+// If no default for an extension is defined ErrMissingExtension is returned.
+func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) {
+	t := reflect.TypeOf(extension.ExtensionType)
+	props := extensionProperties(extension)
+
+	sf, _, err := fieldDefault(t, props)
+	if err != nil {
+		return nil, err
+	}
+
+	if sf == nil || sf.value == nil {
+		// There is no default value.
+		return nil, ErrMissingExtension
+	}
+
+	if t.Kind() != reflect.Ptr {
+		// We do not need to return a Ptr, we can directly return sf.value.
+		return sf.value, nil
+	}
+
+	// We need to return an interface{} that is a pointer to sf.value.
+	value := reflect.New(t).Elem()
+	value.Set(reflect.New(value.Type().Elem()))
+	if sf.kind == reflect.Int32 {
+		// We may have an int32 or an enum, but the underlying data is int32.
+		// Since we can't set an int32 into a non int32 reflect.value directly
+		// set it as a int32.
+		value.Elem().SetInt(int64(sf.value.(int32)))
+	} else {
+		value.Elem().Set(reflect.ValueOf(sf.value))
+	}
+	return value.Interface(), nil
+}
+
+// decodeExtension decodes an extension encoded in b.
+func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
+	o := NewBuffer(b)
+
+	t := reflect.TypeOf(extension.ExtensionType)
+
+	props := extensionProperties(extension)
+
+	// t is a pointer to a struct, pointer to basic type or a slice.
+	// Allocate a "field" to store the pointer/slice itself; the
+	// pointer/slice will be stored here. We pass
+	// the address of this field to props.dec.
+	// This passes a zero field and a *t and lets props.dec
+	// interpret it as a *struct{ x t }.
+	value := reflect.New(t).Elem()
+
+	for {
+		// Discard wire type and field number varint. It isn't needed.
+		if _, err := o.DecodeVarint(); err != nil {
+			return nil, err
+		}
+
+		if err := props.dec(o, props, toStructPointer(value.Addr())); err != nil {
+			return nil, err
+		}
+
+		if o.index >= len(o.buf) {
+			break
+		}
+	}
+	return value.Interface(), nil
+}
+
+// GetExtensions returns a slice of the extensions present in pb that are also listed in es.
+// The returned slice has the same length as es; missing extensions will appear as nil elements.
+func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) {
+	epb, ok := extendable(pb)
+	if !ok {
+		return nil, errors.New("proto: not an extendable proto")
+	}
+	extensions = make([]interface{}, len(es))
+	for i, e := range es {
+		extensions[i], err = GetExtension(epb, e)
+		if err == ErrMissingExtension {
+			err = nil
+		}
+		if err != nil {
+			return
+		}
+	}
+	return
+}
+
+// ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order.
+// For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing
+// just the Field field, which defines the extension's field number.
+func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) {
+	epb, ok := extendable(pb)
+	if !ok {
+		return nil, fmt.Errorf("proto: %T is not an extendable proto.Message", pb)
+	}
+	registeredExtensions := RegisteredExtensions(pb)
+
+	emap, mu := epb.extensionsRead()
+	if emap == nil {
+		return nil, nil
+	}
+	mu.Lock()
+	defer mu.Unlock()
+	extensions := make([]*ExtensionDesc, 0, len(emap))
+	for extid, e := range emap {
+		desc := e.desc
+		if desc == nil {
+			desc = registeredExtensions[extid]
+			if desc == nil {
+				desc = &ExtensionDesc{Field: extid}
+			}
+		}
+
+		extensions = append(extensions, desc)
+	}
+	return extensions, nil
+}
+
+// SetExtension sets the specified extension of pb to the specified value.
+func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error {
+	epb, ok := extendable(pb)
+	if !ok {
+		return errors.New("proto: not an extendable proto")
+	}
+	if err := checkExtensionTypes(epb, extension); err != nil {
+		return err
+	}
+	typ := reflect.TypeOf(extension.ExtensionType)
+	if typ != reflect.TypeOf(value) {
+		return errors.New("proto: bad extension value type")
+	}
+	// nil extension values need to be caught early, because the
+	// encoder can't distinguish an ErrNil due to a nil extension
+	// from an ErrNil due to a missing field. Extensions are
+	// always optional, so the encoder would just swallow the error
+	// and drop all the extensions from the encoded message.
+	if reflect.ValueOf(value).IsNil() {
+		return fmt.Errorf("proto: SetExtension called with nil value of type %T", value)
+	}
+
+	extmap := epb.extensionsWrite()
+	extmap[extension.Field] = Extension{desc: extension, value: value}
+	return nil
+}
+
+// ClearAllExtensions clears all extensions from pb.
+func ClearAllExtensions(pb Message) {
+	epb, ok := extendable(pb)
+	if !ok {
+		return
+	}
+	m := epb.extensionsWrite()
+	for k := range m {
+		delete(m, k)
+	}
+}
+
+// A global registry of extensions.
+// The generated code will register the generated descriptors by calling RegisterExtension.
+
+var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc)
+
+// RegisterExtension is called from the generated code.
+func RegisterExtension(desc *ExtensionDesc) {
+	st := reflect.TypeOf(desc.ExtendedType).Elem()
+	m := extensionMaps[st]
+	if m == nil {
+		m = make(map[int32]*ExtensionDesc)
+		extensionMaps[st] = m
+	}
+	if _, ok := m[desc.Field]; ok {
+		panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field)))
+	}
+	m[desc.Field] = desc
+}
+
+// RegisteredExtensions returns a map of the registered extensions of a
+// protocol buffer struct, indexed by the extension number.
+// The argument pb should be a nil pointer to the struct type.
+func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc {
+	return extensionMaps[reflect.TypeOf(pb).Elem()]
+}

+ 897 - 0
vendor/github.com/golang/protobuf/proto/lib.go

@@ -0,0 +1,897 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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 proto converts data structures to and from the wire format of
+protocol buffers.  It works in concert with the Go source code generated
+for .proto files by the protocol compiler.
+
+A summary of the properties of the protocol buffer interface
+for a protocol buffer variable v:
+
+  - Names are turned from camel_case to CamelCase for export.
+  - There are no methods on v to set fields; just treat
+	them as structure fields.
+  - There are getters that return a field's value if set,
+	and return the field's default value if unset.
+	The getters work even if the receiver is a nil message.
+  - The zero value for a struct is its correct initialization state.
+	All desired fields must be set before marshaling.
+  - A Reset() method will restore a protobuf struct to its zero state.
+  - Non-repeated fields are pointers to the values; nil means unset.
+	That is, optional or required field int32 f becomes F *int32.
+  - Repeated fields are slices.
+  - Helper functions are available to aid the setting of fields.
+	msg.Foo = proto.String("hello") // set field
+  - Constants are defined to hold the default values of all fields that
+	have them.  They have the form Default_StructName_FieldName.
+	Because the getter methods handle defaulted values,
+	direct use of these constants should be rare.
+  - Enums are given type names and maps from names to values.
+	Enum values are prefixed by the enclosing message's name, or by the
+	enum's type name if it is a top-level enum. Enum types have a String
+	method, and a Enum method to assist in message construction.
+  - Nested messages, groups and enums have type names prefixed with the name of
+	the surrounding message type.
+  - Extensions are given descriptor names that start with E_,
+	followed by an underscore-delimited list of the nested messages
+	that contain it (if any) followed by the CamelCased name of the
+	extension field itself.  HasExtension, ClearExtension, GetExtension
+	and SetExtension are functions for manipulating extensions.
+  - Oneof field sets are given a single field in their message,
+	with distinguished wrapper types for each possible field value.
+  - Marshal and Unmarshal are functions to encode and decode the wire format.
+
+When the .proto file specifies `syntax="proto3"`, there are some differences:
+
+  - Non-repeated fields of non-message type are values instead of pointers.
+  - Enum types do not get an Enum method.
+
+The simplest way to describe this is to see an example.
+Given file test.proto, containing
+
+	package example;
+
+	enum FOO { X = 17; }
+
+	message Test {
+	  required string label = 1;
+	  optional int32 type = 2 [default=77];
+	  repeated int64 reps = 3;
+	  optional group OptionalGroup = 4 {
+	    required string RequiredField = 5;
+	  }
+	  oneof union {
+	    int32 number = 6;
+	    string name = 7;
+	  }
+	}
+
+The resulting file, test.pb.go, is:
+
+	package example
+
+	import proto "github.com/golang/protobuf/proto"
+	import math "math"
+
+	type FOO int32
+	const (
+		FOO_X FOO = 17
+	)
+	var FOO_name = map[int32]string{
+		17: "X",
+	}
+	var FOO_value = map[string]int32{
+		"X": 17,
+	}
+
+	func (x FOO) Enum() *FOO {
+		p := new(FOO)
+		*p = x
+		return p
+	}
+	func (x FOO) String() string {
+		return proto.EnumName(FOO_name, int32(x))
+	}
+	func (x *FOO) UnmarshalJSON(data []byte) error {
+		value, err := proto.UnmarshalJSONEnum(FOO_value, data)
+		if err != nil {
+			return err
+		}
+		*x = FOO(value)
+		return nil
+	}
+
+	type Test struct {
+		Label         *string             `protobuf:"bytes,1,req,name=label" json:"label,omitempty"`
+		Type          *int32              `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"`
+		Reps          []int64             `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"`
+		Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"`
+		// Types that are valid to be assigned to Union:
+		//	*Test_Number
+		//	*Test_Name
+		Union            isTest_Union `protobuf_oneof:"union"`
+		XXX_unrecognized []byte       `json:"-"`
+	}
+	func (m *Test) Reset()         { *m = Test{} }
+	func (m *Test) String() string { return proto.CompactTextString(m) }
+	func (*Test) ProtoMessage() {}
+
+	type isTest_Union interface {
+		isTest_Union()
+	}
+
+	type Test_Number struct {
+		Number int32 `protobuf:"varint,6,opt,name=number"`
+	}
+	type Test_Name struct {
+		Name string `protobuf:"bytes,7,opt,name=name"`
+	}
+
+	func (*Test_Number) isTest_Union() {}
+	func (*Test_Name) isTest_Union()   {}
+
+	func (m *Test) GetUnion() isTest_Union {
+		if m != nil {
+			return m.Union
+		}
+		return nil
+	}
+	const Default_Test_Type int32 = 77
+
+	func (m *Test) GetLabel() string {
+		if m != nil && m.Label != nil {
+			return *m.Label
+		}
+		return ""
+	}
+
+	func (m *Test) GetType() int32 {
+		if m != nil && m.Type != nil {
+			return *m.Type
+		}
+		return Default_Test_Type
+	}
+
+	func (m *Test) GetOptionalgroup() *Test_OptionalGroup {
+		if m != nil {
+			return m.Optionalgroup
+		}
+		return nil
+	}
+
+	type Test_OptionalGroup struct {
+		RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"`
+	}
+	func (m *Test_OptionalGroup) Reset()         { *m = Test_OptionalGroup{} }
+	func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) }
+
+	func (m *Test_OptionalGroup) GetRequiredField() string {
+		if m != nil && m.RequiredField != nil {
+			return *m.RequiredField
+		}
+		return ""
+	}
+
+	func (m *Test) GetNumber() int32 {
+		if x, ok := m.GetUnion().(*Test_Number); ok {
+			return x.Number
+		}
+		return 0
+	}
+
+	func (m *Test) GetName() string {
+		if x, ok := m.GetUnion().(*Test_Name); ok {
+			return x.Name
+		}
+		return ""
+	}
+
+	func init() {
+		proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
+	}
+
+To create and play with a Test object:
+
+	package main
+
+	import (
+		"log"
+
+		"github.com/golang/protobuf/proto"
+		pb "./example.pb"
+	)
+
+	func main() {
+		test := &pb.Test{
+			Label: proto.String("hello"),
+			Type:  proto.Int32(17),
+			Reps:  []int64{1, 2, 3},
+			Optionalgroup: &pb.Test_OptionalGroup{
+				RequiredField: proto.String("good bye"),
+			},
+			Union: &pb.Test_Name{"fred"},
+		}
+		data, err := proto.Marshal(test)
+		if err != nil {
+			log.Fatal("marshaling error: ", err)
+		}
+		newTest := &pb.Test{}
+		err = proto.Unmarshal(data, newTest)
+		if err != nil {
+			log.Fatal("unmarshaling error: ", err)
+		}
+		// Now test and newTest contain the same data.
+		if test.GetLabel() != newTest.GetLabel() {
+			log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel())
+		}
+		// Use a type switch to determine which oneof was set.
+		switch u := test.Union.(type) {
+		case *pb.Test_Number: // u.Number contains the number.
+		case *pb.Test_Name: // u.Name contains the string.
+		}
+		// etc.
+	}
+*/
+package proto
+
+import (
+	"encoding/json"
+	"fmt"
+	"log"
+	"reflect"
+	"sort"
+	"strconv"
+	"sync"
+)
+
+// Message is implemented by generated protocol buffer messages.
+type Message interface {
+	Reset()
+	String() string
+	ProtoMessage()
+}
+
+// Stats records allocation details about the protocol buffer encoders
+// and decoders.  Useful for tuning the library itself.
+type Stats struct {
+	Emalloc uint64 // mallocs in encode
+	Dmalloc uint64 // mallocs in decode
+	Encode  uint64 // number of encodes
+	Decode  uint64 // number of decodes
+	Chit    uint64 // number of cache hits
+	Cmiss   uint64 // number of cache misses
+	Size    uint64 // number of sizes
+}
+
+// Set to true to enable stats collection.
+const collectStats = false
+
+var stats Stats
+
+// GetStats returns a copy of the global Stats structure.
+func GetStats() Stats { return stats }
+
+// A Buffer is a buffer manager for marshaling and unmarshaling
+// protocol buffers.  It may be reused between invocations to
+// reduce memory usage.  It is not necessary to use a Buffer;
+// the global functions Marshal and Unmarshal create a
+// temporary Buffer and are fine for most applications.
+type Buffer struct {
+	buf   []byte // encode/decode byte stream
+	index int    // read point
+
+	// pools of basic types to amortize allocation.
+	bools   []bool
+	uint32s []uint32
+	uint64s []uint64
+
+	// extra pools, only used with pointer_reflect.go
+	int32s   []int32
+	int64s   []int64
+	float32s []float32
+	float64s []float64
+}
+
+// NewBuffer allocates a new Buffer and initializes its internal data to
+// the contents of the argument slice.
+func NewBuffer(e []byte) *Buffer {
+	return &Buffer{buf: e}
+}
+
+// Reset resets the Buffer, ready for marshaling a new protocol buffer.
+func (p *Buffer) Reset() {
+	p.buf = p.buf[0:0] // for reading/writing
+	p.index = 0        // for reading
+}
+
+// SetBuf replaces the internal buffer with the slice,
+// ready for unmarshaling the contents of the slice.
+func (p *Buffer) SetBuf(s []byte) {
+	p.buf = s
+	p.index = 0
+}
+
+// Bytes returns the contents of the Buffer.
+func (p *Buffer) Bytes() []byte { return p.buf }
+
+/*
+ * Helper routines for simplifying the creation of optional fields of basic type.
+ */
+
+// Bool is a helper routine that allocates a new bool value
+// to store v and returns a pointer to it.
+func Bool(v bool) *bool {
+	return &v
+}
+
+// Int32 is a helper routine that allocates a new int32 value
+// to store v and returns a pointer to it.
+func Int32(v int32) *int32 {
+	return &v
+}
+
+// Int is a helper routine that allocates a new int32 value
+// to store v and returns a pointer to it, but unlike Int32
+// its argument value is an int.
+func Int(v int) *int32 {
+	p := new(int32)
+	*p = int32(v)
+	return p
+}
+
+// Int64 is a helper routine that allocates a new int64 value
+// to store v and returns a pointer to it.
+func Int64(v int64) *int64 {
+	return &v
+}
+
+// Float32 is a helper routine that allocates a new float32 value
+// to store v and returns a pointer to it.
+func Float32(v float32) *float32 {
+	return &v
+}
+
+// Float64 is a helper routine that allocates a new float64 value
+// to store v and returns a pointer to it.
+func Float64(v float64) *float64 {
+	return &v
+}
+
+// Uint32 is a helper routine that allocates a new uint32 value
+// to store v and returns a pointer to it.
+func Uint32(v uint32) *uint32 {
+	return &v
+}
+
+// Uint64 is a helper routine that allocates a new uint64 value
+// to store v and returns a pointer to it.
+func Uint64(v uint64) *uint64 {
+	return &v
+}
+
+// String is a helper routine that allocates a new string value
+// to store v and returns a pointer to it.
+func String(v string) *string {
+	return &v
+}
+
+// EnumName is a helper function to simplify printing protocol buffer enums
+// by name.  Given an enum map and a value, it returns a useful string.
+func EnumName(m map[int32]string, v int32) string {
+	s, ok := m[v]
+	if ok {
+		return s
+	}
+	return strconv.Itoa(int(v))
+}
+
+// UnmarshalJSONEnum is a helper function to simplify recovering enum int values
+// from their JSON-encoded representation. Given a map from the enum's symbolic
+// names to its int values, and a byte buffer containing the JSON-encoded
+// value, it returns an int32 that can be cast to the enum type by the caller.
+//
+// The function can deal with both JSON representations, numeric and symbolic.
+func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) {
+	if data[0] == '"' {
+		// New style: enums are strings.
+		var repr string
+		if err := json.Unmarshal(data, &repr); err != nil {
+			return -1, err
+		}
+		val, ok := m[repr]
+		if !ok {
+			return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr)
+		}
+		return val, nil
+	}
+	// Old style: enums are ints.
+	var val int32
+	if err := json.Unmarshal(data, &val); err != nil {
+		return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName)
+	}
+	return val, nil
+}
+
+// DebugPrint dumps the encoded data in b in a debugging format with a header
+// including the string s. Used in testing but made available for general debugging.
+func (p *Buffer) DebugPrint(s string, b []byte) {
+	var u uint64
+
+	obuf := p.buf
+	index := p.index
+	p.buf = b
+	p.index = 0
+	depth := 0
+
+	fmt.Printf("\n--- %s ---\n", s)
+
+out:
+	for {
+		for i := 0; i < depth; i++ {
+			fmt.Print("  ")
+		}
+
+		index := p.index
+		if index == len(p.buf) {
+			break
+		}
+
+		op, err := p.DecodeVarint()
+		if err != nil {
+			fmt.Printf("%3d: fetching op err %v\n", index, err)
+			break out
+		}
+		tag := op >> 3
+		wire := op & 7
+
+		switch wire {
+		default:
+			fmt.Printf("%3d: t=%3d unknown wire=%d\n",
+				index, tag, wire)
+			break out
+
+		case WireBytes:
+			var r []byte
+
+			r, err = p.DecodeRawBytes(false)
+			if err != nil {
+				break out
+			}
+			fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r))
+			if len(r) <= 6 {
+				for i := 0; i < len(r); i++ {
+					fmt.Printf(" %.2x", r[i])
+				}
+			} else {
+				for i := 0; i < 3; i++ {
+					fmt.Printf(" %.2x", r[i])
+				}
+				fmt.Printf(" ..")
+				for i := len(r) - 3; i < len(r); i++ {
+					fmt.Printf(" %.2x", r[i])
+				}
+			}
+			fmt.Printf("\n")
+
+		case WireFixed32:
+			u, err = p.DecodeFixed32()
+			if err != nil {
+				fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err)
+				break out
+			}
+			fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u)
+
+		case WireFixed64:
+			u, err = p.DecodeFixed64()
+			if err != nil {
+				fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err)
+				break out
+			}
+			fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u)
+
+		case WireVarint:
+			u, err = p.DecodeVarint()
+			if err != nil {
+				fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err)
+				break out
+			}
+			fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u)
+
+		case WireStartGroup:
+			fmt.Printf("%3d: t=%3d start\n", index, tag)
+			depth++
+
+		case WireEndGroup:
+			depth--
+			fmt.Printf("%3d: t=%3d end\n", index, tag)
+		}
+	}
+
+	if depth != 0 {
+		fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth)
+	}
+	fmt.Printf("\n")
+
+	p.buf = obuf
+	p.index = index
+}
+
+// SetDefaults sets unset protocol buffer fields to their default values.
+// It only modifies fields that are both unset and have defined defaults.
+// It recursively sets default values in any non-nil sub-messages.
+func SetDefaults(pb Message) {
+	setDefaults(reflect.ValueOf(pb), true, false)
+}
+
+// v is a pointer to a struct.
+func setDefaults(v reflect.Value, recur, zeros bool) {
+	v = v.Elem()
+
+	defaultMu.RLock()
+	dm, ok := defaults[v.Type()]
+	defaultMu.RUnlock()
+	if !ok {
+		dm = buildDefaultMessage(v.Type())
+		defaultMu.Lock()
+		defaults[v.Type()] = dm
+		defaultMu.Unlock()
+	}
+
+	for _, sf := range dm.scalars {
+		f := v.Field(sf.index)
+		if !f.IsNil() {
+			// field already set
+			continue
+		}
+		dv := sf.value
+		if dv == nil && !zeros {
+			// no explicit default, and don't want to set zeros
+			continue
+		}
+		fptr := f.Addr().Interface() // **T
+		// TODO: Consider batching the allocations we do here.
+		switch sf.kind {
+		case reflect.Bool:
+			b := new(bool)
+			if dv != nil {
+				*b = dv.(bool)
+			}
+			*(fptr.(**bool)) = b
+		case reflect.Float32:
+			f := new(float32)
+			if dv != nil {
+				*f = dv.(float32)
+			}
+			*(fptr.(**float32)) = f
+		case reflect.Float64:
+			f := new(float64)
+			if dv != nil {
+				*f = dv.(float64)
+			}
+			*(fptr.(**float64)) = f
+		case reflect.Int32:
+			// might be an enum
+			if ft := f.Type(); ft != int32PtrType {
+				// enum
+				f.Set(reflect.New(ft.Elem()))
+				if dv != nil {
+					f.Elem().SetInt(int64(dv.(int32)))
+				}
+			} else {
+				// int32 field
+				i := new(int32)
+				if dv != nil {
+					*i = dv.(int32)
+				}
+				*(fptr.(**int32)) = i
+			}
+		case reflect.Int64:
+			i := new(int64)
+			if dv != nil {
+				*i = dv.(int64)
+			}
+			*(fptr.(**int64)) = i
+		case reflect.String:
+			s := new(string)
+			if dv != nil {
+				*s = dv.(string)
+			}
+			*(fptr.(**string)) = s
+		case reflect.Uint8:
+			// exceptional case: []byte
+			var b []byte
+			if dv != nil {
+				db := dv.([]byte)
+				b = make([]byte, len(db))
+				copy(b, db)
+			} else {
+				b = []byte{}
+			}
+			*(fptr.(*[]byte)) = b
+		case reflect.Uint32:
+			u := new(uint32)
+			if dv != nil {
+				*u = dv.(uint32)
+			}
+			*(fptr.(**uint32)) = u
+		case reflect.Uint64:
+			u := new(uint64)
+			if dv != nil {
+				*u = dv.(uint64)
+			}
+			*(fptr.(**uint64)) = u
+		default:
+			log.Printf("proto: can't set default for field %v (sf.kind=%v)", f, sf.kind)
+		}
+	}
+
+	for _, ni := range dm.nested {
+		f := v.Field(ni)
+		// f is *T or []*T or map[T]*T
+		switch f.Kind() {
+		case reflect.Ptr:
+			if f.IsNil() {
+				continue
+			}
+			setDefaults(f, recur, zeros)
+
+		case reflect.Slice:
+			for i := 0; i < f.Len(); i++ {
+				e := f.Index(i)
+				if e.IsNil() {
+					continue
+				}
+				setDefaults(e, recur, zeros)
+			}
+
+		case reflect.Map:
+			for _, k := range f.MapKeys() {
+				e := f.MapIndex(k)
+				if e.IsNil() {
+					continue
+				}
+				setDefaults(e, recur, zeros)
+			}
+		}
+	}
+}
+
+var (
+	// defaults maps a protocol buffer struct type to a slice of the fields,
+	// with its scalar fields set to their proto-declared non-zero default values.
+	defaultMu sync.RWMutex
+	defaults  = make(map[reflect.Type]defaultMessage)
+
+	int32PtrType = reflect.TypeOf((*int32)(nil))
+)
+
+// defaultMessage represents information about the default values of a message.
+type defaultMessage struct {
+	scalars []scalarField
+	nested  []int // struct field index of nested messages
+}
+
+type scalarField struct {
+	index int          // struct field index
+	kind  reflect.Kind // element type (the T in *T or []T)
+	value interface{}  // the proto-declared default value, or nil
+}
+
+// t is a struct type.
+func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
+	sprop := GetProperties(t)
+	for _, prop := range sprop.Prop {
+		fi, ok := sprop.decoderTags.get(prop.Tag)
+		if !ok {
+			// XXX_unrecognized
+			continue
+		}
+		ft := t.Field(fi).Type
+
+		sf, nested, err := fieldDefault(ft, prop)
+		switch {
+		case err != nil:
+			log.Print(err)
+		case nested:
+			dm.nested = append(dm.nested, fi)
+		case sf != nil:
+			sf.index = fi
+			dm.scalars = append(dm.scalars, *sf)
+		}
+	}
+
+	return dm
+}
+
+// fieldDefault returns the scalarField for field type ft.
+// sf will be nil if the field can not have a default.
+// nestedMessage will be true if this is a nested message.
+// Note that sf.index is not set on return.
+func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) {
+	var canHaveDefault bool
+	switch ft.Kind() {
+	case reflect.Ptr:
+		if ft.Elem().Kind() == reflect.Struct {
+			nestedMessage = true
+		} else {
+			canHaveDefault = true // proto2 scalar field
+		}
+
+	case reflect.Slice:
+		switch ft.Elem().Kind() {
+		case reflect.Ptr:
+			nestedMessage = true // repeated message
+		case reflect.Uint8:
+			canHaveDefault = true // bytes field
+		}
+
+	case reflect.Map:
+		if ft.Elem().Kind() == reflect.Ptr {
+			nestedMessage = true // map with message values
+		}
+	}
+
+	if !canHaveDefault {
+		if nestedMessage {
+			return nil, true, nil
+		}
+		return nil, false, nil
+	}
+
+	// We now know that ft is a pointer or slice.
+	sf = &scalarField{kind: ft.Elem().Kind()}
+
+	// scalar fields without defaults
+	if !prop.HasDefault {
+		return sf, false, nil
+	}
+
+	// a scalar field: either *T or []byte
+	switch ft.Elem().Kind() {
+	case reflect.Bool:
+		x, err := strconv.ParseBool(prop.Default)
+		if err != nil {
+			return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err)
+		}
+		sf.value = x
+	case reflect.Float32:
+		x, err := strconv.ParseFloat(prop.Default, 32)
+		if err != nil {
+			return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err)
+		}
+		sf.value = float32(x)
+	case reflect.Float64:
+		x, err := strconv.ParseFloat(prop.Default, 64)
+		if err != nil {
+			return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err)
+		}
+		sf.value = x
+	case reflect.Int32:
+		x, err := strconv.ParseInt(prop.Default, 10, 32)
+		if err != nil {
+			return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err)
+		}
+		sf.value = int32(x)
+	case reflect.Int64:
+		x, err := strconv.ParseInt(prop.Default, 10, 64)
+		if err != nil {
+			return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err)
+		}
+		sf.value = x
+	case reflect.String:
+		sf.value = prop.Default
+	case reflect.Uint8:
+		// []byte (not *uint8)
+		sf.value = []byte(prop.Default)
+	case reflect.Uint32:
+		x, err := strconv.ParseUint(prop.Default, 10, 32)
+		if err != nil {
+			return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err)
+		}
+		sf.value = uint32(x)
+	case reflect.Uint64:
+		x, err := strconv.ParseUint(prop.Default, 10, 64)
+		if err != nil {
+			return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err)
+		}
+		sf.value = x
+	default:
+		return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind())
+	}
+
+	return sf, false, nil
+}
+
+// Map fields may have key types of non-float scalars, strings and enums.
+// The easiest way to sort them in some deterministic order is to use fmt.
+// If this turns out to be inefficient we can always consider other options,
+// such as doing a Schwartzian transform.
+
+func mapKeys(vs []reflect.Value) sort.Interface {
+	s := mapKeySorter{
+		vs: vs,
+		// default Less function: textual comparison
+		less: func(a, b reflect.Value) bool {
+			return fmt.Sprint(a.Interface()) < fmt.Sprint(b.Interface())
+		},
+	}
+
+	// Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps;
+	// numeric keys are sorted numerically.
+	if len(vs) == 0 {
+		return s
+	}
+	switch vs[0].Kind() {
+	case reflect.Int32, reflect.Int64:
+		s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() }
+	case reflect.Uint32, reflect.Uint64:
+		s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() }
+	}
+
+	return s
+}
+
+type mapKeySorter struct {
+	vs   []reflect.Value
+	less func(a, b reflect.Value) bool
+}
+
+func (s mapKeySorter) Len() int      { return len(s.vs) }
+func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] }
+func (s mapKeySorter) Less(i, j int) bool {
+	return s.less(s.vs[i], s.vs[j])
+}
+
+// isProto3Zero reports whether v is a zero proto3 value.
+func isProto3Zero(v reflect.Value) bool {
+	switch v.Kind() {
+	case reflect.Bool:
+		return !v.Bool()
+	case reflect.Int32, reflect.Int64:
+		return v.Int() == 0
+	case reflect.Uint32, reflect.Uint64:
+		return v.Uint() == 0
+	case reflect.Float32, reflect.Float64:
+		return v.Float() == 0
+	case reflect.String:
+		return v.String() == ""
+	}
+	return false
+}
+
+// ProtoPackageIsVersion2 is referenced from generated protocol buffer files
+// to assert that that code is compatible with this version of the proto package.
+const ProtoPackageIsVersion2 = true
+
+// ProtoPackageIsVersion1 is referenced from generated protocol buffer files
+// to assert that that code is compatible with this version of the proto package.
+const ProtoPackageIsVersion1 = true

+ 311 - 0
vendor/github.com/golang/protobuf/proto/message_set.go

@@ -0,0 +1,311 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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 proto
+
+/*
+ * Support for message sets.
+ */
+
+import (
+	"bytes"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"reflect"
+	"sort"
+)
+
+// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID.
+// A message type ID is required for storing a protocol buffer in a message set.
+var errNoMessageTypeID = errors.New("proto does not have a message type ID")
+
+// The first two types (_MessageSet_Item and messageSet)
+// model what the protocol compiler produces for the following protocol message:
+//   message MessageSet {
+//     repeated group Item = 1 {
+//       required int32 type_id = 2;
+//       required string message = 3;
+//     };
+//   }
+// That is the MessageSet wire format. We can't use a proto to generate these
+// because that would introduce a circular dependency between it and this package.
+
+type _MessageSet_Item struct {
+	TypeId  *int32 `protobuf:"varint,2,req,name=type_id"`
+	Message []byte `protobuf:"bytes,3,req,name=message"`
+}
+
+type messageSet struct {
+	Item             []*_MessageSet_Item `protobuf:"group,1,rep"`
+	XXX_unrecognized []byte
+	// TODO: caching?
+}
+
+// Make sure messageSet is a Message.
+var _ Message = (*messageSet)(nil)
+
+// messageTypeIder is an interface satisfied by a protocol buffer type
+// that may be stored in a MessageSet.
+type messageTypeIder interface {
+	MessageTypeId() int32
+}
+
+func (ms *messageSet) find(pb Message) *_MessageSet_Item {
+	mti, ok := pb.(messageTypeIder)
+	if !ok {
+		return nil
+	}
+	id := mti.MessageTypeId()
+	for _, item := range ms.Item {
+		if *item.TypeId == id {
+			return item
+		}
+	}
+	return nil
+}
+
+func (ms *messageSet) Has(pb Message) bool {
+	if ms.find(pb) != nil {
+		return true
+	}
+	return false
+}
+
+func (ms *messageSet) Unmarshal(pb Message) error {
+	if item := ms.find(pb); item != nil {
+		return Unmarshal(item.Message, pb)
+	}
+	if _, ok := pb.(messageTypeIder); !ok {
+		return errNoMessageTypeID
+	}
+	return nil // TODO: return error instead?
+}
+
+func (ms *messageSet) Marshal(pb Message) error {
+	msg, err := Marshal(pb)
+	if err != nil {
+		return err
+	}
+	if item := ms.find(pb); item != nil {
+		// reuse existing item
+		item.Message = msg
+		return nil
+	}
+
+	mti, ok := pb.(messageTypeIder)
+	if !ok {
+		return errNoMessageTypeID
+	}
+
+	mtid := mti.MessageTypeId()
+	ms.Item = append(ms.Item, &_MessageSet_Item{
+		TypeId:  &mtid,
+		Message: msg,
+	})
+	return nil
+}
+
+func (ms *messageSet) Reset()         { *ms = messageSet{} }
+func (ms *messageSet) String() string { return CompactTextString(ms) }
+func (*messageSet) ProtoMessage()     {}
+
+// Support for the message_set_wire_format message option.
+
+func skipVarint(buf []byte) []byte {
+	i := 0
+	for ; buf[i]&0x80 != 0; i++ {
+	}
+	return buf[i+1:]
+}
+
+// MarshalMessageSet encodes the extension map represented by m in the message set wire format.
+// It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option.
+func MarshalMessageSet(exts interface{}) ([]byte, error) {
+	var m map[int32]Extension
+	switch exts := exts.(type) {
+	case *XXX_InternalExtensions:
+		if err := encodeExtensions(exts); err != nil {
+			return nil, err
+		}
+		m, _ = exts.extensionsRead()
+	case map[int32]Extension:
+		if err := encodeExtensionsMap(exts); err != nil {
+			return nil, err
+		}
+		m = exts
+	default:
+		return nil, errors.New("proto: not an extension map")
+	}
+
+	// Sort extension IDs to provide a deterministic encoding.
+	// See also enc_map in encode.go.
+	ids := make([]int, 0, len(m))
+	for id := range m {
+		ids = append(ids, int(id))
+	}
+	sort.Ints(ids)
+
+	ms := &messageSet{Item: make([]*_MessageSet_Item, 0, len(m))}
+	for _, id := range ids {
+		e := m[int32(id)]
+		// Remove the wire type and field number varint, as well as the length varint.
+		msg := skipVarint(skipVarint(e.enc))
+
+		ms.Item = append(ms.Item, &_MessageSet_Item{
+			TypeId:  Int32(int32(id)),
+			Message: msg,
+		})
+	}
+	return Marshal(ms)
+}
+
+// UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
+// It is called by generated Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
+func UnmarshalMessageSet(buf []byte, exts interface{}) error {
+	var m map[int32]Extension
+	switch exts := exts.(type) {
+	case *XXX_InternalExtensions:
+		m = exts.extensionsWrite()
+	case map[int32]Extension:
+		m = exts
+	default:
+		return errors.New("proto: not an extension map")
+	}
+
+	ms := new(messageSet)
+	if err := Unmarshal(buf, ms); err != nil {
+		return err
+	}
+	for _, item := range ms.Item {
+		id := *item.TypeId
+		msg := item.Message
+
+		// Restore wire type and field number varint, plus length varint.
+		// Be careful to preserve duplicate items.
+		b := EncodeVarint(uint64(id)<<3 | WireBytes)
+		if ext, ok := m[id]; ok {
+			// Existing data; rip off the tag and length varint
+			// so we join the new data correctly.
+			// We can assume that ext.enc is set because we are unmarshaling.
+			o := ext.enc[len(b):]   // skip wire type and field number
+			_, n := DecodeVarint(o) // calculate length of length varint
+			o = o[n:]               // skip length varint
+			msg = append(o, msg...) // join old data and new data
+		}
+		b = append(b, EncodeVarint(uint64(len(msg)))...)
+		b = append(b, msg...)
+
+		m[id] = Extension{enc: b}
+	}
+	return nil
+}
+
+// MarshalMessageSetJSON encodes the extension map represented by m in JSON format.
+// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
+func MarshalMessageSetJSON(exts interface{}) ([]byte, error) {
+	var m map[int32]Extension
+	switch exts := exts.(type) {
+	case *XXX_InternalExtensions:
+		m, _ = exts.extensionsRead()
+	case map[int32]Extension:
+		m = exts
+	default:
+		return nil, errors.New("proto: not an extension map")
+	}
+	var b bytes.Buffer
+	b.WriteByte('{')
+
+	// Process the map in key order for deterministic output.
+	ids := make([]int32, 0, len(m))
+	for id := range m {
+		ids = append(ids, id)
+	}
+	sort.Sort(int32Slice(ids)) // int32Slice defined in text.go
+
+	for i, id := range ids {
+		ext := m[id]
+		if i > 0 {
+			b.WriteByte(',')
+		}
+
+		msd, ok := messageSetMap[id]
+		if !ok {
+			// Unknown type; we can't render it, so skip it.
+			continue
+		}
+		fmt.Fprintf(&b, `"[%s]":`, msd.name)
+
+		x := ext.value
+		if x == nil {
+			x = reflect.New(msd.t.Elem()).Interface()
+			if err := Unmarshal(ext.enc, x.(Message)); err != nil {
+				return nil, err
+			}
+		}
+		d, err := json.Marshal(x)
+		if err != nil {
+			return nil, err
+		}
+		b.Write(d)
+	}
+	b.WriteByte('}')
+	return b.Bytes(), nil
+}
+
+// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format.
+// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
+func UnmarshalMessageSetJSON(buf []byte, exts interface{}) error {
+	// Common-case fast path.
+	if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) {
+		return nil
+	}
+
+	// This is fairly tricky, and it's not clear that it is needed.
+	return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented")
+}
+
+// A global registry of types that can be used in a MessageSet.
+
+var messageSetMap = make(map[int32]messageSetDesc)
+
+type messageSetDesc struct {
+	t    reflect.Type // pointer to struct
+	name string
+}
+
+// RegisterMessageSetType is called from the generated code.
+func RegisterMessageSetType(m Message, fieldNum int32, name string) {
+	messageSetMap[fieldNum] = messageSetDesc{
+		t:    reflect.TypeOf(m),
+		name: name,
+	}
+}

+ 484 - 0
vendor/github.com/golang/protobuf/proto/pointer_reflect.go

@@ -0,0 +1,484 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2012 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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.
+
+// +build appengine js
+
+// This file contains an implementation of proto field accesses using package reflect.
+// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
+// be used on App Engine.
+
+package proto
+
+import (
+	"math"
+	"reflect"
+)
+
+// A structPointer is a pointer to a struct.
+type structPointer struct {
+	v reflect.Value
+}
+
+// toStructPointer returns a structPointer equivalent to the given reflect value.
+// The reflect value must itself be a pointer to a struct.
+func toStructPointer(v reflect.Value) structPointer {
+	return structPointer{v}
+}
+
+// IsNil reports whether p is nil.
+func structPointer_IsNil(p structPointer) bool {
+	return p.v.IsNil()
+}
+
+// Interface returns the struct pointer as an interface value.
+func structPointer_Interface(p structPointer, _ reflect.Type) interface{} {
+	return p.v.Interface()
+}
+
+// A field identifies a field in a struct, accessible from a structPointer.
+// In this implementation, a field is identified by the sequence of field indices
+// passed to reflect's FieldByIndex.
+type field []int
+
+// toField returns a field equivalent to the given reflect field.
+func toField(f *reflect.StructField) field {
+	return f.Index
+}
+
+// invalidField is an invalid field identifier.
+var invalidField = field(nil)
+
+// IsValid reports whether the field identifier is valid.
+func (f field) IsValid() bool { return f != nil }
+
+// field returns the given field in the struct as a reflect value.
+func structPointer_field(p structPointer, f field) reflect.Value {
+	// Special case: an extension map entry with a value of type T
+	// passes a *T to the struct-handling code with a zero field,
+	// expecting that it will be treated as equivalent to *struct{ X T },
+	// which has the same memory layout. We have to handle that case
+	// specially, because reflect will panic if we call FieldByIndex on a
+	// non-struct.
+	if f == nil {
+		return p.v.Elem()
+	}
+
+	return p.v.Elem().FieldByIndex(f)
+}
+
+// ifield returns the given field in the struct as an interface value.
+func structPointer_ifield(p structPointer, f field) interface{} {
+	return structPointer_field(p, f).Addr().Interface()
+}
+
+// Bytes returns the address of a []byte field in the struct.
+func structPointer_Bytes(p structPointer, f field) *[]byte {
+	return structPointer_ifield(p, f).(*[]byte)
+}
+
+// BytesSlice returns the address of a [][]byte field in the struct.
+func structPointer_BytesSlice(p structPointer, f field) *[][]byte {
+	return structPointer_ifield(p, f).(*[][]byte)
+}
+
+// Bool returns the address of a *bool field in the struct.
+func structPointer_Bool(p structPointer, f field) **bool {
+	return structPointer_ifield(p, f).(**bool)
+}
+
+// BoolVal returns the address of a bool field in the struct.
+func structPointer_BoolVal(p structPointer, f field) *bool {
+	return structPointer_ifield(p, f).(*bool)
+}
+
+// BoolSlice returns the address of a []bool field in the struct.
+func structPointer_BoolSlice(p structPointer, f field) *[]bool {
+	return structPointer_ifield(p, f).(*[]bool)
+}
+
+// String returns the address of a *string field in the struct.
+func structPointer_String(p structPointer, f field) **string {
+	return structPointer_ifield(p, f).(**string)
+}
+
+// StringVal returns the address of a string field in the struct.
+func structPointer_StringVal(p structPointer, f field) *string {
+	return structPointer_ifield(p, f).(*string)
+}
+
+// StringSlice returns the address of a []string field in the struct.
+func structPointer_StringSlice(p structPointer, f field) *[]string {
+	return structPointer_ifield(p, f).(*[]string)
+}
+
+// Extensions returns the address of an extension map field in the struct.
+func structPointer_Extensions(p structPointer, f field) *XXX_InternalExtensions {
+	return structPointer_ifield(p, f).(*XXX_InternalExtensions)
+}
+
+// ExtMap returns the address of an extension map field in the struct.
+func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
+	return structPointer_ifield(p, f).(*map[int32]Extension)
+}
+
+// NewAt returns the reflect.Value for a pointer to a field in the struct.
+func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value {
+	return structPointer_field(p, f).Addr()
+}
+
+// SetStructPointer writes a *struct field in the struct.
+func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
+	structPointer_field(p, f).Set(q.v)
+}
+
+// GetStructPointer reads a *struct field in the struct.
+func structPointer_GetStructPointer(p structPointer, f field) structPointer {
+	return structPointer{structPointer_field(p, f)}
+}
+
+// StructPointerSlice the address of a []*struct field in the struct.
+func structPointer_StructPointerSlice(p structPointer, f field) structPointerSlice {
+	return structPointerSlice{structPointer_field(p, f)}
+}
+
+// A structPointerSlice represents the address of a slice of pointers to structs
+// (themselves messages or groups). That is, v.Type() is *[]*struct{...}.
+type structPointerSlice struct {
+	v reflect.Value
+}
+
+func (p structPointerSlice) Len() int                  { return p.v.Len() }
+func (p structPointerSlice) Index(i int) structPointer { return structPointer{p.v.Index(i)} }
+func (p structPointerSlice) Append(q structPointer) {
+	p.v.Set(reflect.Append(p.v, q.v))
+}
+
+var (
+	int32Type   = reflect.TypeOf(int32(0))
+	uint32Type  = reflect.TypeOf(uint32(0))
+	float32Type = reflect.TypeOf(float32(0))
+	int64Type   = reflect.TypeOf(int64(0))
+	uint64Type  = reflect.TypeOf(uint64(0))
+	float64Type = reflect.TypeOf(float64(0))
+)
+
+// A word32 represents a field of type *int32, *uint32, *float32, or *enum.
+// That is, v.Type() is *int32, *uint32, *float32, or *enum and v is assignable.
+type word32 struct {
+	v reflect.Value
+}
+
+// IsNil reports whether p is nil.
+func word32_IsNil(p word32) bool {
+	return p.v.IsNil()
+}
+
+// Set sets p to point at a newly allocated word with bits set to x.
+func word32_Set(p word32, o *Buffer, x uint32) {
+	t := p.v.Type().Elem()
+	switch t {
+	case int32Type:
+		if len(o.int32s) == 0 {
+			o.int32s = make([]int32, uint32PoolSize)
+		}
+		o.int32s[0] = int32(x)
+		p.v.Set(reflect.ValueOf(&o.int32s[0]))
+		o.int32s = o.int32s[1:]
+		return
+	case uint32Type:
+		if len(o.uint32s) == 0 {
+			o.uint32s = make([]uint32, uint32PoolSize)
+		}
+		o.uint32s[0] = x
+		p.v.Set(reflect.ValueOf(&o.uint32s[0]))
+		o.uint32s = o.uint32s[1:]
+		return
+	case float32Type:
+		if len(o.float32s) == 0 {
+			o.float32s = make([]float32, uint32PoolSize)
+		}
+		o.float32s[0] = math.Float32frombits(x)
+		p.v.Set(reflect.ValueOf(&o.float32s[0]))
+		o.float32s = o.float32s[1:]
+		return
+	}
+
+	// must be enum
+	p.v.Set(reflect.New(t))
+	p.v.Elem().SetInt(int64(int32(x)))
+}
+
+// Get gets the bits pointed at by p, as a uint32.
+func word32_Get(p word32) uint32 {
+	elem := p.v.Elem()
+	switch elem.Kind() {
+	case reflect.Int32:
+		return uint32(elem.Int())
+	case reflect.Uint32:
+		return uint32(elem.Uint())
+	case reflect.Float32:
+		return math.Float32bits(float32(elem.Float()))
+	}
+	panic("unreachable")
+}
+
+// Word32 returns a reference to a *int32, *uint32, *float32, or *enum field in the struct.
+func structPointer_Word32(p structPointer, f field) word32 {
+	return word32{structPointer_field(p, f)}
+}
+
+// A word32Val represents a field of type int32, uint32, float32, or enum.
+// That is, v.Type() is int32, uint32, float32, or enum and v is assignable.
+type word32Val struct {
+	v reflect.Value
+}
+
+// Set sets *p to x.
+func word32Val_Set(p word32Val, x uint32) {
+	switch p.v.Type() {
+	case int32Type:
+		p.v.SetInt(int64(x))
+		return
+	case uint32Type:
+		p.v.SetUint(uint64(x))
+		return
+	case float32Type:
+		p.v.SetFloat(float64(math.Float32frombits(x)))
+		return
+	}
+
+	// must be enum
+	p.v.SetInt(int64(int32(x)))
+}
+
+// Get gets the bits pointed at by p, as a uint32.
+func word32Val_Get(p word32Val) uint32 {
+	elem := p.v
+	switch elem.Kind() {
+	case reflect.Int32:
+		return uint32(elem.Int())
+	case reflect.Uint32:
+		return uint32(elem.Uint())
+	case reflect.Float32:
+		return math.Float32bits(float32(elem.Float()))
+	}
+	panic("unreachable")
+}
+
+// Word32Val returns a reference to a int32, uint32, float32, or enum field in the struct.
+func structPointer_Word32Val(p structPointer, f field) word32Val {
+	return word32Val{structPointer_field(p, f)}
+}
+
+// A word32Slice is a slice of 32-bit values.
+// That is, v.Type() is []int32, []uint32, []float32, or []enum.
+type word32Slice struct {
+	v reflect.Value
+}
+
+func (p word32Slice) Append(x uint32) {
+	n, m := p.v.Len(), p.v.Cap()
+	if n < m {
+		p.v.SetLen(n + 1)
+	} else {
+		t := p.v.Type().Elem()
+		p.v.Set(reflect.Append(p.v, reflect.Zero(t)))
+	}
+	elem := p.v.Index(n)
+	switch elem.Kind() {
+	case reflect.Int32:
+		elem.SetInt(int64(int32(x)))
+	case reflect.Uint32:
+		elem.SetUint(uint64(x))
+	case reflect.Float32:
+		elem.SetFloat(float64(math.Float32frombits(x)))
+	}
+}
+
+func (p word32Slice) Len() int {
+	return p.v.Len()
+}
+
+func (p word32Slice) Index(i int) uint32 {
+	elem := p.v.Index(i)
+	switch elem.Kind() {
+	case reflect.Int32:
+		return uint32(elem.Int())
+	case reflect.Uint32:
+		return uint32(elem.Uint())
+	case reflect.Float32:
+		return math.Float32bits(float32(elem.Float()))
+	}
+	panic("unreachable")
+}
+
+// Word32Slice returns a reference to a []int32, []uint32, []float32, or []enum field in the struct.
+func structPointer_Word32Slice(p structPointer, f field) word32Slice {
+	return word32Slice{structPointer_field(p, f)}
+}
+
+// word64 is like word32 but for 64-bit values.
+type word64 struct {
+	v reflect.Value
+}
+
+func word64_Set(p word64, o *Buffer, x uint64) {
+	t := p.v.Type().Elem()
+	switch t {
+	case int64Type:
+		if len(o.int64s) == 0 {
+			o.int64s = make([]int64, uint64PoolSize)
+		}
+		o.int64s[0] = int64(x)
+		p.v.Set(reflect.ValueOf(&o.int64s[0]))
+		o.int64s = o.int64s[1:]
+		return
+	case uint64Type:
+		if len(o.uint64s) == 0 {
+			o.uint64s = make([]uint64, uint64PoolSize)
+		}
+		o.uint64s[0] = x
+		p.v.Set(reflect.ValueOf(&o.uint64s[0]))
+		o.uint64s = o.uint64s[1:]
+		return
+	case float64Type:
+		if len(o.float64s) == 0 {
+			o.float64s = make([]float64, uint64PoolSize)
+		}
+		o.float64s[0] = math.Float64frombits(x)
+		p.v.Set(reflect.ValueOf(&o.float64s[0]))
+		o.float64s = o.float64s[1:]
+		return
+	}
+	panic("unreachable")
+}
+
+func word64_IsNil(p word64) bool {
+	return p.v.IsNil()
+}
+
+func word64_Get(p word64) uint64 {
+	elem := p.v.Elem()
+	switch elem.Kind() {
+	case reflect.Int64:
+		return uint64(elem.Int())
+	case reflect.Uint64:
+		return elem.Uint()
+	case reflect.Float64:
+		return math.Float64bits(elem.Float())
+	}
+	panic("unreachable")
+}
+
+func structPointer_Word64(p structPointer, f field) word64 {
+	return word64{structPointer_field(p, f)}
+}
+
+// word64Val is like word32Val but for 64-bit values.
+type word64Val struct {
+	v reflect.Value
+}
+
+func word64Val_Set(p word64Val, o *Buffer, x uint64) {
+	switch p.v.Type() {
+	case int64Type:
+		p.v.SetInt(int64(x))
+		return
+	case uint64Type:
+		p.v.SetUint(x)
+		return
+	case float64Type:
+		p.v.SetFloat(math.Float64frombits(x))
+		return
+	}
+	panic("unreachable")
+}
+
+func word64Val_Get(p word64Val) uint64 {
+	elem := p.v
+	switch elem.Kind() {
+	case reflect.Int64:
+		return uint64(elem.Int())
+	case reflect.Uint64:
+		return elem.Uint()
+	case reflect.Float64:
+		return math.Float64bits(elem.Float())
+	}
+	panic("unreachable")
+}
+
+func structPointer_Word64Val(p structPointer, f field) word64Val {
+	return word64Val{structPointer_field(p, f)}
+}
+
+type word64Slice struct {
+	v reflect.Value
+}
+
+func (p word64Slice) Append(x uint64) {
+	n, m := p.v.Len(), p.v.Cap()
+	if n < m {
+		p.v.SetLen(n + 1)
+	} else {
+		t := p.v.Type().Elem()
+		p.v.Set(reflect.Append(p.v, reflect.Zero(t)))
+	}
+	elem := p.v.Index(n)
+	switch elem.Kind() {
+	case reflect.Int64:
+		elem.SetInt(int64(int64(x)))
+	case reflect.Uint64:
+		elem.SetUint(uint64(x))
+	case reflect.Float64:
+		elem.SetFloat(float64(math.Float64frombits(x)))
+	}
+}
+
+func (p word64Slice) Len() int {
+	return p.v.Len()
+}
+
+func (p word64Slice) Index(i int) uint64 {
+	elem := p.v.Index(i)
+	switch elem.Kind() {
+	case reflect.Int64:
+		return uint64(elem.Int())
+	case reflect.Uint64:
+		return uint64(elem.Uint())
+	case reflect.Float64:
+		return math.Float64bits(float64(elem.Float()))
+	}
+	panic("unreachable")
+}
+
+func structPointer_Word64Slice(p structPointer, f field) word64Slice {
+	return word64Slice{structPointer_field(p, f)}
+}

+ 270 - 0
vendor/github.com/golang/protobuf/proto/pointer_unsafe.go

@@ -0,0 +1,270 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2012 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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.
+
+// +build !appengine,!js
+
+// This file contains the implementation of the proto field accesses using package unsafe.
+
+package proto
+
+import (
+	"reflect"
+	"unsafe"
+)
+
+// NOTE: These type_Foo functions would more idiomatically be methods,
+// but Go does not allow methods on pointer types, and we must preserve
+// some pointer type for the garbage collector. We use these
+// funcs with clunky names as our poor approximation to methods.
+//
+// An alternative would be
+//	type structPointer struct { p unsafe.Pointer }
+// but that does not registerize as well.
+
+// A structPointer is a pointer to a struct.
+type structPointer unsafe.Pointer
+
+// toStructPointer returns a structPointer equivalent to the given reflect value.
+func toStructPointer(v reflect.Value) structPointer {
+	return structPointer(unsafe.Pointer(v.Pointer()))
+}
+
+// IsNil reports whether p is nil.
+func structPointer_IsNil(p structPointer) bool {
+	return p == nil
+}
+
+// Interface returns the struct pointer, assumed to have element type t,
+// as an interface value.
+func structPointer_Interface(p structPointer, t reflect.Type) interface{} {
+	return reflect.NewAt(t, unsafe.Pointer(p)).Interface()
+}
+
+// A field identifies a field in a struct, accessible from a structPointer.
+// In this implementation, a field is identified by its byte offset from the start of the struct.
+type field uintptr
+
+// toField returns a field equivalent to the given reflect field.
+func toField(f *reflect.StructField) field {
+	return field(f.Offset)
+}
+
+// invalidField is an invalid field identifier.
+const invalidField = ^field(0)
+
+// IsValid reports whether the field identifier is valid.
+func (f field) IsValid() bool {
+	return f != ^field(0)
+}
+
+// Bytes returns the address of a []byte field in the struct.
+func structPointer_Bytes(p structPointer, f field) *[]byte {
+	return (*[]byte)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// BytesSlice returns the address of a [][]byte field in the struct.
+func structPointer_BytesSlice(p structPointer, f field) *[][]byte {
+	return (*[][]byte)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// Bool returns the address of a *bool field in the struct.
+func structPointer_Bool(p structPointer, f field) **bool {
+	return (**bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// BoolVal returns the address of a bool field in the struct.
+func structPointer_BoolVal(p structPointer, f field) *bool {
+	return (*bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// BoolSlice returns the address of a []bool field in the struct.
+func structPointer_BoolSlice(p structPointer, f field) *[]bool {
+	return (*[]bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// String returns the address of a *string field in the struct.
+func structPointer_String(p structPointer, f field) **string {
+	return (**string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// StringVal returns the address of a string field in the struct.
+func structPointer_StringVal(p structPointer, f field) *string {
+	return (*string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// StringSlice returns the address of a []string field in the struct.
+func structPointer_StringSlice(p structPointer, f field) *[]string {
+	return (*[]string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// ExtMap returns the address of an extension map field in the struct.
+func structPointer_Extensions(p structPointer, f field) *XXX_InternalExtensions {
+	return (*XXX_InternalExtensions)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
+	return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// NewAt returns the reflect.Value for a pointer to a field in the struct.
+func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value {
+	return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f)))
+}
+
+// SetStructPointer writes a *struct field in the struct.
+func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
+	*(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) = q
+}
+
+// GetStructPointer reads a *struct field in the struct.
+func structPointer_GetStructPointer(p structPointer, f field) structPointer {
+	return *(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// StructPointerSlice the address of a []*struct field in the struct.
+func structPointer_StructPointerSlice(p structPointer, f field) *structPointerSlice {
+	return (*structPointerSlice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// A structPointerSlice represents a slice of pointers to structs (themselves submessages or groups).
+type structPointerSlice []structPointer
+
+func (v *structPointerSlice) Len() int                  { return len(*v) }
+func (v *structPointerSlice) Index(i int) structPointer { return (*v)[i] }
+func (v *structPointerSlice) Append(p structPointer)    { *v = append(*v, p) }
+
+// A word32 is the address of a "pointer to 32-bit value" field.
+type word32 **uint32
+
+// IsNil reports whether *v is nil.
+func word32_IsNil(p word32) bool {
+	return *p == nil
+}
+
+// Set sets *v to point at a newly allocated word set to x.
+func word32_Set(p word32, o *Buffer, x uint32) {
+	if len(o.uint32s) == 0 {
+		o.uint32s = make([]uint32, uint32PoolSize)
+	}
+	o.uint32s[0] = x
+	*p = &o.uint32s[0]
+	o.uint32s = o.uint32s[1:]
+}
+
+// Get gets the value pointed at by *v.
+func word32_Get(p word32) uint32 {
+	return **p
+}
+
+// Word32 returns the address of a *int32, *uint32, *float32, or *enum field in the struct.
+func structPointer_Word32(p structPointer, f field) word32 {
+	return word32((**uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
+}
+
+// A word32Val is the address of a 32-bit value field.
+type word32Val *uint32
+
+// Set sets *p to x.
+func word32Val_Set(p word32Val, x uint32) {
+	*p = x
+}
+
+// Get gets the value pointed at by p.
+func word32Val_Get(p word32Val) uint32 {
+	return *p
+}
+
+// Word32Val returns the address of a *int32, *uint32, *float32, or *enum field in the struct.
+func structPointer_Word32Val(p structPointer, f field) word32Val {
+	return word32Val((*uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
+}
+
+// A word32Slice is a slice of 32-bit values.
+type word32Slice []uint32
+
+func (v *word32Slice) Append(x uint32)    { *v = append(*v, x) }
+func (v *word32Slice) Len() int           { return len(*v) }
+func (v *word32Slice) Index(i int) uint32 { return (*v)[i] }
+
+// Word32Slice returns the address of a []int32, []uint32, []float32, or []enum field in the struct.
+func structPointer_Word32Slice(p structPointer, f field) *word32Slice {
+	return (*word32Slice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}
+
+// word64 is like word32 but for 64-bit values.
+type word64 **uint64
+
+func word64_Set(p word64, o *Buffer, x uint64) {
+	if len(o.uint64s) == 0 {
+		o.uint64s = make([]uint64, uint64PoolSize)
+	}
+	o.uint64s[0] = x
+	*p = &o.uint64s[0]
+	o.uint64s = o.uint64s[1:]
+}
+
+func word64_IsNil(p word64) bool {
+	return *p == nil
+}
+
+func word64_Get(p word64) uint64 {
+	return **p
+}
+
+func structPointer_Word64(p structPointer, f field) word64 {
+	return word64((**uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
+}
+
+// word64Val is like word32Val but for 64-bit values.
+type word64Val *uint64
+
+func word64Val_Set(p word64Val, o *Buffer, x uint64) {
+	*p = x
+}
+
+func word64Val_Get(p word64Val) uint64 {
+	return *p
+}
+
+func structPointer_Word64Val(p structPointer, f field) word64Val {
+	return word64Val((*uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
+}
+
+// word64Slice is like word32Slice but for 64-bit values.
+type word64Slice []uint64
+
+func (v *word64Slice) Append(x uint64)    { *v = append(*v, x) }
+func (v *word64Slice) Len() int           { return len(*v) }
+func (v *word64Slice) Index(i int) uint64 { return (*v)[i] }
+
+func structPointer_Word64Slice(p structPointer, f field) *word64Slice {
+	return (*word64Slice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+}

+ 872 - 0
vendor/github.com/golang/protobuf/proto/properties.go

@@ -0,0 +1,872 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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 proto
+
+/*
+ * Routines for encoding data into the wire format for protocol buffers.
+ */
+
+import (
+	"fmt"
+	"log"
+	"os"
+	"reflect"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+)
+
+const debug bool = false
+
+// Constants that identify the encoding of a value on the wire.
+const (
+	WireVarint     = 0
+	WireFixed64    = 1
+	WireBytes      = 2
+	WireStartGroup = 3
+	WireEndGroup   = 4
+	WireFixed32    = 5
+)
+
+const startSize = 10 // initial slice/string sizes
+
+// Encoders are defined in encode.go
+// An encoder outputs the full representation of a field, including its
+// tag and encoder type.
+type encoder func(p *Buffer, prop *Properties, base structPointer) error
+
+// A valueEncoder encodes a single integer in a particular encoding.
+type valueEncoder func(o *Buffer, x uint64) error
+
+// Sizers are defined in encode.go
+// A sizer returns the encoded size of a field, including its tag and encoder
+// type.
+type sizer func(prop *Properties, base structPointer) int
+
+// A valueSizer returns the encoded size of a single integer in a particular
+// encoding.
+type valueSizer func(x uint64) int
+
+// Decoders are defined in decode.go
+// A decoder creates a value from its wire representation.
+// Unrecognized subelements are saved in unrec.
+type decoder func(p *Buffer, prop *Properties, base structPointer) error
+
+// A valueDecoder decodes a single integer in a particular encoding.
+type valueDecoder func(o *Buffer) (x uint64, err error)
+
+// A oneofMarshaler does the marshaling for all oneof fields in a message.
+type oneofMarshaler func(Message, *Buffer) error
+
+// A oneofUnmarshaler does the unmarshaling for a oneof field in a message.
+type oneofUnmarshaler func(Message, int, int, *Buffer) (bool, error)
+
+// A oneofSizer does the sizing for all oneof fields in a message.
+type oneofSizer func(Message) int
+
+// tagMap is an optimization over map[int]int for typical protocol buffer
+// use-cases. Encoded protocol buffers are often in tag order with small tag
+// numbers.
+type tagMap struct {
+	fastTags []int
+	slowTags map[int]int
+}
+
+// tagMapFastLimit is the upper bound on the tag number that will be stored in
+// the tagMap slice rather than its map.
+const tagMapFastLimit = 1024
+
+func (p *tagMap) get(t int) (int, bool) {
+	if t > 0 && t < tagMapFastLimit {
+		if t >= len(p.fastTags) {
+			return 0, false
+		}
+		fi := p.fastTags[t]
+		return fi, fi >= 0
+	}
+	fi, ok := p.slowTags[t]
+	return fi, ok
+}
+
+func (p *tagMap) put(t int, fi int) {
+	if t > 0 && t < tagMapFastLimit {
+		for len(p.fastTags) < t+1 {
+			p.fastTags = append(p.fastTags, -1)
+		}
+		p.fastTags[t] = fi
+		return
+	}
+	if p.slowTags == nil {
+		p.slowTags = make(map[int]int)
+	}
+	p.slowTags[t] = fi
+}
+
+// StructProperties represents properties for all the fields of a struct.
+// decoderTags and decoderOrigNames should only be used by the decoder.
+type StructProperties struct {
+	Prop             []*Properties  // properties for each field
+	reqCount         int            // required count
+	decoderTags      tagMap         // map from proto tag to struct field number
+	decoderOrigNames map[string]int // map from original name to struct field number
+	order            []int          // list of struct field numbers in tag order
+	unrecField       field          // field id of the XXX_unrecognized []byte field
+	extendable       bool           // is this an extendable proto
+
+	oneofMarshaler   oneofMarshaler
+	oneofUnmarshaler oneofUnmarshaler
+	oneofSizer       oneofSizer
+	stype            reflect.Type
+
+	// OneofTypes contains information about the oneof fields in this message.
+	// It is keyed by the original name of a field.
+	OneofTypes map[string]*OneofProperties
+}
+
+// OneofProperties represents information about a specific field in a oneof.
+type OneofProperties struct {
+	Type  reflect.Type // pointer to generated struct type for this oneof field
+	Field int          // struct field number of the containing oneof in the message
+	Prop  *Properties
+}
+
+// Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.
+// See encode.go, (*Buffer).enc_struct.
+
+func (sp *StructProperties) Len() int { return len(sp.order) }
+func (sp *StructProperties) Less(i, j int) bool {
+	return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag
+}
+func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] }
+
+// Properties represents the protocol-specific behavior of a single struct field.
+type Properties struct {
+	Name     string // name of the field, for error messages
+	OrigName string // original name before protocol compiler (always set)
+	JSONName string // name to use for JSON; determined by protoc
+	Wire     string
+	WireType int
+	Tag      int
+	Required bool
+	Optional bool
+	Repeated bool
+	Packed   bool   // relevant for repeated primitives only
+	Enum     string // set for enum types only
+	proto3   bool   // whether this is known to be a proto3 field; set for []byte only
+	oneof    bool   // whether this is a oneof field
+
+	Default    string // default value
+	HasDefault bool   // whether an explicit default was provided
+	def_uint64 uint64
+
+	enc           encoder
+	valEnc        valueEncoder // set for bool and numeric types only
+	field         field
+	tagcode       []byte // encoding of EncodeVarint((Tag<<3)|WireType)
+	tagbuf        [8]byte
+	stype         reflect.Type      // set for struct types only
+	sprop         *StructProperties // set for struct types only
+	isMarshaler   bool
+	isUnmarshaler bool
+
+	mtype    reflect.Type // set for map types only
+	mkeyprop *Properties  // set for map types only
+	mvalprop *Properties  // set for map types only
+
+	size    sizer
+	valSize valueSizer // set for bool and numeric types only
+
+	dec    decoder
+	valDec valueDecoder // set for bool and numeric types only
+
+	// If this is a packable field, this will be the decoder for the packed version of the field.
+	packedDec decoder
+}
+
+// String formats the properties in the protobuf struct field tag style.
+func (p *Properties) String() string {
+	s := p.Wire
+	s = ","
+	s += strconv.Itoa(p.Tag)
+	if p.Required {
+		s += ",req"
+	}
+	if p.Optional {
+		s += ",opt"
+	}
+	if p.Repeated {
+		s += ",rep"
+	}
+	if p.Packed {
+		s += ",packed"
+	}
+	s += ",name=" + p.OrigName
+	if p.JSONName != p.OrigName {
+		s += ",json=" + p.JSONName
+	}
+	if p.proto3 {
+		s += ",proto3"
+	}
+	if p.oneof {
+		s += ",oneof"
+	}
+	if len(p.Enum) > 0 {
+		s += ",enum=" + p.Enum
+	}
+	if p.HasDefault {
+		s += ",def=" + p.Default
+	}
+	return s
+}
+
+// Parse populates p by parsing a string in the protobuf struct field tag style.
+func (p *Properties) Parse(s string) {
+	// "bytes,49,opt,name=foo,def=hello!"
+	fields := strings.Split(s, ",") // breaks def=, but handled below.
+	if len(fields) < 2 {
+		fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s)
+		return
+	}
+
+	p.Wire = fields[0]
+	switch p.Wire {
+	case "varint":
+		p.WireType = WireVarint
+		p.valEnc = (*Buffer).EncodeVarint
+		p.valDec = (*Buffer).DecodeVarint
+		p.valSize = sizeVarint
+	case "fixed32":
+		p.WireType = WireFixed32
+		p.valEnc = (*Buffer).EncodeFixed32
+		p.valDec = (*Buffer).DecodeFixed32
+		p.valSize = sizeFixed32
+	case "fixed64":
+		p.WireType = WireFixed64
+		p.valEnc = (*Buffer).EncodeFixed64
+		p.valDec = (*Buffer).DecodeFixed64
+		p.valSize = sizeFixed64
+	case "zigzag32":
+		p.WireType = WireVarint
+		p.valEnc = (*Buffer).EncodeZigzag32
+		p.valDec = (*Buffer).DecodeZigzag32
+		p.valSize = sizeZigzag32
+	case "zigzag64":
+		p.WireType = WireVarint
+		p.valEnc = (*Buffer).EncodeZigzag64
+		p.valDec = (*Buffer).DecodeZigzag64
+		p.valSize = sizeZigzag64
+	case "bytes", "group":
+		p.WireType = WireBytes
+		// no numeric converter for non-numeric types
+	default:
+		fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s)
+		return
+	}
+
+	var err error
+	p.Tag, err = strconv.Atoi(fields[1])
+	if err != nil {
+		return
+	}
+
+	for i := 2; i < len(fields); i++ {
+		f := fields[i]
+		switch {
+		case f == "req":
+			p.Required = true
+		case f == "opt":
+			p.Optional = true
+		case f == "rep":
+			p.Repeated = true
+		case f == "packed":
+			p.Packed = true
+		case strings.HasPrefix(f, "name="):
+			p.OrigName = f[5:]
+		case strings.HasPrefix(f, "json="):
+			p.JSONName = f[5:]
+		case strings.HasPrefix(f, "enum="):
+			p.Enum = f[5:]
+		case f == "proto3":
+			p.proto3 = true
+		case f == "oneof":
+			p.oneof = true
+		case strings.HasPrefix(f, "def="):
+			p.HasDefault = true
+			p.Default = f[4:] // rest of string
+			if i+1 < len(fields) {
+				// Commas aren't escaped, and def is always last.
+				p.Default += "," + strings.Join(fields[i+1:], ",")
+				break
+			}
+		}
+	}
+}
+
+func logNoSliceEnc(t1, t2 reflect.Type) {
+	fmt.Fprintf(os.Stderr, "proto: no slice oenc for %T = []%T\n", t1, t2)
+}
+
+var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
+
+// Initialize the fields for encoding and decoding.
+func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
+	p.enc = nil
+	p.dec = nil
+	p.size = nil
+
+	switch t1 := typ; t1.Kind() {
+	default:
+		fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", t1)
+
+	// proto3 scalar types
+
+	case reflect.Bool:
+		p.enc = (*Buffer).enc_proto3_bool
+		p.dec = (*Buffer).dec_proto3_bool
+		p.size = size_proto3_bool
+	case reflect.Int32:
+		p.enc = (*Buffer).enc_proto3_int32
+		p.dec = (*Buffer).dec_proto3_int32
+		p.size = size_proto3_int32
+	case reflect.Uint32:
+		p.enc = (*Buffer).enc_proto3_uint32
+		p.dec = (*Buffer).dec_proto3_int32 // can reuse
+		p.size = size_proto3_uint32
+	case reflect.Int64, reflect.Uint64:
+		p.enc = (*Buffer).enc_proto3_int64
+		p.dec = (*Buffer).dec_proto3_int64
+		p.size = size_proto3_int64
+	case reflect.Float32:
+		p.enc = (*Buffer).enc_proto3_uint32 // can just treat them as bits
+		p.dec = (*Buffer).dec_proto3_int32
+		p.size = size_proto3_uint32
+	case reflect.Float64:
+		p.enc = (*Buffer).enc_proto3_int64 // can just treat them as bits
+		p.dec = (*Buffer).dec_proto3_int64
+		p.size = size_proto3_int64
+	case reflect.String:
+		p.enc = (*Buffer).enc_proto3_string
+		p.dec = (*Buffer).dec_proto3_string
+		p.size = size_proto3_string
+
+	case reflect.Ptr:
+		switch t2 := t1.Elem(); t2.Kind() {
+		default:
+			fmt.Fprintf(os.Stderr, "proto: no encoder function for %v -> %v\n", t1, t2)
+			break
+		case reflect.Bool:
+			p.enc = (*Buffer).enc_bool
+			p.dec = (*Buffer).dec_bool
+			p.size = size_bool
+		case reflect.Int32:
+			p.enc = (*Buffer).enc_int32
+			p.dec = (*Buffer).dec_int32
+			p.size = size_int32
+		case reflect.Uint32:
+			p.enc = (*Buffer).enc_uint32
+			p.dec = (*Buffer).dec_int32 // can reuse
+			p.size = size_uint32
+		case reflect.Int64, reflect.Uint64:
+			p.enc = (*Buffer).enc_int64
+			p.dec = (*Buffer).dec_int64
+			p.size = size_int64
+		case reflect.Float32:
+			p.enc = (*Buffer).enc_uint32 // can just treat them as bits
+			p.dec = (*Buffer).dec_int32
+			p.size = size_uint32
+		case reflect.Float64:
+			p.enc = (*Buffer).enc_int64 // can just treat them as bits
+			p.dec = (*Buffer).dec_int64
+			p.size = size_int64
+		case reflect.String:
+			p.enc = (*Buffer).enc_string
+			p.dec = (*Buffer).dec_string
+			p.size = size_string
+		case reflect.Struct:
+			p.stype = t1.Elem()
+			p.isMarshaler = isMarshaler(t1)
+			p.isUnmarshaler = isUnmarshaler(t1)
+			if p.Wire == "bytes" {
+				p.enc = (*Buffer).enc_struct_message
+				p.dec = (*Buffer).dec_struct_message
+				p.size = size_struct_message
+			} else {
+				p.enc = (*Buffer).enc_struct_group
+				p.dec = (*Buffer).dec_struct_group
+				p.size = size_struct_group
+			}
+		}
+
+	case reflect.Slice:
+		switch t2 := t1.Elem(); t2.Kind() {
+		default:
+			logNoSliceEnc(t1, t2)
+			break
+		case reflect.Bool:
+			if p.Packed {
+				p.enc = (*Buffer).enc_slice_packed_bool
+				p.size = size_slice_packed_bool
+			} else {
+				p.enc = (*Buffer).enc_slice_bool
+				p.size = size_slice_bool
+			}
+			p.dec = (*Buffer).dec_slice_bool
+			p.packedDec = (*Buffer).dec_slice_packed_bool
+		case reflect.Int32:
+			if p.Packed {
+				p.enc = (*Buffer).enc_slice_packed_int32
+				p.size = size_slice_packed_int32
+			} else {
+				p.enc = (*Buffer).enc_slice_int32
+				p.size = size_slice_int32
+			}
+			p.dec = (*Buffer).dec_slice_int32
+			p.packedDec = (*Buffer).dec_slice_packed_int32
+		case reflect.Uint32:
+			if p.Packed {
+				p.enc = (*Buffer).enc_slice_packed_uint32
+				p.size = size_slice_packed_uint32
+			} else {
+				p.enc = (*Buffer).enc_slice_uint32
+				p.size = size_slice_uint32
+			}
+			p.dec = (*Buffer).dec_slice_int32
+			p.packedDec = (*Buffer).dec_slice_packed_int32
+		case reflect.Int64, reflect.Uint64:
+			if p.Packed {
+				p.enc = (*Buffer).enc_slice_packed_int64
+				p.size = size_slice_packed_int64
+			} else {
+				p.enc = (*Buffer).enc_slice_int64
+				p.size = size_slice_int64
+			}
+			p.dec = (*Buffer).dec_slice_int64
+			p.packedDec = (*Buffer).dec_slice_packed_int64
+		case reflect.Uint8:
+			p.dec = (*Buffer).dec_slice_byte
+			if p.proto3 {
+				p.enc = (*Buffer).enc_proto3_slice_byte
+				p.size = size_proto3_slice_byte
+			} else {
+				p.enc = (*Buffer).enc_slice_byte
+				p.size = size_slice_byte
+			}
+		case reflect.Float32, reflect.Float64:
+			switch t2.Bits() {
+			case 32:
+				// can just treat them as bits
+				if p.Packed {
+					p.enc = (*Buffer).enc_slice_packed_uint32
+					p.size = size_slice_packed_uint32
+				} else {
+					p.enc = (*Buffer).enc_slice_uint32
+					p.size = size_slice_uint32
+				}
+				p.dec = (*Buffer).dec_slice_int32
+				p.packedDec = (*Buffer).dec_slice_packed_int32
+			case 64:
+				// can just treat them as bits
+				if p.Packed {
+					p.enc = (*Buffer).enc_slice_packed_int64
+					p.size = size_slice_packed_int64
+				} else {
+					p.enc = (*Buffer).enc_slice_int64
+					p.size = size_slice_int64
+				}
+				p.dec = (*Buffer).dec_slice_int64
+				p.packedDec = (*Buffer).dec_slice_packed_int64
+			default:
+				logNoSliceEnc(t1, t2)
+				break
+			}
+		case reflect.String:
+			p.enc = (*Buffer).enc_slice_string
+			p.dec = (*Buffer).dec_slice_string
+			p.size = size_slice_string
+		case reflect.Ptr:
+			switch t3 := t2.Elem(); t3.Kind() {
+			default:
+				fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T -> %T\n", t1, t2, t3)
+				break
+			case reflect.Struct:
+				p.stype = t2.Elem()
+				p.isMarshaler = isMarshaler(t2)
+				p.isUnmarshaler = isUnmarshaler(t2)
+				if p.Wire == "bytes" {
+					p.enc = (*Buffer).enc_slice_struct_message
+					p.dec = (*Buffer).dec_slice_struct_message
+					p.size = size_slice_struct_message
+				} else {
+					p.enc = (*Buffer).enc_slice_struct_group
+					p.dec = (*Buffer).dec_slice_struct_group
+					p.size = size_slice_struct_group
+				}
+			}
+		case reflect.Slice:
+			switch t2.Elem().Kind() {
+			default:
+				fmt.Fprintf(os.Stderr, "proto: no slice elem oenc for %T -> %T -> %T\n", t1, t2, t2.Elem())
+				break
+			case reflect.Uint8:
+				p.enc = (*Buffer).enc_slice_slice_byte
+				p.dec = (*Buffer).dec_slice_slice_byte
+				p.size = size_slice_slice_byte
+			}
+		}
+
+	case reflect.Map:
+		p.enc = (*Buffer).enc_new_map
+		p.dec = (*Buffer).dec_new_map
+		p.size = size_new_map
+
+		p.mtype = t1
+		p.mkeyprop = &Properties{}
+		p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
+		p.mvalprop = &Properties{}
+		vtype := p.mtype.Elem()
+		if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {
+			// The value type is not a message (*T) or bytes ([]byte),
+			// so we need encoders for the pointer to this type.
+			vtype = reflect.PtrTo(vtype)
+		}
+		p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
+	}
+
+	// precalculate tag code
+	wire := p.WireType
+	if p.Packed {
+		wire = WireBytes
+	}
+	x := uint32(p.Tag)<<3 | uint32(wire)
+	i := 0
+	for i = 0; x > 127; i++ {
+		p.tagbuf[i] = 0x80 | uint8(x&0x7F)
+		x >>= 7
+	}
+	p.tagbuf[i] = uint8(x)
+	p.tagcode = p.tagbuf[0 : i+1]
+
+	if p.stype != nil {
+		if lockGetProp {
+			p.sprop = GetProperties(p.stype)
+		} else {
+			p.sprop = getPropertiesLocked(p.stype)
+		}
+	}
+}
+
+var (
+	marshalerType   = reflect.TypeOf((*Marshaler)(nil)).Elem()
+	unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
+)
+
+// isMarshaler reports whether type t implements Marshaler.
+func isMarshaler(t reflect.Type) bool {
+	// We're checking for (likely) pointer-receiver methods
+	// so if t is not a pointer, something is very wrong.
+	// The calls above only invoke isMarshaler on pointer types.
+	if t.Kind() != reflect.Ptr {
+		panic("proto: misuse of isMarshaler")
+	}
+	return t.Implements(marshalerType)
+}
+
+// isUnmarshaler reports whether type t implements Unmarshaler.
+func isUnmarshaler(t reflect.Type) bool {
+	// We're checking for (likely) pointer-receiver methods
+	// so if t is not a pointer, something is very wrong.
+	// The calls above only invoke isUnmarshaler on pointer types.
+	if t.Kind() != reflect.Ptr {
+		panic("proto: misuse of isUnmarshaler")
+	}
+	return t.Implements(unmarshalerType)
+}
+
+// Init populates the properties from a protocol buffer struct tag.
+func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {
+	p.init(typ, name, tag, f, true)
+}
+
+func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) {
+	// "bytes,49,opt,def=hello!"
+	p.Name = name
+	p.OrigName = name
+	if f != nil {
+		p.field = toField(f)
+	}
+	if tag == "" {
+		return
+	}
+	p.Parse(tag)
+	p.setEncAndDec(typ, f, lockGetProp)
+}
+
+var (
+	propertiesMu  sync.RWMutex
+	propertiesMap = make(map[reflect.Type]*StructProperties)
+)
+
+// GetProperties returns the list of properties for the type represented by t.
+// t must represent a generated struct type of a protocol message.
+func GetProperties(t reflect.Type) *StructProperties {
+	if t.Kind() != reflect.Struct {
+		panic("proto: type must have kind struct")
+	}
+
+	// Most calls to GetProperties in a long-running program will be
+	// retrieving details for types we have seen before.
+	propertiesMu.RLock()
+	sprop, ok := propertiesMap[t]
+	propertiesMu.RUnlock()
+	if ok {
+		if collectStats {
+			stats.Chit++
+		}
+		return sprop
+	}
+
+	propertiesMu.Lock()
+	sprop = getPropertiesLocked(t)
+	propertiesMu.Unlock()
+	return sprop
+}
+
+// getPropertiesLocked requires that propertiesMu is held.
+func getPropertiesLocked(t reflect.Type) *StructProperties {
+	if prop, ok := propertiesMap[t]; ok {
+		if collectStats {
+			stats.Chit++
+		}
+		return prop
+	}
+	if collectStats {
+		stats.Cmiss++
+	}
+
+	prop := new(StructProperties)
+	// in case of recursive protos, fill this in now.
+	propertiesMap[t] = prop
+
+	// build properties
+	prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType) ||
+		reflect.PtrTo(t).Implements(extendableProtoV1Type)
+	prop.unrecField = invalidField
+	prop.Prop = make([]*Properties, t.NumField())
+	prop.order = make([]int, t.NumField())
+
+	for i := 0; i < t.NumField(); i++ {
+		f := t.Field(i)
+		p := new(Properties)
+		name := f.Name
+		p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
+
+		if f.Name == "XXX_InternalExtensions" { // special case
+			p.enc = (*Buffer).enc_exts
+			p.dec = nil // not needed
+			p.size = size_exts
+		} else if f.Name == "XXX_extensions" { // special case
+			p.enc = (*Buffer).enc_map
+			p.dec = nil // not needed
+			p.size = size_map
+		} else if f.Name == "XXX_unrecognized" { // special case
+			prop.unrecField = toField(&f)
+		}
+		oneof := f.Tag.Get("protobuf_oneof") // special case
+		if oneof != "" {
+			// Oneof fields don't use the traditional protobuf tag.
+			p.OrigName = oneof
+		}
+		prop.Prop[i] = p
+		prop.order[i] = i
+		if debug {
+			print(i, " ", f.Name, " ", t.String(), " ")
+			if p.Tag > 0 {
+				print(p.String())
+			}
+			print("\n")
+		}
+		if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && oneof == "" {
+			fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]")
+		}
+	}
+
+	// Re-order prop.order.
+	sort.Sort(prop)
+
+	type oneofMessage interface {
+		XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
+	}
+	if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok {
+		var oots []interface{}
+		prop.oneofMarshaler, prop.oneofUnmarshaler, prop.oneofSizer, oots = om.XXX_OneofFuncs()
+		prop.stype = t
+
+		// Interpret oneof metadata.
+		prop.OneofTypes = make(map[string]*OneofProperties)
+		for _, oot := range oots {
+			oop := &OneofProperties{
+				Type: reflect.ValueOf(oot).Type(), // *T
+				Prop: new(Properties),
+			}
+			sft := oop.Type.Elem().Field(0)
+			oop.Prop.Name = sft.Name
+			oop.Prop.Parse(sft.Tag.Get("protobuf"))
+			// There will be exactly one interface field that
+			// this new value is assignable to.
+			for i := 0; i < t.NumField(); i++ {
+				f := t.Field(i)
+				if f.Type.Kind() != reflect.Interface {
+					continue
+				}
+				if !oop.Type.AssignableTo(f.Type) {
+					continue
+				}
+				oop.Field = i
+				break
+			}
+			prop.OneofTypes[oop.Prop.OrigName] = oop
+		}
+	}
+
+	// build required counts
+	// build tags
+	reqCount := 0
+	prop.decoderOrigNames = make(map[string]int)
+	for i, p := range prop.Prop {
+		if strings.HasPrefix(p.Name, "XXX_") {
+			// Internal fields should not appear in tags/origNames maps.
+			// They are handled specially when encoding and decoding.
+			continue
+		}
+		if p.Required {
+			reqCount++
+		}
+		prop.decoderTags.put(p.Tag, i)
+		prop.decoderOrigNames[p.OrigName] = i
+	}
+	prop.reqCount = reqCount
+
+	return prop
+}
+
+// Return the Properties object for the x[0]'th field of the structure.
+func propByIndex(t reflect.Type, x []int) *Properties {
+	if len(x) != 1 {
+		fmt.Fprintf(os.Stderr, "proto: field index dimension %d (not 1) for type %s\n", len(x), t)
+		return nil
+	}
+	prop := GetProperties(t)
+	return prop.Prop[x[0]]
+}
+
+// Get the address and type of a pointer to a struct from an interface.
+func getbase(pb Message) (t reflect.Type, b structPointer, err error) {
+	if pb == nil {
+		err = ErrNil
+		return
+	}
+	// get the reflect type of the pointer to the struct.
+	t = reflect.TypeOf(pb)
+	// get the address of the struct.
+	value := reflect.ValueOf(pb)
+	b = toStructPointer(value)
+	return
+}
+
+// A global registry of enum types.
+// The generated code will register the generated maps by calling RegisterEnum.
+
+var enumValueMaps = make(map[string]map[string]int32)
+
+// RegisterEnum is called from the generated code to install the enum descriptor
+// maps into the global table to aid parsing text format protocol buffers.
+func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) {
+	if _, ok := enumValueMaps[typeName]; ok {
+		panic("proto: duplicate enum registered: " + typeName)
+	}
+	enumValueMaps[typeName] = valueMap
+}
+
+// EnumValueMap returns the mapping from names to integers of the
+// enum type enumType, or a nil if not found.
+func EnumValueMap(enumType string) map[string]int32 {
+	return enumValueMaps[enumType]
+}
+
+// A registry of all linked message types.
+// The string is a fully-qualified proto name ("pkg.Message").
+var (
+	protoTypes    = make(map[string]reflect.Type)
+	revProtoTypes = make(map[reflect.Type]string)
+)
+
+// RegisterType is called from generated code and maps from the fully qualified
+// proto name to the type (pointer to struct) of the protocol buffer.
+func RegisterType(x Message, name string) {
+	if _, ok := protoTypes[name]; ok {
+		// TODO: Some day, make this a panic.
+		log.Printf("proto: duplicate proto type registered: %s", name)
+		return
+	}
+	t := reflect.TypeOf(x)
+	protoTypes[name] = t
+	revProtoTypes[t] = name
+}
+
+// MessageName returns the fully-qualified proto name for the given message type.
+func MessageName(x Message) string {
+	type xname interface {
+		XXX_MessageName() string
+	}
+	if m, ok := x.(xname); ok {
+		return m.XXX_MessageName()
+	}
+	return revProtoTypes[reflect.TypeOf(x)]
+}
+
+// MessageType returns the message type (pointer to struct) for a named message.
+func MessageType(name string) reflect.Type { return protoTypes[name] }
+
+// A registry of all linked proto files.
+var (
+	protoFiles = make(map[string][]byte) // file name => fileDescriptor
+)
+
+// RegisterFile is called from generated code and maps from the
+// full file name of a .proto file to its compressed FileDescriptorProto.
+func RegisterFile(filename string, fileDescriptor []byte) {
+	protoFiles[filename] = fileDescriptor
+}
+
+// FileDescriptor returns the compressed FileDescriptorProto for a .proto file.
+func FileDescriptor(filename string) []byte { return protoFiles[filename] }

+ 854 - 0
vendor/github.com/golang/protobuf/proto/text.go

@@ -0,0 +1,854 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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 proto
+
+// Functions for writing the text protocol buffer format.
+
+import (
+	"bufio"
+	"bytes"
+	"encoding"
+	"errors"
+	"fmt"
+	"io"
+	"log"
+	"math"
+	"reflect"
+	"sort"
+	"strings"
+)
+
+var (
+	newline         = []byte("\n")
+	spaces          = []byte("                                        ")
+	gtNewline       = []byte(">\n")
+	endBraceNewline = []byte("}\n")
+	backslashN      = []byte{'\\', 'n'}
+	backslashR      = []byte{'\\', 'r'}
+	backslashT      = []byte{'\\', 't'}
+	backslashDQ     = []byte{'\\', '"'}
+	backslashBS     = []byte{'\\', '\\'}
+	posInf          = []byte("inf")
+	negInf          = []byte("-inf")
+	nan             = []byte("nan")
+)
+
+type writer interface {
+	io.Writer
+	WriteByte(byte) error
+}
+
+// textWriter is an io.Writer that tracks its indentation level.
+type textWriter struct {
+	ind      int
+	complete bool // if the current position is a complete line
+	compact  bool // whether to write out as a one-liner
+	w        writer
+}
+
+func (w *textWriter) WriteString(s string) (n int, err error) {
+	if !strings.Contains(s, "\n") {
+		if !w.compact && w.complete {
+			w.writeIndent()
+		}
+		w.complete = false
+		return io.WriteString(w.w, s)
+	}
+	// WriteString is typically called without newlines, so this
+	// codepath and its copy are rare.  We copy to avoid
+	// duplicating all of Write's logic here.
+	return w.Write([]byte(s))
+}
+
+func (w *textWriter) Write(p []byte) (n int, err error) {
+	newlines := bytes.Count(p, newline)
+	if newlines == 0 {
+		if !w.compact && w.complete {
+			w.writeIndent()
+		}
+		n, err = w.w.Write(p)
+		w.complete = false
+		return n, err
+	}
+
+	frags := bytes.SplitN(p, newline, newlines+1)
+	if w.compact {
+		for i, frag := range frags {
+			if i > 0 {
+				if err := w.w.WriteByte(' '); err != nil {
+					return n, err
+				}
+				n++
+			}
+			nn, err := w.w.Write(frag)
+			n += nn
+			if err != nil {
+				return n, err
+			}
+		}
+		return n, nil
+	}
+
+	for i, frag := range frags {
+		if w.complete {
+			w.writeIndent()
+		}
+		nn, err := w.w.Write(frag)
+		n += nn
+		if err != nil {
+			return n, err
+		}
+		if i+1 < len(frags) {
+			if err := w.w.WriteByte('\n'); err != nil {
+				return n, err
+			}
+			n++
+		}
+	}
+	w.complete = len(frags[len(frags)-1]) == 0
+	return n, nil
+}
+
+func (w *textWriter) WriteByte(c byte) error {
+	if w.compact && c == '\n' {
+		c = ' '
+	}
+	if !w.compact && w.complete {
+		w.writeIndent()
+	}
+	err := w.w.WriteByte(c)
+	w.complete = c == '\n'
+	return err
+}
+
+func (w *textWriter) indent() { w.ind++ }
+
+func (w *textWriter) unindent() {
+	if w.ind == 0 {
+		log.Print("proto: textWriter unindented too far")
+		return
+	}
+	w.ind--
+}
+
+func writeName(w *textWriter, props *Properties) error {
+	if _, err := w.WriteString(props.OrigName); err != nil {
+		return err
+	}
+	if props.Wire != "group" {
+		return w.WriteByte(':')
+	}
+	return nil
+}
+
+// raw is the interface satisfied by RawMessage.
+type raw interface {
+	Bytes() []byte
+}
+
+func requiresQuotes(u string) bool {
+	// When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted.
+	for _, ch := range u {
+		switch {
+		case ch == '.' || ch == '/' || ch == '_':
+			continue
+		case '0' <= ch && ch <= '9':
+			continue
+		case 'A' <= ch && ch <= 'Z':
+			continue
+		case 'a' <= ch && ch <= 'z':
+			continue
+		default:
+			return true
+		}
+	}
+	return false
+}
+
+// isAny reports whether sv is a google.protobuf.Any message
+func isAny(sv reflect.Value) bool {
+	type wkt interface {
+		XXX_WellKnownType() string
+	}
+	t, ok := sv.Addr().Interface().(wkt)
+	return ok && t.XXX_WellKnownType() == "Any"
+}
+
+// writeProto3Any writes an expanded google.protobuf.Any message.
+//
+// It returns (false, nil) if sv value can't be unmarshaled (e.g. because
+// required messages are not linked in).
+//
+// It returns (true, error) when sv was written in expanded format or an error
+// was encountered.
+func (tm *TextMarshaler) writeProto3Any(w *textWriter, sv reflect.Value) (bool, error) {
+	turl := sv.FieldByName("TypeUrl")
+	val := sv.FieldByName("Value")
+	if !turl.IsValid() || !val.IsValid() {
+		return true, errors.New("proto: invalid google.protobuf.Any message")
+	}
+
+	b, ok := val.Interface().([]byte)
+	if !ok {
+		return true, errors.New("proto: invalid google.protobuf.Any message")
+	}
+
+	parts := strings.Split(turl.String(), "/")
+	mt := MessageType(parts[len(parts)-1])
+	if mt == nil {
+		return false, nil
+	}
+	m := reflect.New(mt.Elem())
+	if err := Unmarshal(b, m.Interface().(Message)); err != nil {
+		return false, nil
+	}
+	w.Write([]byte("["))
+	u := turl.String()
+	if requiresQuotes(u) {
+		writeString(w, u)
+	} else {
+		w.Write([]byte(u))
+	}
+	if w.compact {
+		w.Write([]byte("]:<"))
+	} else {
+		w.Write([]byte("]: <\n"))
+		w.ind++
+	}
+	if err := tm.writeStruct(w, m.Elem()); err != nil {
+		return true, err
+	}
+	if w.compact {
+		w.Write([]byte("> "))
+	} else {
+		w.ind--
+		w.Write([]byte(">\n"))
+	}
+	return true, nil
+}
+
+func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
+	if tm.ExpandAny && isAny(sv) {
+		if canExpand, err := tm.writeProto3Any(w, sv); canExpand {
+			return err
+		}
+	}
+	st := sv.Type()
+	sprops := GetProperties(st)
+	for i := 0; i < sv.NumField(); i++ {
+		fv := sv.Field(i)
+		props := sprops.Prop[i]
+		name := st.Field(i).Name
+
+		if strings.HasPrefix(name, "XXX_") {
+			// There are two XXX_ fields:
+			//   XXX_unrecognized []byte
+			//   XXX_extensions   map[int32]proto.Extension
+			// The first is handled here;
+			// the second is handled at the bottom of this function.
+			if name == "XXX_unrecognized" && !fv.IsNil() {
+				if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil {
+					return err
+				}
+			}
+			continue
+		}
+		if fv.Kind() == reflect.Ptr && fv.IsNil() {
+			// Field not filled in. This could be an optional field or
+			// a required field that wasn't filled in. Either way, there
+			// isn't anything we can show for it.
+			continue
+		}
+		if fv.Kind() == reflect.Slice && fv.IsNil() {
+			// Repeated field that is empty, or a bytes field that is unused.
+			continue
+		}
+
+		if props.Repeated && fv.Kind() == reflect.Slice {
+			// Repeated field.
+			for j := 0; j < fv.Len(); j++ {
+				if err := writeName(w, props); err != nil {
+					return err
+				}
+				if !w.compact {
+					if err := w.WriteByte(' '); err != nil {
+						return err
+					}
+				}
+				v := fv.Index(j)
+				if v.Kind() == reflect.Ptr && v.IsNil() {
+					// A nil message in a repeated field is not valid,
+					// but we can handle that more gracefully than panicking.
+					if _, err := w.Write([]byte("<nil>\n")); err != nil {
+						return err
+					}
+					continue
+				}
+				if err := tm.writeAny(w, v, props); err != nil {
+					return err
+				}
+				if err := w.WriteByte('\n'); err != nil {
+					return err
+				}
+			}
+			continue
+		}
+		if fv.Kind() == reflect.Map {
+			// Map fields are rendered as a repeated struct with key/value fields.
+			keys := fv.MapKeys()
+			sort.Sort(mapKeys(keys))
+			for _, key := range keys {
+				val := fv.MapIndex(key)
+				if err := writeName(w, props); err != nil {
+					return err
+				}
+				if !w.compact {
+					if err := w.WriteByte(' '); err != nil {
+						return err
+					}
+				}
+				// open struct
+				if err := w.WriteByte('<'); err != nil {
+					return err
+				}
+				if !w.compact {
+					if err := w.WriteByte('\n'); err != nil {
+						return err
+					}
+				}
+				w.indent()
+				// key
+				if _, err := w.WriteString("key:"); err != nil {
+					return err
+				}
+				if !w.compact {
+					if err := w.WriteByte(' '); err != nil {
+						return err
+					}
+				}
+				if err := tm.writeAny(w, key, props.mkeyprop); err != nil {
+					return err
+				}
+				if err := w.WriteByte('\n'); err != nil {
+					return err
+				}
+				// nil values aren't legal, but we can avoid panicking because of them.
+				if val.Kind() != reflect.Ptr || !val.IsNil() {
+					// value
+					if _, err := w.WriteString("value:"); err != nil {
+						return err
+					}
+					if !w.compact {
+						if err := w.WriteByte(' '); err != nil {
+							return err
+						}
+					}
+					if err := tm.writeAny(w, val, props.mvalprop); err != nil {
+						return err
+					}
+					if err := w.WriteByte('\n'); err != nil {
+						return err
+					}
+				}
+				// close struct
+				w.unindent()
+				if err := w.WriteByte('>'); err != nil {
+					return err
+				}
+				if err := w.WriteByte('\n'); err != nil {
+					return err
+				}
+			}
+			continue
+		}
+		if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 {
+			// empty bytes field
+			continue
+		}
+		if fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice {
+			// proto3 non-repeated scalar field; skip if zero value
+			if isProto3Zero(fv) {
+				continue
+			}
+		}
+
+		if fv.Kind() == reflect.Interface {
+			// Check if it is a oneof.
+			if st.Field(i).Tag.Get("protobuf_oneof") != "" {
+				// fv is nil, or holds a pointer to generated struct.
+				// That generated struct has exactly one field,
+				// which has a protobuf struct tag.
+				if fv.IsNil() {
+					continue
+				}
+				inner := fv.Elem().Elem() // interface -> *T -> T
+				tag := inner.Type().Field(0).Tag.Get("protobuf")
+				props = new(Properties) // Overwrite the outer props var, but not its pointee.
+				props.Parse(tag)
+				// Write the value in the oneof, not the oneof itself.
+				fv = inner.Field(0)
+
+				// Special case to cope with malformed messages gracefully:
+				// If the value in the oneof is a nil pointer, don't panic
+				// in writeAny.
+				if fv.Kind() == reflect.Ptr && fv.IsNil() {
+					// Use errors.New so writeAny won't render quotes.
+					msg := errors.New("/* nil */")
+					fv = reflect.ValueOf(&msg).Elem()
+				}
+			}
+		}
+
+		if err := writeName(w, props); err != nil {
+			return err
+		}
+		if !w.compact {
+			if err := w.WriteByte(' '); err != nil {
+				return err
+			}
+		}
+		if b, ok := fv.Interface().(raw); ok {
+			if err := writeRaw(w, b.Bytes()); err != nil {
+				return err
+			}
+			continue
+		}
+
+		// Enums have a String method, so writeAny will work fine.
+		if err := tm.writeAny(w, fv, props); err != nil {
+			return err
+		}
+
+		if err := w.WriteByte('\n'); err != nil {
+			return err
+		}
+	}
+
+	// Extensions (the XXX_extensions field).
+	pv := sv.Addr()
+	if _, ok := extendable(pv.Interface()); ok {
+		if err := tm.writeExtensions(w, pv); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+// writeRaw writes an uninterpreted raw message.
+func writeRaw(w *textWriter, b []byte) error {
+	if err := w.WriteByte('<'); err != nil {
+		return err
+	}
+	if !w.compact {
+		if err := w.WriteByte('\n'); err != nil {
+			return err
+		}
+	}
+	w.indent()
+	if err := writeUnknownStruct(w, b); err != nil {
+		return err
+	}
+	w.unindent()
+	if err := w.WriteByte('>'); err != nil {
+		return err
+	}
+	return nil
+}
+
+// writeAny writes an arbitrary field.
+func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error {
+	v = reflect.Indirect(v)
+
+	// Floats have special cases.
+	if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 {
+		x := v.Float()
+		var b []byte
+		switch {
+		case math.IsInf(x, 1):
+			b = posInf
+		case math.IsInf(x, -1):
+			b = negInf
+		case math.IsNaN(x):
+			b = nan
+		}
+		if b != nil {
+			_, err := w.Write(b)
+			return err
+		}
+		// Other values are handled below.
+	}
+
+	// We don't attempt to serialise every possible value type; only those
+	// that can occur in protocol buffers.
+	switch v.Kind() {
+	case reflect.Slice:
+		// Should only be a []byte; repeated fields are handled in writeStruct.
+		if err := writeString(w, string(v.Bytes())); err != nil {
+			return err
+		}
+	case reflect.String:
+		if err := writeString(w, v.String()); err != nil {
+			return err
+		}
+	case reflect.Struct:
+		// Required/optional group/message.
+		var bra, ket byte = '<', '>'
+		if props != nil && props.Wire == "group" {
+			bra, ket = '{', '}'
+		}
+		if err := w.WriteByte(bra); err != nil {
+			return err
+		}
+		if !w.compact {
+			if err := w.WriteByte('\n'); err != nil {
+				return err
+			}
+		}
+		w.indent()
+		if etm, ok := v.Interface().(encoding.TextMarshaler); ok {
+			text, err := etm.MarshalText()
+			if err != nil {
+				return err
+			}
+			if _, err = w.Write(text); err != nil {
+				return err
+			}
+		} else if err := tm.writeStruct(w, v); err != nil {
+			return err
+		}
+		w.unindent()
+		if err := w.WriteByte(ket); err != nil {
+			return err
+		}
+	default:
+		_, err := fmt.Fprint(w, v.Interface())
+		return err
+	}
+	return nil
+}
+
+// equivalent to C's isprint.
+func isprint(c byte) bool {
+	return c >= 0x20 && c < 0x7f
+}
+
+// writeString writes a string in the protocol buffer text format.
+// It is similar to strconv.Quote except we don't use Go escape sequences,
+// we treat the string as a byte sequence, and we use octal escapes.
+// These differences are to maintain interoperability with the other
+// languages' implementations of the text format.
+func writeString(w *textWriter, s string) error {
+	// use WriteByte here to get any needed indent
+	if err := w.WriteByte('"'); err != nil {
+		return err
+	}
+	// Loop over the bytes, not the runes.
+	for i := 0; i < len(s); i++ {
+		var err error
+		// Divergence from C++: we don't escape apostrophes.
+		// There's no need to escape them, and the C++ parser
+		// copes with a naked apostrophe.
+		switch c := s[i]; c {
+		case '\n':
+			_, err = w.w.Write(backslashN)
+		case '\r':
+			_, err = w.w.Write(backslashR)
+		case '\t':
+			_, err = w.w.Write(backslashT)
+		case '"':
+			_, err = w.w.Write(backslashDQ)
+		case '\\':
+			_, err = w.w.Write(backslashBS)
+		default:
+			if isprint(c) {
+				err = w.w.WriteByte(c)
+			} else {
+				_, err = fmt.Fprintf(w.w, "\\%03o", c)
+			}
+		}
+		if err != nil {
+			return err
+		}
+	}
+	return w.WriteByte('"')
+}
+
+func writeUnknownStruct(w *textWriter, data []byte) (err error) {
+	if !w.compact {
+		if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil {
+			return err
+		}
+	}
+	b := NewBuffer(data)
+	for b.index < len(b.buf) {
+		x, err := b.DecodeVarint()
+		if err != nil {
+			_, err := fmt.Fprintf(w, "/* %v */\n", err)
+			return err
+		}
+		wire, tag := x&7, x>>3
+		if wire == WireEndGroup {
+			w.unindent()
+			if _, err := w.Write(endBraceNewline); err != nil {
+				return err
+			}
+			continue
+		}
+		if _, err := fmt.Fprint(w, tag); err != nil {
+			return err
+		}
+		if wire != WireStartGroup {
+			if err := w.WriteByte(':'); err != nil {
+				return err
+			}
+		}
+		if !w.compact || wire == WireStartGroup {
+			if err := w.WriteByte(' '); err != nil {
+				return err
+			}
+		}
+		switch wire {
+		case WireBytes:
+			buf, e := b.DecodeRawBytes(false)
+			if e == nil {
+				_, err = fmt.Fprintf(w, "%q", buf)
+			} else {
+				_, err = fmt.Fprintf(w, "/* %v */", e)
+			}
+		case WireFixed32:
+			x, err = b.DecodeFixed32()
+			err = writeUnknownInt(w, x, err)
+		case WireFixed64:
+			x, err = b.DecodeFixed64()
+			err = writeUnknownInt(w, x, err)
+		case WireStartGroup:
+			err = w.WriteByte('{')
+			w.indent()
+		case WireVarint:
+			x, err = b.DecodeVarint()
+			err = writeUnknownInt(w, x, err)
+		default:
+			_, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire)
+		}
+		if err != nil {
+			return err
+		}
+		if err = w.WriteByte('\n'); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func writeUnknownInt(w *textWriter, x uint64, err error) error {
+	if err == nil {
+		_, err = fmt.Fprint(w, x)
+	} else {
+		_, err = fmt.Fprintf(w, "/* %v */", err)
+	}
+	return err
+}
+
+type int32Slice []int32
+
+func (s int32Slice) Len() int           { return len(s) }
+func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] }
+func (s int32Slice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
+
+// writeExtensions writes all the extensions in pv.
+// pv is assumed to be a pointer to a protocol message struct that is extendable.
+func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error {
+	emap := extensionMaps[pv.Type().Elem()]
+	ep, _ := extendable(pv.Interface())
+
+	// Order the extensions by ID.
+	// This isn't strictly necessary, but it will give us
+	// canonical output, which will also make testing easier.
+	m, mu := ep.extensionsRead()
+	if m == nil {
+		return nil
+	}
+	mu.Lock()
+	ids := make([]int32, 0, len(m))
+	for id := range m {
+		ids = append(ids, id)
+	}
+	sort.Sort(int32Slice(ids))
+	mu.Unlock()
+
+	for _, extNum := range ids {
+		ext := m[extNum]
+		var desc *ExtensionDesc
+		if emap != nil {
+			desc = emap[extNum]
+		}
+		if desc == nil {
+			// Unknown extension.
+			if err := writeUnknownStruct(w, ext.enc); err != nil {
+				return err
+			}
+			continue
+		}
+
+		pb, err := GetExtension(ep, desc)
+		if err != nil {
+			return fmt.Errorf("failed getting extension: %v", err)
+		}
+
+		// Repeated extensions will appear as a slice.
+		if !desc.repeated() {
+			if err := tm.writeExtension(w, desc.Name, pb); err != nil {
+				return err
+			}
+		} else {
+			v := reflect.ValueOf(pb)
+			for i := 0; i < v.Len(); i++ {
+				if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {
+					return err
+				}
+			}
+		}
+	}
+	return nil
+}
+
+func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error {
+	if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil {
+		return err
+	}
+	if !w.compact {
+		if err := w.WriteByte(' '); err != nil {
+			return err
+		}
+	}
+	if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil {
+		return err
+	}
+	if err := w.WriteByte('\n'); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (w *textWriter) writeIndent() {
+	if !w.complete {
+		return
+	}
+	remain := w.ind * 2
+	for remain > 0 {
+		n := remain
+		if n > len(spaces) {
+			n = len(spaces)
+		}
+		w.w.Write(spaces[:n])
+		remain -= n
+	}
+	w.complete = false
+}
+
+// TextMarshaler is a configurable text format marshaler.
+type TextMarshaler struct {
+	Compact   bool // use compact text format (one line).
+	ExpandAny bool // expand google.protobuf.Any messages of known types
+}
+
+// Marshal writes a given protocol buffer in text format.
+// The only errors returned are from w.
+func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error {
+	val := reflect.ValueOf(pb)
+	if pb == nil || val.IsNil() {
+		w.Write([]byte("<nil>"))
+		return nil
+	}
+	var bw *bufio.Writer
+	ww, ok := w.(writer)
+	if !ok {
+		bw = bufio.NewWriter(w)
+		ww = bw
+	}
+	aw := &textWriter{
+		w:        ww,
+		complete: true,
+		compact:  tm.Compact,
+	}
+
+	if etm, ok := pb.(encoding.TextMarshaler); ok {
+		text, err := etm.MarshalText()
+		if err != nil {
+			return err
+		}
+		if _, err = aw.Write(text); err != nil {
+			return err
+		}
+		if bw != nil {
+			return bw.Flush()
+		}
+		return nil
+	}
+	// Dereference the received pointer so we don't have outer < and >.
+	v := reflect.Indirect(val)
+	if err := tm.writeStruct(aw, v); err != nil {
+		return err
+	}
+	if bw != nil {
+		return bw.Flush()
+	}
+	return nil
+}
+
+// Text is the same as Marshal, but returns the string directly.
+func (tm *TextMarshaler) Text(pb Message) string {
+	var buf bytes.Buffer
+	tm.Marshal(&buf, pb)
+	return buf.String()
+}
+
+var (
+	defaultTextMarshaler = TextMarshaler{}
+	compactTextMarshaler = TextMarshaler{Compact: true}
+)
+
+// TODO: consider removing some of the Marshal functions below.
+
+// MarshalText writes a given protocol buffer in text format.
+// The only errors returned are from w.
+func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) }
+
+// MarshalTextString is the same as MarshalText, but returns the string directly.
+func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) }
+
+// CompactText writes a given protocol buffer in compact text format (one line).
+func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) }
+
+// CompactTextString is the same as CompactText, but returns the string directly.
+func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) }

+ 895 - 0
vendor/github.com/golang/protobuf/proto/text_parser.go

@@ -0,0 +1,895 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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 proto
+
+// Functions for parsing the Text protocol buffer format.
+// TODO: message sets.
+
+import (
+	"encoding"
+	"errors"
+	"fmt"
+	"reflect"
+	"strconv"
+	"strings"
+	"unicode/utf8"
+)
+
+// Error string emitted when deserializing Any and fields are already set
+const anyRepeatedlyUnpacked = "Any message unpacked multiple times, or %q already set"
+
+type ParseError struct {
+	Message string
+	Line    int // 1-based line number
+	Offset  int // 0-based byte offset from start of input
+}
+
+func (p *ParseError) Error() string {
+	if p.Line == 1 {
+		// show offset only for first line
+		return fmt.Sprintf("line 1.%d: %v", p.Offset, p.Message)
+	}
+	return fmt.Sprintf("line %d: %v", p.Line, p.Message)
+}
+
+type token struct {
+	value    string
+	err      *ParseError
+	line     int    // line number
+	offset   int    // byte number from start of input, not start of line
+	unquoted string // the unquoted version of value, if it was a quoted string
+}
+
+func (t *token) String() string {
+	if t.err == nil {
+		return fmt.Sprintf("%q (line=%d, offset=%d)", t.value, t.line, t.offset)
+	}
+	return fmt.Sprintf("parse error: %v", t.err)
+}
+
+type textParser struct {
+	s            string // remaining input
+	done         bool   // whether the parsing is finished (success or error)
+	backed       bool   // whether back() was called
+	offset, line int
+	cur          token
+}
+
+func newTextParser(s string) *textParser {
+	p := new(textParser)
+	p.s = s
+	p.line = 1
+	p.cur.line = 1
+	return p
+}
+
+func (p *textParser) errorf(format string, a ...interface{}) *ParseError {
+	pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset}
+	p.cur.err = pe
+	p.done = true
+	return pe
+}
+
+// Numbers and identifiers are matched by [-+._A-Za-z0-9]
+func isIdentOrNumberChar(c byte) bool {
+	switch {
+	case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z':
+		return true
+	case '0' <= c && c <= '9':
+		return true
+	}
+	switch c {
+	case '-', '+', '.', '_':
+		return true
+	}
+	return false
+}
+
+func isWhitespace(c byte) bool {
+	switch c {
+	case ' ', '\t', '\n', '\r':
+		return true
+	}
+	return false
+}
+
+func isQuote(c byte) bool {
+	switch c {
+	case '"', '\'':
+		return true
+	}
+	return false
+}
+
+func (p *textParser) skipWhitespace() {
+	i := 0
+	for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') {
+		if p.s[i] == '#' {
+			// comment; skip to end of line or input
+			for i < len(p.s) && p.s[i] != '\n' {
+				i++
+			}
+			if i == len(p.s) {
+				break
+			}
+		}
+		if p.s[i] == '\n' {
+			p.line++
+		}
+		i++
+	}
+	p.offset += i
+	p.s = p.s[i:len(p.s)]
+	if len(p.s) == 0 {
+		p.done = true
+	}
+}
+
+func (p *textParser) advance() {
+	// Skip whitespace
+	p.skipWhitespace()
+	if p.done {
+		return
+	}
+
+	// Start of non-whitespace
+	p.cur.err = nil
+	p.cur.offset, p.cur.line = p.offset, p.line
+	p.cur.unquoted = ""
+	switch p.s[0] {
+	case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/':
+		// Single symbol
+		p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)]
+	case '"', '\'':
+		// Quoted string
+		i := 1
+		for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' {
+			if p.s[i] == '\\' && i+1 < len(p.s) {
+				// skip escaped char
+				i++
+			}
+			i++
+		}
+		if i >= len(p.s) || p.s[i] != p.s[0] {
+			p.errorf("unmatched quote")
+			return
+		}
+		unq, err := unquoteC(p.s[1:i], rune(p.s[0]))
+		if err != nil {
+			p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err)
+			return
+		}
+		p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)]
+		p.cur.unquoted = unq
+	default:
+		i := 0
+		for i < len(p.s) && isIdentOrNumberChar(p.s[i]) {
+			i++
+		}
+		if i == 0 {
+			p.errorf("unexpected byte %#x", p.s[0])
+			return
+		}
+		p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)]
+	}
+	p.offset += len(p.cur.value)
+}
+
+var (
+	errBadUTF8 = errors.New("proto: bad UTF-8")
+	errBadHex  = errors.New("proto: bad hexadecimal")
+)
+
+func unquoteC(s string, quote rune) (string, error) {
+	// This is based on C++'s tokenizer.cc.
+	// Despite its name, this is *not* parsing C syntax.
+	// For instance, "\0" is an invalid quoted string.
+
+	// Avoid allocation in trivial cases.
+	simple := true
+	for _, r := range s {
+		if r == '\\' || r == quote {
+			simple = false
+			break
+		}
+	}
+	if simple {
+		return s, nil
+	}
+
+	buf := make([]byte, 0, 3*len(s)/2)
+	for len(s) > 0 {
+		r, n := utf8.DecodeRuneInString(s)
+		if r == utf8.RuneError && n == 1 {
+			return "", errBadUTF8
+		}
+		s = s[n:]
+		if r != '\\' {
+			if r < utf8.RuneSelf {
+				buf = append(buf, byte(r))
+			} else {
+				buf = append(buf, string(r)...)
+			}
+			continue
+		}
+
+		ch, tail, err := unescape(s)
+		if err != nil {
+			return "", err
+		}
+		buf = append(buf, ch...)
+		s = tail
+	}
+	return string(buf), nil
+}
+
+func unescape(s string) (ch string, tail string, err error) {
+	r, n := utf8.DecodeRuneInString(s)
+	if r == utf8.RuneError && n == 1 {
+		return "", "", errBadUTF8
+	}
+	s = s[n:]
+	switch r {
+	case 'a':
+		return "\a", s, nil
+	case 'b':
+		return "\b", s, nil
+	case 'f':
+		return "\f", s, nil
+	case 'n':
+		return "\n", s, nil
+	case 'r':
+		return "\r", s, nil
+	case 't':
+		return "\t", s, nil
+	case 'v':
+		return "\v", s, nil
+	case '?':
+		return "?", s, nil // trigraph workaround
+	case '\'', '"', '\\':
+		return string(r), s, nil
+	case '0', '1', '2', '3', '4', '5', '6', '7', 'x', 'X':
+		if len(s) < 2 {
+			return "", "", fmt.Errorf(`\%c requires 2 following digits`, r)
+		}
+		base := 8
+		ss := s[:2]
+		s = s[2:]
+		if r == 'x' || r == 'X' {
+			base = 16
+		} else {
+			ss = string(r) + ss
+		}
+		i, err := strconv.ParseUint(ss, base, 8)
+		if err != nil {
+			return "", "", err
+		}
+		return string([]byte{byte(i)}), s, nil
+	case 'u', 'U':
+		n := 4
+		if r == 'U' {
+			n = 8
+		}
+		if len(s) < n {
+			return "", "", fmt.Errorf(`\%c requires %d digits`, r, n)
+		}
+
+		bs := make([]byte, n/2)
+		for i := 0; i < n; i += 2 {
+			a, ok1 := unhex(s[i])
+			b, ok2 := unhex(s[i+1])
+			if !ok1 || !ok2 {
+				return "", "", errBadHex
+			}
+			bs[i/2] = a<<4 | b
+		}
+		s = s[n:]
+		return string(bs), s, nil
+	}
+	return "", "", fmt.Errorf(`unknown escape \%c`, r)
+}
+
+// Adapted from src/pkg/strconv/quote.go.
+func unhex(b byte) (v byte, ok bool) {
+	switch {
+	case '0' <= b && b <= '9':
+		return b - '0', true
+	case 'a' <= b && b <= 'f':
+		return b - 'a' + 10, true
+	case 'A' <= b && b <= 'F':
+		return b - 'A' + 10, true
+	}
+	return 0, false
+}
+
+// Back off the parser by one token. Can only be done between calls to next().
+// It makes the next advance() a no-op.
+func (p *textParser) back() { p.backed = true }
+
+// Advances the parser and returns the new current token.
+func (p *textParser) next() *token {
+	if p.backed || p.done {
+		p.backed = false
+		return &p.cur
+	}
+	p.advance()
+	if p.done {
+		p.cur.value = ""
+	} else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) {
+		// Look for multiple quoted strings separated by whitespace,
+		// and concatenate them.
+		cat := p.cur
+		for {
+			p.skipWhitespace()
+			if p.done || !isQuote(p.s[0]) {
+				break
+			}
+			p.advance()
+			if p.cur.err != nil {
+				return &p.cur
+			}
+			cat.value += " " + p.cur.value
+			cat.unquoted += p.cur.unquoted
+		}
+		p.done = false // parser may have seen EOF, but we want to return cat
+		p.cur = cat
+	}
+	return &p.cur
+}
+
+func (p *textParser) consumeToken(s string) error {
+	tok := p.next()
+	if tok.err != nil {
+		return tok.err
+	}
+	if tok.value != s {
+		p.back()
+		return p.errorf("expected %q, found %q", s, tok.value)
+	}
+	return nil
+}
+
+// Return a RequiredNotSetError indicating which required field was not set.
+func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError {
+	st := sv.Type()
+	sprops := GetProperties(st)
+	for i := 0; i < st.NumField(); i++ {
+		if !isNil(sv.Field(i)) {
+			continue
+		}
+
+		props := sprops.Prop[i]
+		if props.Required {
+			return &RequiredNotSetError{fmt.Sprintf("%v.%v", st, props.OrigName)}
+		}
+	}
+	return &RequiredNotSetError{fmt.Sprintf("%v.<unknown field name>", st)} // should not happen
+}
+
+// Returns the index in the struct for the named field, as well as the parsed tag properties.
+func structFieldByName(sprops *StructProperties, name string) (int, *Properties, bool) {
+	i, ok := sprops.decoderOrigNames[name]
+	if ok {
+		return i, sprops.Prop[i], true
+	}
+	return -1, nil, false
+}
+
+// Consume a ':' from the input stream (if the next token is a colon),
+// returning an error if a colon is needed but not present.
+func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseError {
+	tok := p.next()
+	if tok.err != nil {
+		return tok.err
+	}
+	if tok.value != ":" {
+		// Colon is optional when the field is a group or message.
+		needColon := true
+		switch props.Wire {
+		case "group":
+			needColon = false
+		case "bytes":
+			// A "bytes" field is either a message, a string, or a repeated field;
+			// those three become *T, *string and []T respectively, so we can check for
+			// this field being a pointer to a non-string.
+			if typ.Kind() == reflect.Ptr {
+				// *T or *string
+				if typ.Elem().Kind() == reflect.String {
+					break
+				}
+			} else if typ.Kind() == reflect.Slice {
+				// []T or []*T
+				if typ.Elem().Kind() != reflect.Ptr {
+					break
+				}
+			} else if typ.Kind() == reflect.String {
+				// The proto3 exception is for a string field,
+				// which requires a colon.
+				break
+			}
+			needColon = false
+		}
+		if needColon {
+			return p.errorf("expected ':', found %q", tok.value)
+		}
+		p.back()
+	}
+	return nil
+}
+
+func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
+	st := sv.Type()
+	sprops := GetProperties(st)
+	reqCount := sprops.reqCount
+	var reqFieldErr error
+	fieldSet := make(map[string]bool)
+	// A struct is a sequence of "name: value", terminated by one of
+	// '>' or '}', or the end of the input.  A name may also be
+	// "[extension]" or "[type/url]".
+	//
+	// The whole struct can also be an expanded Any message, like:
+	// [type/url] < ... struct contents ... >
+	for {
+		tok := p.next()
+		if tok.err != nil {
+			return tok.err
+		}
+		if tok.value == terminator {
+			break
+		}
+		if tok.value == "[" {
+			// Looks like an extension or an Any.
+			//
+			// TODO: Check whether we need to handle
+			// namespace rooted names (e.g. ".something.Foo").
+			extName, err := p.consumeExtName()
+			if err != nil {
+				return err
+			}
+
+			if s := strings.LastIndex(extName, "/"); s >= 0 {
+				// If it contains a slash, it's an Any type URL.
+				messageName := extName[s+1:]
+				mt := MessageType(messageName)
+				if mt == nil {
+					return p.errorf("unrecognized message %q in google.protobuf.Any", messageName)
+				}
+				tok = p.next()
+				if tok.err != nil {
+					return tok.err
+				}
+				// consume an optional colon
+				if tok.value == ":" {
+					tok = p.next()
+					if tok.err != nil {
+						return tok.err
+					}
+				}
+				var terminator string
+				switch tok.value {
+				case "<":
+					terminator = ">"
+				case "{":
+					terminator = "}"
+				default:
+					return p.errorf("expected '{' or '<', found %q", tok.value)
+				}
+				v := reflect.New(mt.Elem())
+				if pe := p.readStruct(v.Elem(), terminator); pe != nil {
+					return pe
+				}
+				b, err := Marshal(v.Interface().(Message))
+				if err != nil {
+					return p.errorf("failed to marshal message of type %q: %v", messageName, err)
+				}
+				if fieldSet["type_url"] {
+					return p.errorf(anyRepeatedlyUnpacked, "type_url")
+				}
+				if fieldSet["value"] {
+					return p.errorf(anyRepeatedlyUnpacked, "value")
+				}
+				sv.FieldByName("TypeUrl").SetString(extName)
+				sv.FieldByName("Value").SetBytes(b)
+				fieldSet["type_url"] = true
+				fieldSet["value"] = true
+				continue
+			}
+
+			var desc *ExtensionDesc
+			// This could be faster, but it's functional.
+			// TODO: Do something smarter than a linear scan.
+			for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) {
+				if d.Name == extName {
+					desc = d
+					break
+				}
+			}
+			if desc == nil {
+				return p.errorf("unrecognized extension %q", extName)
+			}
+
+			props := &Properties{}
+			props.Parse(desc.Tag)
+
+			typ := reflect.TypeOf(desc.ExtensionType)
+			if err := p.checkForColon(props, typ); err != nil {
+				return err
+			}
+
+			rep := desc.repeated()
+
+			// Read the extension structure, and set it in
+			// the value we're constructing.
+			var ext reflect.Value
+			if !rep {
+				ext = reflect.New(typ).Elem()
+			} else {
+				ext = reflect.New(typ.Elem()).Elem()
+			}
+			if err := p.readAny(ext, props); err != nil {
+				if _, ok := err.(*RequiredNotSetError); !ok {
+					return err
+				}
+				reqFieldErr = err
+			}
+			ep := sv.Addr().Interface().(Message)
+			if !rep {
+				SetExtension(ep, desc, ext.Interface())
+			} else {
+				old, err := GetExtension(ep, desc)
+				var sl reflect.Value
+				if err == nil {
+					sl = reflect.ValueOf(old) // existing slice
+				} else {
+					sl = reflect.MakeSlice(typ, 0, 1)
+				}
+				sl = reflect.Append(sl, ext)
+				SetExtension(ep, desc, sl.Interface())
+			}
+			if err := p.consumeOptionalSeparator(); err != nil {
+				return err
+			}
+			continue
+		}
+
+		// This is a normal, non-extension field.
+		name := tok.value
+		var dst reflect.Value
+		fi, props, ok := structFieldByName(sprops, name)
+		if ok {
+			dst = sv.Field(fi)
+		} else if oop, ok := sprops.OneofTypes[name]; ok {
+			// It is a oneof.
+			props = oop.Prop
+			nv := reflect.New(oop.Type.Elem())
+			dst = nv.Elem().Field(0)
+			field := sv.Field(oop.Field)
+			if !field.IsNil() {
+				return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, sv.Type().Field(oop.Field).Name)
+			}
+			field.Set(nv)
+		}
+		if !dst.IsValid() {
+			return p.errorf("unknown field name %q in %v", name, st)
+		}
+
+		if dst.Kind() == reflect.Map {
+			// Consume any colon.
+			if err := p.checkForColon(props, dst.Type()); err != nil {
+				return err
+			}
+
+			// Construct the map if it doesn't already exist.
+			if dst.IsNil() {
+				dst.Set(reflect.MakeMap(dst.Type()))
+			}
+			key := reflect.New(dst.Type().Key()).Elem()
+			val := reflect.New(dst.Type().Elem()).Elem()
+
+			// The map entry should be this sequence of tokens:
+			//	< key : KEY value : VALUE >
+			// However, implementations may omit key or value, and technically
+			// we should support them in any order.  See b/28924776 for a time
+			// this went wrong.
+
+			tok := p.next()
+			var terminator string
+			switch tok.value {
+			case "<":
+				terminator = ">"
+			case "{":
+				terminator = "}"
+			default:
+				return p.errorf("expected '{' or '<', found %q", tok.value)
+			}
+			for {
+				tok := p.next()
+				if tok.err != nil {
+					return tok.err
+				}
+				if tok.value == terminator {
+					break
+				}
+				switch tok.value {
+				case "key":
+					if err := p.consumeToken(":"); err != nil {
+						return err
+					}
+					if err := p.readAny(key, props.mkeyprop); err != nil {
+						return err
+					}
+					if err := p.consumeOptionalSeparator(); err != nil {
+						return err
+					}
+				case "value":
+					if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil {
+						return err
+					}
+					if err := p.readAny(val, props.mvalprop); err != nil {
+						return err
+					}
+					if err := p.consumeOptionalSeparator(); err != nil {
+						return err
+					}
+				default:
+					p.back()
+					return p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value)
+				}
+			}
+
+			dst.SetMapIndex(key, val)
+			continue
+		}
+
+		// Check that it's not already set if it's not a repeated field.
+		if !props.Repeated && fieldSet[name] {
+			return p.errorf("non-repeated field %q was repeated", name)
+		}
+
+		if err := p.checkForColon(props, dst.Type()); err != nil {
+			return err
+		}
+
+		// Parse into the field.
+		fieldSet[name] = true
+		if err := p.readAny(dst, props); err != nil {
+			if _, ok := err.(*RequiredNotSetError); !ok {
+				return err
+			}
+			reqFieldErr = err
+		}
+		if props.Required {
+			reqCount--
+		}
+
+		if err := p.consumeOptionalSeparator(); err != nil {
+			return err
+		}
+
+	}
+
+	if reqCount > 0 {
+		return p.missingRequiredFieldError(sv)
+	}
+	return reqFieldErr
+}
+
+// consumeExtName consumes extension name or expanded Any type URL and the
+// following ']'. It returns the name or URL consumed.
+func (p *textParser) consumeExtName() (string, error) {
+	tok := p.next()
+	if tok.err != nil {
+		return "", tok.err
+	}
+
+	// If extension name or type url is quoted, it's a single token.
+	if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] {
+		name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0]))
+		if err != nil {
+			return "", err
+		}
+		return name, p.consumeToken("]")
+	}
+
+	// Consume everything up to "]"
+	var parts []string
+	for tok.value != "]" {
+		parts = append(parts, tok.value)
+		tok = p.next()
+		if tok.err != nil {
+			return "", p.errorf("unrecognized type_url or extension name: %s", tok.err)
+		}
+	}
+	return strings.Join(parts, ""), nil
+}
+
+// consumeOptionalSeparator consumes an optional semicolon or comma.
+// It is used in readStruct to provide backward compatibility.
+func (p *textParser) consumeOptionalSeparator() error {
+	tok := p.next()
+	if tok.err != nil {
+		return tok.err
+	}
+	if tok.value != ";" && tok.value != "," {
+		p.back()
+	}
+	return nil
+}
+
+func (p *textParser) readAny(v reflect.Value, props *Properties) error {
+	tok := p.next()
+	if tok.err != nil {
+		return tok.err
+	}
+	if tok.value == "" {
+		return p.errorf("unexpected EOF")
+	}
+
+	switch fv := v; fv.Kind() {
+	case reflect.Slice:
+		at := v.Type()
+		if at.Elem().Kind() == reflect.Uint8 {
+			// Special case for []byte
+			if tok.value[0] != '"' && tok.value[0] != '\'' {
+				// Deliberately written out here, as the error after
+				// this switch statement would write "invalid []byte: ...",
+				// which is not as user-friendly.
+				return p.errorf("invalid string: %v", tok.value)
+			}
+			bytes := []byte(tok.unquoted)
+			fv.Set(reflect.ValueOf(bytes))
+			return nil
+		}
+		// Repeated field.
+		if tok.value == "[" {
+			// Repeated field with list notation, like [1,2,3].
+			for {
+				fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))
+				err := p.readAny(fv.Index(fv.Len()-1), props)
+				if err != nil {
+					return err
+				}
+				tok := p.next()
+				if tok.err != nil {
+					return tok.err
+				}
+				if tok.value == "]" {
+					break
+				}
+				if tok.value != "," {
+					return p.errorf("Expected ']' or ',' found %q", tok.value)
+				}
+			}
+			return nil
+		}
+		// One value of the repeated field.
+		p.back()
+		fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))
+		return p.readAny(fv.Index(fv.Len()-1), props)
+	case reflect.Bool:
+		// true/1/t/True or false/f/0/False.
+		switch tok.value {
+		case "true", "1", "t", "True":
+			fv.SetBool(true)
+			return nil
+		case "false", "0", "f", "False":
+			fv.SetBool(false)
+			return nil
+		}
+	case reflect.Float32, reflect.Float64:
+		v := tok.value
+		// Ignore 'f' for compatibility with output generated by C++, but don't
+		// remove 'f' when the value is "-inf" or "inf".
+		if strings.HasSuffix(v, "f") && tok.value != "-inf" && tok.value != "inf" {
+			v = v[:len(v)-1]
+		}
+		if f, err := strconv.ParseFloat(v, fv.Type().Bits()); err == nil {
+			fv.SetFloat(f)
+			return nil
+		}
+	case reflect.Int32:
+		if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil {
+			fv.SetInt(x)
+			return nil
+		}
+
+		if len(props.Enum) == 0 {
+			break
+		}
+		m, ok := enumValueMaps[props.Enum]
+		if !ok {
+			break
+		}
+		x, ok := m[tok.value]
+		if !ok {
+			break
+		}
+		fv.SetInt(int64(x))
+		return nil
+	case reflect.Int64:
+		if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil {
+			fv.SetInt(x)
+			return nil
+		}
+
+	case reflect.Ptr:
+		// A basic field (indirected through pointer), or a repeated message/group
+		p.back()
+		fv.Set(reflect.New(fv.Type().Elem()))
+		return p.readAny(fv.Elem(), props)
+	case reflect.String:
+		if tok.value[0] == '"' || tok.value[0] == '\'' {
+			fv.SetString(tok.unquoted)
+			return nil
+		}
+	case reflect.Struct:
+		var terminator string
+		switch tok.value {
+		case "{":
+			terminator = "}"
+		case "<":
+			terminator = ">"
+		default:
+			return p.errorf("expected '{' or '<', found %q", tok.value)
+		}
+		// TODO: Handle nested messages which implement encoding.TextUnmarshaler.
+		return p.readStruct(fv, terminator)
+	case reflect.Uint32:
+		if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil {
+			fv.SetUint(x)
+			return nil
+		}
+	case reflect.Uint64:
+		if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil {
+			fv.SetUint(x)
+			return nil
+		}
+	}
+	return p.errorf("invalid %v: %v", v.Type(), tok.value)
+}
+
+// UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb
+// before starting to unmarshal, so any existing data in pb is always removed.
+// If a required field is not set and no other error occurs,
+// UnmarshalText returns *RequiredNotSetError.
+func UnmarshalText(s string, pb Message) error {
+	if um, ok := pb.(encoding.TextUnmarshaler); ok {
+		err := um.UnmarshalText([]byte(s))
+		return err
+	}
+	pb.Reset()
+	v := reflect.ValueOf(pb)
+	if pe := newTextParser(s).readStruct(v.Elem(), ""); pe != nil {
+		return pe
+	}
+	return nil
+}

+ 171 - 0
vendor/github.com/google/go-github/AUTHORS

@@ -0,0 +1,171 @@
+# This is the official list of go-github authors for copyright purposes.
+#
+# This does not necessarily list everyone who has contributed code, since in
+# some cases, their employer may be the copyright holder. To see the full list
+# of contributors, see the revision history in source control or
+# https://github.com/google/go-github/graphs/contributors.
+#
+# Authors who wish to be recognized in this file should add themselves (or
+# their employer, as appropriate).
+
+178inaba <masahiro.furudate@gmail.com>
+Abhinav Gupta <mail@abhinavg.net>
+Ahmed Hagy <a.akram93@gmail.com>
+Ainsley Chong <ainsley.chong@gmail.com>
+Akeda Bagus <akeda@x-team.com>
+Alec Thomas <alec@swapoff.org>
+Aleks Clark <aleks.clark@gmail.com>
+Alex Bramley <a.bramley@gmail.com>
+Alexander Harkness <me@bearbin.net>
+Allen Sun <shlallen1990@gmail.com>
+Amey Sakhadeo <me@ameyms.com>
+Andreas Garnæs <https://github.com/andreas>
+Andrew Ryabchun <aryabchun@mail.ua>
+Andy Hume <andyhume@gmail.com>
+Andy Lindeman <andy@lindeman.io>
+Anshuman Bhartiya <anshuman.bhartiya@gmail.com>
+Antoine Pelisse <apelisse@gmail.com>
+Anubha Kushwaha <anubha_bt2k14@dtu.ac.in>
+Aravind <aravindkp@outlook.in>
+Arıl Bozoluk <arilbozoluk@hotmail.com>
+Austin Dizzy <dizzy@wow.com>
+Beshr Kayali <beshrkayali@gmail.com>
+Beyang Liu <beyang.liu@gmail.com>
+Billy Lynch <wlynch92@gmail.com>
+Björn Häuser <b.haeuser@rebuy.de>
+Brad Harris <bmharris@gmail.com>
+Bradley Falzon <brad@teambrad.net>
+Brian Egizi <brian@mojotech.com>
+Bryan Boreham <bryan@weave.works>
+Cami Diez <diezcami@gmail.com>
+Carlos Alexandro Becker <caarlos0@gmail.com>
+chandresh-pancholi <chandreshpancholi007@gmail.com>
+Charlie Yan <charlieyan08@gmail.com>
+Chris King <chriskingnet@gmail.com>
+Chris Roche <chris@vsco.co>
+Chris Schaefer <chris@dtzq.com>
+Christoph Sassenberg <defsprite@gmail.com>
+Colin Misare <github.com/cmisare>
+Craig Peterson <cpeterson@stackoverflow.com>
+Cristian Maglie <c.maglie@bug.st>
+Daehyeok Mun <daehyeok@gmail.com>
+Daniel Leavitt <daniel.leavitt@gmail.com>
+Dave Du Cros <davidducros@gmail.com>
+Dave Henderson <dhenderson@gmail.com>
+David Deng <daviddengcn@gmail.com>
+Dennis Webb <dennis@bluesentryit.com>
+Diego Lapiduz <diego.lapiduz@cfpb.gov>
+Dmitri Shuralyov <shurcooL@gmail.com>
+dmnlk <seikima2demon@gmail.com>
+Don Petersen <don@donpetersen.net>
+Doug Turner <doug.turner@gmail.com>
+Drew Fradette <drew.fradette@gmail.com>
+Eli Uriegas <seemethere101@gmail.com>
+Elliott Beach <elliott2.71828@gmail.com>
+erwinvaneyk <erwinvaneyk@gmail.com>
+Fabrice <fabrice.vaillant@student.ecp.fr>
+Filippo Valsorda <hi@filippo.io>
+Florian Forster <ff@octo.it>
+Francesc Gil <xescugil@gmail.com>
+Francis <hello@francismakes.com>
+Fredrik Jönsson <fredrik.jonsson@izettle.com>
+Garrett Squire <garrettsquire@gmail.com>
+Georgy Buranov <gburanov@gmail.com>
+Gnahz <p@oath.pl>
+Google Inc.
+griffin_stewie <panterathefamilyguy@gmail.com>
+Guz Alexander <kalimatas@gmail.com>
+Hanno Hecker <hanno.hecker@zalando.de>
+Hari haran <hariharan.uno@gmail.com>
+haya14busa <hayabusa1419@gmail.com>
+Huy Tr <kingbazoka@gmail.com>
+huydx <doxuanhuy@gmail.com>
+i2bskn <i2bskn@gmail.com>
+Isao Jonas <isao.jonas@gmail.com>
+isqua <isqua@isqua.ru>
+Jameel Haffejee <RC1140@republiccommandos.co.za>
+Jan Kosecki <jan.kosecki91@gmail.com>
+Jeremy Morris <jeremylevanmorris@gmail.com>
+Jihoon Chung <j.c@navercorp.com>
+Jimmi Dyson <jimmidyson@gmail.com>
+Joe Tsai <joetsai@digital-static.net>
+John Barton <jrbarton@gmail.com>
+John Engelman <john.r.engelman@gmail.com>
+jpbelanger-mtl <jp.belanger@gmail.com>
+Juan Basso <jrbasso@gmail.com>
+Julien Rostand <jrostand@users.noreply.github.com>
+Justin Abrahms <justin@abrah.ms>
+jzhoucliqr <jzhou@cliqr.com>
+Katrina Owen <kytrinyx@github.com>
+Keita Urashima <ursm@ursm.jp>
+Kevin Burke <kev@inburke.com>
+Konrad Malawski <konrad.malawski@project13.pl>
+Kookheon Kwon <kucuny@gmail.com>
+Krzysztof Kowalczyk <kkowalczyk@gmail.com>
+Kshitij Saraogi <KshitijSaraogi@gmail.com>
+kyokomi <kyoko1220adword@gmail.com>
+Lucas Alcantara <lucasalcantaraf@gmail.com>
+Luke Evers <me@lukevers.com>
+Luke Kysow <lkysow@gmail.com>
+Luke Roberts <email@luke-roberts.co.uk>
+Luke Young <luke@hydrantlabs.org>
+Maksim Zhylinski <uzzable@gmail.com>
+Martin-Louis Bright <mlbright@gmail.com>
+Mat Geist <matgeist@gmail.com>
+Matt Brender <mjbrender@gmail.com>
+Matt Landis <landis.matt@gmail.com>
+Maxime Bury <maxime.bury@gmail.com>
+Michael Tiller <michael.tiller@gmail.com>
+Michał Glapa <michal.glapa@gmail.com>
+Nathan VanBenschoten <nvanbenschoten@gmail.com>
+Neil O'Toole <neilotoole@apache.org>
+Nick Miyake <nmiyake@palantir.com>
+Nick Spragg <nick.spragg@bbc.co.uk>
+Nikhita Raghunath <nikitaraghunath@gmail.com>
+Noah Zoschke <noah+sso2@convox.com>
+ns-cweber <cweber@narrativescience.com>
+Ondřej Kupka <ondra.cap@gmail.com>
+Panagiotis Moustafellos <pmoust@gmail.com>
+Parker Moore <parkrmoore@gmail.com>
+Pavel Shtanko <pavel.shtanko@gmail.com>
+Petr Shevtsov <petr.shevtsov@gmail.com>
+Pierre Carrier <pierre@meteor.com>
+Piotr Zurek <p.zurek@gmail.com>
+Quinn Slack <qslack@qslack.com>
+Rackspace US, Inc.
+RaviTeja Pothana <ravi-teja@live.com>
+rc1140 <jameel@republiccommandos.co.za>
+Red Hat, Inc.
+Rob Figueiredo <robfig@yext.com>
+Ronak Jain <ronakjain@outlook.in>
+Ruben Vereecken <rubenvereecken@gmail.com>
+Ryan Lower <rpjlower@gmail.com>
+Sahil Dua <sahildua2305@gmail.com>
+saisi <saisi@users.noreply.github.com>
+Sam Minnée <sam@silverstripe.com>
+Sander van Harmelen <svanharmelen@schubergphilis.com>
+Sarasa Kisaragi <lingsamuelgrace@gmail.com>
+Sean Wang <sean@decrypted.org>
+Sebastian Mandrean <sebastian.mandrean@gmail.com>
+Sebastian Mæland Pedersen <sem.pedersen@stud.uis.no>
+Sevki <s@sevki.org>
+Shawn Catanzarite <me@shawncatz.com>
+Shawn Smith <shawnpsmith@gmail.com>
+sona-tar <sona.zip@gmail.com>
+SoundCloud, Ltd.
+Stian Eikeland <stian@eikeland.se>
+Thomas Bruyelle <thomas.bruyelle@gmail.com>
+Timothée Peignier <timothee.peignier@tryphon.org>
+Trey Tacon <ttacon@gmail.com>
+ttacon <ttacon@gmail.com>
+Varadarajan Aravamudhan <varadaraajan@gmail.com>
+Victor Castell <victor@victorcastell.com>
+Victor Vrantchan <vrancean+github@gmail.com>
+Vlad Ungureanu <vladu@palantir.com>
+Will Maier <wcmaier@gmail.com>
+William Bailey <mail@williambailey.org.uk>
+Yann Malet <yann.malet@gmail.com>
+Yannick Utard <yannickutard@gmail.com>
+Yicheng Qin <qycqycqycqycqyc@gmail.com>
+Yumikiyo Osanai <yumios.art@gmail.com>
+Zach Latta <zach@zachlatta.com>

+ 341 - 0
vendor/github.com/google/go-github/LICENSE

@@ -0,0 +1,341 @@
+Copyright (c) 2013 The go-github AUTHORS. 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.
+
+----------
+
+Some documentation is taken from the GitHub Developer site
+<https://developer.github.com/>, which is available under the following Creative
+Commons Attribution 3.0 License. This applies only to the go-github source
+code and would not apply to any compiled binaries.
+
+THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE
+COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY
+COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
+AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
+
+BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE
+TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY
+BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS
+CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND
+CONDITIONS.
+
+1. Definitions
+
+ a. "Adaptation" means a work based upon the Work, or upon the Work and
+    other pre-existing works, such as a translation, adaptation,
+    derivative work, arrangement of music or other alterations of a
+    literary or artistic work, or phonogram or performance and includes
+    cinematographic adaptations or any other form in which the Work may be
+    recast, transformed, or adapted including in any form recognizably
+    derived from the original, except that a work that constitutes a
+    Collection will not be considered an Adaptation for the purpose of
+    this License. For the avoidance of doubt, where the Work is a musical
+    work, performance or phonogram, the synchronization of the Work in
+    timed-relation with a moving image ("synching") will be considered an
+    Adaptation for the purpose of this License.
+ b. "Collection" means a collection of literary or artistic works, such as
+    encyclopedias and anthologies, or performances, phonograms or
+    broadcasts, or other works or subject matter other than works listed
+    in Section 1(f) below, which, by reason of the selection and
+    arrangement of their contents, constitute intellectual creations, in
+    which the Work is included in its entirety in unmodified form along
+    with one or more other contributions, each constituting separate and
+    independent works in themselves, which together are assembled into a
+    collective whole. A work that constitutes a Collection will not be
+    considered an Adaptation (as defined above) for the purposes of this
+    License.
+ c. "Distribute" means to make available to the public the original and
+    copies of the Work or Adaptation, as appropriate, through sale or
+    other transfer of ownership.
+ d. "Licensor" means the individual, individuals, entity or entities that
+    offer(s) the Work under the terms of this License.
+ e. "Original Author" means, in the case of a literary or artistic work,
+    the individual, individuals, entity or entities who created the Work
+    or if no individual or entity can be identified, the publisher; and in
+    addition (i) in the case of a performance the actors, singers,
+    musicians, dancers, and other persons who act, sing, deliver, declaim,
+    play in, interpret or otherwise perform literary or artistic works or
+    expressions of folklore; (ii) in the case of a phonogram the producer
+    being the person or legal entity who first fixes the sounds of a
+    performance or other sounds; and, (iii) in the case of broadcasts, the
+    organization that transmits the broadcast.
+ f. "Work" means the literary and/or artistic work offered under the terms
+    of this License including without limitation any production in the
+    literary, scientific and artistic domain, whatever may be the mode or
+    form of its expression including digital form, such as a book,
+    pamphlet and other writing; a lecture, address, sermon or other work
+    of the same nature; a dramatic or dramatico-musical work; a
+    choreographic work or entertainment in dumb show; a musical
+    composition with or without words; a cinematographic work to which are
+    assimilated works expressed by a process analogous to cinematography;
+    a work of drawing, painting, architecture, sculpture, engraving or
+    lithography; a photographic work to which are assimilated works
+    expressed by a process analogous to photography; a work of applied
+    art; an illustration, map, plan, sketch or three-dimensional work
+    relative to geography, topography, architecture or science; a
+    performance; a broadcast; a phonogram; a compilation of data to the
+    extent it is protected as a copyrightable work; or a work performed by
+    a variety or circus performer to the extent it is not otherwise
+    considered a literary or artistic work.
+ g. "You" means an individual or entity exercising rights under this
+    License who has not previously violated the terms of this License with
+    respect to the Work, or who has received express permission from the
+    Licensor to exercise rights under this License despite a previous
+    violation.
+ h. "Publicly Perform" means to perform public recitations of the Work and
+    to communicate to the public those public recitations, by any means or
+    process, including by wire or wireless means or public digital
+    performances; to make available to the public Works in such a way that
+    members of the public may access these Works from a place and at a
+    place individually chosen by them; to perform the Work to the public
+    by any means or process and the communication to the public of the
+    performances of the Work, including by public digital performance; to
+    broadcast and rebroadcast the Work by any means including signs,
+    sounds or images.
+ i. "Reproduce" means to make copies of the Work by any means including
+    without limitation by sound or visual recordings and the right of
+    fixation and reproducing fixations of the Work, including storage of a
+    protected performance or phonogram in digital form or other electronic
+    medium.
+
+2. Fair Dealing Rights. Nothing in this License is intended to reduce,
+limit, or restrict any uses free from copyright or rights arising from
+limitations or exceptions that are provided for in connection with the
+copyright protection under copyright law or other applicable laws.
+
+3. License Grant. Subject to the terms and conditions of this License,
+Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
+perpetual (for the duration of the applicable copyright) license to
+exercise the rights in the Work as stated below:
+
+ a. to Reproduce the Work, to incorporate the Work into one or more
+    Collections, and to Reproduce the Work as incorporated in the
+    Collections;
+ b. to create and Reproduce Adaptations provided that any such Adaptation,
+    including any translation in any medium, takes reasonable steps to
+    clearly label, demarcate or otherwise identify that changes were made
+    to the original Work. For example, a translation could be marked "The
+    original work was translated from English to Spanish," or a
+    modification could indicate "The original work has been modified.";
+ c. to Distribute and Publicly Perform the Work including as incorporated
+    in Collections; and,
+ d. to Distribute and Publicly Perform Adaptations.
+ e. For the avoidance of doubt:
+
+     i. Non-waivable Compulsory License Schemes. In those jurisdictions in
+        which the right to collect royalties through any statutory or
+        compulsory licensing scheme cannot be waived, the Licensor
+        reserves the exclusive right to collect such royalties for any
+        exercise by You of the rights granted under this License;
+    ii. Waivable Compulsory License Schemes. In those jurisdictions in
+        which the right to collect royalties through any statutory or
+        compulsory licensing scheme can be waived, the Licensor waives the
+        exclusive right to collect such royalties for any exercise by You
+        of the rights granted under this License; and,
+   iii. Voluntary License Schemes. The Licensor waives the right to
+        collect royalties, whether individually or, in the event that the
+        Licensor is a member of a collecting society that administers
+        voluntary licensing schemes, via that society, from any exercise
+        by You of the rights granted under this License.
+
+The above rights may be exercised in all media and formats whether now
+known or hereafter devised. The above rights include the right to make
+such modifications as are technically necessary to exercise the rights in
+other media and formats. Subject to Section 8(f), all rights not expressly
+granted by Licensor are hereby reserved.
+
+4. Restrictions. The license granted in Section 3 above is expressly made
+subject to and limited by the following restrictions:
+
+ a. You may Distribute or Publicly Perform the Work only under the terms
+    of this License. You must include a copy of, or the Uniform Resource
+    Identifier (URI) for, this License with every copy of the Work You
+    Distribute or Publicly Perform. You may not offer or impose any terms
+    on the Work that restrict the terms of this License or the ability of
+    the recipient of the Work to exercise the rights granted to that
+    recipient under the terms of the License. You may not sublicense the
+    Work. You must keep intact all notices that refer to this License and
+    to the disclaimer of warranties with every copy of the Work You
+    Distribute or Publicly Perform. When You Distribute or Publicly
+    Perform the Work, You may not impose any effective technological
+    measures on the Work that restrict the ability of a recipient of the
+    Work from You to exercise the rights granted to that recipient under
+    the terms of the License. This Section 4(a) applies to the Work as
+    incorporated in a Collection, but this does not require the Collection
+    apart from the Work itself to be made subject to the terms of this
+    License. If You create a Collection, upon notice from any Licensor You
+    must, to the extent practicable, remove from the Collection any credit
+    as required by Section 4(b), as requested. If You create an
+    Adaptation, upon notice from any Licensor You must, to the extent
+    practicable, remove from the Adaptation any credit as required by
+    Section 4(b), as requested.
+ b. If You Distribute, or Publicly Perform the Work or any Adaptations or
+    Collections, You must, unless a request has been made pursuant to
+    Section 4(a), keep intact all copyright notices for the Work and
+    provide, reasonable to the medium or means You are utilizing: (i) the
+    name of the Original Author (or pseudonym, if applicable) if supplied,
+    and/or if the Original Author and/or Licensor designate another party
+    or parties (e.g., a sponsor institute, publishing entity, journal) for
+    attribution ("Attribution Parties") in Licensor's copyright notice,
+    terms of service or by other reasonable means, the name of such party
+    or parties; (ii) the title of the Work if supplied; (iii) to the
+    extent reasonably practicable, the URI, if any, that Licensor
+    specifies to be associated with the Work, unless such URI does not
+    refer to the copyright notice or licensing information for the Work;
+    and (iv) , consistent with Section 3(b), in the case of an Adaptation,
+    a credit identifying the use of the Work in the Adaptation (e.g.,
+    "French translation of the Work by Original Author," or "Screenplay
+    based on original Work by Original Author"). The credit required by
+    this Section 4 (b) may be implemented in any reasonable manner;
+    provided, however, that in the case of a Adaptation or Collection, at
+    a minimum such credit will appear, if a credit for all contributing
+    authors of the Adaptation or Collection appears, then as part of these
+    credits and in a manner at least as prominent as the credits for the
+    other contributing authors. For the avoidance of doubt, You may only
+    use the credit required by this Section for the purpose of attribution
+    in the manner set out above and, by exercising Your rights under this
+    License, You may not implicitly or explicitly assert or imply any
+    connection with, sponsorship or endorsement by the Original Author,
+    Licensor and/or Attribution Parties, as appropriate, of You or Your
+    use of the Work, without the separate, express prior written
+    permission of the Original Author, Licensor and/or Attribution
+    Parties.
+ c. Except as otherwise agreed in writing by the Licensor or as may be
+    otherwise permitted by applicable law, if You Reproduce, Distribute or
+    Publicly Perform the Work either by itself or as part of any
+    Adaptations or Collections, You must not distort, mutilate, modify or
+    take other derogatory action in relation to the Work which would be
+    prejudicial to the Original Author's honor or reputation. Licensor
+    agrees that in those jurisdictions (e.g. Japan), in which any exercise
+    of the right granted in Section 3(b) of this License (the right to
+    make Adaptations) would be deemed to be a distortion, mutilation,
+    modification or other derogatory action prejudicial to the Original
+    Author's honor and reputation, the Licensor will waive or not assert,
+    as appropriate, this Section, to the fullest extent permitted by the
+    applicable national law, to enable You to reasonably exercise Your
+    right under Section 3(b) of this License (right to make Adaptations)
+    but not otherwise.
+
+5. Representations, Warranties and Disclaimer
+
+UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR
+OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY
+KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
+INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
+FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
+LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS,
+WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION
+OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
+
+6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE
+LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR
+ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES
+ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS
+BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. Termination
+
+ a. This License and the rights granted hereunder will terminate
+    automatically upon any breach by You of the terms of this License.
+    Individuals or entities who have received Adaptations or Collections
+    from You under this License, however, will not have their licenses
+    terminated provided such individuals or entities remain in full
+    compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will
+    survive any termination of this License.
+ b. Subject to the above terms and conditions, the license granted here is
+    perpetual (for the duration of the applicable copyright in the Work).
+    Notwithstanding the above, Licensor reserves the right to release the
+    Work under different license terms or to stop distributing the Work at
+    any time; provided, however that any such election will not serve to
+    withdraw this License (or any other license that has been, or is
+    required to be, granted under the terms of this License), and this
+    License will continue in full force and effect unless terminated as
+    stated above.
+
+8. Miscellaneous
+
+ a. Each time You Distribute or Publicly Perform the Work or a Collection,
+    the Licensor offers to the recipient a license to the Work on the same
+    terms and conditions as the license granted to You under this License.
+ b. Each time You Distribute or Publicly Perform an Adaptation, Licensor
+    offers to the recipient a license to the original Work on the same
+    terms and conditions as the license granted to You under this License.
+ c. If any provision of this License is invalid or unenforceable under
+    applicable law, it shall not affect the validity or enforceability of
+    the remainder of the terms of this License, and without further action
+    by the parties to this agreement, such provision shall be reformed to
+    the minimum extent necessary to make such provision valid and
+    enforceable.
+ d. No term or provision of this License shall be deemed waived and no
+    breach consented to unless such waiver or consent shall be in writing
+    and signed by the party to be charged with such waiver or consent.
+ e. This License constitutes the entire agreement between the parties with
+    respect to the Work licensed here. There are no understandings,
+    agreements or representations with respect to the Work not specified
+    here. Licensor shall not be bound by any additional provisions that
+    may appear in any communication from You. This License may not be
+    modified without the mutual written agreement of the Licensor and You.
+ f. The rights granted under, and the subject matter referenced, in this
+    License were drafted utilizing the terminology of the Berne Convention
+    for the Protection of Literary and Artistic Works (as amended on
+    September 28, 1979), the Rome Convention of 1961, the WIPO Copyright
+    Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996
+    and the Universal Copyright Convention (as revised on July 24, 1971).
+    These rights and subject matter take effect in the relevant
+    jurisdiction in which the License terms are sought to be enforced
+    according to the corresponding provisions of the implementation of
+    those treaty provisions in the applicable national law. If the
+    standard suite of rights granted under applicable copyright law
+    includes additional rights not granted under this License, such
+    additional rights are deemed to be included in the License; this
+    License is not intended to restrict the license of any rights under
+    applicable law.
+
+
+Creative Commons Notice
+
+    Creative Commons is not a party to this License, and makes no warranty
+    whatsoever in connection with the Work. Creative Commons will not be
+    liable to You or any party on any legal theory for any damages
+    whatsoever, including without limitation any general, special,
+    incidental or consequential damages arising in connection to this
+    license. Notwithstanding the foregoing two (2) sentences, if Creative
+    Commons has expressly identified itself as the Licensor hereunder, it
+    shall have all rights and obligations of Licensor.
+
+    Except for the limited purpose of indicating to the public that the
+    Work is licensed under the CCPL, Creative Commons does not authorize
+    the use by either party of the trademark "Creative Commons" or any
+    related trademark or logo of Creative Commons without the prior
+    written consent of Creative Commons. Any permitted use will be in
+    compliance with Creative Commons' then-current trademark usage
+    guidelines, as may be published on its website or otherwise made
+    available upon request from time to time. For the avoidance of doubt,
+    this trademark restriction does not form part of this License.
+
+    Creative Commons may be contacted at http://creativecommons.org/.

+ 69 - 0
vendor/github.com/google/go-github/github/activity.go

@@ -0,0 +1,69 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import "context"
+
+// ActivityService handles communication with the activity related
+// methods of the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/
+type ActivityService service
+
+// FeedLink represents a link to a related resource.
+type FeedLink struct {
+	HRef *string `json:"href,omitempty"`
+	Type *string `json:"type,omitempty"`
+}
+
+// Feeds represents timeline resources in Atom format.
+type Feeds struct {
+	TimelineURL                 *string  `json:"timeline_url,omitempty"`
+	UserURL                     *string  `json:"user_url,omitempty"`
+	CurrentUserPublicURL        *string  `json:"current_user_public_url,omitempty"`
+	CurrentUserURL              *string  `json:"current_user_url,omitempty"`
+	CurrentUserActorURL         *string  `json:"current_user_actor_url,omitempty"`
+	CurrentUserOrganizationURL  *string  `json:"current_user_organization_url,omitempty"`
+	CurrentUserOrganizationURLs []string `json:"current_user_organization_urls,omitempty"`
+	Links                       *struct {
+		Timeline                 *FeedLink  `json:"timeline,omitempty"`
+		User                     *FeedLink  `json:"user,omitempty"`
+		CurrentUserPublic        *FeedLink  `json:"current_user_public,omitempty"`
+		CurrentUser              *FeedLink  `json:"current_user,omitempty"`
+		CurrentUserActor         *FeedLink  `json:"current_user_actor,omitempty"`
+		CurrentUserOrganization  *FeedLink  `json:"current_user_organization,omitempty"`
+		CurrentUserOrganizations []FeedLink `json:"current_user_organizations,omitempty"`
+	} `json:"_links,omitempty"`
+}
+
+// ListFeeds lists all the feeds available to the authenticated user.
+//
+// GitHub provides several timeline resources in Atom format:
+//     Timeline: The GitHub global public timeline
+//     User: The public timeline for any user, using URI template
+//     Current user public: The public timeline for the authenticated user
+//     Current user: The private timeline for the authenticated user
+//     Current user actor: The private timeline for activity created by the
+//         authenticated user
+//     Current user organizations: The private timeline for the organizations
+//         the authenticated user is a member of.
+//
+// Note: Private feeds are only returned when authenticating via Basic Auth
+// since current feed URIs use the older, non revocable auth tokens.
+func (s *ActivityService) ListFeeds(ctx context.Context) (*Feeds, *Response, error) {
+	req, err := s.client.NewRequest("GET", "feeds", nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	f := &Feeds{}
+	resp, err := s.client.Do(ctx, req, f)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return f, resp, nil
+}

+ 324 - 0
vendor/github.com/google/go-github/github/activity_events.go

@@ -0,0 +1,324 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"time"
+)
+
+// Event represents a GitHub event.
+type Event struct {
+	Type       *string          `json:"type,omitempty"`
+	Public     *bool            `json:"public,omitempty"`
+	RawPayload *json.RawMessage `json:"payload,omitempty"`
+	Repo       *Repository      `json:"repo,omitempty"`
+	Actor      *User            `json:"actor,omitempty"`
+	Org        *Organization    `json:"org,omitempty"`
+	CreatedAt  *time.Time       `json:"created_at,omitempty"`
+	ID         *string          `json:"id,omitempty"`
+}
+
+func (e Event) String() string {
+	return Stringify(e)
+}
+
+// ParsePayload parses the event payload. For recognized event types,
+// a value of the corresponding struct type will be returned.
+func (e *Event) ParsePayload() (payload interface{}, err error) {
+	switch *e.Type {
+	case "CommitCommentEvent":
+		payload = &CommitCommentEvent{}
+	case "CreateEvent":
+		payload = &CreateEvent{}
+	case "DeleteEvent":
+		payload = &DeleteEvent{}
+	case "DeploymentEvent":
+		payload = &DeploymentEvent{}
+	case "DeploymentStatusEvent":
+		payload = &DeploymentStatusEvent{}
+	case "ForkEvent":
+		payload = &ForkEvent{}
+	case "GollumEvent":
+		payload = &GollumEvent{}
+	case "InstallationEvent":
+		payload = &InstallationEvent{}
+	case "InstallationRepositoriesEvent":
+		payload = &InstallationRepositoriesEvent{}
+	case "IssueCommentEvent":
+		payload = &IssueCommentEvent{}
+	case "IssuesEvent":
+		payload = &IssuesEvent{}
+	case "LabelEvent":
+		payload = &LabelEvent{}
+	case "MarketplacePurchaseEvent":
+		payload = &MarketplacePurchaseEvent{}
+	case "MemberEvent":
+		payload = &MemberEvent{}
+	case "MembershipEvent":
+		payload = &MembershipEvent{}
+	case "MilestoneEvent":
+		payload = &MilestoneEvent{}
+	case "OrganizationEvent":
+		payload = &OrganizationEvent{}
+	case "OrgBlockEvent":
+		payload = &OrgBlockEvent{}
+	case "PageBuildEvent":
+		payload = &PageBuildEvent{}
+	case "PingEvent":
+		payload = &PingEvent{}
+	case "ProjectEvent":
+		payload = &ProjectEvent{}
+	case "ProjectCardEvent":
+		payload = &ProjectCardEvent{}
+	case "ProjectColumnEvent":
+		payload = &ProjectColumnEvent{}
+	case "PublicEvent":
+		payload = &PublicEvent{}
+	case "PullRequestEvent":
+		payload = &PullRequestEvent{}
+	case "PullRequestReviewEvent":
+		payload = &PullRequestReviewEvent{}
+	case "PullRequestReviewCommentEvent":
+		payload = &PullRequestReviewCommentEvent{}
+	case "PushEvent":
+		payload = &PushEvent{}
+	case "ReleaseEvent":
+		payload = &ReleaseEvent{}
+	case "RepositoryEvent":
+		payload = &RepositoryEvent{}
+	case "StatusEvent":
+		payload = &StatusEvent{}
+	case "TeamEvent":
+		payload = &TeamEvent{}
+	case "TeamAddEvent":
+		payload = &TeamAddEvent{}
+	case "WatchEvent":
+		payload = &WatchEvent{}
+	}
+	err = json.Unmarshal(*e.RawPayload, &payload)
+	return payload, err
+}
+
+// Payload returns the parsed event payload. For recognized event types,
+// a value of the corresponding struct type will be returned.
+//
+// Deprecated: Use ParsePayload instead, which returns an error
+// rather than panics if JSON unmarshaling raw payload fails.
+func (e *Event) Payload() (payload interface{}) {
+	var err error
+	payload, err = e.ParsePayload()
+	if err != nil {
+		panic(err)
+	}
+	return payload
+}
+
+// ListEvents drinks from the firehose of all public events across GitHub.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events
+func (s *ActivityService) ListEvents(ctx context.Context, opt *ListOptions) ([]*Event, *Response, error) {
+	u, err := addOptions("events", opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var events []*Event
+	resp, err := s.client.Do(ctx, req, &events)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return events, resp, nil
+}
+
+// ListRepositoryEvents lists events for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/#list-repository-events
+func (s *ActivityService) ListRepositoryEvents(ctx context.Context, owner, repo string, opt *ListOptions) ([]*Event, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/events", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var events []*Event
+	resp, err := s.client.Do(ctx, req, &events)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return events, resp, nil
+}
+
+// ListIssueEventsForRepository lists issue events for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/#list-issue-events-for-a-repository
+func (s *ActivityService) ListIssueEventsForRepository(ctx context.Context, owner, repo string, opt *ListOptions) ([]*IssueEvent, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/events", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var events []*IssueEvent
+	resp, err := s.client.Do(ctx, req, &events)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return events, resp, nil
+}
+
+// ListEventsForRepoNetwork lists public events for a network of repositories.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-a-network-of-repositories
+func (s *ActivityService) ListEventsForRepoNetwork(ctx context.Context, owner, repo string, opt *ListOptions) ([]*Event, *Response, error) {
+	u := fmt.Sprintf("networks/%v/%v/events", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var events []*Event
+	resp, err := s.client.Do(ctx, req, &events)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return events, resp, nil
+}
+
+// ListEventsForOrganization lists public events for an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/#list-public-events-for-an-organization
+func (s *ActivityService) ListEventsForOrganization(ctx context.Context, org string, opt *ListOptions) ([]*Event, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/events", org)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var events []*Event
+	resp, err := s.client.Do(ctx, req, &events)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return events, resp, nil
+}
+
+// ListEventsPerformedByUser lists the events performed by a user. If publicOnly is
+// true, only public events will be returned.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-performed-by-a-user
+func (s *ActivityService) ListEventsPerformedByUser(ctx context.Context, user string, publicOnly bool, opt *ListOptions) ([]*Event, *Response, error) {
+	var u string
+	if publicOnly {
+		u = fmt.Sprintf("users/%v/events/public", user)
+	} else {
+		u = fmt.Sprintf("users/%v/events", user)
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var events []*Event
+	resp, err := s.client.Do(ctx, req, &events)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return events, resp, nil
+}
+
+// ListEventsReceivedByUser lists the events received by a user. If publicOnly is
+// true, only public events will be returned.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-that-a-user-has-received
+func (s *ActivityService) ListEventsReceivedByUser(ctx context.Context, user string, publicOnly bool, opt *ListOptions) ([]*Event, *Response, error) {
+	var u string
+	if publicOnly {
+		u = fmt.Sprintf("users/%v/received_events/public", user)
+	} else {
+		u = fmt.Sprintf("users/%v/received_events", user)
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var events []*Event
+	resp, err := s.client.Do(ctx, req, &events)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return events, resp, nil
+}
+
+// ListUserEventsForOrganization provides the user’s organization dashboard. You
+// must be authenticated as the user to view this.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/#list-events-for-an-organization
+func (s *ActivityService) ListUserEventsForOrganization(ctx context.Context, org, user string, opt *ListOptions) ([]*Event, *Response, error) {
+	u := fmt.Sprintf("users/%v/events/orgs/%v", user, org)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var events []*Event
+	resp, err := s.client.Do(ctx, req, &events)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return events, resp, nil
+}

+ 223 - 0
vendor/github.com/google/go-github/github/activity_notifications.go

@@ -0,0 +1,223 @@
+// Copyright 2014 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// Notification identifies a GitHub notification for a user.
+type Notification struct {
+	ID         *string              `json:"id,omitempty"`
+	Repository *Repository          `json:"repository,omitempty"`
+	Subject    *NotificationSubject `json:"subject,omitempty"`
+
+	// Reason identifies the event that triggered the notification.
+	//
+	// GitHub API docs: https://developer.github.com/v3/activity/notifications/#notification-reasons
+	Reason *string `json:"reason,omitempty"`
+
+	Unread     *bool      `json:"unread,omitempty"`
+	UpdatedAt  *time.Time `json:"updated_at,omitempty"`
+	LastReadAt *time.Time `json:"last_read_at,omitempty"`
+	URL        *string    `json:"url,omitempty"`
+}
+
+// NotificationSubject identifies the subject of a notification.
+type NotificationSubject struct {
+	Title            *string `json:"title,omitempty"`
+	URL              *string `json:"url,omitempty"`
+	LatestCommentURL *string `json:"latest_comment_url,omitempty"`
+	Type             *string `json:"type,omitempty"`
+}
+
+// NotificationListOptions specifies the optional parameters to the
+// ActivityService.ListNotifications method.
+type NotificationListOptions struct {
+	All           bool      `url:"all,omitempty"`
+	Participating bool      `url:"participating,omitempty"`
+	Since         time.Time `url:"since,omitempty"`
+	Before        time.Time `url:"before,omitempty"`
+
+	ListOptions
+}
+
+// ListNotifications lists all notifications for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/notifications/#list-your-notifications
+func (s *ActivityService) ListNotifications(ctx context.Context, opt *NotificationListOptions) ([]*Notification, *Response, error) {
+	u := fmt.Sprintf("notifications")
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var notifications []*Notification
+	resp, err := s.client.Do(ctx, req, &notifications)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return notifications, resp, nil
+}
+
+// ListRepositoryNotifications lists all notifications in a given repository
+// for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/notifications/#list-your-notifications-in-a-repository
+func (s *ActivityService) ListRepositoryNotifications(ctx context.Context, owner, repo string, opt *NotificationListOptions) ([]*Notification, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/notifications", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var notifications []*Notification
+	resp, err := s.client.Do(ctx, req, &notifications)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return notifications, resp, nil
+}
+
+type markReadOptions struct {
+	LastReadAt time.Time `json:"last_read_at,omitempty"`
+}
+
+// MarkNotificationsRead marks all notifications up to lastRead as read.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/notifications/#mark-as-read
+func (s *ActivityService) MarkNotificationsRead(ctx context.Context, lastRead time.Time) (*Response, error) {
+	opts := &markReadOptions{
+		LastReadAt: lastRead,
+	}
+	req, err := s.client.NewRequest("PUT", "notifications", opts)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// MarkRepositoryNotificationsRead marks all notifications up to lastRead in
+// the specified repository as read.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/notifications/#mark-notifications-as-read-in-a-repository
+func (s *ActivityService) MarkRepositoryNotificationsRead(ctx context.Context, owner, repo string, lastRead time.Time) (*Response, error) {
+	opts := &markReadOptions{
+		LastReadAt: lastRead,
+	}
+	u := fmt.Sprintf("repos/%v/%v/notifications", owner, repo)
+	req, err := s.client.NewRequest("PUT", u, opts)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// GetThread gets the specified notification thread.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/notifications/#view-a-single-thread
+func (s *ActivityService) GetThread(ctx context.Context, id string) (*Notification, *Response, error) {
+	u := fmt.Sprintf("notifications/threads/%v", id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	notification := new(Notification)
+	resp, err := s.client.Do(ctx, req, notification)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return notification, resp, nil
+}
+
+// MarkThreadRead marks the specified thread as read.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/notifications/#mark-a-thread-as-read
+func (s *ActivityService) MarkThreadRead(ctx context.Context, id string) (*Response, error) {
+	u := fmt.Sprintf("notifications/threads/%v", id)
+
+	req, err := s.client.NewRequest("PATCH", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// GetThreadSubscription checks to see if the authenticated user is subscribed
+// to a thread.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/notifications/#get-a-thread-subscription
+func (s *ActivityService) GetThreadSubscription(ctx context.Context, id string) (*Subscription, *Response, error) {
+	u := fmt.Sprintf("notifications/threads/%v/subscription", id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	sub := new(Subscription)
+	resp, err := s.client.Do(ctx, req, sub)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return sub, resp, nil
+}
+
+// SetThreadSubscription sets the subscription for the specified thread for the
+// authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/notifications/#set-a-thread-subscription
+func (s *ActivityService) SetThreadSubscription(ctx context.Context, id string, subscription *Subscription) (*Subscription, *Response, error) {
+	u := fmt.Sprintf("notifications/threads/%v/subscription", id)
+
+	req, err := s.client.NewRequest("PUT", u, subscription)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	sub := new(Subscription)
+	resp, err := s.client.Do(ctx, req, sub)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return sub, resp, nil
+}
+
+// DeleteThreadSubscription deletes the subscription for the specified thread
+// for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/notifications/#delete-a-thread-subscription
+func (s *ActivityService) DeleteThreadSubscription(ctx context.Context, id string) (*Response, error) {
+	u := fmt.Sprintf("notifications/threads/%v/subscription", id)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}

+ 135 - 0
vendor/github.com/google/go-github/github/activity_star.go

@@ -0,0 +1,135 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// StarredRepository is returned by ListStarred.
+type StarredRepository struct {
+	StarredAt  *Timestamp  `json:"starred_at,omitempty"`
+	Repository *Repository `json:"repo,omitempty"`
+}
+
+// Stargazer represents a user that has starred a repository.
+type Stargazer struct {
+	StarredAt *Timestamp `json:"starred_at,omitempty"`
+	User      *User      `json:"user,omitempty"`
+}
+
+// ListStargazers lists people who have starred the specified repo.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/starring/#list-stargazers
+func (s *ActivityService) ListStargazers(ctx context.Context, owner, repo string, opt *ListOptions) ([]*Stargazer, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/stargazers", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeStarringPreview)
+
+	var stargazers []*Stargazer
+	resp, err := s.client.Do(ctx, req, &stargazers)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return stargazers, resp, nil
+}
+
+// ActivityListStarredOptions specifies the optional parameters to the
+// ActivityService.ListStarred method.
+type ActivityListStarredOptions struct {
+	// How to sort the repository list. Possible values are: created, updated,
+	// pushed, full_name. Default is "full_name".
+	Sort string `url:"sort,omitempty"`
+
+	// Direction in which to sort repositories. Possible values are: asc, desc.
+	// Default is "asc" when sort is "full_name", otherwise default is "desc".
+	Direction string `url:"direction,omitempty"`
+
+	ListOptions
+}
+
+// ListStarred lists all the repos starred by a user. Passing the empty string
+// will list the starred repositories for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/starring/#list-repositories-being-starred
+func (s *ActivityService) ListStarred(ctx context.Context, user string, opt *ActivityListStarredOptions) ([]*StarredRepository, *Response, error) {
+	var u string
+	if user != "" {
+		u = fmt.Sprintf("users/%v/starred", user)
+	} else {
+		u = "user/starred"
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeStarringPreview)
+
+	var repos []*StarredRepository
+	resp, err := s.client.Do(ctx, req, &repos)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repos, resp, nil
+}
+
+// IsStarred checks if a repository is starred by authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/starring/#check-if-you-are-starring-a-repository
+func (s *ActivityService) IsStarred(ctx context.Context, owner, repo string) (bool, *Response, error) {
+	u := fmt.Sprintf("user/starred/%v/%v", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return false, nil, err
+	}
+	resp, err := s.client.Do(ctx, req, nil)
+	starred, err := parseBoolResponse(err)
+	return starred, resp, err
+}
+
+// Star a repository as the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/starring/#star-a-repository
+func (s *ActivityService) Star(ctx context.Context, owner, repo string) (*Response, error) {
+	u := fmt.Sprintf("user/starred/%v/%v", owner, repo)
+	req, err := s.client.NewRequest("PUT", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
+
+// Unstar a repository as the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/starring/#unstar-a-repository
+func (s *ActivityService) Unstar(ctx context.Context, owner, repo string) (*Response, error) {
+	u := fmt.Sprintf("user/starred/%v/%v", owner, repo)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}

+ 146 - 0
vendor/github.com/google/go-github/github/activity_watching.go

@@ -0,0 +1,146 @@
+// Copyright 2014 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// Subscription identifies a repository or thread subscription.
+type Subscription struct {
+	Subscribed *bool      `json:"subscribed,omitempty"`
+	Ignored    *bool      `json:"ignored,omitempty"`
+	Reason     *string    `json:"reason,omitempty"`
+	CreatedAt  *Timestamp `json:"created_at,omitempty"`
+	URL        *string    `json:"url,omitempty"`
+
+	// only populated for repository subscriptions
+	RepositoryURL *string `json:"repository_url,omitempty"`
+
+	// only populated for thread subscriptions
+	ThreadURL *string `json:"thread_url,omitempty"`
+}
+
+// ListWatchers lists watchers of a particular repo.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/watching/#list-watchers
+func (s *ActivityService) ListWatchers(ctx context.Context, owner, repo string, opt *ListOptions) ([]*User, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/subscribers", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var watchers []*User
+	resp, err := s.client.Do(ctx, req, &watchers)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return watchers, resp, nil
+}
+
+// ListWatched lists the repositories the specified user is watching. Passing
+// the empty string will fetch watched repos for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/watching/#list-repositories-being-watched
+func (s *ActivityService) ListWatched(ctx context.Context, user string, opt *ListOptions) ([]*Repository, *Response, error) {
+	var u string
+	if user != "" {
+		u = fmt.Sprintf("users/%v/subscriptions", user)
+	} else {
+		u = "user/subscriptions"
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var watched []*Repository
+	resp, err := s.client.Do(ctx, req, &watched)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return watched, resp, nil
+}
+
+// GetRepositorySubscription returns the subscription for the specified
+// repository for the authenticated user. If the authenticated user is not
+// watching the repository, a nil Subscription is returned.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/watching/#get-a-repository-subscription
+func (s *ActivityService) GetRepositorySubscription(ctx context.Context, owner, repo string) (*Subscription, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/subscription", owner, repo)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	sub := new(Subscription)
+	resp, err := s.client.Do(ctx, req, sub)
+	if err != nil {
+		// if it's just a 404, don't return that as an error
+		_, err = parseBoolResponse(err)
+		return nil, resp, err
+	}
+
+	return sub, resp, nil
+}
+
+// SetRepositorySubscription sets the subscription for the specified repository
+// for the authenticated user.
+//
+// To watch a repository, set subscription.Subscribed to true.
+// To ignore notifications made within a repository, set subscription.Ignored to true.
+// To stop watching a repository, use DeleteRepositorySubscription.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/watching/#set-a-repository-subscription
+func (s *ActivityService) SetRepositorySubscription(ctx context.Context, owner, repo string, subscription *Subscription) (*Subscription, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/subscription", owner, repo)
+
+	req, err := s.client.NewRequest("PUT", u, subscription)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	sub := new(Subscription)
+	resp, err := s.client.Do(ctx, req, sub)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return sub, resp, nil
+}
+
+// DeleteRepositorySubscription deletes the subscription for the specified
+// repository for the authenticated user.
+//
+// This is used to stop watching a repository. To control whether or not to
+// receive notifications from a repository, use SetRepositorySubscription.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/watching/#delete-a-repository-subscription
+func (s *ActivityService) DeleteRepositorySubscription(ctx context.Context, owner, repo string) (*Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/subscription", owner, repo)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}

+ 101 - 0
vendor/github.com/google/go-github/github/admin.go

@@ -0,0 +1,101 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// AdminService handles communication with the admin related methods of the
+// GitHub API. These API routes are normally only accessible for GitHub
+// Enterprise installations.
+//
+// GitHub API docs: https://developer.github.com/v3/enterprise/
+type AdminService service
+
+// TeamLDAPMapping represents the mapping between a GitHub team and an LDAP group.
+type TeamLDAPMapping struct {
+	ID          *int64  `json:"id,omitempty"`
+	LDAPDN      *string `json:"ldap_dn,omitempty"`
+	URL         *string `json:"url,omitempty"`
+	Name        *string `json:"name,omitempty"`
+	Slug        *string `json:"slug,omitempty"`
+	Description *string `json:"description,omitempty"`
+	Privacy     *string `json:"privacy,omitempty"`
+	Permission  *string `json:"permission,omitempty"`
+
+	MembersURL      *string `json:"members_url,omitempty"`
+	RepositoriesURL *string `json:"repositories_url,omitempty"`
+}
+
+func (m TeamLDAPMapping) String() string {
+	return Stringify(m)
+}
+
+// UserLDAPMapping represents the mapping between a GitHub user and an LDAP user.
+type UserLDAPMapping struct {
+	ID         *int64  `json:"id,omitempty"`
+	LDAPDN     *string `json:"ldap_dn,omitempty"`
+	Login      *string `json:"login,omitempty"`
+	AvatarURL  *string `json:"avatar_url,omitempty"`
+	GravatarID *string `json:"gravatar_id,omitempty"`
+	Type       *string `json:"type,omitempty"`
+	SiteAdmin  *bool   `json:"site_admin,omitempty"`
+
+	URL               *string `json:"url,omitempty"`
+	EventsURL         *string `json:"events_url,omitempty"`
+	FollowingURL      *string `json:"following_url,omitempty"`
+	FollowersURL      *string `json:"followers_url,omitempty"`
+	GistsURL          *string `json:"gists_url,omitempty"`
+	OrganizationsURL  *string `json:"organizations_url,omitempty"`
+	ReceivedEventsURL *string `json:"received_events_url,omitempty"`
+	ReposURL          *string `json:"repos_url,omitempty"`
+	StarredURL        *string `json:"starred_url,omitempty"`
+	SubscriptionsURL  *string `json:"subscriptions_url,omitempty"`
+}
+
+func (m UserLDAPMapping) String() string {
+	return Stringify(m)
+}
+
+// UpdateUserLDAPMapping updates the mapping between a GitHub user and an LDAP user.
+//
+// GitHub API docs: https://developer.github.com/v3/enterprise/ldap/#update-ldap-mapping-for-a-user
+func (s *AdminService) UpdateUserLDAPMapping(ctx context.Context, user string, mapping *UserLDAPMapping) (*UserLDAPMapping, *Response, error) {
+	u := fmt.Sprintf("admin/ldap/users/%v/mapping", user)
+	req, err := s.client.NewRequest("PATCH", u, mapping)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	m := new(UserLDAPMapping)
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// UpdateTeamLDAPMapping updates the mapping between a GitHub team and an LDAP group.
+//
+// GitHub API docs: https://developer.github.com/v3/enterprise/ldap/#update-ldap-mapping-for-a-team
+func (s *AdminService) UpdateTeamLDAPMapping(ctx context.Context, team int64, mapping *TeamLDAPMapping) (*TeamLDAPMapping, *Response, error) {
+	u := fmt.Sprintf("admin/ldap/teams/%v/mapping", team)
+	req, err := s.client.NewRequest("PATCH", u, mapping)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	m := new(TeamLDAPMapping)
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}

+ 171 - 0
vendor/github.com/google/go-github/github/admin_stats.go

@@ -0,0 +1,171 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// AdminStats represents a variety of stats of a Github Enterprise
+// installation.
+type AdminStats struct {
+	Issues     *IssueStats     `json:"issues,omitempty"`
+	Hooks      *HookStats      `json:"hooks,omitempty"`
+	Milestones *MilestoneStats `json:"milestones,omitempty"`
+	Orgs       *OrgStats       `json:"orgs,omitempty"`
+	Comments   *CommentStats   `json:"comments,omitempty"`
+	Pages      *PageStats      `json:"pages,omitempty"`
+	Users      *UserStats      `json:"users,omitempty"`
+	Gists      *GistStats      `json:"gists,omitempty"`
+	Pulls      *PullStats      `json:"pulls,omitempty"`
+	Repos      *RepoStats      `json:"repos,omitempty"`
+}
+
+func (s AdminStats) String() string {
+	return Stringify(s)
+}
+
+// IssueStats represents the number of total, open and closed issues.
+type IssueStats struct {
+	TotalIssues  *int `json:"total_issues,omitempty"`
+	OpenIssues   *int `json:"open_issues,omitempty"`
+	ClosedIssues *int `json:"closed_issues,omitempty"`
+}
+
+func (s IssueStats) String() string {
+	return Stringify(s)
+}
+
+// HookStats represents the number of total, active and inactive hooks.
+type HookStats struct {
+	TotalHooks    *int `json:"total_hooks,omitempty"`
+	ActiveHooks   *int `json:"active_hooks,omitempty"`
+	InactiveHooks *int `json:"inactive_hooks,omitempty"`
+}
+
+func (s HookStats) String() string {
+	return Stringify(s)
+}
+
+// MilestoneStats represents the number of total, open and close milestones.
+type MilestoneStats struct {
+	TotalMilestones  *int `json:"total_milestones,omitempty"`
+	OpenMilestones   *int `json:"open_milestones,omitempty"`
+	ClosedMilestones *int `json:"closed_milestones,omitempty"`
+}
+
+func (s MilestoneStats) String() string {
+	return Stringify(s)
+}
+
+// OrgStats represents the number of total, disabled organizations and the team
+// and team member count.
+type OrgStats struct {
+	TotalOrgs        *int `json:"total_orgs,omitempty"`
+	DisabledOrgs     *int `json:"disabled_orgs,omitempty"`
+	TotalTeams       *int `json:"total_teams,omitempty"`
+	TotalTeamMembers *int `json:"total_team_members,omitempty"`
+}
+
+func (s OrgStats) String() string {
+	return Stringify(s)
+}
+
+// CommentStats represents the number of total comments on commits, gists, issues
+// and pull requests.
+type CommentStats struct {
+	TotalCommitComments      *int `json:"total_commit_comments,omitempty"`
+	TotalGistComments        *int `json:"total_gist_comments,omitempty"`
+	TotalIssueComments       *int `json:"total_issue_comments,omitempty"`
+	TotalPullRequestComments *int `json:"total_pull_request_comments,omitempty"`
+}
+
+func (s CommentStats) String() string {
+	return Stringify(s)
+}
+
+// PageStats represents the total number of github pages.
+type PageStats struct {
+	TotalPages *int `json:"total_pages,omitempty"`
+}
+
+func (s PageStats) String() string {
+	return Stringify(s)
+}
+
+// UserStats represents the number of total, admin and suspended users.
+type UserStats struct {
+	TotalUsers     *int `json:"total_users,omitempty"`
+	AdminUsers     *int `json:"admin_users,omitempty"`
+	SuspendedUsers *int `json:"suspended_users,omitempty"`
+}
+
+func (s UserStats) String() string {
+	return Stringify(s)
+}
+
+//GistStats represents the number of total, private and public gists.
+type GistStats struct {
+	TotalGists   *int `json:"total_gists,omitempty"`
+	PrivateGists *int `json:"private_gists,omitempty"`
+	PublicGists  *int `json:"public_gists,omitempty"`
+}
+
+func (s GistStats) String() string {
+	return Stringify(s)
+}
+
+// PullStats represents the number of total, merged, mergable and unmergeable
+// pull-requests.
+type PullStats struct {
+	TotalPulls      *int `json:"total_pulls,omitempty"`
+	MergedPulls     *int `json:"merged_pulls,omitempty"`
+	MergablePulls   *int `json:"mergeable_pulls,omitempty"`
+	UnmergablePulls *int `json:"unmergeable_pulls,omitempty"`
+}
+
+func (s PullStats) String() string {
+	return Stringify(s)
+}
+
+// RepoStats represents the number of total, root, fork, organization repositories
+// together with the total number of pushes and wikis.
+type RepoStats struct {
+	TotalRepos  *int `json:"total_repos,omitempty"`
+	RootRepos   *int `json:"root_repos,omitempty"`
+	ForkRepos   *int `json:"fork_repos,omitempty"`
+	OrgRepos    *int `json:"org_repos,omitempty"`
+	TotalPushes *int `json:"total_pushes,omitempty"`
+	TotalWikis  *int `json:"total_wikis,omitempty"`
+}
+
+func (s RepoStats) String() string {
+	return Stringify(s)
+}
+
+// GetAdminStats returns a variety of metrics about a Github Enterprise
+// installation.
+//
+// Please note that this is only available to site administrators,
+// otherwise it will error with a 404 not found (instead of 401 or 403).
+//
+// GitHub API docs: https://developer.github.com/v3/enterprise-admin/admin_stats/
+func (s *AdminService) GetAdminStats(ctx context.Context) (*AdminStats, *Response, error) {
+	u := fmt.Sprintf("enterprise/stats/all")
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	m := new(AdminStats)
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}

+ 169 - 0
vendor/github.com/google/go-github/github/apps.go

@@ -0,0 +1,169 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// AppsService provides access to the installation related functions
+// in the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/
+type AppsService service
+
+// App represents a GitHub App.
+type App struct {
+	ID          *int64     `json:"id,omitempty"`
+	Owner       *User      `json:"owner,omitempty"`
+	Name        *string    `json:"name,omitempty"`
+	Description *string    `json:"description,omitempty"`
+	ExternalURL *string    `json:"external_url,omitempty"`
+	HTMLURL     *string    `json:"html_url,omitempty"`
+	CreatedAt   *time.Time `json:"created_at,omitempty"`
+	UpdatedAt   *time.Time `json:"updated_at,omitempty"`
+}
+
+// InstallationToken represents an installation token.
+type InstallationToken struct {
+	Token     *string    `json:"token,omitempty"`
+	ExpiresAt *time.Time `json:"expires_at,omitempty"`
+}
+
+// Get a single GitHub App. Passing the empty string will get
+// the authenticated GitHub App.
+//
+// Note: appSlug is just the URL-friendly name of your GitHub App.
+// You can find this on the settings page for your GitHub App
+// (e.g., https://github.com/settings/apps/:app_slug).
+//
+// GitHub API docs: https://developer.github.com/v3/apps/#get-a-single-github-app
+func (s *AppsService) Get(ctx context.Context, appSlug string) (*App, *Response, error) {
+	var u string
+	if appSlug != "" {
+		u = fmt.Sprintf("apps/%v", appSlug)
+	} else {
+		u = "app"
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeIntegrationPreview)
+
+	app := new(App)
+	resp, err := s.client.Do(ctx, req, app)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return app, resp, nil
+}
+
+// ListInstallations lists the installations that the current GitHub App has.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/#find-installations
+func (s *AppsService) ListInstallations(ctx context.Context, opt *ListOptions) ([]*Installation, *Response, error) {
+	u, err := addOptions("app/installations", opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeIntegrationPreview)
+
+	var i []*Installation
+	resp, err := s.client.Do(ctx, req, &i)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return i, resp, nil
+}
+
+// GetInstallation returns the specified installation.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/#get-a-single-installation
+func (s *AppsService) GetInstallation(ctx context.Context, id int64) (*Installation, *Response, error) {
+	u := fmt.Sprintf("app/installations/%v", id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeIntegrationPreview)
+
+	i := new(Installation)
+	resp, err := s.client.Do(ctx, req, i)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return i, resp, nil
+}
+
+// ListUserInstallations lists installations that are accessible to the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/#list-installations-for-user
+func (s *AppsService) ListUserInstallations(ctx context.Context, opt *ListOptions) ([]*Installation, *Response, error) {
+	u, err := addOptions("user/installations", opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeIntegrationPreview)
+
+	var i struct {
+		Installations []*Installation `json:"installations"`
+	}
+	resp, err := s.client.Do(ctx, req, &i)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return i.Installations, resp, nil
+}
+
+// CreateInstallationToken creates a new installation token.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/#create-a-new-installation-token
+func (s *AppsService) CreateInstallationToken(ctx context.Context, id int64) (*InstallationToken, *Response, error) {
+	u := fmt.Sprintf("installations/%v/access_tokens", id)
+
+	req, err := s.client.NewRequest("POST", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeIntegrationPreview)
+
+	t := new(InstallationToken)
+	resp, err := s.client.Do(ctx, req, t)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return t, resp, nil
+}

+ 114 - 0
vendor/github.com/google/go-github/github/apps_installation.go

@@ -0,0 +1,114 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// Installation represents a GitHub Apps installation.
+type Installation struct {
+	ID              *int64  `json:"id,omitempty"`
+	Account         *User   `json:"account,omitempty"`
+	AccessTokensURL *string `json:"access_tokens_url,omitempty"`
+	RepositoriesURL *string `json:"repositories_url,omitempty"`
+	HTMLURL         *string `json:"html_url,omitempty"`
+}
+
+func (i Installation) String() string {
+	return Stringify(i)
+}
+
+// ListRepos lists the repositories that are accessible to the authenticated installation.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/installations/#list-repositories
+func (s *AppsService) ListRepos(ctx context.Context, opt *ListOptions) ([]*Repository, *Response, error) {
+	u, err := addOptions("installation/repositories", opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeIntegrationPreview)
+
+	var r struct {
+		Repositories []*Repository `json:"repositories"`
+	}
+	resp, err := s.client.Do(ctx, req, &r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r.Repositories, resp, nil
+}
+
+// ListUserRepos lists repositories that are accessible
+// to the authenticated user for an installation.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/installations/#list-repositories-accessible-to-the-user-for-an-installation
+func (s *AppsService) ListUserRepos(ctx context.Context, id int64, opt *ListOptions) ([]*Repository, *Response, error) {
+	u := fmt.Sprintf("user/installations/%v/repositories", id)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeIntegrationPreview)
+
+	var r struct {
+		Repositories []*Repository `json:"repositories"`
+	}
+	resp, err := s.client.Do(ctx, req, &r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r.Repositories, resp, nil
+}
+
+// AddRepository adds a single repository to an installation.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/installations/#add-repository-to-installation
+func (s *AppsService) AddRepository(ctx context.Context, instID, repoID int64) (*Repository, *Response, error) {
+	u := fmt.Sprintf("apps/installations/%v/repositories/%v", instID, repoID)
+	req, err := s.client.NewRequest("PUT", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r := new(Repository)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// RemoveRepository removes a single repository from an installation.
+//
+// GitHub docs: https://developer.github.com/v3/apps/installations/#remove-repository-from-installation
+func (s *AppsService) RemoveRepository(ctx context.Context, instID, repoID int64) (*Response, error) {
+	u := fmt.Sprintf("apps/installations/%v/repositories/%v", instID, repoID)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}

+ 180 - 0
vendor/github.com/google/go-github/github/apps_marketplace.go

@@ -0,0 +1,180 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// MarketplaceService handles communication with the marketplace related
+// methods of the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/marketplace/
+type MarketplaceService struct {
+	client *Client
+	// Stubbed controls whether endpoints that return stubbed data are used
+	// instead of production endpoints. Stubbed data is fake data that's useful
+	// for testing your GitHub Apps. Stubbed data is hard-coded and will not
+	// change based on actual subscriptions.
+	//
+	// GitHub API docs: https://developer.github.com/v3/apps/marketplace/
+	Stubbed bool
+}
+
+// MarketplacePlan represents a GitHub Apps Marketplace Listing Plan.
+type MarketplacePlan struct {
+	URL                 *string   `json:"url,omitempty"`
+	AccountsURL         *string   `json:"accounts_url,omitempty"`
+	ID                  *int64    `json:"id,omitempty"`
+	Name                *string   `json:"name,omitempty"`
+	Description         *string   `json:"description,omitempty"`
+	MonthlyPriceInCents *int      `json:"monthly_price_in_cents,omitempty"`
+	YearlyPriceInCents  *int      `json:"yearly_price_in_cents,omitempty"`
+	PriceModel          *string   `json:"price_model,omitempty"`
+	UnitName            *string   `json:"unit_name,omitempty"`
+	Bullets             *[]string `json:"bullets,omitempty"`
+}
+
+// MarketplacePurchase represents a GitHub Apps Marketplace Purchase.
+type MarketplacePurchase struct {
+	BillingCycle    *string                 `json:"billing_cycle,omitempty"`
+	NextBillingDate *string                 `json:"next_billing_date,omitempty"`
+	UnitCount       *int                    `json:"unit_count,omitempty"`
+	Plan            *MarketplacePlan        `json:"plan,omitempty"`
+	Account         *MarketplacePlanAccount `json:"account,omitempty"`
+}
+
+// MarketplacePlanAccount represents a GitHub Account (user or organization) on a specific plan.
+type MarketplacePlanAccount struct {
+	URL                      *string              `json:"url,omitempty"`
+	Type                     *string              `json:"type,omitempty"`
+	ID                       *int64               `json:"id,omitempty"`
+	Login                    *string              `json:"login,omitempty"`
+	Email                    *string              `json:"email,omitempty"`
+	OrganizationBillingEmail *string              `json:"organization_billing_email,omitempty"`
+	MarketplacePurchase      *MarketplacePurchase `json:"marketplace_purchase,omitempty"`
+}
+
+// ListPlans lists all plans for your Marketplace listing.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#list-all-plans-for-your-marketplace-listing
+func (s *MarketplaceService) ListPlans(ctx context.Context, opt *ListOptions) ([]*MarketplacePlan, *Response, error) {
+	uri := s.marketplaceURI("plans")
+	u, err := addOptions(uri, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMarketplacePreview)
+
+	var plans []*MarketplacePlan
+	resp, err := s.client.Do(ctx, req, &plans)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return plans, resp, nil
+}
+
+// ListPlanAccountsForPlan lists all GitHub accounts (user or organization) on a specific plan.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#list-all-github-accounts-user-or-organization-on-a-specific-plan
+func (s *MarketplaceService) ListPlanAccountsForPlan(ctx context.Context, planID int64, opt *ListOptions) ([]*MarketplacePlanAccount, *Response, error) {
+	uri := s.marketplaceURI(fmt.Sprintf("plans/%v/accounts", planID))
+	u, err := addOptions(uri, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMarketplacePreview)
+
+	var accounts []*MarketplacePlanAccount
+	resp, err := s.client.Do(ctx, req, &accounts)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return accounts, resp, nil
+}
+
+// ListPlanAccountsForAccount lists all GitHub accounts (user or organization) associated with an account.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#check-if-a-github-account-is-associated-with-any-marketplace-listing
+func (s *MarketplaceService) ListPlanAccountsForAccount(ctx context.Context, accountID int64, opt *ListOptions) ([]*MarketplacePlanAccount, *Response, error) {
+	uri := s.marketplaceURI(fmt.Sprintf("accounts/%v", accountID))
+	u, err := addOptions(uri, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMarketplacePreview)
+
+	var accounts []*MarketplacePlanAccount
+	resp, err := s.client.Do(ctx, req, &accounts)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return accounts, resp, nil
+}
+
+// ListMarketplacePurchasesForUser lists all GitHub marketplace purchases made by a user.
+//
+// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#get-a-users-marketplace-purchases
+func (s *MarketplaceService) ListMarketplacePurchasesForUser(ctx context.Context, opt *ListOptions) ([]*MarketplacePurchase, *Response, error) {
+	uri := "user/marketplace_purchases"
+	if s.Stubbed {
+		uri = "user/marketplace_purchases/stubbed"
+	}
+
+	u, err := addOptions(uri, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMarketplacePreview)
+
+	var purchases []*MarketplacePurchase
+	resp, err := s.client.Do(ctx, req, &purchases)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return purchases, resp, nil
+}
+
+func (s *MarketplaceService) marketplaceURI(endpoint string) string {
+	url := "marketplace_listing"
+	if s.Stubbed {
+		url = "marketplace_listing/stubbed"
+	}
+	return url + "/" + endpoint
+}

+ 435 - 0
vendor/github.com/google/go-github/github/authorizations.go

@@ -0,0 +1,435 @@
+// Copyright 2015 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// Scope models a GitHub authorization scope.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth/#scopes
+type Scope string
+
+// This is the set of scopes for GitHub API V3
+const (
+	ScopeNone           Scope = "(no scope)" // REVISIT: is this actually returned, or just a documentation artifact?
+	ScopeUser           Scope = "user"
+	ScopeUserEmail      Scope = "user:email"
+	ScopeUserFollow     Scope = "user:follow"
+	ScopePublicRepo     Scope = "public_repo"
+	ScopeRepo           Scope = "repo"
+	ScopeRepoDeployment Scope = "repo_deployment"
+	ScopeRepoStatus     Scope = "repo:status"
+	ScopeDeleteRepo     Scope = "delete_repo"
+	ScopeNotifications  Scope = "notifications"
+	ScopeGist           Scope = "gist"
+	ScopeReadRepoHook   Scope = "read:repo_hook"
+	ScopeWriteRepoHook  Scope = "write:repo_hook"
+	ScopeAdminRepoHook  Scope = "admin:repo_hook"
+	ScopeAdminOrgHook   Scope = "admin:org_hook"
+	ScopeReadOrg        Scope = "read:org"
+	ScopeWriteOrg       Scope = "write:org"
+	ScopeAdminOrg       Scope = "admin:org"
+	ScopeReadPublicKey  Scope = "read:public_key"
+	ScopeWritePublicKey Scope = "write:public_key"
+	ScopeAdminPublicKey Scope = "admin:public_key"
+	ScopeReadGPGKey     Scope = "read:gpg_key"
+	ScopeWriteGPGKey    Scope = "write:gpg_key"
+	ScopeAdminGPGKey    Scope = "admin:gpg_key"
+)
+
+// AuthorizationsService handles communication with the authorization related
+// methods of the GitHub API.
+//
+// This service requires HTTP Basic Authentication; it cannot be accessed using
+// an OAuth token.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/
+type AuthorizationsService service
+
+// Authorization represents an individual GitHub authorization.
+type Authorization struct {
+	ID             *int64            `json:"id,omitempty"`
+	URL            *string           `json:"url,omitempty"`
+	Scopes         []Scope           `json:"scopes,omitempty"`
+	Token          *string           `json:"token,omitempty"`
+	TokenLastEight *string           `json:"token_last_eight,omitempty"`
+	HashedToken    *string           `json:"hashed_token,omitempty"`
+	App            *AuthorizationApp `json:"app,omitempty"`
+	Note           *string           `json:"note,omitempty"`
+	NoteURL        *string           `json:"note_url,omitempty"`
+	UpdatedAt      *Timestamp        `json:"updated_at,omitempty"`
+	CreatedAt      *Timestamp        `json:"created_at,omitempty"`
+	Fingerprint    *string           `json:"fingerprint,omitempty"`
+
+	// User is only populated by the Check and Reset methods.
+	User *User `json:"user,omitempty"`
+}
+
+func (a Authorization) String() string {
+	return Stringify(a)
+}
+
+// AuthorizationApp represents an individual GitHub app (in the context of authorization).
+type AuthorizationApp struct {
+	URL      *string `json:"url,omitempty"`
+	Name     *string `json:"name,omitempty"`
+	ClientID *string `json:"client_id,omitempty"`
+}
+
+func (a AuthorizationApp) String() string {
+	return Stringify(a)
+}
+
+// Grant represents an OAuth application that has been granted access to an account.
+type Grant struct {
+	ID        *int64            `json:"id,omitempty"`
+	URL       *string           `json:"url,omitempty"`
+	App       *AuthorizationApp `json:"app,omitempty"`
+	CreatedAt *Timestamp        `json:"created_at,omitempty"`
+	UpdatedAt *Timestamp        `json:"updated_at,omitempty"`
+	Scopes    []string          `json:"scopes,omitempty"`
+}
+
+func (g Grant) String() string {
+	return Stringify(g)
+}
+
+// AuthorizationRequest represents a request to create an authorization.
+type AuthorizationRequest struct {
+	Scopes       []Scope `json:"scopes,omitempty"`
+	Note         *string `json:"note,omitempty"`
+	NoteURL      *string `json:"note_url,omitempty"`
+	ClientID     *string `json:"client_id,omitempty"`
+	ClientSecret *string `json:"client_secret,omitempty"`
+	Fingerprint  *string `json:"fingerprint,omitempty"`
+}
+
+func (a AuthorizationRequest) String() string {
+	return Stringify(a)
+}
+
+// AuthorizationUpdateRequest represents a request to update an authorization.
+//
+// Note that for any one update, you must only provide one of the "scopes"
+// fields. That is, you may provide only one of "Scopes", or "AddScopes", or
+// "RemoveScopes".
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#update-an-existing-authorization
+type AuthorizationUpdateRequest struct {
+	Scopes       []string `json:"scopes,omitempty"`
+	AddScopes    []string `json:"add_scopes,omitempty"`
+	RemoveScopes []string `json:"remove_scopes,omitempty"`
+	Note         *string  `json:"note,omitempty"`
+	NoteURL      *string  `json:"note_url,omitempty"`
+	Fingerprint  *string  `json:"fingerprint,omitempty"`
+}
+
+func (a AuthorizationUpdateRequest) String() string {
+	return Stringify(a)
+}
+
+// List the authorizations for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#list-your-authorizations
+func (s *AuthorizationsService) List(ctx context.Context, opt *ListOptions) ([]*Authorization, *Response, error) {
+	u := "authorizations"
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var auths []*Authorization
+	resp, err := s.client.Do(ctx, req, &auths)
+	if err != nil {
+		return nil, resp, err
+	}
+	return auths, resp, nil
+}
+
+// Get a single authorization.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#get-a-single-authorization
+func (s *AuthorizationsService) Get(ctx context.Context, id int64) (*Authorization, *Response, error) {
+	u := fmt.Sprintf("authorizations/%d", id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	a := new(Authorization)
+	resp, err := s.client.Do(ctx, req, a)
+	if err != nil {
+		return nil, resp, err
+	}
+	return a, resp, nil
+}
+
+// Create a new authorization for the specified OAuth application.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#create-a-new-authorization
+func (s *AuthorizationsService) Create(ctx context.Context, auth *AuthorizationRequest) (*Authorization, *Response, error) {
+	u := "authorizations"
+
+	req, err := s.client.NewRequest("POST", u, auth)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	a := new(Authorization)
+	resp, err := s.client.Do(ctx, req, a)
+	if err != nil {
+		return nil, resp, err
+	}
+	return a, resp, nil
+}
+
+// GetOrCreateForApp creates a new authorization for the specified OAuth
+// application, only if an authorization for that application doesn’t already
+// exist for the user.
+//
+// If a new token is created, the HTTP status code will be "201 Created", and
+// the returned Authorization.Token field will be populated. If an existing
+// token is returned, the status code will be "200 OK" and the
+// Authorization.Token field will be empty.
+//
+// clientID is the OAuth Client ID with which to create the token.
+//
+// GitHub API docs:
+// https://developer.github.com/v3/oauth_authorizations/#get-or-create-an-authorization-for-a-specific-app
+// https://developer.github.com/v3/oauth_authorizations/#get-or-create-an-authorization-for-a-specific-app-and-fingerprint
+func (s *AuthorizationsService) GetOrCreateForApp(ctx context.Context, clientID string, auth *AuthorizationRequest) (*Authorization, *Response, error) {
+	var u string
+	if auth.Fingerprint == nil || *auth.Fingerprint == "" {
+		u = fmt.Sprintf("authorizations/clients/%v", clientID)
+	} else {
+		u = fmt.Sprintf("authorizations/clients/%v/%v", clientID, *auth.Fingerprint)
+	}
+
+	req, err := s.client.NewRequest("PUT", u, auth)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	a := new(Authorization)
+	resp, err := s.client.Do(ctx, req, a)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return a, resp, nil
+}
+
+// Edit a single authorization.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#update-an-existing-authorization
+func (s *AuthorizationsService) Edit(ctx context.Context, id int64, auth *AuthorizationUpdateRequest) (*Authorization, *Response, error) {
+	u := fmt.Sprintf("authorizations/%d", id)
+
+	req, err := s.client.NewRequest("PATCH", u, auth)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	a := new(Authorization)
+	resp, err := s.client.Do(ctx, req, a)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return a, resp, nil
+}
+
+// Delete a single authorization.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#delete-an-authorization
+func (s *AuthorizationsService) Delete(ctx context.Context, id int64) (*Response, error) {
+	u := fmt.Sprintf("authorizations/%d", id)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// Check if an OAuth token is valid for a specific app.
+//
+// Note that this operation requires the use of BasicAuth, but where the
+// username is the OAuth application clientID, and the password is its
+// clientSecret. Invalid tokens will return a 404 Not Found.
+//
+// The returned Authorization.User field will be populated.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#check-an-authorization
+func (s *AuthorizationsService) Check(ctx context.Context, clientID string, token string) (*Authorization, *Response, error) {
+	u := fmt.Sprintf("applications/%v/tokens/%v", clientID, token)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	a := new(Authorization)
+	resp, err := s.client.Do(ctx, req, a)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return a, resp, nil
+}
+
+// Reset is used to reset a valid OAuth token without end user involvement.
+// Applications must save the "token" property in the response, because changes
+// take effect immediately.
+//
+// Note that this operation requires the use of BasicAuth, but where the
+// username is the OAuth application clientID, and the password is its
+// clientSecret. Invalid tokens will return a 404 Not Found.
+//
+// The returned Authorization.User field will be populated.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#reset-an-authorization
+func (s *AuthorizationsService) Reset(ctx context.Context, clientID string, token string) (*Authorization, *Response, error) {
+	u := fmt.Sprintf("applications/%v/tokens/%v", clientID, token)
+
+	req, err := s.client.NewRequest("POST", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	a := new(Authorization)
+	resp, err := s.client.Do(ctx, req, a)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return a, resp, nil
+}
+
+// Revoke an authorization for an application.
+//
+// Note that this operation requires the use of BasicAuth, but where the
+// username is the OAuth application clientID, and the password is its
+// clientSecret. Invalid tokens will return a 404 Not Found.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#revoke-an-authorization-for-an-application
+func (s *AuthorizationsService) Revoke(ctx context.Context, clientID string, token string) (*Response, error) {
+	u := fmt.Sprintf("applications/%v/tokens/%v", clientID, token)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ListGrants lists the set of OAuth applications that have been granted
+// access to a user's account. This will return one entry for each application
+// that has been granted access to the account, regardless of the number of
+// tokens an application has generated for the user.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#list-your-grants
+func (s *AuthorizationsService) ListGrants(ctx context.Context, opt *ListOptions) ([]*Grant, *Response, error) {
+	u, err := addOptions("applications/grants", opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	grants := []*Grant{}
+	resp, err := s.client.Do(ctx, req, &grants)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return grants, resp, nil
+}
+
+// GetGrant gets a single OAuth application grant.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#get-a-single-grant
+func (s *AuthorizationsService) GetGrant(ctx context.Context, id int64) (*Grant, *Response, error) {
+	u := fmt.Sprintf("applications/grants/%d", id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	grant := new(Grant)
+	resp, err := s.client.Do(ctx, req, grant)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return grant, resp, nil
+}
+
+// DeleteGrant deletes an OAuth application grant. Deleting an application's
+// grant will also delete all OAuth tokens associated with the application for
+// the user.
+//
+// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#delete-a-grant
+func (s *AuthorizationsService) DeleteGrant(ctx context.Context, id int64) (*Response, error) {
+	u := fmt.Sprintf("applications/grants/%d", id)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// CreateImpersonation creates an impersonation OAuth token.
+//
+// This requires admin permissions. With the returned Authorization.Token
+// you can e.g. create or delete a user's public SSH key. NOTE: creating a
+// new token automatically revokes an existing one.
+//
+// GitHub API docs: https://developer.github.com/enterprise/2.5/v3/users/administration/#create-an-impersonation-oauth-token
+func (s *AuthorizationsService) CreateImpersonation(ctx context.Context, username string, authReq *AuthorizationRequest) (*Authorization, *Response, error) {
+	u := fmt.Sprintf("admin/users/%v/authorizations", username)
+	req, err := s.client.NewRequest("POST", u, authReq)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	a := new(Authorization)
+	resp, err := s.client.Do(ctx, req, a)
+	if err != nil {
+		return nil, resp, err
+	}
+	return a, resp, nil
+}
+
+// DeleteImpersonation deletes an impersonation OAuth token.
+//
+// NOTE: there can be only one at a time.
+//
+// GitHub API docs: https://developer.github.com/enterprise/2.5/v3/users/administration/#delete-an-impersonation-oauth-token
+func (s *AuthorizationsService) DeleteImpersonation(ctx context.Context, username string) (*Response, error) {
+	u := fmt.Sprintf("admin/users/%v/authorizations", username)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}

+ 191 - 0
vendor/github.com/google/go-github/github/doc.go

@@ -0,0 +1,191 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package github provides a client for using the GitHub API.
+
+Usage:
+
+	import "github.com/google/go-github/github"
+
+Construct a new GitHub client, then use the various services on the client to
+access different parts of the GitHub API. For example:
+
+	client := github.NewClient(nil)
+
+	// list all organizations for user "willnorris"
+	orgs, _, err := client.Organizations.List(ctx, "willnorris", nil)
+
+Some API methods have optional parameters that can be passed. For example:
+
+	client := github.NewClient(nil)
+
+	// list public repositories for org "github"
+	opt := &github.RepositoryListByOrgOptions{Type: "public"}
+	repos, _, err := client.Repositories.ListByOrg(ctx, "github", opt)
+
+The services of a client divide the API into logical chunks and correspond to
+the structure of the GitHub API documentation at
+https://developer.github.com/v3/.
+
+Authentication
+
+The go-github library does not directly handle authentication. Instead, when
+creating a new client, pass an http.Client that can handle authentication for
+you. The easiest and recommended way to do this is using the golang.org/x/oauth2
+library, but you can always use any other library that provides an http.Client.
+If you have an OAuth2 access token (for example, a personal API token), you can
+use it with the oauth2 library using:
+
+	import "golang.org/x/oauth2"
+
+	func main() {
+		ctx := context.Background()
+		ts := oauth2.StaticTokenSource(
+			&oauth2.Token{AccessToken: "... your access token ..."},
+		)
+		tc := oauth2.NewClient(ctx, ts)
+
+		client := github.NewClient(tc)
+
+		// list all repositories for the authenticated user
+		repos, _, err := client.Repositories.List(ctx, "", nil)
+	}
+
+Note that when using an authenticated Client, all calls made by the client will
+include the specified OAuth token. Therefore, authenticated clients should
+almost never be shared between different users.
+
+See the oauth2 docs for complete instructions on using that library.
+
+For API methods that require HTTP Basic Authentication, use the
+BasicAuthTransport.
+
+GitHub Apps authentication can be provided by the
+https://github.com/bradleyfalzon/ghinstallation package.
+
+	import "github.com/bradleyfalzon/ghinstallation"
+
+	func main() {
+		// Wrap the shared transport for use with the integration ID 1 authenticating with installation ID 99.
+		itr, err := ghinstallation.NewKeyFromFile(http.DefaultTransport, 1, 99, "2016-10-19.private-key.pem")
+		if err != nil {
+			// Handle error.
+		}
+
+		// Use installation transport with client
+		client := github.NewClient(&http.Client{Transport: itr})
+
+		// Use client...
+	}
+
+Rate Limiting
+
+GitHub imposes a rate limit on all API clients. Unauthenticated clients are
+limited to 60 requests per hour, while authenticated clients can make up to
+5,000 requests per hour. The Search API has a custom rate limit. Unauthenticated
+clients are limited to 10 requests per minute, while authenticated clients
+can make up to 30 requests per minute. To receive the higher rate limit when
+making calls that are not issued on behalf of a user,
+use UnauthenticatedRateLimitedTransport.
+
+The returned Response.Rate value contains the rate limit information
+from the most recent API call. If a recent enough response isn't
+available, you can use RateLimits to fetch the most up-to-date rate
+limit data for the client.
+
+To detect an API rate limit error, you can check if its type is *github.RateLimitError:
+
+	repos, _, err := client.Repositories.List(ctx, "", nil)
+	if _, ok := err.(*github.RateLimitError); ok {
+		log.Println("hit rate limit")
+	}
+
+Learn more about GitHub rate limiting at
+https://developer.github.com/v3/#rate-limiting.
+
+Accepted Status
+
+Some endpoints may return a 202 Accepted status code, meaning that the
+information required is not yet ready and was scheduled to be gathered on
+the GitHub side. Methods known to behave like this are documented specifying
+this behavior.
+
+To detect this condition of error, you can check if its type is
+*github.AcceptedError:
+
+	stats, _, err := client.Repositories.ListContributorsStats(ctx, org, repo)
+	if _, ok := err.(*github.AcceptedError); ok {
+		log.Println("scheduled on GitHub side")
+	}
+
+Conditional Requests
+
+The GitHub API has good support for conditional requests which will help
+prevent you from burning through your rate limit, as well as help speed up your
+application. go-github does not handle conditional requests directly, but is
+instead designed to work with a caching http.Transport. We recommend using
+https://github.com/gregjones/httpcache for that.
+
+Learn more about GitHub conditional requests at
+https://developer.github.com/v3/#conditional-requests.
+
+Creating and Updating Resources
+
+All structs for GitHub resources use pointer values for all non-repeated fields.
+This allows distinguishing between unset fields and those set to a zero-value.
+Helper functions have been provided to easily create these pointers for string,
+bool, and int values. For example:
+
+	// create a new private repository named "foo"
+	repo := &github.Repository{
+		Name:    github.String("foo"),
+		Private: github.Bool(true),
+	}
+	client.Repositories.Create(ctx, "", repo)
+
+Users who have worked with protocol buffers should find this pattern familiar.
+
+Pagination
+
+All requests for resource collections (repos, pull requests, issues, etc.)
+support pagination. Pagination options are described in the
+github.ListOptions struct and passed to the list methods directly or as an
+embedded type of a more specific list options struct (for example
+github.PullRequestListOptions). Pages information is available via the
+github.Response struct.
+
+	client := github.NewClient(nil)
+
+	opt := &github.RepositoryListByOrgOptions{
+		ListOptions: github.ListOptions{PerPage: 10},
+	}
+	// get all pages of results
+	var allRepos []*github.Repository
+	for {
+		repos, resp, err := client.Repositories.ListByOrg(ctx, "github", opt)
+		if err != nil {
+			return err
+		}
+		allRepos = append(allRepos, repos...)
+		if resp.NextPage == 0 {
+			break
+		}
+		opt.Page = resp.NextPage
+	}
+
+Google App Engine
+
+Go on App Engine Classic (which as of this writing uses Go 1.6) can not use
+the "context" import and still relies on "golang.org/x/net/context".
+As a result, if you wish to continue to use "go-github" on App Engine Classic,
+you will need to rewrite all the "context" imports using the following command:
+
+	gofmt -w -r '"context" -> "golang.org/x/net/context"' *.go
+
+See "with_appengine.go" for more details.
+
+*/
+package github

+ 748 - 0
vendor/github.com/google/go-github/github/event_types.go

@@ -0,0 +1,748 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// These event types are shared between the Events API and used as Webhook payloads.
+
+package github
+
+// CommitCommentEvent is triggered when a commit comment is created.
+// The Webhook event name is "commit_comment".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#commitcommentevent
+type CommitCommentEvent struct {
+	Comment *RepositoryComment `json:"comment,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Action       *string       `json:"action,omitempty"`
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// CreateEvent represents a created repository, branch, or tag.
+// The Webhook event name is "create".
+//
+// Note: webhooks will not receive this event for created repositories.
+// Additionally, webhooks will not receive this event for tags if more
+// than three tags are pushed at once.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#createevent
+type CreateEvent struct {
+	Ref *string `json:"ref,omitempty"`
+	// RefType is the object that was created. Possible values are: "repository", "branch", "tag".
+	RefType      *string `json:"ref_type,omitempty"`
+	MasterBranch *string `json:"master_branch,omitempty"`
+	Description  *string `json:"description,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	PusherType   *string       `json:"pusher_type,omitempty"`
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// DeleteEvent represents a deleted branch or tag.
+// The Webhook event name is "delete".
+//
+// Note: webhooks will not receive this event for tags if more than three tags
+// are deleted at once.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#deleteevent
+type DeleteEvent struct {
+	Ref *string `json:"ref,omitempty"`
+	// RefType is the object that was deleted. Possible values are: "branch", "tag".
+	RefType *string `json:"ref_type,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	PusherType   *string       `json:"pusher_type,omitempty"`
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// DeploymentEvent represents a deployment.
+// The Webhook event name is "deployment".
+//
+// Events of this type are not visible in timelines, they are only used to trigger hooks.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#deploymentevent
+type DeploymentEvent struct {
+	Deployment *Deployment `json:"deployment,omitempty"`
+	Repo       *Repository `json:"repository,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// DeploymentStatusEvent represents a deployment status.
+// The Webhook event name is "deployment_status".
+//
+// Events of this type are not visible in timelines, they are only used to trigger hooks.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#deploymentstatusevent
+type DeploymentStatusEvent struct {
+	Deployment       *Deployment       `json:"deployment,omitempty"`
+	DeploymentStatus *DeploymentStatus `json:"deployment_status,omitempty"`
+	Repo             *Repository       `json:"repository,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// ForkEvent is triggered when a user forks a repository.
+// The Webhook event name is "fork".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#forkevent
+type ForkEvent struct {
+	// Forkee is the created repository.
+	Forkee *Repository `json:"forkee,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// Page represents a single Wiki page.
+type Page struct {
+	PageName *string `json:"page_name,omitempty"`
+	Title    *string `json:"title,omitempty"`
+	Summary  *string `json:"summary,omitempty"`
+	Action   *string `json:"action,omitempty"`
+	SHA      *string `json:"sha,omitempty"`
+	HTMLURL  *string `json:"html_url,omitempty"`
+}
+
+// GollumEvent is triggered when a Wiki page is created or updated.
+// The Webhook event name is "gollum".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#gollumevent
+type GollumEvent struct {
+	Pages []*Page `json:"pages,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// EditChange represents the changes when an issue, pull request, or comment has
+// been edited.
+type EditChange struct {
+	Title *struct {
+		From *string `json:"from,omitempty"`
+	} `json:"title,omitempty"`
+	Body *struct {
+		From *string `json:"from,omitempty"`
+	} `json:"body,omitempty"`
+}
+
+// ProjectChange represents the changes when a project has been edited.
+type ProjectChange struct {
+	Name *struct {
+		From *string `json:"from,omitempty"`
+	} `json:"name,omitempty"`
+	Body *struct {
+		From *string `json:"from,omitempty"`
+	} `json:"body,omitempty"`
+}
+
+// ProjectCardChange represents the changes when a project card has been edited.
+type ProjectCardChange struct {
+	Note *struct {
+		From *string `json:"from,omitempty"`
+	} `json:"note,omitempty"`
+}
+
+// ProjectColumnChange represents the changes when a project column has been edited.
+type ProjectColumnChange struct {
+	Name *struct {
+		From *string `json:"from,omitempty"`
+	} `json:"name,omitempty"`
+}
+
+// TeamChange represents the changes when a team has been edited.
+type TeamChange struct {
+	Description *struct {
+		From *string `json:"from,omitempty"`
+	} `json:"description,omitempty"`
+	Name *struct {
+		From *string `json:"from,omitempty"`
+	} `json:"name,omitempty"`
+	Privacy *struct {
+		From *string `json:"from,omitempty"`
+	} `json:"privacy,omitempty"`
+	Repository *struct {
+		Permissions *struct {
+			From *struct {
+				Admin *bool `json:"admin,omitempty"`
+				Pull  *bool `json:"pull,omitempty"`
+				Push  *bool `json:"push,omitempty"`
+			} `json:"from,omitempty"`
+		} `json:"permissions,omitempty"`
+	} `json:"repository,omitempty"`
+}
+
+// InstallationEvent is triggered when a GitHub App has been installed or uninstalled.
+// The Webhook event name is "installation".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#installationevent
+type InstallationEvent struct {
+	// The action that was performed. Can be either "created" or "deleted".
+	Action       *string       `json:"action,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// InstallationRepositoriesEvent is triggered when a repository is added or
+// removed from an installation. The Webhook event name is "installation_repositories".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#installationrepositoriesevent
+type InstallationRepositoriesEvent struct {
+	// The action that was performed. Can be either "added" or "removed".
+	Action              *string       `json:"action,omitempty"`
+	RepositoriesAdded   []*Repository `json:"repositories_added,omitempty"`
+	RepositoriesRemoved []*Repository `json:"repositories_removed,omitempty"`
+	RepositorySelection *string       `json:"repository_selection,omitempty"`
+	Sender              *User         `json:"sender,omitempty"`
+	Installation        *Installation `json:"installation,omitempty"`
+}
+
+// IssueCommentEvent is triggered when an issue comment is created on an issue
+// or pull request.
+// The Webhook event name is "issue_comment".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#issuecommentevent
+type IssueCommentEvent struct {
+	// Action is the action that was performed on the comment.
+	// Possible values are: "created", "edited", "deleted".
+	Action  *string       `json:"action,omitempty"`
+	Issue   *Issue        `json:"issue,omitempty"`
+	Comment *IssueComment `json:"comment,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Changes      *EditChange   `json:"changes,omitempty"`
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// IssuesEvent is triggered when an issue is assigned, unassigned, labeled,
+// unlabeled, opened, closed, or reopened.
+// The Webhook event name is "issues".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#issuesevent
+type IssuesEvent struct {
+	// Action is the action that was performed. Possible values are: "assigned",
+	// "unassigned", "labeled", "unlabeled", "opened", "closed", "reopened", "edited".
+	Action   *string `json:"action,omitempty"`
+	Issue    *Issue  `json:"issue,omitempty"`
+	Assignee *User   `json:"assignee,omitempty"`
+	Label    *Label  `json:"label,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Changes      *EditChange   `json:"changes,omitempty"`
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// LabelEvent is triggered when a repository's label is created, edited, or deleted.
+// The Webhook event name is "label"
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#labelevent
+type LabelEvent struct {
+	// Action is the action that was performed. Possible values are:
+	// "created", "edited", "deleted"
+	Action *string `json:"action,omitempty"`
+	Label  *Label  `json:"label,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Changes      *EditChange   `json:"changes,omitempty"`
+	Repo         *Repository   `json:"repository,omitempty"`
+	Org          *Organization `json:"organization,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// MarketplacePurchaseEvent is triggered when a user purchases, cancels, or changes
+// their GitHub Marketplace plan.
+// Webhook event name "marketplace_purchase".
+//
+// Github API docs: https://developer.github.com/v3/activity/events/types/#marketplacepurchaseevent
+type MarketplacePurchaseEvent struct {
+	// Action is the action that was performed. Possible values are:
+	// "purchased", "cancelled", "changed".
+	Action *string `json:"action,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	EffectiveDate               *Timestamp           `json:"effective_date,omitempty"`
+	MarketplacePurchase         *MarketplacePurchase `json:"marketplace_purchase,omitempty"`
+	PreviousMarketplacePurchase *MarketplacePurchase `json:"previous_marketplace_purchase,omitempty"`
+	Sender                      *User                `json:"sender,omitempty"`
+	Installation                *Installation        `json:"installation,omitempty"`
+}
+
+// MemberEvent is triggered when a user is added as a collaborator to a repository.
+// The Webhook event name is "member".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#memberevent
+type MemberEvent struct {
+	// Action is the action that was performed. Possible value is: "added".
+	Action *string `json:"action,omitempty"`
+	Member *User   `json:"member,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// MembershipEvent is triggered when a user is added or removed from a team.
+// The Webhook event name is "membership".
+//
+// Events of this type are not visible in timelines, they are only used to
+// trigger organization webhooks.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#membershipevent
+type MembershipEvent struct {
+	// Action is the action that was performed. Possible values are: "added", "removed".
+	Action *string `json:"action,omitempty"`
+	// Scope is the scope of the membership. Possible value is: "team".
+	Scope  *string `json:"scope,omitempty"`
+	Member *User   `json:"member,omitempty"`
+	Team   *Team   `json:"team,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Org          *Organization `json:"organization,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// MilestoneEvent is triggered when a milestone is created, closed, opened, edited, or deleted.
+// The Webhook event name is "milestone".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#milestoneevent
+type MilestoneEvent struct {
+	// Action is the action that was performed. Possible values are:
+	// "created", "closed", "opened", "edited", "deleted"
+	Action    *string    `json:"action,omitempty"`
+	Milestone *Milestone `json:"milestone,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Changes      *EditChange   `json:"changes,omitempty"`
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Org          *Organization `json:"organization,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// OrganizationEvent is triggered when a user is added, removed, or invited to an organization.
+// Events of this type are not visible in timelines. These events are only used to trigger organization hooks.
+// Webhook event name is "organization".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#organizationevent
+type OrganizationEvent struct {
+	// Action is the action that was performed.
+	// Can be one of "member_added", "member_removed", or "member_invited".
+	Action *string `json:"action,omitempty"`
+
+	// Invitaion is the invitation for the user or email if the action is "member_invited".
+	Invitation *Invitation `json:"invitation,omitempty"`
+
+	// Membership is the membership between the user and the organization.
+	// Not present when the action is "member_invited".
+	Membership *Membership `json:"membership,omitempty"`
+
+	Organization *Organization `json:"organization,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// OrgBlockEvent is triggered when an organization blocks or unblocks a user.
+// The Webhook event name is "org_block".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#orgblockevent
+type OrgBlockEvent struct {
+	// Action is the action that was performed.
+	// Can be "blocked" or "unblocked".
+	Action       *string       `json:"action,omitempty"`
+	BlockedUser  *User         `json:"blocked_user,omitempty"`
+	Organization *Organization `json:"organization,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// PageBuildEvent represents an attempted build of a GitHub Pages site, whether
+// successful or not.
+// The Webhook event name is "page_build".
+//
+// This event is triggered on push to a GitHub Pages enabled branch (gh-pages
+// for project pages, master for user and organization pages).
+//
+// Events of this type are not visible in timelines, they are only used to trigger hooks.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#pagebuildevent
+type PageBuildEvent struct {
+	Build *PagesBuild `json:"build,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	ID           *int64        `json:"id,omitempty"`
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// PingEvent is triggered when a Webhook is added to GitHub.
+//
+// GitHub API docs: https://developer.github.com/webhooks/#ping-event
+type PingEvent struct {
+	// Random string of GitHub zen.
+	Zen *string `json:"zen,omitempty"`
+	// The ID of the webhook that triggered the ping.
+	HookID *int64 `json:"hook_id,omitempty"`
+	// The webhook configuration.
+	Hook         *Hook         `json:"hook,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// ProjectEvent is triggered when project is created, modified or deleted.
+// The webhook event name is "project".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#projectevent
+type ProjectEvent struct {
+	Action  *string        `json:"action,omitempty"`
+	Changes *ProjectChange `json:"changes,omitempty"`
+	Project *Project       `json:"project,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Repo         *Repository   `json:"repository,omitempty"`
+	Org          *Organization `json:"organization,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// ProjectCardEvent is triggered when a project card is created, updated, moved, converted to an issue, or deleted.
+// The webhook event name is "project_card".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#projectcardevent
+type ProjectCardEvent struct {
+	Action      *string            `json:"action,omitempty"`
+	Changes     *ProjectCardChange `json:"changes,omitempty"`
+	AfterID     *int64             `json:"after_id,omitempty"`
+	ProjectCard *ProjectCard       `json:"project_card,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Repo         *Repository   `json:"repository,omitempty"`
+	Org          *Organization `json:"organization,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// ProjectColumnEvent is triggered when a project column is created, updated, moved, or deleted.
+// The webhook event name is "project_column".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#projectcolumnevent
+type ProjectColumnEvent struct {
+	Action        *string              `json:"action,omitempty"`
+	Changes       *ProjectColumnChange `json:"changes,omitempty"`
+	AfterID       *int64               `json:"after_id,omitempty"`
+	ProjectColumn *ProjectColumn       `json:"project_column,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Repo         *Repository   `json:"repository,omitempty"`
+	Org          *Organization `json:"organization,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// PublicEvent is triggered when a private repository is open sourced.
+// According to GitHub: "Without a doubt: the best GitHub event."
+// The Webhook event name is "public".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#publicevent
+type PublicEvent struct {
+	// The following fields are only populated by Webhook events.
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// PullRequestEvent is triggered when a pull request is assigned, unassigned,
+// labeled, unlabeled, opened, closed, reopened, or synchronized.
+// The Webhook event name is "pull_request".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#pullrequestevent
+type PullRequestEvent struct {
+	// Action is the action that was performed. Possible values are:
+	// "assigned", "unassigned", "review_requested", "review_request_removed", "labeled", "unlabeled",
+	// "opened", "closed", "reopened", "synchronize", "edited".
+	// If the action is "closed" and the merged key is false,
+	// the pull request was closed with unmerged commits. If the action is "closed"
+	// and the merged key is true, the pull request was merged.
+	Action      *string      `json:"action,omitempty"`
+	Number      *int         `json:"number,omitempty"`
+	PullRequest *PullRequest `json:"pull_request,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Changes            *EditChange   `json:"changes,omitempty"`
+	RequestedReviewers []*User       `json:"requested_reviewers,omitempty"` // Populated in "review_requested", "review_request_removed" event deliveries.
+	Repo               *Repository   `json:"repository,omitempty"`
+	Sender             *User         `json:"sender,omitempty"`
+	Installation       *Installation `json:"installation,omitempty"`
+}
+
+// PullRequestReviewEvent is triggered when a review is submitted on a pull
+// request.
+// The Webhook event name is "pull_request_review".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#pullrequestreviewevent
+type PullRequestReviewEvent struct {
+	// Action is always "submitted".
+	Action      *string            `json:"action,omitempty"`
+	Review      *PullRequestReview `json:"review,omitempty"`
+	PullRequest *PullRequest       `json:"pull_request,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+
+	// The following field is only present when the webhook is triggered on
+	// a repository belonging to an organization.
+	Organization *Organization `json:"organization,omitempty"`
+}
+
+// PullRequestReviewCommentEvent is triggered when a comment is created on a
+// portion of the unified diff of a pull request.
+// The Webhook event name is "pull_request_review_comment".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#pullrequestreviewcommentevent
+type PullRequestReviewCommentEvent struct {
+	// Action is the action that was performed on the comment.
+	// Possible values are: "created", "edited", "deleted".
+	Action      *string             `json:"action,omitempty"`
+	PullRequest *PullRequest        `json:"pull_request,omitempty"`
+	Comment     *PullRequestComment `json:"comment,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Changes      *EditChange   `json:"changes,omitempty"`
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// PushEvent represents a git push to a GitHub repository.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#pushevent
+type PushEvent struct {
+	PushID       *int64            `json:"push_id,omitempty"`
+	Head         *string           `json:"head,omitempty"`
+	Ref          *string           `json:"ref,omitempty"`
+	Size         *int              `json:"size,omitempty"`
+	Commits      []PushEventCommit `json:"commits,omitempty"`
+	Before       *string           `json:"before,omitempty"`
+	DistinctSize *int              `json:"distinct_size,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	After        *string              `json:"after,omitempty"`
+	Created      *bool                `json:"created,omitempty"`
+	Deleted      *bool                `json:"deleted,omitempty"`
+	Forced       *bool                `json:"forced,omitempty"`
+	BaseRef      *string              `json:"base_ref,omitempty"`
+	Compare      *string              `json:"compare,omitempty"`
+	Repo         *PushEventRepository `json:"repository,omitempty"`
+	HeadCommit   *PushEventCommit     `json:"head_commit,omitempty"`
+	Pusher       *User                `json:"pusher,omitempty"`
+	Sender       *User                `json:"sender,omitempty"`
+	Installation *Installation        `json:"installation,omitempty"`
+}
+
+func (p PushEvent) String() string {
+	return Stringify(p)
+}
+
+// PushEventCommit represents a git commit in a GitHub PushEvent.
+type PushEventCommit struct {
+	Message  *string       `json:"message,omitempty"`
+	Author   *CommitAuthor `json:"author,omitempty"`
+	URL      *string       `json:"url,omitempty"`
+	Distinct *bool         `json:"distinct,omitempty"`
+
+	// The following fields are only populated by Events API.
+	SHA *string `json:"sha,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	ID        *string       `json:"id,omitempty"`
+	TreeID    *string       `json:"tree_id,omitempty"`
+	Timestamp *Timestamp    `json:"timestamp,omitempty"`
+	Committer *CommitAuthor `json:"committer,omitempty"`
+	Added     []string      `json:"added,omitempty"`
+	Removed   []string      `json:"removed,omitempty"`
+	Modified  []string      `json:"modified,omitempty"`
+}
+
+func (p PushEventCommit) String() string {
+	return Stringify(p)
+}
+
+// PushEventRepository represents the repo object in a PushEvent payload.
+type PushEventRepository struct {
+	ID              *int64              `json:"id,omitempty"`
+	Name            *string             `json:"name,omitempty"`
+	FullName        *string             `json:"full_name,omitempty"`
+	Owner           *PushEventRepoOwner `json:"owner,omitempty"`
+	Private         *bool               `json:"private,omitempty"`
+	Description     *string             `json:"description,omitempty"`
+	Fork            *bool               `json:"fork,omitempty"`
+	CreatedAt       *Timestamp          `json:"created_at,omitempty"`
+	PushedAt        *Timestamp          `json:"pushed_at,omitempty"`
+	UpdatedAt       *Timestamp          `json:"updated_at,omitempty"`
+	Homepage        *string             `json:"homepage,omitempty"`
+	Size            *int                `json:"size,omitempty"`
+	StargazersCount *int                `json:"stargazers_count,omitempty"`
+	WatchersCount   *int                `json:"watchers_count,omitempty"`
+	Language        *string             `json:"language,omitempty"`
+	HasIssues       *bool               `json:"has_issues,omitempty"`
+	HasDownloads    *bool               `json:"has_downloads,omitempty"`
+	HasWiki         *bool               `json:"has_wiki,omitempty"`
+	HasPages        *bool               `json:"has_pages,omitempty"`
+	ForksCount      *int                `json:"forks_count,omitempty"`
+	OpenIssuesCount *int                `json:"open_issues_count,omitempty"`
+	DefaultBranch   *string             `json:"default_branch,omitempty"`
+	MasterBranch    *string             `json:"master_branch,omitempty"`
+	Organization    *string             `json:"organization,omitempty"`
+	URL             *string             `json:"url,omitempty"`
+	ArchiveURL      *string             `json:"archive_url,omitempty"`
+	HTMLURL         *string             `json:"html_url,omitempty"`
+	StatusesURL     *string             `json:"statuses_url,omitempty"`
+	GitURL          *string             `json:"git_url,omitempty"`
+	SSHURL          *string             `json:"ssh_url,omitempty"`
+	CloneURL        *string             `json:"clone_url,omitempty"`
+	SVNURL          *string             `json:"svn_url,omitempty"`
+}
+
+// PushEventRepoOwner is a basic representation of user/org in a PushEvent payload.
+type PushEventRepoOwner struct {
+	Name  *string `json:"name,omitempty"`
+	Email *string `json:"email,omitempty"`
+}
+
+// ReleaseEvent is triggered when a release is published.
+// The Webhook event name is "release".
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#releaseevent
+type ReleaseEvent struct {
+	// Action is the action that was performed. Possible value is: "published".
+	Action  *string            `json:"action,omitempty"`
+	Release *RepositoryRelease `json:"release,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// RepositoryEvent is triggered when a repository is created.
+// The Webhook event name is "repository".
+//
+// Events of this type are not visible in timelines, they are only used to
+// trigger organization webhooks.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#repositoryevent
+type RepositoryEvent struct {
+	// Action is the action that was performed. Possible values are: "created", "deleted",
+	// "publicized", "privatized".
+	Action *string     `json:"action,omitempty"`
+	Repo   *Repository `json:"repository,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Org          *Organization `json:"organization,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// StatusEvent is triggered when the status of a Git commit changes.
+// The Webhook event name is "status".
+//
+// Events of this type are not visible in timelines, they are only used to
+// trigger hooks.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#statusevent
+type StatusEvent struct {
+	SHA *string `json:"sha,omitempty"`
+	// State is the new state. Possible values are: "pending", "success", "failure", "error".
+	State       *string   `json:"state,omitempty"`
+	Description *string   `json:"description,omitempty"`
+	TargetURL   *string   `json:"target_url,omitempty"`
+	Branches    []*Branch `json:"branches,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	ID           *int64            `json:"id,omitempty"`
+	Name         *string           `json:"name,omitempty"`
+	Context      *string           `json:"context,omitempty"`
+	Commit       *RepositoryCommit `json:"commit,omitempty"`
+	CreatedAt    *Timestamp        `json:"created_at,omitempty"`
+	UpdatedAt    *Timestamp        `json:"updated_at,omitempty"`
+	Repo         *Repository       `json:"repository,omitempty"`
+	Sender       *User             `json:"sender,omitempty"`
+	Installation *Installation     `json:"installation,omitempty"`
+}
+
+// TeamEvent is triggered when an organization's team is created, modified or deleted.
+// The Webhook event name is "team".
+//
+// Events of this type are not visible in timelines. These events are only used
+// to trigger hooks.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#teamevent
+type TeamEvent struct {
+	Action  *string     `json:"action,omitempty"`
+	Team    *Team       `json:"team,omitempty"`
+	Changes *TeamChange `json:"changes,omitempty"`
+	Repo    *Repository `json:"repository,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Org          *Organization `json:"organization,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// TeamAddEvent is triggered when a repository is added to a team.
+// The Webhook event name is "team_add".
+//
+// Events of this type are not visible in timelines. These events are only used
+// to trigger hooks.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#teamaddevent
+type TeamAddEvent struct {
+	Team *Team       `json:"team,omitempty"`
+	Repo *Repository `json:"repository,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Org          *Organization `json:"organization,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}
+
+// WatchEvent is related to starring a repository, not watching. See this API
+// blog post for an explanation: https://developer.github.com/changes/2012-09-05-watcher-api/
+//
+// The event’s actor is the user who starred a repository, and the event’s
+// repository is the repository that was starred.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#watchevent
+type WatchEvent struct {
+	// Action is the action that was performed. Possible value is: "started".
+	Action *string `json:"action,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Repo         *Repository   `json:"repository,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+	Installation *Installation `json:"installation,omitempty"`
+}

+ 332 - 0
vendor/github.com/google/go-github/github/gen-accessors.go

@@ -0,0 +1,332 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+// gen-accessors generates accessor methods for structs with pointer fields.
+//
+// It is meant to be used by the go-github authors in conjunction with the
+// go generate tool before sending a commit to GitHub.
+package main
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"go/ast"
+	"go/format"
+	"go/parser"
+	"go/token"
+	"io/ioutil"
+	"log"
+	"os"
+	"sort"
+	"strings"
+	"text/template"
+)
+
+const (
+	fileSuffix = "-accessors.go"
+)
+
+var (
+	verbose = flag.Bool("v", false, "Print verbose log messages")
+
+	sourceTmpl = template.Must(template.New("source").Parse(source))
+
+	// blacklistStructMethod lists "struct.method" combos to skip.
+	blacklistStructMethod = map[string]bool{
+		"RepositoryContent.GetContent":    true,
+		"Client.GetBaseURL":               true,
+		"Client.GetUploadURL":             true,
+		"ErrorResponse.GetResponse":       true,
+		"RateLimitError.GetResponse":      true,
+		"AbuseRateLimitError.GetResponse": true,
+	}
+	// blacklistStruct lists structs to skip.
+	blacklistStruct = map[string]bool{
+		"Client": true,
+	}
+)
+
+func logf(fmt string, args ...interface{}) {
+	if *verbose {
+		log.Printf(fmt, args...)
+	}
+}
+
+func main() {
+	flag.Parse()
+	fset := token.NewFileSet()
+
+	pkgs, err := parser.ParseDir(fset, ".", sourceFilter, 0)
+	if err != nil {
+		log.Fatal(err)
+		return
+	}
+
+	for pkgName, pkg := range pkgs {
+		t := &templateData{
+			filename: pkgName + fileSuffix,
+			Year:     2017,
+			Package:  pkgName,
+			Imports:  map[string]string{},
+		}
+		for filename, f := range pkg.Files {
+			logf("Processing %v...", filename)
+			if err := t.processAST(f); err != nil {
+				log.Fatal(err)
+			}
+		}
+		if err := t.dump(); err != nil {
+			log.Fatal(err)
+		}
+	}
+	logf("Done.")
+}
+
+func (t *templateData) processAST(f *ast.File) error {
+	for _, decl := range f.Decls {
+		gd, ok := decl.(*ast.GenDecl)
+		if !ok {
+			continue
+		}
+		for _, spec := range gd.Specs {
+			ts, ok := spec.(*ast.TypeSpec)
+			if !ok {
+				continue
+			}
+			// Skip unexported identifiers.
+			if !ts.Name.IsExported() {
+				logf("Struct %v is unexported; skipping.", ts.Name)
+				continue
+			}
+			// Check if the struct is blacklisted.
+			if blacklistStruct[ts.Name.Name] {
+				logf("Struct %v is blacklisted; skipping.", ts.Name)
+				continue
+			}
+			st, ok := ts.Type.(*ast.StructType)
+			if !ok {
+				continue
+			}
+			for _, field := range st.Fields.List {
+				se, ok := field.Type.(*ast.StarExpr)
+				if len(field.Names) == 0 || !ok {
+					continue
+				}
+
+				fieldName := field.Names[0]
+				// Skip unexported identifiers.
+				if !fieldName.IsExported() {
+					logf("Field %v is unexported; skipping.", fieldName)
+					continue
+				}
+				// Check if "struct.method" is blacklisted.
+				if key := fmt.Sprintf("%v.Get%v", ts.Name, fieldName); blacklistStructMethod[key] {
+					logf("Method %v is blacklisted; skipping.", key)
+					continue
+				}
+
+				switch x := se.X.(type) {
+				case *ast.ArrayType:
+					t.addArrayType(x, ts.Name.String(), fieldName.String())
+				case *ast.Ident:
+					t.addIdent(x, ts.Name.String(), fieldName.String())
+				case *ast.MapType:
+					t.addMapType(x, ts.Name.String(), fieldName.String())
+				case *ast.SelectorExpr:
+					t.addSelectorExpr(x, ts.Name.String(), fieldName.String())
+				default:
+					logf("processAST: type %q, field %q, unknown %T: %+v", ts.Name, fieldName, x, x)
+				}
+			}
+		}
+	}
+	return nil
+}
+
+func sourceFilter(fi os.FileInfo) bool {
+	return !strings.HasSuffix(fi.Name(), "_test.go") && !strings.HasSuffix(fi.Name(), fileSuffix)
+}
+
+func (t *templateData) dump() error {
+	if len(t.Getters) == 0 {
+		logf("No getters for %v; skipping.", t.filename)
+		return nil
+	}
+
+	// Sort getters by ReceiverType.FieldName.
+	sort.Sort(byName(t.Getters))
+
+	var buf bytes.Buffer
+	if err := sourceTmpl.Execute(&buf, t); err != nil {
+		return err
+	}
+	clean, err := format.Source(buf.Bytes())
+	if err != nil {
+		return err
+	}
+
+	logf("Writing %v...", t.filename)
+	return ioutil.WriteFile(t.filename, clean, 0644)
+}
+
+func newGetter(receiverType, fieldName, fieldType, zeroValue string, namedStruct bool) *getter {
+	return &getter{
+		sortVal:      strings.ToLower(receiverType) + "." + strings.ToLower(fieldName),
+		ReceiverVar:  strings.ToLower(receiverType[:1]),
+		ReceiverType: receiverType,
+		FieldName:    fieldName,
+		FieldType:    fieldType,
+		ZeroValue:    zeroValue,
+		NamedStruct:  namedStruct,
+	}
+}
+
+func (t *templateData) addArrayType(x *ast.ArrayType, receiverType, fieldName string) {
+	var eltType string
+	switch elt := x.Elt.(type) {
+	case *ast.Ident:
+		eltType = elt.String()
+	default:
+		logf("addArrayType: type %q, field %q: unknown elt type: %T %+v; skipping.", receiverType, fieldName, elt, elt)
+		return
+	}
+
+	t.Getters = append(t.Getters, newGetter(receiverType, fieldName, "[]"+eltType, "nil", false))
+}
+
+func (t *templateData) addIdent(x *ast.Ident, receiverType, fieldName string) {
+	var zeroValue string
+	var namedStruct = false
+	switch x.String() {
+	case "int", "int64":
+		zeroValue = "0"
+	case "string":
+		zeroValue = `""`
+	case "bool":
+		zeroValue = "false"
+	case "Timestamp":
+		zeroValue = "Timestamp{}"
+	default:
+		zeroValue = "nil"
+		namedStruct = true
+	}
+
+	t.Getters = append(t.Getters, newGetter(receiverType, fieldName, x.String(), zeroValue, namedStruct))
+}
+
+func (t *templateData) addMapType(x *ast.MapType, receiverType, fieldName string) {
+	var keyType string
+	switch key := x.Key.(type) {
+	case *ast.Ident:
+		keyType = key.String()
+	default:
+		logf("addMapType: type %q, field %q: unknown key type: %T %+v; skipping.", receiverType, fieldName, key, key)
+		return
+	}
+
+	var valueType string
+	switch value := x.Value.(type) {
+	case *ast.Ident:
+		valueType = value.String()
+	default:
+		logf("addMapType: type %q, field %q: unknown value type: %T %+v; skipping.", receiverType, fieldName, value, value)
+		return
+	}
+
+	fieldType := fmt.Sprintf("map[%v]%v", keyType, valueType)
+	zeroValue := fmt.Sprintf("map[%v]%v{}", keyType, valueType)
+	t.Getters = append(t.Getters, newGetter(receiverType, fieldName, fieldType, zeroValue, false))
+}
+
+func (t *templateData) addSelectorExpr(x *ast.SelectorExpr, receiverType, fieldName string) {
+	if strings.ToLower(fieldName[:1]) == fieldName[:1] { // Non-exported field.
+		return
+	}
+
+	var xX string
+	if xx, ok := x.X.(*ast.Ident); ok {
+		xX = xx.String()
+	}
+
+	switch xX {
+	case "time", "json":
+		if xX == "json" {
+			t.Imports["encoding/json"] = "encoding/json"
+		} else {
+			t.Imports[xX] = xX
+		}
+		fieldType := fmt.Sprintf("%v.%v", xX, x.Sel.Name)
+		zeroValue := fmt.Sprintf("%v.%v{}", xX, x.Sel.Name)
+		if xX == "time" && x.Sel.Name == "Duration" {
+			zeroValue = "0"
+		}
+		t.Getters = append(t.Getters, newGetter(receiverType, fieldName, fieldType, zeroValue, false))
+	default:
+		logf("addSelectorExpr: xX %q, type %q, field %q: unknown x=%+v; skipping.", xX, receiverType, fieldName, x)
+	}
+}
+
+type templateData struct {
+	filename string
+	Year     int
+	Package  string
+	Imports  map[string]string
+	Getters  []*getter
+}
+
+type getter struct {
+	sortVal      string // Lower-case version of "ReceiverType.FieldName".
+	ReceiverVar  string // The one-letter variable name to match the ReceiverType.
+	ReceiverType string
+	FieldName    string
+	FieldType    string
+	ZeroValue    string
+	NamedStruct  bool // Getter for named struct.
+}
+
+type byName []*getter
+
+func (b byName) Len() int           { return len(b) }
+func (b byName) Less(i, j int) bool { return b[i].sortVal < b[j].sortVal }
+func (b byName) Swap(i, j int)      { b[i], b[j] = b[j], b[i] }
+
+const source = `// Copyright {{.Year}} The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code generated by gen-accessors; DO NOT EDIT.
+
+package {{.Package}}
+{{with .Imports}}
+import (
+  {{- range . -}}
+  "{{.}}"
+  {{end -}}
+)
+{{end}}
+{{range .Getters}}
+{{if .NamedStruct}}
+// Get{{.FieldName}} returns the {{.FieldName}} field.
+func ({{.ReceiverVar}} *{{.ReceiverType}}) Get{{.FieldName}}() *{{.FieldType}} {
+  if {{.ReceiverVar}} == nil {
+    return {{.ZeroValue}}
+  }
+  return {{.ReceiverVar}}.{{.FieldName}}
+}
+{{else}}
+// Get{{.FieldName}} returns the {{.FieldName}} field if it's non-nil, zero value otherwise.
+func ({{.ReceiverVar}} *{{.ReceiverType}}) Get{{.FieldName}}() {{.FieldType}} {
+  if {{.ReceiverVar}} == nil || {{.ReceiverVar}}.{{.FieldName}} == nil {
+    return {{.ZeroValue}}
+  }
+  return *{{.ReceiverVar}}.{{.FieldName}}
+}
+{{end}}
+{{end}}
+`

+ 388 - 0
vendor/github.com/google/go-github/github/gists.go

@@ -0,0 +1,388 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// GistsService handles communication with the Gist related
+// methods of the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/
+type GistsService service
+
+// Gist represents a GitHub's gist.
+type Gist struct {
+	ID          *string                   `json:"id,omitempty"`
+	Description *string                   `json:"description,omitempty"`
+	Public      *bool                     `json:"public,omitempty"`
+	Owner       *User                     `json:"owner,omitempty"`
+	Files       map[GistFilename]GistFile `json:"files,omitempty"`
+	Comments    *int                      `json:"comments,omitempty"`
+	HTMLURL     *string                   `json:"html_url,omitempty"`
+	GitPullURL  *string                   `json:"git_pull_url,omitempty"`
+	GitPushURL  *string                   `json:"git_push_url,omitempty"`
+	CreatedAt   *time.Time                `json:"created_at,omitempty"`
+	UpdatedAt   *time.Time                `json:"updated_at,omitempty"`
+	NodeID      *string                   `json:"node_id,omitempty"`
+}
+
+func (g Gist) String() string {
+	return Stringify(g)
+}
+
+// GistFilename represents filename on a gist.
+type GistFilename string
+
+// GistFile represents a file on a gist.
+type GistFile struct {
+	Size     *int    `json:"size,omitempty"`
+	Filename *string `json:"filename,omitempty"`
+	Language *string `json:"language,omitempty"`
+	Type     *string `json:"type,omitempty"`
+	RawURL   *string `json:"raw_url,omitempty"`
+	Content  *string `json:"content,omitempty"`
+}
+
+func (g GistFile) String() string {
+	return Stringify(g)
+}
+
+// GistCommit represents a commit on a gist.
+type GistCommit struct {
+	URL          *string      `json:"url,omitempty"`
+	Version      *string      `json:"version,omitempty"`
+	User         *User        `json:"user,omitempty"`
+	ChangeStatus *CommitStats `json:"change_status,omitempty"`
+	CommittedAt  *Timestamp   `json:"committed_at,omitempty"`
+	NodeID       *string      `json:"node_id,omitempty"`
+}
+
+func (gc GistCommit) String() string {
+	return Stringify(gc)
+}
+
+// GistFork represents a fork of a gist.
+type GistFork struct {
+	URL       *string    `json:"url,omitempty"`
+	User      *User      `json:"user,omitempty"`
+	ID        *string    `json:"id,omitempty"`
+	CreatedAt *Timestamp `json:"created_at,omitempty"`
+	UpdatedAt *Timestamp `json:"updated_at,omitempty"`
+	NodeID    *string    `json:"node_id,omitempty"`
+}
+
+func (gf GistFork) String() string {
+	return Stringify(gf)
+}
+
+// GistListOptions specifies the optional parameters to the
+// GistsService.List, GistsService.ListAll, and GistsService.ListStarred methods.
+type GistListOptions struct {
+	// Since filters Gists by time.
+	Since time.Time `url:"since,omitempty"`
+
+	ListOptions
+}
+
+// List gists for a user. Passing the empty string will list
+// all public gists if called anonymously. However, if the call
+// is authenticated, it will returns all gists for the authenticated
+// user.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#list-gists
+func (s *GistsService) List(ctx context.Context, user string, opt *GistListOptions) ([]*Gist, *Response, error) {
+	var u string
+	if user != "" {
+		u = fmt.Sprintf("users/%v/gists", user)
+	} else {
+		u = "gists"
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	var gists []*Gist
+	resp, err := s.client.Do(ctx, req, &gists)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return gists, resp, nil
+}
+
+// ListAll lists all public gists.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#list-gists
+func (s *GistsService) ListAll(ctx context.Context, opt *GistListOptions) ([]*Gist, *Response, error) {
+	u, err := addOptions("gists/public", opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	var gists []*Gist
+	resp, err := s.client.Do(ctx, req, &gists)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return gists, resp, nil
+}
+
+// ListStarred lists starred gists of authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#list-gists
+func (s *GistsService) ListStarred(ctx context.Context, opt *GistListOptions) ([]*Gist, *Response, error) {
+	u, err := addOptions("gists/starred", opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	var gists []*Gist
+	resp, err := s.client.Do(ctx, req, &gists)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return gists, resp, nil
+}
+
+// Get a single gist.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#get-a-single-gist
+func (s *GistsService) Get(ctx context.Context, id string) (*Gist, *Response, error) {
+	u := fmt.Sprintf("gists/%v", id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	gist := new(Gist)
+	resp, err := s.client.Do(ctx, req, gist)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return gist, resp, nil
+}
+
+// GetRevision gets a specific revision of a gist.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#get-a-specific-revision-of-a-gist
+func (s *GistsService) GetRevision(ctx context.Context, id, sha string) (*Gist, *Response, error) {
+	u := fmt.Sprintf("gists/%v/%v", id, sha)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	gist := new(Gist)
+	resp, err := s.client.Do(ctx, req, gist)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return gist, resp, nil
+}
+
+// Create a gist for authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#create-a-gist
+func (s *GistsService) Create(ctx context.Context, gist *Gist) (*Gist, *Response, error) {
+	u := "gists"
+	req, err := s.client.NewRequest("POST", u, gist)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	g := new(Gist)
+	resp, err := s.client.Do(ctx, req, g)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return g, resp, nil
+}
+
+// Edit a gist.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#edit-a-gist
+func (s *GistsService) Edit(ctx context.Context, id string, gist *Gist) (*Gist, *Response, error) {
+	u := fmt.Sprintf("gists/%v", id)
+	req, err := s.client.NewRequest("PATCH", u, gist)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	g := new(Gist)
+	resp, err := s.client.Do(ctx, req, g)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return g, resp, nil
+}
+
+// ListCommits lists commits of a gist.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#list-gist-commits
+func (s *GistsService) ListCommits(ctx context.Context, id string, opt *ListOptions) ([]*GistCommit, *Response, error) {
+	u := fmt.Sprintf("gists/%v/commits", id)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	var gistCommits []*GistCommit
+	resp, err := s.client.Do(ctx, req, &gistCommits)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return gistCommits, resp, nil
+}
+
+// Delete a gist.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#delete-a-gist
+func (s *GistsService) Delete(ctx context.Context, id string) (*Response, error) {
+	u := fmt.Sprintf("gists/%v", id)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
+
+// Star a gist on behalf of authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#star-a-gist
+func (s *GistsService) Star(ctx context.Context, id string) (*Response, error) {
+	u := fmt.Sprintf("gists/%v/star", id)
+	req, err := s.client.NewRequest("PUT", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
+
+// Unstar a gist on a behalf of authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#unstar-a-gist
+func (s *GistsService) Unstar(ctx context.Context, id string) (*Response, error) {
+	u := fmt.Sprintf("gists/%v/star", id)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
+
+// IsStarred checks if a gist is starred by authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#check-if-a-gist-is-starred
+func (s *GistsService) IsStarred(ctx context.Context, id string) (bool, *Response, error) {
+	u := fmt.Sprintf("gists/%v/star", id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return false, nil, err
+	}
+	resp, err := s.client.Do(ctx, req, nil)
+	starred, err := parseBoolResponse(err)
+	return starred, resp, err
+}
+
+// Fork a gist.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#fork-a-gist
+func (s *GistsService) Fork(ctx context.Context, id string) (*Gist, *Response, error) {
+	u := fmt.Sprintf("gists/%v/forks", id)
+	req, err := s.client.NewRequest("POST", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	g := new(Gist)
+	resp, err := s.client.Do(ctx, req, g)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return g, resp, nil
+}
+
+// ListForks lists forks of a gist.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/#list-gist-forks
+func (s *GistsService) ListForks(ctx context.Context, id string) ([]*GistFork, *Response, error) {
+	u := fmt.Sprintf("gists/%v/forks", id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	var gistForks []*GistFork
+	resp, err := s.client.Do(ctx, req, &gistForks)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return gistForks, resp, nil
+}

+ 119 - 0
vendor/github.com/google/go-github/github/gists_comments.go

@@ -0,0 +1,119 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// GistComment represents a Gist comment.
+type GistComment struct {
+	ID        *int64     `json:"id,omitempty"`
+	URL       *string    `json:"url,omitempty"`
+	Body      *string    `json:"body,omitempty"`
+	User      *User      `json:"user,omitempty"`
+	CreatedAt *time.Time `json:"created_at,omitempty"`
+}
+
+func (g GistComment) String() string {
+	return Stringify(g)
+}
+
+// ListComments lists all comments for a gist.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/comments/#list-comments-on-a-gist
+func (s *GistsService) ListComments(ctx context.Context, gistID string, opt *ListOptions) ([]*GistComment, *Response, error) {
+	u := fmt.Sprintf("gists/%v/comments", gistID)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var comments []*GistComment
+	resp, err := s.client.Do(ctx, req, &comments)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return comments, resp, nil
+}
+
+// GetComment retrieves a single comment from a gist.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/comments/#get-a-single-comment
+func (s *GistsService) GetComment(ctx context.Context, gistID string, commentID int64) (*GistComment, *Response, error) {
+	u := fmt.Sprintf("gists/%v/comments/%v", gistID, commentID)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	c := new(GistComment)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// CreateComment creates a comment for a gist.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/comments/#create-a-comment
+func (s *GistsService) CreateComment(ctx context.Context, gistID string, comment *GistComment) (*GistComment, *Response, error) {
+	u := fmt.Sprintf("gists/%v/comments", gistID)
+	req, err := s.client.NewRequest("POST", u, comment)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	c := new(GistComment)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// EditComment edits an existing gist comment.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/comments/#edit-a-comment
+func (s *GistsService) EditComment(ctx context.Context, gistID string, commentID int64, comment *GistComment) (*GistComment, *Response, error) {
+	u := fmt.Sprintf("gists/%v/comments/%v", gistID, commentID)
+	req, err := s.client.NewRequest("PATCH", u, comment)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	c := new(GistComment)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// DeleteComment deletes a gist comment.
+//
+// GitHub API docs: https://developer.github.com/v3/gists/comments/#delete-a-comment
+func (s *GistsService) DeleteComment(ctx context.Context, gistID string, commentID int64) (*Response, error) {
+	u := fmt.Sprintf("gists/%v/comments/%v", gistID, commentID)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}

+ 12 - 0
vendor/github.com/google/go-github/github/git.go

@@ -0,0 +1,12 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+// GitService handles communication with the git data related
+// methods of the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/git/
+type GitService service

+ 57 - 0
vendor/github.com/google/go-github/github/git_blobs.go

@@ -0,0 +1,57 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// Blob represents a blob object.
+type Blob struct {
+	Content  *string `json:"content,omitempty"`
+	Encoding *string `json:"encoding,omitempty"`
+	SHA      *string `json:"sha,omitempty"`
+	Size     *int    `json:"size,omitempty"`
+	URL      *string `json:"url,omitempty"`
+	NodeID   *string `json:"node_id,omitempty"`
+}
+
+// GetBlob fetchs a blob from a repo given a SHA.
+//
+// GitHub API docs: https://developer.github.com/v3/git/blobs/#get-a-blob
+func (s *GitService) GetBlob(ctx context.Context, owner string, repo string, sha string) (*Blob, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/git/blobs/%v", owner, repo, sha)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	blob := new(Blob)
+	resp, err := s.client.Do(ctx, req, blob)
+	return blob, resp, err
+}
+
+// CreateBlob creates a blob object.
+//
+// GitHub API docs: https://developer.github.com/v3/git/blobs/#create-a-blob
+func (s *GitService) CreateBlob(ctx context.Context, owner string, repo string, blob *Blob) (*Blob, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/git/blobs", owner, repo)
+	req, err := s.client.NewRequest("POST", u, blob)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	t := new(Blob)
+	resp, err := s.client.Do(ctx, req, t)
+	return t, resp, err
+}

+ 139 - 0
vendor/github.com/google/go-github/github/git_commits.go

@@ -0,0 +1,139 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"strings"
+	"time"
+)
+
+// SignatureVerification represents GPG signature verification.
+type SignatureVerification struct {
+	Verified  *bool   `json:"verified,omitempty"`
+	Reason    *string `json:"reason,omitempty"`
+	Signature *string `json:"signature,omitempty"`
+	Payload   *string `json:"payload,omitempty"`
+}
+
+// Commit represents a GitHub commit.
+type Commit struct {
+	SHA          *string                `json:"sha,omitempty"`
+	Author       *CommitAuthor          `json:"author,omitempty"`
+	Committer    *CommitAuthor          `json:"committer,omitempty"`
+	Message      *string                `json:"message,omitempty"`
+	Tree         *Tree                  `json:"tree,omitempty"`
+	Parents      []Commit               `json:"parents,omitempty"`
+	Stats        *CommitStats           `json:"stats,omitempty"`
+	HTMLURL      *string                `json:"html_url,omitempty"`
+	URL          *string                `json:"url,omitempty"`
+	Verification *SignatureVerification `json:"verification,omitempty"`
+	NodeID       *string                `json:"node_id,omitempty"`
+
+	// CommentCount is the number of GitHub comments on the commit. This
+	// is only populated for requests that fetch GitHub data like
+	// Pulls.ListCommits, Repositories.ListCommits, etc.
+	CommentCount *int `json:"comment_count,omitempty"`
+}
+
+func (c Commit) String() string {
+	return Stringify(c)
+}
+
+// CommitAuthor represents the author or committer of a commit. The commit
+// author may not correspond to a GitHub User.
+type CommitAuthor struct {
+	Date  *time.Time `json:"date,omitempty"`
+	Name  *string    `json:"name,omitempty"`
+	Email *string    `json:"email,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Login *string `json:"username,omitempty"` // Renamed for go-github consistency.
+}
+
+func (c CommitAuthor) String() string {
+	return Stringify(c)
+}
+
+// GetCommit fetchs the Commit object for a given SHA.
+//
+// GitHub API docs: https://developer.github.com/v3/git/commits/#get-a-commit
+func (s *GitService) GetCommit(ctx context.Context, owner string, repo string, sha string) (*Commit, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/git/commits/%v", owner, repo, sha)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeGitSigningPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	c := new(Commit)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// createCommit represents the body of a CreateCommit request.
+type createCommit struct {
+	Author    *CommitAuthor `json:"author,omitempty"`
+	Committer *CommitAuthor `json:"committer,omitempty"`
+	Message   *string       `json:"message,omitempty"`
+	Tree      *string       `json:"tree,omitempty"`
+	Parents   []string      `json:"parents,omitempty"`
+}
+
+// CreateCommit creates a new commit in a repository.
+// commit must not be nil.
+//
+// The commit.Committer is optional and will be filled with the commit.Author
+// data if omitted. If the commit.Author is omitted, it will be filled in with
+// the authenticated user’s information and the current date.
+//
+// GitHub API docs: https://developer.github.com/v3/git/commits/#create-a-commit
+func (s *GitService) CreateCommit(ctx context.Context, owner string, repo string, commit *Commit) (*Commit, *Response, error) {
+	if commit == nil {
+		return nil, nil, fmt.Errorf("commit must be provided")
+	}
+
+	u := fmt.Sprintf("repos/%v/%v/git/commits", owner, repo)
+
+	parents := make([]string, len(commit.Parents))
+	for i, parent := range commit.Parents {
+		parents[i] = *parent.SHA
+	}
+
+	body := &createCommit{
+		Author:    commit.Author,
+		Committer: commit.Committer,
+		Message:   commit.Message,
+		Parents:   parents,
+	}
+	if commit.Tree != nil {
+		body.Tree = commit.Tree.SHA
+	}
+
+	req, err := s.client.NewRequest("POST", u, body)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	c := new(Commit)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}

+ 233 - 0
vendor/github.com/google/go-github/github/git_refs.go

@@ -0,0 +1,233 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"strings"
+)
+
+// Reference represents a GitHub reference.
+type Reference struct {
+	Ref    *string    `json:"ref"`
+	URL    *string    `json:"url"`
+	Object *GitObject `json:"object"`
+	NodeID *string    `json:"node_id,omitempty"`
+}
+
+func (r Reference) String() string {
+	return Stringify(r)
+}
+
+// GitObject represents a Git object.
+type GitObject struct {
+	Type *string `json:"type"`
+	SHA  *string `json:"sha"`
+	URL  *string `json:"url"`
+}
+
+func (o GitObject) String() string {
+	return Stringify(o)
+}
+
+// createRefRequest represents the payload for creating a reference.
+type createRefRequest struct {
+	Ref *string `json:"ref"`
+	SHA *string `json:"sha"`
+}
+
+// updateRefRequest represents the payload for updating a reference.
+type updateRefRequest struct {
+	SHA   *string `json:"sha"`
+	Force *bool   `json:"force"`
+}
+
+// GetRef fetches a single Reference object for a given Git ref.
+// If there is no exact match, GetRef will return an error.
+//
+// Note: The GitHub API can return multiple matches.
+// If you wish to use this functionality please use the GetRefs() method.
+//
+// GitHub API docs: https://developer.github.com/v3/git/refs/#get-a-reference
+func (s *GitService) GetRef(ctx context.Context, owner string, repo string, ref string) (*Reference, *Response, error) {
+	ref = strings.TrimPrefix(ref, "refs/")
+	u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, ref)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	r := new(Reference)
+	resp, err := s.client.Do(ctx, req, r)
+	if _, ok := err.(*json.UnmarshalTypeError); ok {
+		// Multiple refs, means there wasn't an exact match.
+		return nil, resp, errors.New("no exact match found for this ref")
+	} else if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// GetRefs fetches a slice of Reference objects for a given Git ref.
+// If there is an exact match, only that ref is returned.
+// If there is no exact match, GitHub returns all refs that start with ref.
+// If returned error is nil, there will be at least 1 ref returned.
+// For example:
+//
+// 	"heads/featureA" -> ["refs/heads/featureA"]                         // Exact match, single ref is returned.
+// 	"heads/feature"  -> ["refs/heads/featureA", "refs/heads/featureB"]  // All refs that start with ref.
+// 	"heads/notexist" -> []                                              // Returns an error.
+//
+// GitHub API docs: https://developer.github.com/v3/git/refs/#get-a-reference
+func (s *GitService) GetRefs(ctx context.Context, owner string, repo string, ref string) ([]*Reference, *Response, error) {
+	ref = strings.TrimPrefix(ref, "refs/")
+	u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, ref)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	var rawJSON json.RawMessage
+	resp, err := s.client.Do(ctx, req, &rawJSON)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	// Prioritize the most common case: a single returned ref.
+	r := new(Reference)
+	singleUnmarshalError := json.Unmarshal(rawJSON, r)
+	if singleUnmarshalError == nil {
+		return []*Reference{r}, resp, nil
+	}
+
+	// Attempt to unmarshal multiple refs.
+	var rs []*Reference
+	multipleUnmarshalError := json.Unmarshal(rawJSON, &rs)
+	if multipleUnmarshalError == nil {
+		if len(rs) == 0 {
+			return nil, resp, fmt.Errorf("unexpected response from GitHub API: an array of refs with length 0")
+		}
+		return rs, resp, nil
+	}
+
+	return nil, resp, fmt.Errorf("unmarshalling failed for both single and multiple refs: %s and %s", singleUnmarshalError, multipleUnmarshalError)
+}
+
+// ReferenceListOptions specifies optional parameters to the
+// GitService.ListRefs method.
+type ReferenceListOptions struct {
+	Type string `url:"-"`
+
+	ListOptions
+}
+
+// ListRefs lists all refs in a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/git/refs/#get-all-references
+func (s *GitService) ListRefs(ctx context.Context, owner, repo string, opt *ReferenceListOptions) ([]*Reference, *Response, error) {
+	var u string
+	if opt != nil && opt.Type != "" {
+		u = fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, opt.Type)
+	} else {
+		u = fmt.Sprintf("repos/%v/%v/git/refs", owner, repo)
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	var rs []*Reference
+	resp, err := s.client.Do(ctx, req, &rs)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return rs, resp, nil
+}
+
+// CreateRef creates a new ref in a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/git/refs/#create-a-reference
+func (s *GitService) CreateRef(ctx context.Context, owner string, repo string, ref *Reference) (*Reference, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/git/refs", owner, repo)
+	req, err := s.client.NewRequest("POST", u, &createRefRequest{
+		// back-compat with previous behavior that didn't require 'refs/' prefix
+		Ref: String("refs/" + strings.TrimPrefix(*ref.Ref, "refs/")),
+		SHA: ref.Object.SHA,
+	})
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	r := new(Reference)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// UpdateRef updates an existing ref in a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/git/refs/#update-a-reference
+func (s *GitService) UpdateRef(ctx context.Context, owner string, repo string, ref *Reference, force bool) (*Reference, *Response, error) {
+	refPath := strings.TrimPrefix(*ref.Ref, "refs/")
+	u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, refPath)
+	req, err := s.client.NewRequest("PATCH", u, &updateRefRequest{
+		SHA:   ref.Object.SHA,
+		Force: &force,
+	})
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	r := new(Reference)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// DeleteRef deletes a ref from a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/git/refs/#delete-a-reference
+func (s *GitService) DeleteRef(ctx context.Context, owner string, repo string, ref string) (*Response, error) {
+	ref = strings.TrimPrefix(ref, "refs/")
+	u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, ref)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}

+ 84 - 0
vendor/github.com/google/go-github/github/git_tags.go

@@ -0,0 +1,84 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"strings"
+)
+
+// Tag represents a tag object.
+type Tag struct {
+	Tag          *string                `json:"tag,omitempty"`
+	SHA          *string                `json:"sha,omitempty"`
+	URL          *string                `json:"url,omitempty"`
+	Message      *string                `json:"message,omitempty"`
+	Tagger       *CommitAuthor          `json:"tagger,omitempty"`
+	Object       *GitObject             `json:"object,omitempty"`
+	Verification *SignatureVerification `json:"verification,omitempty"`
+	NodeID       *string                `json:"node_id,omitempty"`
+}
+
+// createTagRequest represents the body of a CreateTag request. This is mostly
+// identical to Tag with the exception that the object SHA and Type are
+// top-level fields, rather than being nested inside a JSON object.
+type createTagRequest struct {
+	Tag     *string       `json:"tag,omitempty"`
+	Message *string       `json:"message,omitempty"`
+	Object  *string       `json:"object,omitempty"`
+	Type    *string       `json:"type,omitempty"`
+	Tagger  *CommitAuthor `json:"tagger,omitempty"`
+}
+
+// GetTag fetchs a tag from a repo given a SHA.
+//
+// GitHub API docs: https://developer.github.com/v3/git/tags/#get-a-tag
+func (s *GitService) GetTag(ctx context.Context, owner string, repo string, sha string) (*Tag, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/git/tags/%v", owner, repo, sha)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeGitSigningPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	tag := new(Tag)
+	resp, err := s.client.Do(ctx, req, tag)
+	return tag, resp, err
+}
+
+// CreateTag creates a tag object.
+//
+// GitHub API docs: https://developer.github.com/v3/git/tags/#create-a-tag-object
+func (s *GitService) CreateTag(ctx context.Context, owner string, repo string, tag *Tag) (*Tag, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/git/tags", owner, repo)
+
+	// convert Tag into a createTagRequest
+	tagRequest := &createTagRequest{
+		Tag:     tag.Tag,
+		Message: tag.Message,
+		Tagger:  tag.Tagger,
+	}
+	if tag.Object != nil {
+		tagRequest.Object = tag.Object.SHA
+		tagRequest.Type = tag.Object.Type
+	}
+
+	req, err := s.client.NewRequest("POST", u, tagRequest)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	t := new(Tag)
+	resp, err := s.client.Do(ctx, req, t)
+	return t, resp, err
+}

+ 93 - 0
vendor/github.com/google/go-github/github/git_trees.go

@@ -0,0 +1,93 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// Tree represents a GitHub tree.
+type Tree struct {
+	SHA     *string     `json:"sha,omitempty"`
+	Entries []TreeEntry `json:"tree,omitempty"`
+}
+
+func (t Tree) String() string {
+	return Stringify(t)
+}
+
+// TreeEntry represents the contents of a tree structure. TreeEntry can
+// represent either a blob, a commit (in the case of a submodule), or another
+// tree.
+type TreeEntry struct {
+	SHA     *string `json:"sha,omitempty"`
+	Path    *string `json:"path,omitempty"`
+	Mode    *string `json:"mode,omitempty"`
+	Type    *string `json:"type,omitempty"`
+	Size    *int    `json:"size,omitempty"`
+	Content *string `json:"content,omitempty"`
+	URL     *string `json:"url,omitempty"`
+}
+
+func (t TreeEntry) String() string {
+	return Stringify(t)
+}
+
+// GetTree fetches the Tree object for a given sha hash from a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/git/trees/#get-a-tree
+func (s *GitService) GetTree(ctx context.Context, owner string, repo string, sha string, recursive bool) (*Tree, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/git/trees/%v", owner, repo, sha)
+	if recursive {
+		u += "?recursive=1"
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	t := new(Tree)
+	resp, err := s.client.Do(ctx, req, t)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return t, resp, nil
+}
+
+// createTree represents the body of a CreateTree request.
+type createTree struct {
+	BaseTree string      `json:"base_tree,omitempty"`
+	Entries  []TreeEntry `json:"tree"`
+}
+
+// CreateTree creates a new tree in a repository. If both a tree and a nested
+// path modifying that tree are specified, it will overwrite the contents of
+// that tree with the new path contents and write a new tree out.
+//
+// GitHub API docs: https://developer.github.com/v3/git/trees/#create-a-tree
+func (s *GitService) CreateTree(ctx context.Context, owner string, repo string, baseTree string, entries []TreeEntry) (*Tree, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/git/trees", owner, repo)
+
+	body := &createTree{
+		BaseTree: baseTree,
+		Entries:  entries,
+	}
+	req, err := s.client.NewRequest("POST", u, body)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	t := new(Tree)
+	resp, err := s.client.Do(ctx, req, t)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return t, resp, nil
+}

+ 10429 - 0
vendor/github.com/google/go-github/github/github-accessors.go

@@ -0,0 +1,10429 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code generated by gen-accessors; DO NOT EDIT.
+
+package github
+
+import (
+	"encoding/json"
+	"time"
+)
+
+// GetRetryAfter returns the RetryAfter field if it's non-nil, zero value otherwise.
+func (a *AbuseRateLimitError) GetRetryAfter() time.Duration {
+	if a == nil || a.RetryAfter == nil {
+		return 0
+	}
+	return *a.RetryAfter
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (a *AdminEnforcement) GetURL() string {
+	if a == nil || a.URL == nil {
+		return ""
+	}
+	return *a.URL
+}
+
+// GetComments returns the Comments field.
+func (a *AdminStats) GetComments() *CommentStats {
+	if a == nil {
+		return nil
+	}
+	return a.Comments
+}
+
+// GetGists returns the Gists field.
+func (a *AdminStats) GetGists() *GistStats {
+	if a == nil {
+		return nil
+	}
+	return a.Gists
+}
+
+// GetHooks returns the Hooks field.
+func (a *AdminStats) GetHooks() *HookStats {
+	if a == nil {
+		return nil
+	}
+	return a.Hooks
+}
+
+// GetIssues returns the Issues field.
+func (a *AdminStats) GetIssues() *IssueStats {
+	if a == nil {
+		return nil
+	}
+	return a.Issues
+}
+
+// GetMilestones returns the Milestones field.
+func (a *AdminStats) GetMilestones() *MilestoneStats {
+	if a == nil {
+		return nil
+	}
+	return a.Milestones
+}
+
+// GetOrgs returns the Orgs field.
+func (a *AdminStats) GetOrgs() *OrgStats {
+	if a == nil {
+		return nil
+	}
+	return a.Orgs
+}
+
+// GetPages returns the Pages field.
+func (a *AdminStats) GetPages() *PageStats {
+	if a == nil {
+		return nil
+	}
+	return a.Pages
+}
+
+// GetPulls returns the Pulls field.
+func (a *AdminStats) GetPulls() *PullStats {
+	if a == nil {
+		return nil
+	}
+	return a.Pulls
+}
+
+// GetRepos returns the Repos field.
+func (a *AdminStats) GetRepos() *RepoStats {
+	if a == nil {
+		return nil
+	}
+	return a.Repos
+}
+
+// GetUsers returns the Users field.
+func (a *AdminStats) GetUsers() *UserStats {
+	if a == nil {
+		return nil
+	}
+	return a.Users
+}
+
+// GetVerifiablePasswordAuthentication returns the VerifiablePasswordAuthentication field if it's non-nil, zero value otherwise.
+func (a *APIMeta) GetVerifiablePasswordAuthentication() bool {
+	if a == nil || a.VerifiablePasswordAuthentication == nil {
+		return false
+	}
+	return *a.VerifiablePasswordAuthentication
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (a *App) GetCreatedAt() time.Time {
+	if a == nil || a.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *a.CreatedAt
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (a *App) GetDescription() string {
+	if a == nil || a.Description == nil {
+		return ""
+	}
+	return *a.Description
+}
+
+// GetExternalURL returns the ExternalURL field if it's non-nil, zero value otherwise.
+func (a *App) GetExternalURL() string {
+	if a == nil || a.ExternalURL == nil {
+		return ""
+	}
+	return *a.ExternalURL
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (a *App) GetHTMLURL() string {
+	if a == nil || a.HTMLURL == nil {
+		return ""
+	}
+	return *a.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (a *App) GetID() int64 {
+	if a == nil || a.ID == nil {
+		return 0
+	}
+	return *a.ID
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (a *App) GetName() string {
+	if a == nil || a.Name == nil {
+		return ""
+	}
+	return *a.Name
+}
+
+// GetOwner returns the Owner field.
+func (a *App) GetOwner() *User {
+	if a == nil {
+		return nil
+	}
+	return a.Owner
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (a *App) GetUpdatedAt() time.Time {
+	if a == nil || a.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *a.UpdatedAt
+}
+
+// GetApp returns the App field.
+func (a *Authorization) GetApp() *AuthorizationApp {
+	if a == nil {
+		return nil
+	}
+	return a.App
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (a *Authorization) GetCreatedAt() Timestamp {
+	if a == nil || a.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *a.CreatedAt
+}
+
+// GetFingerprint returns the Fingerprint field if it's non-nil, zero value otherwise.
+func (a *Authorization) GetFingerprint() string {
+	if a == nil || a.Fingerprint == nil {
+		return ""
+	}
+	return *a.Fingerprint
+}
+
+// GetHashedToken returns the HashedToken field if it's non-nil, zero value otherwise.
+func (a *Authorization) GetHashedToken() string {
+	if a == nil || a.HashedToken == nil {
+		return ""
+	}
+	return *a.HashedToken
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (a *Authorization) GetID() int64 {
+	if a == nil || a.ID == nil {
+		return 0
+	}
+	return *a.ID
+}
+
+// GetNote returns the Note field if it's non-nil, zero value otherwise.
+func (a *Authorization) GetNote() string {
+	if a == nil || a.Note == nil {
+		return ""
+	}
+	return *a.Note
+}
+
+// GetNoteURL returns the NoteURL field if it's non-nil, zero value otherwise.
+func (a *Authorization) GetNoteURL() string {
+	if a == nil || a.NoteURL == nil {
+		return ""
+	}
+	return *a.NoteURL
+}
+
+// GetToken returns the Token field if it's non-nil, zero value otherwise.
+func (a *Authorization) GetToken() string {
+	if a == nil || a.Token == nil {
+		return ""
+	}
+	return *a.Token
+}
+
+// GetTokenLastEight returns the TokenLastEight field if it's non-nil, zero value otherwise.
+func (a *Authorization) GetTokenLastEight() string {
+	if a == nil || a.TokenLastEight == nil {
+		return ""
+	}
+	return *a.TokenLastEight
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (a *Authorization) GetUpdatedAt() Timestamp {
+	if a == nil || a.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *a.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (a *Authorization) GetURL() string {
+	if a == nil || a.URL == nil {
+		return ""
+	}
+	return *a.URL
+}
+
+// GetUser returns the User field.
+func (a *Authorization) GetUser() *User {
+	if a == nil {
+		return nil
+	}
+	return a.User
+}
+
+// GetClientID returns the ClientID field if it's non-nil, zero value otherwise.
+func (a *AuthorizationApp) GetClientID() string {
+	if a == nil || a.ClientID == nil {
+		return ""
+	}
+	return *a.ClientID
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (a *AuthorizationApp) GetName() string {
+	if a == nil || a.Name == nil {
+		return ""
+	}
+	return *a.Name
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (a *AuthorizationApp) GetURL() string {
+	if a == nil || a.URL == nil {
+		return ""
+	}
+	return *a.URL
+}
+
+// GetClientID returns the ClientID field if it's non-nil, zero value otherwise.
+func (a *AuthorizationRequest) GetClientID() string {
+	if a == nil || a.ClientID == nil {
+		return ""
+	}
+	return *a.ClientID
+}
+
+// GetClientSecret returns the ClientSecret field if it's non-nil, zero value otherwise.
+func (a *AuthorizationRequest) GetClientSecret() string {
+	if a == nil || a.ClientSecret == nil {
+		return ""
+	}
+	return *a.ClientSecret
+}
+
+// GetFingerprint returns the Fingerprint field if it's non-nil, zero value otherwise.
+func (a *AuthorizationRequest) GetFingerprint() string {
+	if a == nil || a.Fingerprint == nil {
+		return ""
+	}
+	return *a.Fingerprint
+}
+
+// GetNote returns the Note field if it's non-nil, zero value otherwise.
+func (a *AuthorizationRequest) GetNote() string {
+	if a == nil || a.Note == nil {
+		return ""
+	}
+	return *a.Note
+}
+
+// GetNoteURL returns the NoteURL field if it's non-nil, zero value otherwise.
+func (a *AuthorizationRequest) GetNoteURL() string {
+	if a == nil || a.NoteURL == nil {
+		return ""
+	}
+	return *a.NoteURL
+}
+
+// GetFingerprint returns the Fingerprint field if it's non-nil, zero value otherwise.
+func (a *AuthorizationUpdateRequest) GetFingerprint() string {
+	if a == nil || a.Fingerprint == nil {
+		return ""
+	}
+	return *a.Fingerprint
+}
+
+// GetNote returns the Note field if it's non-nil, zero value otherwise.
+func (a *AuthorizationUpdateRequest) GetNote() string {
+	if a == nil || a.Note == nil {
+		return ""
+	}
+	return *a.Note
+}
+
+// GetNoteURL returns the NoteURL field if it's non-nil, zero value otherwise.
+func (a *AuthorizationUpdateRequest) GetNoteURL() string {
+	if a == nil || a.NoteURL == nil {
+		return ""
+	}
+	return *a.NoteURL
+}
+
+// GetContent returns the Content field if it's non-nil, zero value otherwise.
+func (b *Blob) GetContent() string {
+	if b == nil || b.Content == nil {
+		return ""
+	}
+	return *b.Content
+}
+
+// GetEncoding returns the Encoding field if it's non-nil, zero value otherwise.
+func (b *Blob) GetEncoding() string {
+	if b == nil || b.Encoding == nil {
+		return ""
+	}
+	return *b.Encoding
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (b *Blob) GetNodeID() string {
+	if b == nil || b.NodeID == nil {
+		return ""
+	}
+	return *b.NodeID
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (b *Blob) GetSHA() string {
+	if b == nil || b.SHA == nil {
+		return ""
+	}
+	return *b.SHA
+}
+
+// GetSize returns the Size field if it's non-nil, zero value otherwise.
+func (b *Blob) GetSize() int {
+	if b == nil || b.Size == nil {
+		return 0
+	}
+	return *b.Size
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (b *Blob) GetURL() string {
+	if b == nil || b.URL == nil {
+		return ""
+	}
+	return *b.URL
+}
+
+// GetCommit returns the Commit field.
+func (b *Branch) GetCommit() *RepositoryCommit {
+	if b == nil {
+		return nil
+	}
+	return b.Commit
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (b *Branch) GetName() string {
+	if b == nil || b.Name == nil {
+		return ""
+	}
+	return *b.Name
+}
+
+// GetProtected returns the Protected field if it's non-nil, zero value otherwise.
+func (b *Branch) GetProtected() bool {
+	if b == nil || b.Protected == nil {
+		return false
+	}
+	return *b.Protected
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (c *CodeOfConduct) GetBody() string {
+	if c == nil || c.Body == nil {
+		return ""
+	}
+	return *c.Body
+}
+
+// GetKey returns the Key field if it's non-nil, zero value otherwise.
+func (c *CodeOfConduct) GetKey() string {
+	if c == nil || c.Key == nil {
+		return ""
+	}
+	return *c.Key
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (c *CodeOfConduct) GetName() string {
+	if c == nil || c.Name == nil {
+		return ""
+	}
+	return *c.Name
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (c *CodeOfConduct) GetURL() string {
+	if c == nil || c.URL == nil {
+		return ""
+	}
+	return *c.URL
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (c *CodeResult) GetHTMLURL() string {
+	if c == nil || c.HTMLURL == nil {
+		return ""
+	}
+	return *c.HTMLURL
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (c *CodeResult) GetName() string {
+	if c == nil || c.Name == nil {
+		return ""
+	}
+	return *c.Name
+}
+
+// GetPath returns the Path field if it's non-nil, zero value otherwise.
+func (c *CodeResult) GetPath() string {
+	if c == nil || c.Path == nil {
+		return ""
+	}
+	return *c.Path
+}
+
+// GetRepository returns the Repository field.
+func (c *CodeResult) GetRepository() *Repository {
+	if c == nil {
+		return nil
+	}
+	return c.Repository
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (c *CodeResult) GetSHA() string {
+	if c == nil || c.SHA == nil {
+		return ""
+	}
+	return *c.SHA
+}
+
+// GetIncompleteResults returns the IncompleteResults field if it's non-nil, zero value otherwise.
+func (c *CodeSearchResult) GetIncompleteResults() bool {
+	if c == nil || c.IncompleteResults == nil {
+		return false
+	}
+	return *c.IncompleteResults
+}
+
+// GetTotal returns the Total field if it's non-nil, zero value otherwise.
+func (c *CodeSearchResult) GetTotal() int {
+	if c == nil || c.Total == nil {
+		return 0
+	}
+	return *c.Total
+}
+
+// GetCommitURL returns the CommitURL field if it's non-nil, zero value otherwise.
+func (c *CombinedStatus) GetCommitURL() string {
+	if c == nil || c.CommitURL == nil {
+		return ""
+	}
+	return *c.CommitURL
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (c *CombinedStatus) GetName() string {
+	if c == nil || c.Name == nil {
+		return ""
+	}
+	return *c.Name
+}
+
+// GetRepositoryURL returns the RepositoryURL field if it's non-nil, zero value otherwise.
+func (c *CombinedStatus) GetRepositoryURL() string {
+	if c == nil || c.RepositoryURL == nil {
+		return ""
+	}
+	return *c.RepositoryURL
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (c *CombinedStatus) GetSHA() string {
+	if c == nil || c.SHA == nil {
+		return ""
+	}
+	return *c.SHA
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (c *CombinedStatus) GetState() string {
+	if c == nil || c.State == nil {
+		return ""
+	}
+	return *c.State
+}
+
+// GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise.
+func (c *CombinedStatus) GetTotalCount() int {
+	if c == nil || c.TotalCount == nil {
+		return 0
+	}
+	return *c.TotalCount
+}
+
+// GetTotalCommitComments returns the TotalCommitComments field if it's non-nil, zero value otherwise.
+func (c *CommentStats) GetTotalCommitComments() int {
+	if c == nil || c.TotalCommitComments == nil {
+		return 0
+	}
+	return *c.TotalCommitComments
+}
+
+// GetTotalGistComments returns the TotalGistComments field if it's non-nil, zero value otherwise.
+func (c *CommentStats) GetTotalGistComments() int {
+	if c == nil || c.TotalGistComments == nil {
+		return 0
+	}
+	return *c.TotalGistComments
+}
+
+// GetTotalIssueComments returns the TotalIssueComments field if it's non-nil, zero value otherwise.
+func (c *CommentStats) GetTotalIssueComments() int {
+	if c == nil || c.TotalIssueComments == nil {
+		return 0
+	}
+	return *c.TotalIssueComments
+}
+
+// GetTotalPullRequestComments returns the TotalPullRequestComments field if it's non-nil, zero value otherwise.
+func (c *CommentStats) GetTotalPullRequestComments() int {
+	if c == nil || c.TotalPullRequestComments == nil {
+		return 0
+	}
+	return *c.TotalPullRequestComments
+}
+
+// GetAuthor returns the Author field.
+func (c *Commit) GetAuthor() *CommitAuthor {
+	if c == nil {
+		return nil
+	}
+	return c.Author
+}
+
+// GetCommentCount returns the CommentCount field if it's non-nil, zero value otherwise.
+func (c *Commit) GetCommentCount() int {
+	if c == nil || c.CommentCount == nil {
+		return 0
+	}
+	return *c.CommentCount
+}
+
+// GetCommitter returns the Committer field.
+func (c *Commit) GetCommitter() *CommitAuthor {
+	if c == nil {
+		return nil
+	}
+	return c.Committer
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (c *Commit) GetHTMLURL() string {
+	if c == nil || c.HTMLURL == nil {
+		return ""
+	}
+	return *c.HTMLURL
+}
+
+// GetMessage returns the Message field if it's non-nil, zero value otherwise.
+func (c *Commit) GetMessage() string {
+	if c == nil || c.Message == nil {
+		return ""
+	}
+	return *c.Message
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (c *Commit) GetNodeID() string {
+	if c == nil || c.NodeID == nil {
+		return ""
+	}
+	return *c.NodeID
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (c *Commit) GetSHA() string {
+	if c == nil || c.SHA == nil {
+		return ""
+	}
+	return *c.SHA
+}
+
+// GetStats returns the Stats field.
+func (c *Commit) GetStats() *CommitStats {
+	if c == nil {
+		return nil
+	}
+	return c.Stats
+}
+
+// GetTree returns the Tree field.
+func (c *Commit) GetTree() *Tree {
+	if c == nil {
+		return nil
+	}
+	return c.Tree
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (c *Commit) GetURL() string {
+	if c == nil || c.URL == nil {
+		return ""
+	}
+	return *c.URL
+}
+
+// GetVerification returns the Verification field.
+func (c *Commit) GetVerification() *SignatureVerification {
+	if c == nil {
+		return nil
+	}
+	return c.Verification
+}
+
+// GetDate returns the Date field if it's non-nil, zero value otherwise.
+func (c *CommitAuthor) GetDate() time.Time {
+	if c == nil || c.Date == nil {
+		return time.Time{}
+	}
+	return *c.Date
+}
+
+// GetEmail returns the Email field if it's non-nil, zero value otherwise.
+func (c *CommitAuthor) GetEmail() string {
+	if c == nil || c.Email == nil {
+		return ""
+	}
+	return *c.Email
+}
+
+// GetLogin returns the Login field if it's non-nil, zero value otherwise.
+func (c *CommitAuthor) GetLogin() string {
+	if c == nil || c.Login == nil {
+		return ""
+	}
+	return *c.Login
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (c *CommitAuthor) GetName() string {
+	if c == nil || c.Name == nil {
+		return ""
+	}
+	return *c.Name
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (c *CommitCommentEvent) GetAction() string {
+	if c == nil || c.Action == nil {
+		return ""
+	}
+	return *c.Action
+}
+
+// GetComment returns the Comment field.
+func (c *CommitCommentEvent) GetComment() *RepositoryComment {
+	if c == nil {
+		return nil
+	}
+	return c.Comment
+}
+
+// GetInstallation returns the Installation field.
+func (c *CommitCommentEvent) GetInstallation() *Installation {
+	if c == nil {
+		return nil
+	}
+	return c.Installation
+}
+
+// GetRepo returns the Repo field.
+func (c *CommitCommentEvent) GetRepo() *Repository {
+	if c == nil {
+		return nil
+	}
+	return c.Repo
+}
+
+// GetSender returns the Sender field.
+func (c *CommitCommentEvent) GetSender() *User {
+	if c == nil {
+		return nil
+	}
+	return c.Sender
+}
+
+// GetAdditions returns the Additions field if it's non-nil, zero value otherwise.
+func (c *CommitFile) GetAdditions() int {
+	if c == nil || c.Additions == nil {
+		return 0
+	}
+	return *c.Additions
+}
+
+// GetBlobURL returns the BlobURL field if it's non-nil, zero value otherwise.
+func (c *CommitFile) GetBlobURL() string {
+	if c == nil || c.BlobURL == nil {
+		return ""
+	}
+	return *c.BlobURL
+}
+
+// GetChanges returns the Changes field if it's non-nil, zero value otherwise.
+func (c *CommitFile) GetChanges() int {
+	if c == nil || c.Changes == nil {
+		return 0
+	}
+	return *c.Changes
+}
+
+// GetContentsURL returns the ContentsURL field if it's non-nil, zero value otherwise.
+func (c *CommitFile) GetContentsURL() string {
+	if c == nil || c.ContentsURL == nil {
+		return ""
+	}
+	return *c.ContentsURL
+}
+
+// GetDeletions returns the Deletions field if it's non-nil, zero value otherwise.
+func (c *CommitFile) GetDeletions() int {
+	if c == nil || c.Deletions == nil {
+		return 0
+	}
+	return *c.Deletions
+}
+
+// GetFilename returns the Filename field if it's non-nil, zero value otherwise.
+func (c *CommitFile) GetFilename() string {
+	if c == nil || c.Filename == nil {
+		return ""
+	}
+	return *c.Filename
+}
+
+// GetPatch returns the Patch field if it's non-nil, zero value otherwise.
+func (c *CommitFile) GetPatch() string {
+	if c == nil || c.Patch == nil {
+		return ""
+	}
+	return *c.Patch
+}
+
+// GetRawURL returns the RawURL field if it's non-nil, zero value otherwise.
+func (c *CommitFile) GetRawURL() string {
+	if c == nil || c.RawURL == nil {
+		return ""
+	}
+	return *c.RawURL
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (c *CommitFile) GetSHA() string {
+	if c == nil || c.SHA == nil {
+		return ""
+	}
+	return *c.SHA
+}
+
+// GetStatus returns the Status field if it's non-nil, zero value otherwise.
+func (c *CommitFile) GetStatus() string {
+	if c == nil || c.Status == nil {
+		return ""
+	}
+	return *c.Status
+}
+
+// GetAuthor returns the Author field.
+func (c *CommitResult) GetAuthor() *User {
+	if c == nil {
+		return nil
+	}
+	return c.Author
+}
+
+// GetCommentsURL returns the CommentsURL field if it's non-nil, zero value otherwise.
+func (c *CommitResult) GetCommentsURL() string {
+	if c == nil || c.CommentsURL == nil {
+		return ""
+	}
+	return *c.CommentsURL
+}
+
+// GetCommit returns the Commit field.
+func (c *CommitResult) GetCommit() *Commit {
+	if c == nil {
+		return nil
+	}
+	return c.Commit
+}
+
+// GetCommitter returns the Committer field.
+func (c *CommitResult) GetCommitter() *User {
+	if c == nil {
+		return nil
+	}
+	return c.Committer
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (c *CommitResult) GetHTMLURL() string {
+	if c == nil || c.HTMLURL == nil {
+		return ""
+	}
+	return *c.HTMLURL
+}
+
+// GetRepository returns the Repository field.
+func (c *CommitResult) GetRepository() *Repository {
+	if c == nil {
+		return nil
+	}
+	return c.Repository
+}
+
+// GetScore returns the Score field.
+func (c *CommitResult) GetScore() *float64 {
+	if c == nil {
+		return nil
+	}
+	return c.Score
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (c *CommitResult) GetSHA() string {
+	if c == nil || c.SHA == nil {
+		return ""
+	}
+	return *c.SHA
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (c *CommitResult) GetURL() string {
+	if c == nil || c.URL == nil {
+		return ""
+	}
+	return *c.URL
+}
+
+// GetAheadBy returns the AheadBy field if it's non-nil, zero value otherwise.
+func (c *CommitsComparison) GetAheadBy() int {
+	if c == nil || c.AheadBy == nil {
+		return 0
+	}
+	return *c.AheadBy
+}
+
+// GetBaseCommit returns the BaseCommit field.
+func (c *CommitsComparison) GetBaseCommit() *RepositoryCommit {
+	if c == nil {
+		return nil
+	}
+	return c.BaseCommit
+}
+
+// GetBehindBy returns the BehindBy field if it's non-nil, zero value otherwise.
+func (c *CommitsComparison) GetBehindBy() int {
+	if c == nil || c.BehindBy == nil {
+		return 0
+	}
+	return *c.BehindBy
+}
+
+// GetDiffURL returns the DiffURL field if it's non-nil, zero value otherwise.
+func (c *CommitsComparison) GetDiffURL() string {
+	if c == nil || c.DiffURL == nil {
+		return ""
+	}
+	return *c.DiffURL
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (c *CommitsComparison) GetHTMLURL() string {
+	if c == nil || c.HTMLURL == nil {
+		return ""
+	}
+	return *c.HTMLURL
+}
+
+// GetMergeBaseCommit returns the MergeBaseCommit field.
+func (c *CommitsComparison) GetMergeBaseCommit() *RepositoryCommit {
+	if c == nil {
+		return nil
+	}
+	return c.MergeBaseCommit
+}
+
+// GetPatchURL returns the PatchURL field if it's non-nil, zero value otherwise.
+func (c *CommitsComparison) GetPatchURL() string {
+	if c == nil || c.PatchURL == nil {
+		return ""
+	}
+	return *c.PatchURL
+}
+
+// GetPermalinkURL returns the PermalinkURL field if it's non-nil, zero value otherwise.
+func (c *CommitsComparison) GetPermalinkURL() string {
+	if c == nil || c.PermalinkURL == nil {
+		return ""
+	}
+	return *c.PermalinkURL
+}
+
+// GetStatus returns the Status field if it's non-nil, zero value otherwise.
+func (c *CommitsComparison) GetStatus() string {
+	if c == nil || c.Status == nil {
+		return ""
+	}
+	return *c.Status
+}
+
+// GetTotalCommits returns the TotalCommits field if it's non-nil, zero value otherwise.
+func (c *CommitsComparison) GetTotalCommits() int {
+	if c == nil || c.TotalCommits == nil {
+		return 0
+	}
+	return *c.TotalCommits
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (c *CommitsComparison) GetURL() string {
+	if c == nil || c.URL == nil {
+		return ""
+	}
+	return *c.URL
+}
+
+// GetIncompleteResults returns the IncompleteResults field if it's non-nil, zero value otherwise.
+func (c *CommitsSearchResult) GetIncompleteResults() bool {
+	if c == nil || c.IncompleteResults == nil {
+		return false
+	}
+	return *c.IncompleteResults
+}
+
+// GetTotal returns the Total field if it's non-nil, zero value otherwise.
+func (c *CommitsSearchResult) GetTotal() int {
+	if c == nil || c.Total == nil {
+		return 0
+	}
+	return *c.Total
+}
+
+// GetAdditions returns the Additions field if it's non-nil, zero value otherwise.
+func (c *CommitStats) GetAdditions() int {
+	if c == nil || c.Additions == nil {
+		return 0
+	}
+	return *c.Additions
+}
+
+// GetDeletions returns the Deletions field if it's non-nil, zero value otherwise.
+func (c *CommitStats) GetDeletions() int {
+	if c == nil || c.Deletions == nil {
+		return 0
+	}
+	return *c.Deletions
+}
+
+// GetTotal returns the Total field if it's non-nil, zero value otherwise.
+func (c *CommitStats) GetTotal() int {
+	if c == nil || c.Total == nil {
+		return 0
+	}
+	return *c.Total
+}
+
+// GetCodeOfConduct returns the CodeOfConduct field.
+func (c *CommunityHealthFiles) GetCodeOfConduct() *Metric {
+	if c == nil {
+		return nil
+	}
+	return c.CodeOfConduct
+}
+
+// GetContributing returns the Contributing field.
+func (c *CommunityHealthFiles) GetContributing() *Metric {
+	if c == nil {
+		return nil
+	}
+	return c.Contributing
+}
+
+// GetLicense returns the License field.
+func (c *CommunityHealthFiles) GetLicense() *Metric {
+	if c == nil {
+		return nil
+	}
+	return c.License
+}
+
+// GetReadme returns the Readme field.
+func (c *CommunityHealthFiles) GetReadme() *Metric {
+	if c == nil {
+		return nil
+	}
+	return c.Readme
+}
+
+// GetFiles returns the Files field.
+func (c *CommunityHealthMetrics) GetFiles() *CommunityHealthFiles {
+	if c == nil {
+		return nil
+	}
+	return c.Files
+}
+
+// GetHealthPercentage returns the HealthPercentage field if it's non-nil, zero value otherwise.
+func (c *CommunityHealthMetrics) GetHealthPercentage() int {
+	if c == nil || c.HealthPercentage == nil {
+		return 0
+	}
+	return *c.HealthPercentage
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (c *CommunityHealthMetrics) GetUpdatedAt() time.Time {
+	if c == nil || c.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *c.UpdatedAt
+}
+
+// GetAvatarURL returns the AvatarURL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetAvatarURL() string {
+	if c == nil || c.AvatarURL == nil {
+		return ""
+	}
+	return *c.AvatarURL
+}
+
+// GetContributions returns the Contributions field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetContributions() int {
+	if c == nil || c.Contributions == nil {
+		return 0
+	}
+	return *c.Contributions
+}
+
+// GetEventsURL returns the EventsURL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetEventsURL() string {
+	if c == nil || c.EventsURL == nil {
+		return ""
+	}
+	return *c.EventsURL
+}
+
+// GetFollowersURL returns the FollowersURL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetFollowersURL() string {
+	if c == nil || c.FollowersURL == nil {
+		return ""
+	}
+	return *c.FollowersURL
+}
+
+// GetFollowingURL returns the FollowingURL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetFollowingURL() string {
+	if c == nil || c.FollowingURL == nil {
+		return ""
+	}
+	return *c.FollowingURL
+}
+
+// GetGistsURL returns the GistsURL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetGistsURL() string {
+	if c == nil || c.GistsURL == nil {
+		return ""
+	}
+	return *c.GistsURL
+}
+
+// GetGravatarID returns the GravatarID field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetGravatarID() string {
+	if c == nil || c.GravatarID == nil {
+		return ""
+	}
+	return *c.GravatarID
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetHTMLURL() string {
+	if c == nil || c.HTMLURL == nil {
+		return ""
+	}
+	return *c.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetID() int64 {
+	if c == nil || c.ID == nil {
+		return 0
+	}
+	return *c.ID
+}
+
+// GetLogin returns the Login field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetLogin() string {
+	if c == nil || c.Login == nil {
+		return ""
+	}
+	return *c.Login
+}
+
+// GetOrganizationsURL returns the OrganizationsURL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetOrganizationsURL() string {
+	if c == nil || c.OrganizationsURL == nil {
+		return ""
+	}
+	return *c.OrganizationsURL
+}
+
+// GetReceivedEventsURL returns the ReceivedEventsURL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetReceivedEventsURL() string {
+	if c == nil || c.ReceivedEventsURL == nil {
+		return ""
+	}
+	return *c.ReceivedEventsURL
+}
+
+// GetReposURL returns the ReposURL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetReposURL() string {
+	if c == nil || c.ReposURL == nil {
+		return ""
+	}
+	return *c.ReposURL
+}
+
+// GetSiteAdmin returns the SiteAdmin field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetSiteAdmin() bool {
+	if c == nil || c.SiteAdmin == nil {
+		return false
+	}
+	return *c.SiteAdmin
+}
+
+// GetStarredURL returns the StarredURL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetStarredURL() string {
+	if c == nil || c.StarredURL == nil {
+		return ""
+	}
+	return *c.StarredURL
+}
+
+// GetSubscriptionsURL returns the SubscriptionsURL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetSubscriptionsURL() string {
+	if c == nil || c.SubscriptionsURL == nil {
+		return ""
+	}
+	return *c.SubscriptionsURL
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetType() string {
+	if c == nil || c.Type == nil {
+		return ""
+	}
+	return *c.Type
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetURL() string {
+	if c == nil || c.URL == nil {
+		return ""
+	}
+	return *c.URL
+}
+
+// GetAuthor returns the Author field.
+func (c *ContributorStats) GetAuthor() *Contributor {
+	if c == nil {
+		return nil
+	}
+	return c.Author
+}
+
+// GetTotal returns the Total field if it's non-nil, zero value otherwise.
+func (c *ContributorStats) GetTotal() int {
+	if c == nil || c.Total == nil {
+		return 0
+	}
+	return *c.Total
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (c *CreateEvent) GetDescription() string {
+	if c == nil || c.Description == nil {
+		return ""
+	}
+	return *c.Description
+}
+
+// GetInstallation returns the Installation field.
+func (c *CreateEvent) GetInstallation() *Installation {
+	if c == nil {
+		return nil
+	}
+	return c.Installation
+}
+
+// GetMasterBranch returns the MasterBranch field if it's non-nil, zero value otherwise.
+func (c *CreateEvent) GetMasterBranch() string {
+	if c == nil || c.MasterBranch == nil {
+		return ""
+	}
+	return *c.MasterBranch
+}
+
+// GetPusherType returns the PusherType field if it's non-nil, zero value otherwise.
+func (c *CreateEvent) GetPusherType() string {
+	if c == nil || c.PusherType == nil {
+		return ""
+	}
+	return *c.PusherType
+}
+
+// GetRef returns the Ref field if it's non-nil, zero value otherwise.
+func (c *CreateEvent) GetRef() string {
+	if c == nil || c.Ref == nil {
+		return ""
+	}
+	return *c.Ref
+}
+
+// GetRefType returns the RefType field if it's non-nil, zero value otherwise.
+func (c *CreateEvent) GetRefType() string {
+	if c == nil || c.RefType == nil {
+		return ""
+	}
+	return *c.RefType
+}
+
+// GetRepo returns the Repo field.
+func (c *CreateEvent) GetRepo() *Repository {
+	if c == nil {
+		return nil
+	}
+	return c.Repo
+}
+
+// GetSender returns the Sender field.
+func (c *CreateEvent) GetSender() *User {
+	if c == nil {
+		return nil
+	}
+	return c.Sender
+}
+
+// GetInstallation returns the Installation field.
+func (d *DeleteEvent) GetInstallation() *Installation {
+	if d == nil {
+		return nil
+	}
+	return d.Installation
+}
+
+// GetPusherType returns the PusherType field if it's non-nil, zero value otherwise.
+func (d *DeleteEvent) GetPusherType() string {
+	if d == nil || d.PusherType == nil {
+		return ""
+	}
+	return *d.PusherType
+}
+
+// GetRef returns the Ref field if it's non-nil, zero value otherwise.
+func (d *DeleteEvent) GetRef() string {
+	if d == nil || d.Ref == nil {
+		return ""
+	}
+	return *d.Ref
+}
+
+// GetRefType returns the RefType field if it's non-nil, zero value otherwise.
+func (d *DeleteEvent) GetRefType() string {
+	if d == nil || d.RefType == nil {
+		return ""
+	}
+	return *d.RefType
+}
+
+// GetRepo returns the Repo field.
+func (d *DeleteEvent) GetRepo() *Repository {
+	if d == nil {
+		return nil
+	}
+	return d.Repo
+}
+
+// GetSender returns the Sender field.
+func (d *DeleteEvent) GetSender() *User {
+	if d == nil {
+		return nil
+	}
+	return d.Sender
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetCreatedAt() Timestamp {
+	if d == nil || d.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *d.CreatedAt
+}
+
+// GetCreator returns the Creator field.
+func (d *Deployment) GetCreator() *User {
+	if d == nil {
+		return nil
+	}
+	return d.Creator
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetDescription() string {
+	if d == nil || d.Description == nil {
+		return ""
+	}
+	return *d.Description
+}
+
+// GetEnvironment returns the Environment field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetEnvironment() string {
+	if d == nil || d.Environment == nil {
+		return ""
+	}
+	return *d.Environment
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetID() int64 {
+	if d == nil || d.ID == nil {
+		return 0
+	}
+	return *d.ID
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetNodeID() string {
+	if d == nil || d.NodeID == nil {
+		return ""
+	}
+	return *d.NodeID
+}
+
+// GetRef returns the Ref field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetRef() string {
+	if d == nil || d.Ref == nil {
+		return ""
+	}
+	return *d.Ref
+}
+
+// GetRepositoryURL returns the RepositoryURL field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetRepositoryURL() string {
+	if d == nil || d.RepositoryURL == nil {
+		return ""
+	}
+	return *d.RepositoryURL
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetSHA() string {
+	if d == nil || d.SHA == nil {
+		return ""
+	}
+	return *d.SHA
+}
+
+// GetStatusesURL returns the StatusesURL field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetStatusesURL() string {
+	if d == nil || d.StatusesURL == nil {
+		return ""
+	}
+	return *d.StatusesURL
+}
+
+// GetTask returns the Task field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetTask() string {
+	if d == nil || d.Task == nil {
+		return ""
+	}
+	return *d.Task
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetUpdatedAt() Timestamp {
+	if d == nil || d.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *d.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (d *Deployment) GetURL() string {
+	if d == nil || d.URL == nil {
+		return ""
+	}
+	return *d.URL
+}
+
+// GetDeployment returns the Deployment field.
+func (d *DeploymentEvent) GetDeployment() *Deployment {
+	if d == nil {
+		return nil
+	}
+	return d.Deployment
+}
+
+// GetInstallation returns the Installation field.
+func (d *DeploymentEvent) GetInstallation() *Installation {
+	if d == nil {
+		return nil
+	}
+	return d.Installation
+}
+
+// GetRepo returns the Repo field.
+func (d *DeploymentEvent) GetRepo() *Repository {
+	if d == nil {
+		return nil
+	}
+	return d.Repo
+}
+
+// GetSender returns the Sender field.
+func (d *DeploymentEvent) GetSender() *User {
+	if d == nil {
+		return nil
+	}
+	return d.Sender
+}
+
+// GetAutoMerge returns the AutoMerge field if it's non-nil, zero value otherwise.
+func (d *DeploymentRequest) GetAutoMerge() bool {
+	if d == nil || d.AutoMerge == nil {
+		return false
+	}
+	return *d.AutoMerge
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (d *DeploymentRequest) GetDescription() string {
+	if d == nil || d.Description == nil {
+		return ""
+	}
+	return *d.Description
+}
+
+// GetEnvironment returns the Environment field if it's non-nil, zero value otherwise.
+func (d *DeploymentRequest) GetEnvironment() string {
+	if d == nil || d.Environment == nil {
+		return ""
+	}
+	return *d.Environment
+}
+
+// GetPayload returns the Payload field if it's non-nil, zero value otherwise.
+func (d *DeploymentRequest) GetPayload() string {
+	if d == nil || d.Payload == nil {
+		return ""
+	}
+	return *d.Payload
+}
+
+// GetProductionEnvironment returns the ProductionEnvironment field if it's non-nil, zero value otherwise.
+func (d *DeploymentRequest) GetProductionEnvironment() bool {
+	if d == nil || d.ProductionEnvironment == nil {
+		return false
+	}
+	return *d.ProductionEnvironment
+}
+
+// GetRef returns the Ref field if it's non-nil, zero value otherwise.
+func (d *DeploymentRequest) GetRef() string {
+	if d == nil || d.Ref == nil {
+		return ""
+	}
+	return *d.Ref
+}
+
+// GetRequiredContexts returns the RequiredContexts field if it's non-nil, zero value otherwise.
+func (d *DeploymentRequest) GetRequiredContexts() []string {
+	if d == nil || d.RequiredContexts == nil {
+		return nil
+	}
+	return *d.RequiredContexts
+}
+
+// GetTask returns the Task field if it's non-nil, zero value otherwise.
+func (d *DeploymentRequest) GetTask() string {
+	if d == nil || d.Task == nil {
+		return ""
+	}
+	return *d.Task
+}
+
+// GetTransientEnvironment returns the TransientEnvironment field if it's non-nil, zero value otherwise.
+func (d *DeploymentRequest) GetTransientEnvironment() bool {
+	if d == nil || d.TransientEnvironment == nil {
+		return false
+	}
+	return *d.TransientEnvironment
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatus) GetCreatedAt() Timestamp {
+	if d == nil || d.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *d.CreatedAt
+}
+
+// GetCreator returns the Creator field.
+func (d *DeploymentStatus) GetCreator() *User {
+	if d == nil {
+		return nil
+	}
+	return d.Creator
+}
+
+// GetDeploymentURL returns the DeploymentURL field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatus) GetDeploymentURL() string {
+	if d == nil || d.DeploymentURL == nil {
+		return ""
+	}
+	return *d.DeploymentURL
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatus) GetDescription() string {
+	if d == nil || d.Description == nil {
+		return ""
+	}
+	return *d.Description
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatus) GetID() int64 {
+	if d == nil || d.ID == nil {
+		return 0
+	}
+	return *d.ID
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatus) GetNodeID() string {
+	if d == nil || d.NodeID == nil {
+		return ""
+	}
+	return *d.NodeID
+}
+
+// GetRepositoryURL returns the RepositoryURL field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatus) GetRepositoryURL() string {
+	if d == nil || d.RepositoryURL == nil {
+		return ""
+	}
+	return *d.RepositoryURL
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatus) GetState() string {
+	if d == nil || d.State == nil {
+		return ""
+	}
+	return *d.State
+}
+
+// GetTargetURL returns the TargetURL field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatus) GetTargetURL() string {
+	if d == nil || d.TargetURL == nil {
+		return ""
+	}
+	return *d.TargetURL
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatus) GetUpdatedAt() Timestamp {
+	if d == nil || d.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *d.UpdatedAt
+}
+
+// GetDeployment returns the Deployment field.
+func (d *DeploymentStatusEvent) GetDeployment() *Deployment {
+	if d == nil {
+		return nil
+	}
+	return d.Deployment
+}
+
+// GetDeploymentStatus returns the DeploymentStatus field.
+func (d *DeploymentStatusEvent) GetDeploymentStatus() *DeploymentStatus {
+	if d == nil {
+		return nil
+	}
+	return d.DeploymentStatus
+}
+
+// GetInstallation returns the Installation field.
+func (d *DeploymentStatusEvent) GetInstallation() *Installation {
+	if d == nil {
+		return nil
+	}
+	return d.Installation
+}
+
+// GetRepo returns the Repo field.
+func (d *DeploymentStatusEvent) GetRepo() *Repository {
+	if d == nil {
+		return nil
+	}
+	return d.Repo
+}
+
+// GetSender returns the Sender field.
+func (d *DeploymentStatusEvent) GetSender() *User {
+	if d == nil {
+		return nil
+	}
+	return d.Sender
+}
+
+// GetAutoInactive returns the AutoInactive field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatusRequest) GetAutoInactive() bool {
+	if d == nil || d.AutoInactive == nil {
+		return false
+	}
+	return *d.AutoInactive
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatusRequest) GetDescription() string {
+	if d == nil || d.Description == nil {
+		return ""
+	}
+	return *d.Description
+}
+
+// GetEnvironmentURL returns the EnvironmentURL field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatusRequest) GetEnvironmentURL() string {
+	if d == nil || d.EnvironmentURL == nil {
+		return ""
+	}
+	return *d.EnvironmentURL
+}
+
+// GetLogURL returns the LogURL field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatusRequest) GetLogURL() string {
+	if d == nil || d.LogURL == nil {
+		return ""
+	}
+	return *d.LogURL
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (d *DeploymentStatusRequest) GetState() string {
+	if d == nil || d.State == nil {
+		return ""
+	}
+	return *d.State
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (d *DraftReviewComment) GetBody() string {
+	if d == nil || d.Body == nil {
+		return ""
+	}
+	return *d.Body
+}
+
+// GetPath returns the Path field if it's non-nil, zero value otherwise.
+func (d *DraftReviewComment) GetPath() string {
+	if d == nil || d.Path == nil {
+		return ""
+	}
+	return *d.Path
+}
+
+// GetPosition returns the Position field if it's non-nil, zero value otherwise.
+func (d *DraftReviewComment) GetPosition() int {
+	if d == nil || d.Position == nil {
+		return 0
+	}
+	return *d.Position
+}
+
+// GetActor returns the Actor field.
+func (e *Event) GetActor() *User {
+	if e == nil {
+		return nil
+	}
+	return e.Actor
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (e *Event) GetCreatedAt() time.Time {
+	if e == nil || e.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *e.CreatedAt
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (e *Event) GetID() string {
+	if e == nil || e.ID == nil {
+		return ""
+	}
+	return *e.ID
+}
+
+// GetOrg returns the Org field.
+func (e *Event) GetOrg() *Organization {
+	if e == nil {
+		return nil
+	}
+	return e.Org
+}
+
+// GetPublic returns the Public field if it's non-nil, zero value otherwise.
+func (e *Event) GetPublic() bool {
+	if e == nil || e.Public == nil {
+		return false
+	}
+	return *e.Public
+}
+
+// GetRawPayload returns the RawPayload field if it's non-nil, zero value otherwise.
+func (e *Event) GetRawPayload() json.RawMessage {
+	if e == nil || e.RawPayload == nil {
+		return json.RawMessage{}
+	}
+	return *e.RawPayload
+}
+
+// GetRepo returns the Repo field.
+func (e *Event) GetRepo() *Repository {
+	if e == nil {
+		return nil
+	}
+	return e.Repo
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (e *Event) GetType() string {
+	if e == nil || e.Type == nil {
+		return ""
+	}
+	return *e.Type
+}
+
+// GetHRef returns the HRef field if it's non-nil, zero value otherwise.
+func (f *FeedLink) GetHRef() string {
+	if f == nil || f.HRef == nil {
+		return ""
+	}
+	return *f.HRef
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (f *FeedLink) GetType() string {
+	if f == nil || f.Type == nil {
+		return ""
+	}
+	return *f.Type
+}
+
+// GetCurrentUserActorURL returns the CurrentUserActorURL field if it's non-nil, zero value otherwise.
+func (f *Feeds) GetCurrentUserActorURL() string {
+	if f == nil || f.CurrentUserActorURL == nil {
+		return ""
+	}
+	return *f.CurrentUserActorURL
+}
+
+// GetCurrentUserOrganizationURL returns the CurrentUserOrganizationURL field if it's non-nil, zero value otherwise.
+func (f *Feeds) GetCurrentUserOrganizationURL() string {
+	if f == nil || f.CurrentUserOrganizationURL == nil {
+		return ""
+	}
+	return *f.CurrentUserOrganizationURL
+}
+
+// GetCurrentUserPublicURL returns the CurrentUserPublicURL field if it's non-nil, zero value otherwise.
+func (f *Feeds) GetCurrentUserPublicURL() string {
+	if f == nil || f.CurrentUserPublicURL == nil {
+		return ""
+	}
+	return *f.CurrentUserPublicURL
+}
+
+// GetCurrentUserURL returns the CurrentUserURL field if it's non-nil, zero value otherwise.
+func (f *Feeds) GetCurrentUserURL() string {
+	if f == nil || f.CurrentUserURL == nil {
+		return ""
+	}
+	return *f.CurrentUserURL
+}
+
+// GetTimelineURL returns the TimelineURL field if it's non-nil, zero value otherwise.
+func (f *Feeds) GetTimelineURL() string {
+	if f == nil || f.TimelineURL == nil {
+		return ""
+	}
+	return *f.TimelineURL
+}
+
+// GetUserURL returns the UserURL field if it's non-nil, zero value otherwise.
+func (f *Feeds) GetUserURL() string {
+	if f == nil || f.UserURL == nil {
+		return ""
+	}
+	return *f.UserURL
+}
+
+// GetForkee returns the Forkee field.
+func (f *ForkEvent) GetForkee() *Repository {
+	if f == nil {
+		return nil
+	}
+	return f.Forkee
+}
+
+// GetInstallation returns the Installation field.
+func (f *ForkEvent) GetInstallation() *Installation {
+	if f == nil {
+		return nil
+	}
+	return f.Installation
+}
+
+// GetRepo returns the Repo field.
+func (f *ForkEvent) GetRepo() *Repository {
+	if f == nil {
+		return nil
+	}
+	return f.Repo
+}
+
+// GetSender returns the Sender field.
+func (f *ForkEvent) GetSender() *User {
+	if f == nil {
+		return nil
+	}
+	return f.Sender
+}
+
+// GetComments returns the Comments field if it's non-nil, zero value otherwise.
+func (g *Gist) GetComments() int {
+	if g == nil || g.Comments == nil {
+		return 0
+	}
+	return *g.Comments
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (g *Gist) GetCreatedAt() time.Time {
+	if g == nil || g.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *g.CreatedAt
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (g *Gist) GetDescription() string {
+	if g == nil || g.Description == nil {
+		return ""
+	}
+	return *g.Description
+}
+
+// GetGitPullURL returns the GitPullURL field if it's non-nil, zero value otherwise.
+func (g *Gist) GetGitPullURL() string {
+	if g == nil || g.GitPullURL == nil {
+		return ""
+	}
+	return *g.GitPullURL
+}
+
+// GetGitPushURL returns the GitPushURL field if it's non-nil, zero value otherwise.
+func (g *Gist) GetGitPushURL() string {
+	if g == nil || g.GitPushURL == nil {
+		return ""
+	}
+	return *g.GitPushURL
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (g *Gist) GetHTMLURL() string {
+	if g == nil || g.HTMLURL == nil {
+		return ""
+	}
+	return *g.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (g *Gist) GetID() string {
+	if g == nil || g.ID == nil {
+		return ""
+	}
+	return *g.ID
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (g *Gist) GetNodeID() string {
+	if g == nil || g.NodeID == nil {
+		return ""
+	}
+	return *g.NodeID
+}
+
+// GetOwner returns the Owner field.
+func (g *Gist) GetOwner() *User {
+	if g == nil {
+		return nil
+	}
+	return g.Owner
+}
+
+// GetPublic returns the Public field if it's non-nil, zero value otherwise.
+func (g *Gist) GetPublic() bool {
+	if g == nil || g.Public == nil {
+		return false
+	}
+	return *g.Public
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (g *Gist) GetUpdatedAt() time.Time {
+	if g == nil || g.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *g.UpdatedAt
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (g *GistComment) GetBody() string {
+	if g == nil || g.Body == nil {
+		return ""
+	}
+	return *g.Body
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (g *GistComment) GetCreatedAt() time.Time {
+	if g == nil || g.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *g.CreatedAt
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (g *GistComment) GetID() int64 {
+	if g == nil || g.ID == nil {
+		return 0
+	}
+	return *g.ID
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (g *GistComment) GetURL() string {
+	if g == nil || g.URL == nil {
+		return ""
+	}
+	return *g.URL
+}
+
+// GetUser returns the User field.
+func (g *GistComment) GetUser() *User {
+	if g == nil {
+		return nil
+	}
+	return g.User
+}
+
+// GetChangeStatus returns the ChangeStatus field.
+func (g *GistCommit) GetChangeStatus() *CommitStats {
+	if g == nil {
+		return nil
+	}
+	return g.ChangeStatus
+}
+
+// GetCommittedAt returns the CommittedAt field if it's non-nil, zero value otherwise.
+func (g *GistCommit) GetCommittedAt() Timestamp {
+	if g == nil || g.CommittedAt == nil {
+		return Timestamp{}
+	}
+	return *g.CommittedAt
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (g *GistCommit) GetNodeID() string {
+	if g == nil || g.NodeID == nil {
+		return ""
+	}
+	return *g.NodeID
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (g *GistCommit) GetURL() string {
+	if g == nil || g.URL == nil {
+		return ""
+	}
+	return *g.URL
+}
+
+// GetUser returns the User field.
+func (g *GistCommit) GetUser() *User {
+	if g == nil {
+		return nil
+	}
+	return g.User
+}
+
+// GetVersion returns the Version field if it's non-nil, zero value otherwise.
+func (g *GistCommit) GetVersion() string {
+	if g == nil || g.Version == nil {
+		return ""
+	}
+	return *g.Version
+}
+
+// GetContent returns the Content field if it's non-nil, zero value otherwise.
+func (g *GistFile) GetContent() string {
+	if g == nil || g.Content == nil {
+		return ""
+	}
+	return *g.Content
+}
+
+// GetFilename returns the Filename field if it's non-nil, zero value otherwise.
+func (g *GistFile) GetFilename() string {
+	if g == nil || g.Filename == nil {
+		return ""
+	}
+	return *g.Filename
+}
+
+// GetLanguage returns the Language field if it's non-nil, zero value otherwise.
+func (g *GistFile) GetLanguage() string {
+	if g == nil || g.Language == nil {
+		return ""
+	}
+	return *g.Language
+}
+
+// GetRawURL returns the RawURL field if it's non-nil, zero value otherwise.
+func (g *GistFile) GetRawURL() string {
+	if g == nil || g.RawURL == nil {
+		return ""
+	}
+	return *g.RawURL
+}
+
+// GetSize returns the Size field if it's non-nil, zero value otherwise.
+func (g *GistFile) GetSize() int {
+	if g == nil || g.Size == nil {
+		return 0
+	}
+	return *g.Size
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (g *GistFile) GetType() string {
+	if g == nil || g.Type == nil {
+		return ""
+	}
+	return *g.Type
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (g *GistFork) GetCreatedAt() Timestamp {
+	if g == nil || g.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *g.CreatedAt
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (g *GistFork) GetID() string {
+	if g == nil || g.ID == nil {
+		return ""
+	}
+	return *g.ID
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (g *GistFork) GetNodeID() string {
+	if g == nil || g.NodeID == nil {
+		return ""
+	}
+	return *g.NodeID
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (g *GistFork) GetUpdatedAt() Timestamp {
+	if g == nil || g.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *g.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (g *GistFork) GetURL() string {
+	if g == nil || g.URL == nil {
+		return ""
+	}
+	return *g.URL
+}
+
+// GetUser returns the User field.
+func (g *GistFork) GetUser() *User {
+	if g == nil {
+		return nil
+	}
+	return g.User
+}
+
+// GetPrivateGists returns the PrivateGists field if it's non-nil, zero value otherwise.
+func (g *GistStats) GetPrivateGists() int {
+	if g == nil || g.PrivateGists == nil {
+		return 0
+	}
+	return *g.PrivateGists
+}
+
+// GetPublicGists returns the PublicGists field if it's non-nil, zero value otherwise.
+func (g *GistStats) GetPublicGists() int {
+	if g == nil || g.PublicGists == nil {
+		return 0
+	}
+	return *g.PublicGists
+}
+
+// GetTotalGists returns the TotalGists field if it's non-nil, zero value otherwise.
+func (g *GistStats) GetTotalGists() int {
+	if g == nil || g.TotalGists == nil {
+		return 0
+	}
+	return *g.TotalGists
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (g *Gitignore) GetName() string {
+	if g == nil || g.Name == nil {
+		return ""
+	}
+	return *g.Name
+}
+
+// GetSource returns the Source field if it's non-nil, zero value otherwise.
+func (g *Gitignore) GetSource() string {
+	if g == nil || g.Source == nil {
+		return ""
+	}
+	return *g.Source
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (g *GitObject) GetSHA() string {
+	if g == nil || g.SHA == nil {
+		return ""
+	}
+	return *g.SHA
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (g *GitObject) GetType() string {
+	if g == nil || g.Type == nil {
+		return ""
+	}
+	return *g.Type
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (g *GitObject) GetURL() string {
+	if g == nil || g.URL == nil {
+		return ""
+	}
+	return *g.URL
+}
+
+// GetInstallation returns the Installation field.
+func (g *GollumEvent) GetInstallation() *Installation {
+	if g == nil {
+		return nil
+	}
+	return g.Installation
+}
+
+// GetRepo returns the Repo field.
+func (g *GollumEvent) GetRepo() *Repository {
+	if g == nil {
+		return nil
+	}
+	return g.Repo
+}
+
+// GetSender returns the Sender field.
+func (g *GollumEvent) GetSender() *User {
+	if g == nil {
+		return nil
+	}
+	return g.Sender
+}
+
+// GetEmail returns the Email field if it's non-nil, zero value otherwise.
+func (g *GPGEmail) GetEmail() string {
+	if g == nil || g.Email == nil {
+		return ""
+	}
+	return *g.Email
+}
+
+// GetVerified returns the Verified field if it's non-nil, zero value otherwise.
+func (g *GPGEmail) GetVerified() bool {
+	if g == nil || g.Verified == nil {
+		return false
+	}
+	return *g.Verified
+}
+
+// GetCanCertify returns the CanCertify field if it's non-nil, zero value otherwise.
+func (g *GPGKey) GetCanCertify() bool {
+	if g == nil || g.CanCertify == nil {
+		return false
+	}
+	return *g.CanCertify
+}
+
+// GetCanEncryptComms returns the CanEncryptComms field if it's non-nil, zero value otherwise.
+func (g *GPGKey) GetCanEncryptComms() bool {
+	if g == nil || g.CanEncryptComms == nil {
+		return false
+	}
+	return *g.CanEncryptComms
+}
+
+// GetCanEncryptStorage returns the CanEncryptStorage field if it's non-nil, zero value otherwise.
+func (g *GPGKey) GetCanEncryptStorage() bool {
+	if g == nil || g.CanEncryptStorage == nil {
+		return false
+	}
+	return *g.CanEncryptStorage
+}
+
+// GetCanSign returns the CanSign field if it's non-nil, zero value otherwise.
+func (g *GPGKey) GetCanSign() bool {
+	if g == nil || g.CanSign == nil {
+		return false
+	}
+	return *g.CanSign
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (g *GPGKey) GetCreatedAt() time.Time {
+	if g == nil || g.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *g.CreatedAt
+}
+
+// GetExpiresAt returns the ExpiresAt field if it's non-nil, zero value otherwise.
+func (g *GPGKey) GetExpiresAt() time.Time {
+	if g == nil || g.ExpiresAt == nil {
+		return time.Time{}
+	}
+	return *g.ExpiresAt
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (g *GPGKey) GetID() int64 {
+	if g == nil || g.ID == nil {
+		return 0
+	}
+	return *g.ID
+}
+
+// GetKeyID returns the KeyID field if it's non-nil, zero value otherwise.
+func (g *GPGKey) GetKeyID() string {
+	if g == nil || g.KeyID == nil {
+		return ""
+	}
+	return *g.KeyID
+}
+
+// GetPrimaryKeyID returns the PrimaryKeyID field if it's non-nil, zero value otherwise.
+func (g *GPGKey) GetPrimaryKeyID() int64 {
+	if g == nil || g.PrimaryKeyID == nil {
+		return 0
+	}
+	return *g.PrimaryKeyID
+}
+
+// GetPublicKey returns the PublicKey field if it's non-nil, zero value otherwise.
+func (g *GPGKey) GetPublicKey() string {
+	if g == nil || g.PublicKey == nil {
+		return ""
+	}
+	return *g.PublicKey
+}
+
+// GetApp returns the App field.
+func (g *Grant) GetApp() *AuthorizationApp {
+	if g == nil {
+		return nil
+	}
+	return g.App
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (g *Grant) GetCreatedAt() Timestamp {
+	if g == nil || g.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *g.CreatedAt
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (g *Grant) GetID() int64 {
+	if g == nil || g.ID == nil {
+		return 0
+	}
+	return *g.ID
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (g *Grant) GetUpdatedAt() Timestamp {
+	if g == nil || g.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *g.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (g *Grant) GetURL() string {
+	if g == nil || g.URL == nil {
+		return ""
+	}
+	return *g.URL
+}
+
+// GetActive returns the Active field if it's non-nil, zero value otherwise.
+func (h *Hook) GetActive() bool {
+	if h == nil || h.Active == nil {
+		return false
+	}
+	return *h.Active
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (h *Hook) GetCreatedAt() time.Time {
+	if h == nil || h.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *h.CreatedAt
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (h *Hook) GetID() int64 {
+	if h == nil || h.ID == nil {
+		return 0
+	}
+	return *h.ID
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (h *Hook) GetName() string {
+	if h == nil || h.Name == nil {
+		return ""
+	}
+	return *h.Name
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (h *Hook) GetUpdatedAt() time.Time {
+	if h == nil || h.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *h.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (h *Hook) GetURL() string {
+	if h == nil || h.URL == nil {
+		return ""
+	}
+	return *h.URL
+}
+
+// GetActiveHooks returns the ActiveHooks field if it's non-nil, zero value otherwise.
+func (h *HookStats) GetActiveHooks() int {
+	if h == nil || h.ActiveHooks == nil {
+		return 0
+	}
+	return *h.ActiveHooks
+}
+
+// GetInactiveHooks returns the InactiveHooks field if it's non-nil, zero value otherwise.
+func (h *HookStats) GetInactiveHooks() int {
+	if h == nil || h.InactiveHooks == nil {
+		return 0
+	}
+	return *h.InactiveHooks
+}
+
+// GetTotalHooks returns the TotalHooks field if it's non-nil, zero value otherwise.
+func (h *HookStats) GetTotalHooks() int {
+	if h == nil || h.TotalHooks == nil {
+		return 0
+	}
+	return *h.TotalHooks
+}
+
+// GetAuthorsCount returns the AuthorsCount field if it's non-nil, zero value otherwise.
+func (i *Import) GetAuthorsCount() int {
+	if i == nil || i.AuthorsCount == nil {
+		return 0
+	}
+	return *i.AuthorsCount
+}
+
+// GetAuthorsURL returns the AuthorsURL field if it's non-nil, zero value otherwise.
+func (i *Import) GetAuthorsURL() string {
+	if i == nil || i.AuthorsURL == nil {
+		return ""
+	}
+	return *i.AuthorsURL
+}
+
+// GetCommitCount returns the CommitCount field if it's non-nil, zero value otherwise.
+func (i *Import) GetCommitCount() int {
+	if i == nil || i.CommitCount == nil {
+		return 0
+	}
+	return *i.CommitCount
+}
+
+// GetFailedStep returns the FailedStep field if it's non-nil, zero value otherwise.
+func (i *Import) GetFailedStep() string {
+	if i == nil || i.FailedStep == nil {
+		return ""
+	}
+	return *i.FailedStep
+}
+
+// GetHasLargeFiles returns the HasLargeFiles field if it's non-nil, zero value otherwise.
+func (i *Import) GetHasLargeFiles() bool {
+	if i == nil || i.HasLargeFiles == nil {
+		return false
+	}
+	return *i.HasLargeFiles
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (i *Import) GetHTMLURL() string {
+	if i == nil || i.HTMLURL == nil {
+		return ""
+	}
+	return *i.HTMLURL
+}
+
+// GetHumanName returns the HumanName field if it's non-nil, zero value otherwise.
+func (i *Import) GetHumanName() string {
+	if i == nil || i.HumanName == nil {
+		return ""
+	}
+	return *i.HumanName
+}
+
+// GetLargeFilesCount returns the LargeFilesCount field if it's non-nil, zero value otherwise.
+func (i *Import) GetLargeFilesCount() int {
+	if i == nil || i.LargeFilesCount == nil {
+		return 0
+	}
+	return *i.LargeFilesCount
+}
+
+// GetLargeFilesSize returns the LargeFilesSize field if it's non-nil, zero value otherwise.
+func (i *Import) GetLargeFilesSize() int {
+	if i == nil || i.LargeFilesSize == nil {
+		return 0
+	}
+	return *i.LargeFilesSize
+}
+
+// GetMessage returns the Message field if it's non-nil, zero value otherwise.
+func (i *Import) GetMessage() string {
+	if i == nil || i.Message == nil {
+		return ""
+	}
+	return *i.Message
+}
+
+// GetPercent returns the Percent field if it's non-nil, zero value otherwise.
+func (i *Import) GetPercent() int {
+	if i == nil || i.Percent == nil {
+		return 0
+	}
+	return *i.Percent
+}
+
+// GetPushPercent returns the PushPercent field if it's non-nil, zero value otherwise.
+func (i *Import) GetPushPercent() int {
+	if i == nil || i.PushPercent == nil {
+		return 0
+	}
+	return *i.PushPercent
+}
+
+// GetRepositoryURL returns the RepositoryURL field if it's non-nil, zero value otherwise.
+func (i *Import) GetRepositoryURL() string {
+	if i == nil || i.RepositoryURL == nil {
+		return ""
+	}
+	return *i.RepositoryURL
+}
+
+// GetStatus returns the Status field if it's non-nil, zero value otherwise.
+func (i *Import) GetStatus() string {
+	if i == nil || i.Status == nil {
+		return ""
+	}
+	return *i.Status
+}
+
+// GetStatusText returns the StatusText field if it's non-nil, zero value otherwise.
+func (i *Import) GetStatusText() string {
+	if i == nil || i.StatusText == nil {
+		return ""
+	}
+	return *i.StatusText
+}
+
+// GetTFVCProject returns the TFVCProject field if it's non-nil, zero value otherwise.
+func (i *Import) GetTFVCProject() string {
+	if i == nil || i.TFVCProject == nil {
+		return ""
+	}
+	return *i.TFVCProject
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (i *Import) GetURL() string {
+	if i == nil || i.URL == nil {
+		return ""
+	}
+	return *i.URL
+}
+
+// GetUseLFS returns the UseLFS field if it's non-nil, zero value otherwise.
+func (i *Import) GetUseLFS() string {
+	if i == nil || i.UseLFS == nil {
+		return ""
+	}
+	return *i.UseLFS
+}
+
+// GetVCS returns the VCS field if it's non-nil, zero value otherwise.
+func (i *Import) GetVCS() string {
+	if i == nil || i.VCS == nil {
+		return ""
+	}
+	return *i.VCS
+}
+
+// GetVCSPassword returns the VCSPassword field if it's non-nil, zero value otherwise.
+func (i *Import) GetVCSPassword() string {
+	if i == nil || i.VCSPassword == nil {
+		return ""
+	}
+	return *i.VCSPassword
+}
+
+// GetVCSURL returns the VCSURL field if it's non-nil, zero value otherwise.
+func (i *Import) GetVCSURL() string {
+	if i == nil || i.VCSURL == nil {
+		return ""
+	}
+	return *i.VCSURL
+}
+
+// GetVCSUsername returns the VCSUsername field if it's non-nil, zero value otherwise.
+func (i *Import) GetVCSUsername() string {
+	if i == nil || i.VCSUsername == nil {
+		return ""
+	}
+	return *i.VCSUsername
+}
+
+// GetAccessTokensURL returns the AccessTokensURL field if it's non-nil, zero value otherwise.
+func (i *Installation) GetAccessTokensURL() string {
+	if i == nil || i.AccessTokensURL == nil {
+		return ""
+	}
+	return *i.AccessTokensURL
+}
+
+// GetAccount returns the Account field.
+func (i *Installation) GetAccount() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Account
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (i *Installation) GetHTMLURL() string {
+	if i == nil || i.HTMLURL == nil {
+		return ""
+	}
+	return *i.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (i *Installation) GetID() int64 {
+	if i == nil || i.ID == nil {
+		return 0
+	}
+	return *i.ID
+}
+
+// GetRepositoriesURL returns the RepositoriesURL field if it's non-nil, zero value otherwise.
+func (i *Installation) GetRepositoriesURL() string {
+	if i == nil || i.RepositoriesURL == nil {
+		return ""
+	}
+	return *i.RepositoriesURL
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (i *InstallationEvent) GetAction() string {
+	if i == nil || i.Action == nil {
+		return ""
+	}
+	return *i.Action
+}
+
+// GetInstallation returns the Installation field.
+func (i *InstallationEvent) GetInstallation() *Installation {
+	if i == nil {
+		return nil
+	}
+	return i.Installation
+}
+
+// GetSender returns the Sender field.
+func (i *InstallationEvent) GetSender() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Sender
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (i *InstallationRepositoriesEvent) GetAction() string {
+	if i == nil || i.Action == nil {
+		return ""
+	}
+	return *i.Action
+}
+
+// GetInstallation returns the Installation field.
+func (i *InstallationRepositoriesEvent) GetInstallation() *Installation {
+	if i == nil {
+		return nil
+	}
+	return i.Installation
+}
+
+// GetRepositorySelection returns the RepositorySelection field if it's non-nil, zero value otherwise.
+func (i *InstallationRepositoriesEvent) GetRepositorySelection() string {
+	if i == nil || i.RepositorySelection == nil {
+		return ""
+	}
+	return *i.RepositorySelection
+}
+
+// GetSender returns the Sender field.
+func (i *InstallationRepositoriesEvent) GetSender() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Sender
+}
+
+// GetExpiresAt returns the ExpiresAt field if it's non-nil, zero value otherwise.
+func (i *InstallationToken) GetExpiresAt() time.Time {
+	if i == nil || i.ExpiresAt == nil {
+		return time.Time{}
+	}
+	return *i.ExpiresAt
+}
+
+// GetToken returns the Token field if it's non-nil, zero value otherwise.
+func (i *InstallationToken) GetToken() string {
+	if i == nil || i.Token == nil {
+		return ""
+	}
+	return *i.Token
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (i *Invitation) GetCreatedAt() time.Time {
+	if i == nil || i.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *i.CreatedAt
+}
+
+// GetEmail returns the Email field if it's non-nil, zero value otherwise.
+func (i *Invitation) GetEmail() string {
+	if i == nil || i.Email == nil {
+		return ""
+	}
+	return *i.Email
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (i *Invitation) GetID() int64 {
+	if i == nil || i.ID == nil {
+		return 0
+	}
+	return *i.ID
+}
+
+// GetInviter returns the Inviter field.
+func (i *Invitation) GetInviter() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Inviter
+}
+
+// GetLogin returns the Login field if it's non-nil, zero value otherwise.
+func (i *Invitation) GetLogin() string {
+	if i == nil || i.Login == nil {
+		return ""
+	}
+	return *i.Login
+}
+
+// GetRole returns the Role field if it's non-nil, zero value otherwise.
+func (i *Invitation) GetRole() string {
+	if i == nil || i.Role == nil {
+		return ""
+	}
+	return *i.Role
+}
+
+// GetAssignee returns the Assignee field.
+func (i *Issue) GetAssignee() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Assignee
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (i *Issue) GetBody() string {
+	if i == nil || i.Body == nil {
+		return ""
+	}
+	return *i.Body
+}
+
+// GetClosedAt returns the ClosedAt field if it's non-nil, zero value otherwise.
+func (i *Issue) GetClosedAt() time.Time {
+	if i == nil || i.ClosedAt == nil {
+		return time.Time{}
+	}
+	return *i.ClosedAt
+}
+
+// GetClosedBy returns the ClosedBy field.
+func (i *Issue) GetClosedBy() *User {
+	if i == nil {
+		return nil
+	}
+	return i.ClosedBy
+}
+
+// GetComments returns the Comments field if it's non-nil, zero value otherwise.
+func (i *Issue) GetComments() int {
+	if i == nil || i.Comments == nil {
+		return 0
+	}
+	return *i.Comments
+}
+
+// GetCommentsURL returns the CommentsURL field if it's non-nil, zero value otherwise.
+func (i *Issue) GetCommentsURL() string {
+	if i == nil || i.CommentsURL == nil {
+		return ""
+	}
+	return *i.CommentsURL
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (i *Issue) GetCreatedAt() time.Time {
+	if i == nil || i.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *i.CreatedAt
+}
+
+// GetEventsURL returns the EventsURL field if it's non-nil, zero value otherwise.
+func (i *Issue) GetEventsURL() string {
+	if i == nil || i.EventsURL == nil {
+		return ""
+	}
+	return *i.EventsURL
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (i *Issue) GetHTMLURL() string {
+	if i == nil || i.HTMLURL == nil {
+		return ""
+	}
+	return *i.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (i *Issue) GetID() int64 {
+	if i == nil || i.ID == nil {
+		return 0
+	}
+	return *i.ID
+}
+
+// GetLabelsURL returns the LabelsURL field if it's non-nil, zero value otherwise.
+func (i *Issue) GetLabelsURL() string {
+	if i == nil || i.LabelsURL == nil {
+		return ""
+	}
+	return *i.LabelsURL
+}
+
+// GetLocked returns the Locked field if it's non-nil, zero value otherwise.
+func (i *Issue) GetLocked() bool {
+	if i == nil || i.Locked == nil {
+		return false
+	}
+	return *i.Locked
+}
+
+// GetMilestone returns the Milestone field.
+func (i *Issue) GetMilestone() *Milestone {
+	if i == nil {
+		return nil
+	}
+	return i.Milestone
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (i *Issue) GetNodeID() string {
+	if i == nil || i.NodeID == nil {
+		return ""
+	}
+	return *i.NodeID
+}
+
+// GetNumber returns the Number field if it's non-nil, zero value otherwise.
+func (i *Issue) GetNumber() int {
+	if i == nil || i.Number == nil {
+		return 0
+	}
+	return *i.Number
+}
+
+// GetPullRequestLinks returns the PullRequestLinks field.
+func (i *Issue) GetPullRequestLinks() *PullRequestLinks {
+	if i == nil {
+		return nil
+	}
+	return i.PullRequestLinks
+}
+
+// GetReactions returns the Reactions field.
+func (i *Issue) GetReactions() *Reactions {
+	if i == nil {
+		return nil
+	}
+	return i.Reactions
+}
+
+// GetRepository returns the Repository field.
+func (i *Issue) GetRepository() *Repository {
+	if i == nil {
+		return nil
+	}
+	return i.Repository
+}
+
+// GetRepositoryURL returns the RepositoryURL field if it's non-nil, zero value otherwise.
+func (i *Issue) GetRepositoryURL() string {
+	if i == nil || i.RepositoryURL == nil {
+		return ""
+	}
+	return *i.RepositoryURL
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (i *Issue) GetState() string {
+	if i == nil || i.State == nil {
+		return ""
+	}
+	return *i.State
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (i *Issue) GetTitle() string {
+	if i == nil || i.Title == nil {
+		return ""
+	}
+	return *i.Title
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (i *Issue) GetUpdatedAt() time.Time {
+	if i == nil || i.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *i.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (i *Issue) GetURL() string {
+	if i == nil || i.URL == nil {
+		return ""
+	}
+	return *i.URL
+}
+
+// GetUser returns the User field.
+func (i *Issue) GetUser() *User {
+	if i == nil {
+		return nil
+	}
+	return i.User
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (i *IssueComment) GetBody() string {
+	if i == nil || i.Body == nil {
+		return ""
+	}
+	return *i.Body
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (i *IssueComment) GetCreatedAt() time.Time {
+	if i == nil || i.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *i.CreatedAt
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (i *IssueComment) GetHTMLURL() string {
+	if i == nil || i.HTMLURL == nil {
+		return ""
+	}
+	return *i.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (i *IssueComment) GetID() int64 {
+	if i == nil || i.ID == nil {
+		return 0
+	}
+	return *i.ID
+}
+
+// GetIssueURL returns the IssueURL field if it's non-nil, zero value otherwise.
+func (i *IssueComment) GetIssueURL() string {
+	if i == nil || i.IssueURL == nil {
+		return ""
+	}
+	return *i.IssueURL
+}
+
+// GetReactions returns the Reactions field.
+func (i *IssueComment) GetReactions() *Reactions {
+	if i == nil {
+		return nil
+	}
+	return i.Reactions
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (i *IssueComment) GetUpdatedAt() time.Time {
+	if i == nil || i.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *i.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (i *IssueComment) GetURL() string {
+	if i == nil || i.URL == nil {
+		return ""
+	}
+	return *i.URL
+}
+
+// GetUser returns the User field.
+func (i *IssueComment) GetUser() *User {
+	if i == nil {
+		return nil
+	}
+	return i.User
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (i *IssueCommentEvent) GetAction() string {
+	if i == nil || i.Action == nil {
+		return ""
+	}
+	return *i.Action
+}
+
+// GetChanges returns the Changes field.
+func (i *IssueCommentEvent) GetChanges() *EditChange {
+	if i == nil {
+		return nil
+	}
+	return i.Changes
+}
+
+// GetComment returns the Comment field.
+func (i *IssueCommentEvent) GetComment() *IssueComment {
+	if i == nil {
+		return nil
+	}
+	return i.Comment
+}
+
+// GetInstallation returns the Installation field.
+func (i *IssueCommentEvent) GetInstallation() *Installation {
+	if i == nil {
+		return nil
+	}
+	return i.Installation
+}
+
+// GetIssue returns the Issue field.
+func (i *IssueCommentEvent) GetIssue() *Issue {
+	if i == nil {
+		return nil
+	}
+	return i.Issue
+}
+
+// GetRepo returns the Repo field.
+func (i *IssueCommentEvent) GetRepo() *Repository {
+	if i == nil {
+		return nil
+	}
+	return i.Repo
+}
+
+// GetSender returns the Sender field.
+func (i *IssueCommentEvent) GetSender() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Sender
+}
+
+// GetActor returns the Actor field.
+func (i *IssueEvent) GetActor() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Actor
+}
+
+// GetAssignee returns the Assignee field.
+func (i *IssueEvent) GetAssignee() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Assignee
+}
+
+// GetAssigner returns the Assigner field.
+func (i *IssueEvent) GetAssigner() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Assigner
+}
+
+// GetCommitID returns the CommitID field if it's non-nil, zero value otherwise.
+func (i *IssueEvent) GetCommitID() string {
+	if i == nil || i.CommitID == nil {
+		return ""
+	}
+	return *i.CommitID
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (i *IssueEvent) GetCreatedAt() time.Time {
+	if i == nil || i.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *i.CreatedAt
+}
+
+// GetEvent returns the Event field if it's non-nil, zero value otherwise.
+func (i *IssueEvent) GetEvent() string {
+	if i == nil || i.Event == nil {
+		return ""
+	}
+	return *i.Event
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (i *IssueEvent) GetID() int64 {
+	if i == nil || i.ID == nil {
+		return 0
+	}
+	return *i.ID
+}
+
+// GetIssue returns the Issue field.
+func (i *IssueEvent) GetIssue() *Issue {
+	if i == nil {
+		return nil
+	}
+	return i.Issue
+}
+
+// GetLabel returns the Label field.
+func (i *IssueEvent) GetLabel() *Label {
+	if i == nil {
+		return nil
+	}
+	return i.Label
+}
+
+// GetMilestone returns the Milestone field.
+func (i *IssueEvent) GetMilestone() *Milestone {
+	if i == nil {
+		return nil
+	}
+	return i.Milestone
+}
+
+// GetRename returns the Rename field.
+func (i *IssueEvent) GetRename() *Rename {
+	if i == nil {
+		return nil
+	}
+	return i.Rename
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (i *IssueEvent) GetURL() string {
+	if i == nil || i.URL == nil {
+		return ""
+	}
+	return *i.URL
+}
+
+// GetAssignee returns the Assignee field if it's non-nil, zero value otherwise.
+func (i *IssueRequest) GetAssignee() string {
+	if i == nil || i.Assignee == nil {
+		return ""
+	}
+	return *i.Assignee
+}
+
+// GetAssignees returns the Assignees field if it's non-nil, zero value otherwise.
+func (i *IssueRequest) GetAssignees() []string {
+	if i == nil || i.Assignees == nil {
+		return nil
+	}
+	return *i.Assignees
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (i *IssueRequest) GetBody() string {
+	if i == nil || i.Body == nil {
+		return ""
+	}
+	return *i.Body
+}
+
+// GetLabels returns the Labels field if it's non-nil, zero value otherwise.
+func (i *IssueRequest) GetLabels() []string {
+	if i == nil || i.Labels == nil {
+		return nil
+	}
+	return *i.Labels
+}
+
+// GetMilestone returns the Milestone field if it's non-nil, zero value otherwise.
+func (i *IssueRequest) GetMilestone() int {
+	if i == nil || i.Milestone == nil {
+		return 0
+	}
+	return *i.Milestone
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (i *IssueRequest) GetState() string {
+	if i == nil || i.State == nil {
+		return ""
+	}
+	return *i.State
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (i *IssueRequest) GetTitle() string {
+	if i == nil || i.Title == nil {
+		return ""
+	}
+	return *i.Title
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (i *IssuesEvent) GetAction() string {
+	if i == nil || i.Action == nil {
+		return ""
+	}
+	return *i.Action
+}
+
+// GetAssignee returns the Assignee field.
+func (i *IssuesEvent) GetAssignee() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Assignee
+}
+
+// GetChanges returns the Changes field.
+func (i *IssuesEvent) GetChanges() *EditChange {
+	if i == nil {
+		return nil
+	}
+	return i.Changes
+}
+
+// GetInstallation returns the Installation field.
+func (i *IssuesEvent) GetInstallation() *Installation {
+	if i == nil {
+		return nil
+	}
+	return i.Installation
+}
+
+// GetIssue returns the Issue field.
+func (i *IssuesEvent) GetIssue() *Issue {
+	if i == nil {
+		return nil
+	}
+	return i.Issue
+}
+
+// GetLabel returns the Label field.
+func (i *IssuesEvent) GetLabel() *Label {
+	if i == nil {
+		return nil
+	}
+	return i.Label
+}
+
+// GetRepo returns the Repo field.
+func (i *IssuesEvent) GetRepo() *Repository {
+	if i == nil {
+		return nil
+	}
+	return i.Repo
+}
+
+// GetSender returns the Sender field.
+func (i *IssuesEvent) GetSender() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Sender
+}
+
+// GetIncompleteResults returns the IncompleteResults field if it's non-nil, zero value otherwise.
+func (i *IssuesSearchResult) GetIncompleteResults() bool {
+	if i == nil || i.IncompleteResults == nil {
+		return false
+	}
+	return *i.IncompleteResults
+}
+
+// GetTotal returns the Total field if it's non-nil, zero value otherwise.
+func (i *IssuesSearchResult) GetTotal() int {
+	if i == nil || i.Total == nil {
+		return 0
+	}
+	return *i.Total
+}
+
+// GetClosedIssues returns the ClosedIssues field if it's non-nil, zero value otherwise.
+func (i *IssueStats) GetClosedIssues() int {
+	if i == nil || i.ClosedIssues == nil {
+		return 0
+	}
+	return *i.ClosedIssues
+}
+
+// GetOpenIssues returns the OpenIssues field if it's non-nil, zero value otherwise.
+func (i *IssueStats) GetOpenIssues() int {
+	if i == nil || i.OpenIssues == nil {
+		return 0
+	}
+	return *i.OpenIssues
+}
+
+// GetTotalIssues returns the TotalIssues field if it's non-nil, zero value otherwise.
+func (i *IssueStats) GetTotalIssues() int {
+	if i == nil || i.TotalIssues == nil {
+		return 0
+	}
+	return *i.TotalIssues
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (k *Key) GetID() int64 {
+	if k == nil || k.ID == nil {
+		return 0
+	}
+	return *k.ID
+}
+
+// GetKey returns the Key field if it's non-nil, zero value otherwise.
+func (k *Key) GetKey() string {
+	if k == nil || k.Key == nil {
+		return ""
+	}
+	return *k.Key
+}
+
+// GetReadOnly returns the ReadOnly field if it's non-nil, zero value otherwise.
+func (k *Key) GetReadOnly() bool {
+	if k == nil || k.ReadOnly == nil {
+		return false
+	}
+	return *k.ReadOnly
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (k *Key) GetTitle() string {
+	if k == nil || k.Title == nil {
+		return ""
+	}
+	return *k.Title
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (k *Key) GetURL() string {
+	if k == nil || k.URL == nil {
+		return ""
+	}
+	return *k.URL
+}
+
+// GetColor returns the Color field if it's non-nil, zero value otherwise.
+func (l *Label) GetColor() string {
+	if l == nil || l.Color == nil {
+		return ""
+	}
+	return *l.Color
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (l *Label) GetID() int64 {
+	if l == nil || l.ID == nil {
+		return 0
+	}
+	return *l.ID
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (l *Label) GetName() string {
+	if l == nil || l.Name == nil {
+		return ""
+	}
+	return *l.Name
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (l *Label) GetNodeID() string {
+	if l == nil || l.NodeID == nil {
+		return ""
+	}
+	return *l.NodeID
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (l *Label) GetURL() string {
+	if l == nil || l.URL == nil {
+		return ""
+	}
+	return *l.URL
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (l *LabelEvent) GetAction() string {
+	if l == nil || l.Action == nil {
+		return ""
+	}
+	return *l.Action
+}
+
+// GetChanges returns the Changes field.
+func (l *LabelEvent) GetChanges() *EditChange {
+	if l == nil {
+		return nil
+	}
+	return l.Changes
+}
+
+// GetInstallation returns the Installation field.
+func (l *LabelEvent) GetInstallation() *Installation {
+	if l == nil {
+		return nil
+	}
+	return l.Installation
+}
+
+// GetLabel returns the Label field.
+func (l *LabelEvent) GetLabel() *Label {
+	if l == nil {
+		return nil
+	}
+	return l.Label
+}
+
+// GetOrg returns the Org field.
+func (l *LabelEvent) GetOrg() *Organization {
+	if l == nil {
+		return nil
+	}
+	return l.Org
+}
+
+// GetRepo returns the Repo field.
+func (l *LabelEvent) GetRepo() *Repository {
+	if l == nil {
+		return nil
+	}
+	return l.Repo
+}
+
+// GetOID returns the OID field if it's non-nil, zero value otherwise.
+func (l *LargeFile) GetOID() string {
+	if l == nil || l.OID == nil {
+		return ""
+	}
+	return *l.OID
+}
+
+// GetPath returns the Path field if it's non-nil, zero value otherwise.
+func (l *LargeFile) GetPath() string {
+	if l == nil || l.Path == nil {
+		return ""
+	}
+	return *l.Path
+}
+
+// GetRefName returns the RefName field if it's non-nil, zero value otherwise.
+func (l *LargeFile) GetRefName() string {
+	if l == nil || l.RefName == nil {
+		return ""
+	}
+	return *l.RefName
+}
+
+// GetSize returns the Size field if it's non-nil, zero value otherwise.
+func (l *LargeFile) GetSize() int {
+	if l == nil || l.Size == nil {
+		return 0
+	}
+	return *l.Size
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (l *License) GetBody() string {
+	if l == nil || l.Body == nil {
+		return ""
+	}
+	return *l.Body
+}
+
+// GetConditions returns the Conditions field if it's non-nil, zero value otherwise.
+func (l *License) GetConditions() []string {
+	if l == nil || l.Conditions == nil {
+		return nil
+	}
+	return *l.Conditions
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (l *License) GetDescription() string {
+	if l == nil || l.Description == nil {
+		return ""
+	}
+	return *l.Description
+}
+
+// GetFeatured returns the Featured field if it's non-nil, zero value otherwise.
+func (l *License) GetFeatured() bool {
+	if l == nil || l.Featured == nil {
+		return false
+	}
+	return *l.Featured
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (l *License) GetHTMLURL() string {
+	if l == nil || l.HTMLURL == nil {
+		return ""
+	}
+	return *l.HTMLURL
+}
+
+// GetImplementation returns the Implementation field if it's non-nil, zero value otherwise.
+func (l *License) GetImplementation() string {
+	if l == nil || l.Implementation == nil {
+		return ""
+	}
+	return *l.Implementation
+}
+
+// GetKey returns the Key field if it's non-nil, zero value otherwise.
+func (l *License) GetKey() string {
+	if l == nil || l.Key == nil {
+		return ""
+	}
+	return *l.Key
+}
+
+// GetLimitations returns the Limitations field if it's non-nil, zero value otherwise.
+func (l *License) GetLimitations() []string {
+	if l == nil || l.Limitations == nil {
+		return nil
+	}
+	return *l.Limitations
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (l *License) GetName() string {
+	if l == nil || l.Name == nil {
+		return ""
+	}
+	return *l.Name
+}
+
+// GetPermissions returns the Permissions field if it's non-nil, zero value otherwise.
+func (l *License) GetPermissions() []string {
+	if l == nil || l.Permissions == nil {
+		return nil
+	}
+	return *l.Permissions
+}
+
+// GetSPDXID returns the SPDXID field if it's non-nil, zero value otherwise.
+func (l *License) GetSPDXID() string {
+	if l == nil || l.SPDXID == nil {
+		return ""
+	}
+	return *l.SPDXID
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (l *License) GetURL() string {
+	if l == nil || l.URL == nil {
+		return ""
+	}
+	return *l.URL
+}
+
+// GetAccountsURL returns the AccountsURL field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlan) GetAccountsURL() string {
+	if m == nil || m.AccountsURL == nil {
+		return ""
+	}
+	return *m.AccountsURL
+}
+
+// GetBullets returns the Bullets field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlan) GetBullets() []string {
+	if m == nil || m.Bullets == nil {
+		return nil
+	}
+	return *m.Bullets
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlan) GetDescription() string {
+	if m == nil || m.Description == nil {
+		return ""
+	}
+	return *m.Description
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlan) GetID() int64 {
+	if m == nil || m.ID == nil {
+		return 0
+	}
+	return *m.ID
+}
+
+// GetMonthlyPriceInCents returns the MonthlyPriceInCents field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlan) GetMonthlyPriceInCents() int {
+	if m == nil || m.MonthlyPriceInCents == nil {
+		return 0
+	}
+	return *m.MonthlyPriceInCents
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlan) GetName() string {
+	if m == nil || m.Name == nil {
+		return ""
+	}
+	return *m.Name
+}
+
+// GetPriceModel returns the PriceModel field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlan) GetPriceModel() string {
+	if m == nil || m.PriceModel == nil {
+		return ""
+	}
+	return *m.PriceModel
+}
+
+// GetUnitName returns the UnitName field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlan) GetUnitName() string {
+	if m == nil || m.UnitName == nil {
+		return ""
+	}
+	return *m.UnitName
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlan) GetURL() string {
+	if m == nil || m.URL == nil {
+		return ""
+	}
+	return *m.URL
+}
+
+// GetYearlyPriceInCents returns the YearlyPriceInCents field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlan) GetYearlyPriceInCents() int {
+	if m == nil || m.YearlyPriceInCents == nil {
+		return 0
+	}
+	return *m.YearlyPriceInCents
+}
+
+// GetEmail returns the Email field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlanAccount) GetEmail() string {
+	if m == nil || m.Email == nil {
+		return ""
+	}
+	return *m.Email
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlanAccount) GetID() int64 {
+	if m == nil || m.ID == nil {
+		return 0
+	}
+	return *m.ID
+}
+
+// GetLogin returns the Login field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlanAccount) GetLogin() string {
+	if m == nil || m.Login == nil {
+		return ""
+	}
+	return *m.Login
+}
+
+// GetMarketplacePurchase returns the MarketplacePurchase field.
+func (m *MarketplacePlanAccount) GetMarketplacePurchase() *MarketplacePurchase {
+	if m == nil {
+		return nil
+	}
+	return m.MarketplacePurchase
+}
+
+// GetOrganizationBillingEmail returns the OrganizationBillingEmail field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlanAccount) GetOrganizationBillingEmail() string {
+	if m == nil || m.OrganizationBillingEmail == nil {
+		return ""
+	}
+	return *m.OrganizationBillingEmail
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlanAccount) GetType() string {
+	if m == nil || m.Type == nil {
+		return ""
+	}
+	return *m.Type
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (m *MarketplacePlanAccount) GetURL() string {
+	if m == nil || m.URL == nil {
+		return ""
+	}
+	return *m.URL
+}
+
+// GetAccount returns the Account field.
+func (m *MarketplacePurchase) GetAccount() *MarketplacePlanAccount {
+	if m == nil {
+		return nil
+	}
+	return m.Account
+}
+
+// GetBillingCycle returns the BillingCycle field if it's non-nil, zero value otherwise.
+func (m *MarketplacePurchase) GetBillingCycle() string {
+	if m == nil || m.BillingCycle == nil {
+		return ""
+	}
+	return *m.BillingCycle
+}
+
+// GetNextBillingDate returns the NextBillingDate field if it's non-nil, zero value otherwise.
+func (m *MarketplacePurchase) GetNextBillingDate() string {
+	if m == nil || m.NextBillingDate == nil {
+		return ""
+	}
+	return *m.NextBillingDate
+}
+
+// GetPlan returns the Plan field.
+func (m *MarketplacePurchase) GetPlan() *MarketplacePlan {
+	if m == nil {
+		return nil
+	}
+	return m.Plan
+}
+
+// GetUnitCount returns the UnitCount field if it's non-nil, zero value otherwise.
+func (m *MarketplacePurchase) GetUnitCount() int {
+	if m == nil || m.UnitCount == nil {
+		return 0
+	}
+	return *m.UnitCount
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (m *MarketplacePurchaseEvent) GetAction() string {
+	if m == nil || m.Action == nil {
+		return ""
+	}
+	return *m.Action
+}
+
+// GetEffectiveDate returns the EffectiveDate field if it's non-nil, zero value otherwise.
+func (m *MarketplacePurchaseEvent) GetEffectiveDate() Timestamp {
+	if m == nil || m.EffectiveDate == nil {
+		return Timestamp{}
+	}
+	return *m.EffectiveDate
+}
+
+// GetInstallation returns the Installation field.
+func (m *MarketplacePurchaseEvent) GetInstallation() *Installation {
+	if m == nil {
+		return nil
+	}
+	return m.Installation
+}
+
+// GetMarketplacePurchase returns the MarketplacePurchase field.
+func (m *MarketplacePurchaseEvent) GetMarketplacePurchase() *MarketplacePurchase {
+	if m == nil {
+		return nil
+	}
+	return m.MarketplacePurchase
+}
+
+// GetPreviousMarketplacePurchase returns the PreviousMarketplacePurchase field.
+func (m *MarketplacePurchaseEvent) GetPreviousMarketplacePurchase() *MarketplacePurchase {
+	if m == nil {
+		return nil
+	}
+	return m.PreviousMarketplacePurchase
+}
+
+// GetSender returns the Sender field.
+func (m *MarketplacePurchaseEvent) GetSender() *User {
+	if m == nil {
+		return nil
+	}
+	return m.Sender
+}
+
+// GetText returns the Text field if it's non-nil, zero value otherwise.
+func (m *Match) GetText() string {
+	if m == nil || m.Text == nil {
+		return ""
+	}
+	return *m.Text
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (m *MemberEvent) GetAction() string {
+	if m == nil || m.Action == nil {
+		return ""
+	}
+	return *m.Action
+}
+
+// GetInstallation returns the Installation field.
+func (m *MemberEvent) GetInstallation() *Installation {
+	if m == nil {
+		return nil
+	}
+	return m.Installation
+}
+
+// GetMember returns the Member field.
+func (m *MemberEvent) GetMember() *User {
+	if m == nil {
+		return nil
+	}
+	return m.Member
+}
+
+// GetRepo returns the Repo field.
+func (m *MemberEvent) GetRepo() *Repository {
+	if m == nil {
+		return nil
+	}
+	return m.Repo
+}
+
+// GetSender returns the Sender field.
+func (m *MemberEvent) GetSender() *User {
+	if m == nil {
+		return nil
+	}
+	return m.Sender
+}
+
+// GetOrganization returns the Organization field.
+func (m *Membership) GetOrganization() *Organization {
+	if m == nil {
+		return nil
+	}
+	return m.Organization
+}
+
+// GetOrganizationURL returns the OrganizationURL field if it's non-nil, zero value otherwise.
+func (m *Membership) GetOrganizationURL() string {
+	if m == nil || m.OrganizationURL == nil {
+		return ""
+	}
+	return *m.OrganizationURL
+}
+
+// GetRole returns the Role field if it's non-nil, zero value otherwise.
+func (m *Membership) GetRole() string {
+	if m == nil || m.Role == nil {
+		return ""
+	}
+	return *m.Role
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (m *Membership) GetState() string {
+	if m == nil || m.State == nil {
+		return ""
+	}
+	return *m.State
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (m *Membership) GetURL() string {
+	if m == nil || m.URL == nil {
+		return ""
+	}
+	return *m.URL
+}
+
+// GetUser returns the User field.
+func (m *Membership) GetUser() *User {
+	if m == nil {
+		return nil
+	}
+	return m.User
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (m *MembershipEvent) GetAction() string {
+	if m == nil || m.Action == nil {
+		return ""
+	}
+	return *m.Action
+}
+
+// GetInstallation returns the Installation field.
+func (m *MembershipEvent) GetInstallation() *Installation {
+	if m == nil {
+		return nil
+	}
+	return m.Installation
+}
+
+// GetMember returns the Member field.
+func (m *MembershipEvent) GetMember() *User {
+	if m == nil {
+		return nil
+	}
+	return m.Member
+}
+
+// GetOrg returns the Org field.
+func (m *MembershipEvent) GetOrg() *Organization {
+	if m == nil {
+		return nil
+	}
+	return m.Org
+}
+
+// GetScope returns the Scope field if it's non-nil, zero value otherwise.
+func (m *MembershipEvent) GetScope() string {
+	if m == nil || m.Scope == nil {
+		return ""
+	}
+	return *m.Scope
+}
+
+// GetSender returns the Sender field.
+func (m *MembershipEvent) GetSender() *User {
+	if m == nil {
+		return nil
+	}
+	return m.Sender
+}
+
+// GetTeam returns the Team field.
+func (m *MembershipEvent) GetTeam() *Team {
+	if m == nil {
+		return nil
+	}
+	return m.Team
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (m *Metric) GetHTMLURL() string {
+	if m == nil || m.HTMLURL == nil {
+		return ""
+	}
+	return *m.HTMLURL
+}
+
+// GetKey returns the Key field if it's non-nil, zero value otherwise.
+func (m *Metric) GetKey() string {
+	if m == nil || m.Key == nil {
+		return ""
+	}
+	return *m.Key
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (m *Metric) GetName() string {
+	if m == nil || m.Name == nil {
+		return ""
+	}
+	return *m.Name
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (m *Metric) GetURL() string {
+	if m == nil || m.URL == nil {
+		return ""
+	}
+	return *m.URL
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (m *Migration) GetCreatedAt() string {
+	if m == nil || m.CreatedAt == nil {
+		return ""
+	}
+	return *m.CreatedAt
+}
+
+// GetExcludeAttachments returns the ExcludeAttachments field if it's non-nil, zero value otherwise.
+func (m *Migration) GetExcludeAttachments() bool {
+	if m == nil || m.ExcludeAttachments == nil {
+		return false
+	}
+	return *m.ExcludeAttachments
+}
+
+// GetGUID returns the GUID field if it's non-nil, zero value otherwise.
+func (m *Migration) GetGUID() string {
+	if m == nil || m.GUID == nil {
+		return ""
+	}
+	return *m.GUID
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (m *Migration) GetID() int64 {
+	if m == nil || m.ID == nil {
+		return 0
+	}
+	return *m.ID
+}
+
+// GetLockRepositories returns the LockRepositories field if it's non-nil, zero value otherwise.
+func (m *Migration) GetLockRepositories() bool {
+	if m == nil || m.LockRepositories == nil {
+		return false
+	}
+	return *m.LockRepositories
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (m *Migration) GetState() string {
+	if m == nil || m.State == nil {
+		return ""
+	}
+	return *m.State
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (m *Migration) GetUpdatedAt() string {
+	if m == nil || m.UpdatedAt == nil {
+		return ""
+	}
+	return *m.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (m *Migration) GetURL() string {
+	if m == nil || m.URL == nil {
+		return ""
+	}
+	return *m.URL
+}
+
+// GetClosedAt returns the ClosedAt field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetClosedAt() time.Time {
+	if m == nil || m.ClosedAt == nil {
+		return time.Time{}
+	}
+	return *m.ClosedAt
+}
+
+// GetClosedIssues returns the ClosedIssues field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetClosedIssues() int {
+	if m == nil || m.ClosedIssues == nil {
+		return 0
+	}
+	return *m.ClosedIssues
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetCreatedAt() time.Time {
+	if m == nil || m.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *m.CreatedAt
+}
+
+// GetCreator returns the Creator field.
+func (m *Milestone) GetCreator() *User {
+	if m == nil {
+		return nil
+	}
+	return m.Creator
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetDescription() string {
+	if m == nil || m.Description == nil {
+		return ""
+	}
+	return *m.Description
+}
+
+// GetDueOn returns the DueOn field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetDueOn() time.Time {
+	if m == nil || m.DueOn == nil {
+		return time.Time{}
+	}
+	return *m.DueOn
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetHTMLURL() string {
+	if m == nil || m.HTMLURL == nil {
+		return ""
+	}
+	return *m.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetID() int64 {
+	if m == nil || m.ID == nil {
+		return 0
+	}
+	return *m.ID
+}
+
+// GetLabelsURL returns the LabelsURL field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetLabelsURL() string {
+	if m == nil || m.LabelsURL == nil {
+		return ""
+	}
+	return *m.LabelsURL
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetNodeID() string {
+	if m == nil || m.NodeID == nil {
+		return ""
+	}
+	return *m.NodeID
+}
+
+// GetNumber returns the Number field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetNumber() int {
+	if m == nil || m.Number == nil {
+		return 0
+	}
+	return *m.Number
+}
+
+// GetOpenIssues returns the OpenIssues field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetOpenIssues() int {
+	if m == nil || m.OpenIssues == nil {
+		return 0
+	}
+	return *m.OpenIssues
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetState() string {
+	if m == nil || m.State == nil {
+		return ""
+	}
+	return *m.State
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetTitle() string {
+	if m == nil || m.Title == nil {
+		return ""
+	}
+	return *m.Title
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetUpdatedAt() time.Time {
+	if m == nil || m.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *m.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (m *Milestone) GetURL() string {
+	if m == nil || m.URL == nil {
+		return ""
+	}
+	return *m.URL
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (m *MilestoneEvent) GetAction() string {
+	if m == nil || m.Action == nil {
+		return ""
+	}
+	return *m.Action
+}
+
+// GetChanges returns the Changes field.
+func (m *MilestoneEvent) GetChanges() *EditChange {
+	if m == nil {
+		return nil
+	}
+	return m.Changes
+}
+
+// GetInstallation returns the Installation field.
+func (m *MilestoneEvent) GetInstallation() *Installation {
+	if m == nil {
+		return nil
+	}
+	return m.Installation
+}
+
+// GetMilestone returns the Milestone field.
+func (m *MilestoneEvent) GetMilestone() *Milestone {
+	if m == nil {
+		return nil
+	}
+	return m.Milestone
+}
+
+// GetOrg returns the Org field.
+func (m *MilestoneEvent) GetOrg() *Organization {
+	if m == nil {
+		return nil
+	}
+	return m.Org
+}
+
+// GetRepo returns the Repo field.
+func (m *MilestoneEvent) GetRepo() *Repository {
+	if m == nil {
+		return nil
+	}
+	return m.Repo
+}
+
+// GetSender returns the Sender field.
+func (m *MilestoneEvent) GetSender() *User {
+	if m == nil {
+		return nil
+	}
+	return m.Sender
+}
+
+// GetClosedMilestones returns the ClosedMilestones field if it's non-nil, zero value otherwise.
+func (m *MilestoneStats) GetClosedMilestones() int {
+	if m == nil || m.ClosedMilestones == nil {
+		return 0
+	}
+	return *m.ClosedMilestones
+}
+
+// GetOpenMilestones returns the OpenMilestones field if it's non-nil, zero value otherwise.
+func (m *MilestoneStats) GetOpenMilestones() int {
+	if m == nil || m.OpenMilestones == nil {
+		return 0
+	}
+	return *m.OpenMilestones
+}
+
+// GetTotalMilestones returns the TotalMilestones field if it's non-nil, zero value otherwise.
+func (m *MilestoneStats) GetTotalMilestones() int {
+	if m == nil || m.TotalMilestones == nil {
+		return 0
+	}
+	return *m.TotalMilestones
+}
+
+// GetBase returns the Base field if it's non-nil, zero value otherwise.
+func (n *NewPullRequest) GetBase() string {
+	if n == nil || n.Base == nil {
+		return ""
+	}
+	return *n.Base
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (n *NewPullRequest) GetBody() string {
+	if n == nil || n.Body == nil {
+		return ""
+	}
+	return *n.Body
+}
+
+// GetHead returns the Head field if it's non-nil, zero value otherwise.
+func (n *NewPullRequest) GetHead() string {
+	if n == nil || n.Head == nil {
+		return ""
+	}
+	return *n.Head
+}
+
+// GetIssue returns the Issue field if it's non-nil, zero value otherwise.
+func (n *NewPullRequest) GetIssue() int {
+	if n == nil || n.Issue == nil {
+		return 0
+	}
+	return *n.Issue
+}
+
+// GetMaintainerCanModify returns the MaintainerCanModify field if it's non-nil, zero value otherwise.
+func (n *NewPullRequest) GetMaintainerCanModify() bool {
+	if n == nil || n.MaintainerCanModify == nil {
+		return false
+	}
+	return *n.MaintainerCanModify
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (n *NewPullRequest) GetTitle() string {
+	if n == nil || n.Title == nil {
+		return ""
+	}
+	return *n.Title
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (n *NewTeam) GetDescription() string {
+	if n == nil || n.Description == nil {
+		return ""
+	}
+	return *n.Description
+}
+
+// GetLDAPDN returns the LDAPDN field if it's non-nil, zero value otherwise.
+func (n *NewTeam) GetLDAPDN() string {
+	if n == nil || n.LDAPDN == nil {
+		return ""
+	}
+	return *n.LDAPDN
+}
+
+// GetParentTeamID returns the ParentTeamID field if it's non-nil, zero value otherwise.
+func (n *NewTeam) GetParentTeamID() int64 {
+	if n == nil || n.ParentTeamID == nil {
+		return 0
+	}
+	return *n.ParentTeamID
+}
+
+// GetPermission returns the Permission field if it's non-nil, zero value otherwise.
+func (n *NewTeam) GetPermission() string {
+	if n == nil || n.Permission == nil {
+		return ""
+	}
+	return *n.Permission
+}
+
+// GetPrivacy returns the Privacy field if it's non-nil, zero value otherwise.
+func (n *NewTeam) GetPrivacy() string {
+	if n == nil || n.Privacy == nil {
+		return ""
+	}
+	return *n.Privacy
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (n *Notification) GetID() string {
+	if n == nil || n.ID == nil {
+		return ""
+	}
+	return *n.ID
+}
+
+// GetLastReadAt returns the LastReadAt field if it's non-nil, zero value otherwise.
+func (n *Notification) GetLastReadAt() time.Time {
+	if n == nil || n.LastReadAt == nil {
+		return time.Time{}
+	}
+	return *n.LastReadAt
+}
+
+// GetReason returns the Reason field if it's non-nil, zero value otherwise.
+func (n *Notification) GetReason() string {
+	if n == nil || n.Reason == nil {
+		return ""
+	}
+	return *n.Reason
+}
+
+// GetRepository returns the Repository field.
+func (n *Notification) GetRepository() *Repository {
+	if n == nil {
+		return nil
+	}
+	return n.Repository
+}
+
+// GetSubject returns the Subject field.
+func (n *Notification) GetSubject() *NotificationSubject {
+	if n == nil {
+		return nil
+	}
+	return n.Subject
+}
+
+// GetUnread returns the Unread field if it's non-nil, zero value otherwise.
+func (n *Notification) GetUnread() bool {
+	if n == nil || n.Unread == nil {
+		return false
+	}
+	return *n.Unread
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (n *Notification) GetUpdatedAt() time.Time {
+	if n == nil || n.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *n.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (n *Notification) GetURL() string {
+	if n == nil || n.URL == nil {
+		return ""
+	}
+	return *n.URL
+}
+
+// GetLatestCommentURL returns the LatestCommentURL field if it's non-nil, zero value otherwise.
+func (n *NotificationSubject) GetLatestCommentURL() string {
+	if n == nil || n.LatestCommentURL == nil {
+		return ""
+	}
+	return *n.LatestCommentURL
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (n *NotificationSubject) GetTitle() string {
+	if n == nil || n.Title == nil {
+		return ""
+	}
+	return *n.Title
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (n *NotificationSubject) GetType() string {
+	if n == nil || n.Type == nil {
+		return ""
+	}
+	return *n.Type
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (n *NotificationSubject) GetURL() string {
+	if n == nil || n.URL == nil {
+		return ""
+	}
+	return *n.URL
+}
+
+// GetAvatarURL returns the AvatarURL field if it's non-nil, zero value otherwise.
+func (o *Organization) GetAvatarURL() string {
+	if o == nil || o.AvatarURL == nil {
+		return ""
+	}
+	return *o.AvatarURL
+}
+
+// GetBillingEmail returns the BillingEmail field if it's non-nil, zero value otherwise.
+func (o *Organization) GetBillingEmail() string {
+	if o == nil || o.BillingEmail == nil {
+		return ""
+	}
+	return *o.BillingEmail
+}
+
+// GetBlog returns the Blog field if it's non-nil, zero value otherwise.
+func (o *Organization) GetBlog() string {
+	if o == nil || o.Blog == nil {
+		return ""
+	}
+	return *o.Blog
+}
+
+// GetCollaborators returns the Collaborators field if it's non-nil, zero value otherwise.
+func (o *Organization) GetCollaborators() int {
+	if o == nil || o.Collaborators == nil {
+		return 0
+	}
+	return *o.Collaborators
+}
+
+// GetCompany returns the Company field if it's non-nil, zero value otherwise.
+func (o *Organization) GetCompany() string {
+	if o == nil || o.Company == nil {
+		return ""
+	}
+	return *o.Company
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (o *Organization) GetCreatedAt() time.Time {
+	if o == nil || o.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *o.CreatedAt
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (o *Organization) GetDescription() string {
+	if o == nil || o.Description == nil {
+		return ""
+	}
+	return *o.Description
+}
+
+// GetDiskUsage returns the DiskUsage field if it's non-nil, zero value otherwise.
+func (o *Organization) GetDiskUsage() int {
+	if o == nil || o.DiskUsage == nil {
+		return 0
+	}
+	return *o.DiskUsage
+}
+
+// GetEmail returns the Email field if it's non-nil, zero value otherwise.
+func (o *Organization) GetEmail() string {
+	if o == nil || o.Email == nil {
+		return ""
+	}
+	return *o.Email
+}
+
+// GetEventsURL returns the EventsURL field if it's non-nil, zero value otherwise.
+func (o *Organization) GetEventsURL() string {
+	if o == nil || o.EventsURL == nil {
+		return ""
+	}
+	return *o.EventsURL
+}
+
+// GetFollowers returns the Followers field if it's non-nil, zero value otherwise.
+func (o *Organization) GetFollowers() int {
+	if o == nil || o.Followers == nil {
+		return 0
+	}
+	return *o.Followers
+}
+
+// GetFollowing returns the Following field if it's non-nil, zero value otherwise.
+func (o *Organization) GetFollowing() int {
+	if o == nil || o.Following == nil {
+		return 0
+	}
+	return *o.Following
+}
+
+// GetHooksURL returns the HooksURL field if it's non-nil, zero value otherwise.
+func (o *Organization) GetHooksURL() string {
+	if o == nil || o.HooksURL == nil {
+		return ""
+	}
+	return *o.HooksURL
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (o *Organization) GetHTMLURL() string {
+	if o == nil || o.HTMLURL == nil {
+		return ""
+	}
+	return *o.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (o *Organization) GetID() int64 {
+	if o == nil || o.ID == nil {
+		return 0
+	}
+	return *o.ID
+}
+
+// GetIssuesURL returns the IssuesURL field if it's non-nil, zero value otherwise.
+func (o *Organization) GetIssuesURL() string {
+	if o == nil || o.IssuesURL == nil {
+		return ""
+	}
+	return *o.IssuesURL
+}
+
+// GetLocation returns the Location field if it's non-nil, zero value otherwise.
+func (o *Organization) GetLocation() string {
+	if o == nil || o.Location == nil {
+		return ""
+	}
+	return *o.Location
+}
+
+// GetLogin returns the Login field if it's non-nil, zero value otherwise.
+func (o *Organization) GetLogin() string {
+	if o == nil || o.Login == nil {
+		return ""
+	}
+	return *o.Login
+}
+
+// GetMembersURL returns the MembersURL field if it's non-nil, zero value otherwise.
+func (o *Organization) GetMembersURL() string {
+	if o == nil || o.MembersURL == nil {
+		return ""
+	}
+	return *o.MembersURL
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (o *Organization) GetName() string {
+	if o == nil || o.Name == nil {
+		return ""
+	}
+	return *o.Name
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (o *Organization) GetNodeID() string {
+	if o == nil || o.NodeID == nil {
+		return ""
+	}
+	return *o.NodeID
+}
+
+// GetOwnedPrivateRepos returns the OwnedPrivateRepos field if it's non-nil, zero value otherwise.
+func (o *Organization) GetOwnedPrivateRepos() int {
+	if o == nil || o.OwnedPrivateRepos == nil {
+		return 0
+	}
+	return *o.OwnedPrivateRepos
+}
+
+// GetPlan returns the Plan field.
+func (o *Organization) GetPlan() *Plan {
+	if o == nil {
+		return nil
+	}
+	return o.Plan
+}
+
+// GetPrivateGists returns the PrivateGists field if it's non-nil, zero value otherwise.
+func (o *Organization) GetPrivateGists() int {
+	if o == nil || o.PrivateGists == nil {
+		return 0
+	}
+	return *o.PrivateGists
+}
+
+// GetPublicGists returns the PublicGists field if it's non-nil, zero value otherwise.
+func (o *Organization) GetPublicGists() int {
+	if o == nil || o.PublicGists == nil {
+		return 0
+	}
+	return *o.PublicGists
+}
+
+// GetPublicMembersURL returns the PublicMembersURL field if it's non-nil, zero value otherwise.
+func (o *Organization) GetPublicMembersURL() string {
+	if o == nil || o.PublicMembersURL == nil {
+		return ""
+	}
+	return *o.PublicMembersURL
+}
+
+// GetPublicRepos returns the PublicRepos field if it's non-nil, zero value otherwise.
+func (o *Organization) GetPublicRepos() int {
+	if o == nil || o.PublicRepos == nil {
+		return 0
+	}
+	return *o.PublicRepos
+}
+
+// GetReposURL returns the ReposURL field if it's non-nil, zero value otherwise.
+func (o *Organization) GetReposURL() string {
+	if o == nil || o.ReposURL == nil {
+		return ""
+	}
+	return *o.ReposURL
+}
+
+// GetTotalPrivateRepos returns the TotalPrivateRepos field if it's non-nil, zero value otherwise.
+func (o *Organization) GetTotalPrivateRepos() int {
+	if o == nil || o.TotalPrivateRepos == nil {
+		return 0
+	}
+	return *o.TotalPrivateRepos
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (o *Organization) GetType() string {
+	if o == nil || o.Type == nil {
+		return ""
+	}
+	return *o.Type
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (o *Organization) GetUpdatedAt() time.Time {
+	if o == nil || o.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *o.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (o *Organization) GetURL() string {
+	if o == nil || o.URL == nil {
+		return ""
+	}
+	return *o.URL
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (o *OrganizationEvent) GetAction() string {
+	if o == nil || o.Action == nil {
+		return ""
+	}
+	return *o.Action
+}
+
+// GetInstallation returns the Installation field.
+func (o *OrganizationEvent) GetInstallation() *Installation {
+	if o == nil {
+		return nil
+	}
+	return o.Installation
+}
+
+// GetInvitation returns the Invitation field.
+func (o *OrganizationEvent) GetInvitation() *Invitation {
+	if o == nil {
+		return nil
+	}
+	return o.Invitation
+}
+
+// GetMembership returns the Membership field.
+func (o *OrganizationEvent) GetMembership() *Membership {
+	if o == nil {
+		return nil
+	}
+	return o.Membership
+}
+
+// GetOrganization returns the Organization field.
+func (o *OrganizationEvent) GetOrganization() *Organization {
+	if o == nil {
+		return nil
+	}
+	return o.Organization
+}
+
+// GetSender returns the Sender field.
+func (o *OrganizationEvent) GetSender() *User {
+	if o == nil {
+		return nil
+	}
+	return o.Sender
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (o *OrgBlockEvent) GetAction() string {
+	if o == nil || o.Action == nil {
+		return ""
+	}
+	return *o.Action
+}
+
+// GetBlockedUser returns the BlockedUser field.
+func (o *OrgBlockEvent) GetBlockedUser() *User {
+	if o == nil {
+		return nil
+	}
+	return o.BlockedUser
+}
+
+// GetInstallation returns the Installation field.
+func (o *OrgBlockEvent) GetInstallation() *Installation {
+	if o == nil {
+		return nil
+	}
+	return o.Installation
+}
+
+// GetOrganization returns the Organization field.
+func (o *OrgBlockEvent) GetOrganization() *Organization {
+	if o == nil {
+		return nil
+	}
+	return o.Organization
+}
+
+// GetSender returns the Sender field.
+func (o *OrgBlockEvent) GetSender() *User {
+	if o == nil {
+		return nil
+	}
+	return o.Sender
+}
+
+// GetDisabledOrgs returns the DisabledOrgs field if it's non-nil, zero value otherwise.
+func (o *OrgStats) GetDisabledOrgs() int {
+	if o == nil || o.DisabledOrgs == nil {
+		return 0
+	}
+	return *o.DisabledOrgs
+}
+
+// GetTotalOrgs returns the TotalOrgs field if it's non-nil, zero value otherwise.
+func (o *OrgStats) GetTotalOrgs() int {
+	if o == nil || o.TotalOrgs == nil {
+		return 0
+	}
+	return *o.TotalOrgs
+}
+
+// GetTotalTeamMembers returns the TotalTeamMembers field if it's non-nil, zero value otherwise.
+func (o *OrgStats) GetTotalTeamMembers() int {
+	if o == nil || o.TotalTeamMembers == nil {
+		return 0
+	}
+	return *o.TotalTeamMembers
+}
+
+// GetTotalTeams returns the TotalTeams field if it's non-nil, zero value otherwise.
+func (o *OrgStats) GetTotalTeams() int {
+	if o == nil || o.TotalTeams == nil {
+		return 0
+	}
+	return *o.TotalTeams
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (p *Page) GetAction() string {
+	if p == nil || p.Action == nil {
+		return ""
+	}
+	return *p.Action
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (p *Page) GetHTMLURL() string {
+	if p == nil || p.HTMLURL == nil {
+		return ""
+	}
+	return *p.HTMLURL
+}
+
+// GetPageName returns the PageName field if it's non-nil, zero value otherwise.
+func (p *Page) GetPageName() string {
+	if p == nil || p.PageName == nil {
+		return ""
+	}
+	return *p.PageName
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (p *Page) GetSHA() string {
+	if p == nil || p.SHA == nil {
+		return ""
+	}
+	return *p.SHA
+}
+
+// GetSummary returns the Summary field if it's non-nil, zero value otherwise.
+func (p *Page) GetSummary() string {
+	if p == nil || p.Summary == nil {
+		return ""
+	}
+	return *p.Summary
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (p *Page) GetTitle() string {
+	if p == nil || p.Title == nil {
+		return ""
+	}
+	return *p.Title
+}
+
+// GetBuild returns the Build field.
+func (p *PageBuildEvent) GetBuild() *PagesBuild {
+	if p == nil {
+		return nil
+	}
+	return p.Build
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (p *PageBuildEvent) GetID() int64 {
+	if p == nil || p.ID == nil {
+		return 0
+	}
+	return *p.ID
+}
+
+// GetInstallation returns the Installation field.
+func (p *PageBuildEvent) GetInstallation() *Installation {
+	if p == nil {
+		return nil
+	}
+	return p.Installation
+}
+
+// GetRepo returns the Repo field.
+func (p *PageBuildEvent) GetRepo() *Repository {
+	if p == nil {
+		return nil
+	}
+	return p.Repo
+}
+
+// GetSender returns the Sender field.
+func (p *PageBuildEvent) GetSender() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Sender
+}
+
+// GetCNAME returns the CNAME field if it's non-nil, zero value otherwise.
+func (p *Pages) GetCNAME() string {
+	if p == nil || p.CNAME == nil {
+		return ""
+	}
+	return *p.CNAME
+}
+
+// GetCustom404 returns the Custom404 field if it's non-nil, zero value otherwise.
+func (p *Pages) GetCustom404() bool {
+	if p == nil || p.Custom404 == nil {
+		return false
+	}
+	return *p.Custom404
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (p *Pages) GetHTMLURL() string {
+	if p == nil || p.HTMLURL == nil {
+		return ""
+	}
+	return *p.HTMLURL
+}
+
+// GetStatus returns the Status field if it's non-nil, zero value otherwise.
+func (p *Pages) GetStatus() string {
+	if p == nil || p.Status == nil {
+		return ""
+	}
+	return *p.Status
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (p *Pages) GetURL() string {
+	if p == nil || p.URL == nil {
+		return ""
+	}
+	return *p.URL
+}
+
+// GetCommit returns the Commit field if it's non-nil, zero value otherwise.
+func (p *PagesBuild) GetCommit() string {
+	if p == nil || p.Commit == nil {
+		return ""
+	}
+	return *p.Commit
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (p *PagesBuild) GetCreatedAt() Timestamp {
+	if p == nil || p.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.CreatedAt
+}
+
+// GetDuration returns the Duration field if it's non-nil, zero value otherwise.
+func (p *PagesBuild) GetDuration() int {
+	if p == nil || p.Duration == nil {
+		return 0
+	}
+	return *p.Duration
+}
+
+// GetError returns the Error field.
+func (p *PagesBuild) GetError() *PagesError {
+	if p == nil {
+		return nil
+	}
+	return p.Error
+}
+
+// GetPusher returns the Pusher field.
+func (p *PagesBuild) GetPusher() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Pusher
+}
+
+// GetStatus returns the Status field if it's non-nil, zero value otherwise.
+func (p *PagesBuild) GetStatus() string {
+	if p == nil || p.Status == nil {
+		return ""
+	}
+	return *p.Status
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (p *PagesBuild) GetUpdatedAt() Timestamp {
+	if p == nil || p.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (p *PagesBuild) GetURL() string {
+	if p == nil || p.URL == nil {
+		return ""
+	}
+	return *p.URL
+}
+
+// GetMessage returns the Message field if it's non-nil, zero value otherwise.
+func (p *PagesError) GetMessage() string {
+	if p == nil || p.Message == nil {
+		return ""
+	}
+	return *p.Message
+}
+
+// GetTotalPages returns the TotalPages field if it's non-nil, zero value otherwise.
+func (p *PageStats) GetTotalPages() int {
+	if p == nil || p.TotalPages == nil {
+		return 0
+	}
+	return *p.TotalPages
+}
+
+// GetHook returns the Hook field.
+func (p *PingEvent) GetHook() *Hook {
+	if p == nil {
+		return nil
+	}
+	return p.Hook
+}
+
+// GetHookID returns the HookID field if it's non-nil, zero value otherwise.
+func (p *PingEvent) GetHookID() int64 {
+	if p == nil || p.HookID == nil {
+		return 0
+	}
+	return *p.HookID
+}
+
+// GetInstallation returns the Installation field.
+func (p *PingEvent) GetInstallation() *Installation {
+	if p == nil {
+		return nil
+	}
+	return p.Installation
+}
+
+// GetZen returns the Zen field if it's non-nil, zero value otherwise.
+func (p *PingEvent) GetZen() string {
+	if p == nil || p.Zen == nil {
+		return ""
+	}
+	return *p.Zen
+}
+
+// GetCollaborators returns the Collaborators field if it's non-nil, zero value otherwise.
+func (p *Plan) GetCollaborators() int {
+	if p == nil || p.Collaborators == nil {
+		return 0
+	}
+	return *p.Collaborators
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (p *Plan) GetName() string {
+	if p == nil || p.Name == nil {
+		return ""
+	}
+	return *p.Name
+}
+
+// GetPrivateRepos returns the PrivateRepos field if it's non-nil, zero value otherwise.
+func (p *Plan) GetPrivateRepos() int {
+	if p == nil || p.PrivateRepos == nil {
+		return 0
+	}
+	return *p.PrivateRepos
+}
+
+// GetSpace returns the Space field if it's non-nil, zero value otherwise.
+func (p *Plan) GetSpace() int {
+	if p == nil || p.Space == nil {
+		return 0
+	}
+	return *p.Space
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (p *Project) GetBody() string {
+	if p == nil || p.Body == nil {
+		return ""
+	}
+	return *p.Body
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (p *Project) GetCreatedAt() Timestamp {
+	if p == nil || p.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.CreatedAt
+}
+
+// GetCreator returns the Creator field.
+func (p *Project) GetCreator() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Creator
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (p *Project) GetID() int64 {
+	if p == nil || p.ID == nil {
+		return 0
+	}
+	return *p.ID
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (p *Project) GetName() string {
+	if p == nil || p.Name == nil {
+		return ""
+	}
+	return *p.Name
+}
+
+// GetNumber returns the Number field if it's non-nil, zero value otherwise.
+func (p *Project) GetNumber() int {
+	if p == nil || p.Number == nil {
+		return 0
+	}
+	return *p.Number
+}
+
+// GetOwnerURL returns the OwnerURL field if it's non-nil, zero value otherwise.
+func (p *Project) GetOwnerURL() string {
+	if p == nil || p.OwnerURL == nil {
+		return ""
+	}
+	return *p.OwnerURL
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (p *Project) GetUpdatedAt() Timestamp {
+	if p == nil || p.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (p *Project) GetURL() string {
+	if p == nil || p.URL == nil {
+		return ""
+	}
+	return *p.URL
+}
+
+// GetColumnID returns the ColumnID field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetColumnID() int64 {
+	if p == nil || p.ColumnID == nil {
+		return 0
+	}
+	return *p.ColumnID
+}
+
+// GetColumnURL returns the ColumnURL field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetColumnURL() string {
+	if p == nil || p.ColumnURL == nil {
+		return ""
+	}
+	return *p.ColumnURL
+}
+
+// GetContentURL returns the ContentURL field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetContentURL() string {
+	if p == nil || p.ContentURL == nil {
+		return ""
+	}
+	return *p.ContentURL
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetCreatedAt() Timestamp {
+	if p == nil || p.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.CreatedAt
+}
+
+// GetCreator returns the Creator field.
+func (p *ProjectCard) GetCreator() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Creator
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetID() int64 {
+	if p == nil || p.ID == nil {
+		return 0
+	}
+	return *p.ID
+}
+
+// GetNote returns the Note field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetNote() string {
+	if p == nil || p.Note == nil {
+		return ""
+	}
+	return *p.Note
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetUpdatedAt() Timestamp {
+	if p == nil || p.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetURL() string {
+	if p == nil || p.URL == nil {
+		return ""
+	}
+	return *p.URL
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (p *ProjectCardEvent) GetAction() string {
+	if p == nil || p.Action == nil {
+		return ""
+	}
+	return *p.Action
+}
+
+// GetAfterID returns the AfterID field if it's non-nil, zero value otherwise.
+func (p *ProjectCardEvent) GetAfterID() int64 {
+	if p == nil || p.AfterID == nil {
+		return 0
+	}
+	return *p.AfterID
+}
+
+// GetChanges returns the Changes field.
+func (p *ProjectCardEvent) GetChanges() *ProjectCardChange {
+	if p == nil {
+		return nil
+	}
+	return p.Changes
+}
+
+// GetInstallation returns the Installation field.
+func (p *ProjectCardEvent) GetInstallation() *Installation {
+	if p == nil {
+		return nil
+	}
+	return p.Installation
+}
+
+// GetOrg returns the Org field.
+func (p *ProjectCardEvent) GetOrg() *Organization {
+	if p == nil {
+		return nil
+	}
+	return p.Org
+}
+
+// GetProjectCard returns the ProjectCard field.
+func (p *ProjectCardEvent) GetProjectCard() *ProjectCard {
+	if p == nil {
+		return nil
+	}
+	return p.ProjectCard
+}
+
+// GetRepo returns the Repo field.
+func (p *ProjectCardEvent) GetRepo() *Repository {
+	if p == nil {
+		return nil
+	}
+	return p.Repo
+}
+
+// GetSender returns the Sender field.
+func (p *ProjectCardEvent) GetSender() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Sender
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (p *ProjectColumn) GetCreatedAt() Timestamp {
+	if p == nil || p.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.CreatedAt
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (p *ProjectColumn) GetID() int64 {
+	if p == nil || p.ID == nil {
+		return 0
+	}
+	return *p.ID
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (p *ProjectColumn) GetName() string {
+	if p == nil || p.Name == nil {
+		return ""
+	}
+	return *p.Name
+}
+
+// GetProjectURL returns the ProjectURL field if it's non-nil, zero value otherwise.
+func (p *ProjectColumn) GetProjectURL() string {
+	if p == nil || p.ProjectURL == nil {
+		return ""
+	}
+	return *p.ProjectURL
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (p *ProjectColumn) GetUpdatedAt() Timestamp {
+	if p == nil || p.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.UpdatedAt
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (p *ProjectColumnEvent) GetAction() string {
+	if p == nil || p.Action == nil {
+		return ""
+	}
+	return *p.Action
+}
+
+// GetAfterID returns the AfterID field if it's non-nil, zero value otherwise.
+func (p *ProjectColumnEvent) GetAfterID() int64 {
+	if p == nil || p.AfterID == nil {
+		return 0
+	}
+	return *p.AfterID
+}
+
+// GetChanges returns the Changes field.
+func (p *ProjectColumnEvent) GetChanges() *ProjectColumnChange {
+	if p == nil {
+		return nil
+	}
+	return p.Changes
+}
+
+// GetInstallation returns the Installation field.
+func (p *ProjectColumnEvent) GetInstallation() *Installation {
+	if p == nil {
+		return nil
+	}
+	return p.Installation
+}
+
+// GetOrg returns the Org field.
+func (p *ProjectColumnEvent) GetOrg() *Organization {
+	if p == nil {
+		return nil
+	}
+	return p.Org
+}
+
+// GetProjectColumn returns the ProjectColumn field.
+func (p *ProjectColumnEvent) GetProjectColumn() *ProjectColumn {
+	if p == nil {
+		return nil
+	}
+	return p.ProjectColumn
+}
+
+// GetRepo returns the Repo field.
+func (p *ProjectColumnEvent) GetRepo() *Repository {
+	if p == nil {
+		return nil
+	}
+	return p.Repo
+}
+
+// GetSender returns the Sender field.
+func (p *ProjectColumnEvent) GetSender() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Sender
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (p *ProjectEvent) GetAction() string {
+	if p == nil || p.Action == nil {
+		return ""
+	}
+	return *p.Action
+}
+
+// GetChanges returns the Changes field.
+func (p *ProjectEvent) GetChanges() *ProjectChange {
+	if p == nil {
+		return nil
+	}
+	return p.Changes
+}
+
+// GetInstallation returns the Installation field.
+func (p *ProjectEvent) GetInstallation() *Installation {
+	if p == nil {
+		return nil
+	}
+	return p.Installation
+}
+
+// GetOrg returns the Org field.
+func (p *ProjectEvent) GetOrg() *Organization {
+	if p == nil {
+		return nil
+	}
+	return p.Org
+}
+
+// GetProject returns the Project field.
+func (p *ProjectEvent) GetProject() *Project {
+	if p == nil {
+		return nil
+	}
+	return p.Project
+}
+
+// GetRepo returns the Repo field.
+func (p *ProjectEvent) GetRepo() *Repository {
+	if p == nil {
+		return nil
+	}
+	return p.Repo
+}
+
+// GetSender returns the Sender field.
+func (p *ProjectEvent) GetSender() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Sender
+}
+
+// GetEnforceAdmins returns the EnforceAdmins field.
+func (p *Protection) GetEnforceAdmins() *AdminEnforcement {
+	if p == nil {
+		return nil
+	}
+	return p.EnforceAdmins
+}
+
+// GetRequiredPullRequestReviews returns the RequiredPullRequestReviews field.
+func (p *Protection) GetRequiredPullRequestReviews() *PullRequestReviewsEnforcement {
+	if p == nil {
+		return nil
+	}
+	return p.RequiredPullRequestReviews
+}
+
+// GetRequiredStatusChecks returns the RequiredStatusChecks field.
+func (p *Protection) GetRequiredStatusChecks() *RequiredStatusChecks {
+	if p == nil {
+		return nil
+	}
+	return p.RequiredStatusChecks
+}
+
+// GetRestrictions returns the Restrictions field.
+func (p *Protection) GetRestrictions() *BranchRestrictions {
+	if p == nil {
+		return nil
+	}
+	return p.Restrictions
+}
+
+// GetRequiredPullRequestReviews returns the RequiredPullRequestReviews field.
+func (p *ProtectionRequest) GetRequiredPullRequestReviews() *PullRequestReviewsEnforcementRequest {
+	if p == nil {
+		return nil
+	}
+	return p.RequiredPullRequestReviews
+}
+
+// GetRequiredStatusChecks returns the RequiredStatusChecks field.
+func (p *ProtectionRequest) GetRequiredStatusChecks() *RequiredStatusChecks {
+	if p == nil {
+		return nil
+	}
+	return p.RequiredStatusChecks
+}
+
+// GetRestrictions returns the Restrictions field.
+func (p *ProtectionRequest) GetRestrictions() *BranchRestrictionsRequest {
+	if p == nil {
+		return nil
+	}
+	return p.Restrictions
+}
+
+// GetInstallation returns the Installation field.
+func (p *PublicEvent) GetInstallation() *Installation {
+	if p == nil {
+		return nil
+	}
+	return p.Installation
+}
+
+// GetRepo returns the Repo field.
+func (p *PublicEvent) GetRepo() *Repository {
+	if p == nil {
+		return nil
+	}
+	return p.Repo
+}
+
+// GetSender returns the Sender field.
+func (p *PublicEvent) GetSender() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Sender
+}
+
+// GetAdditions returns the Additions field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetAdditions() int {
+	if p == nil || p.Additions == nil {
+		return 0
+	}
+	return *p.Additions
+}
+
+// GetAssignee returns the Assignee field.
+func (p *PullRequest) GetAssignee() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Assignee
+}
+
+// GetAuthorAssociation returns the AuthorAssociation field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetAuthorAssociation() string {
+	if p == nil || p.AuthorAssociation == nil {
+		return ""
+	}
+	return *p.AuthorAssociation
+}
+
+// GetBase returns the Base field.
+func (p *PullRequest) GetBase() *PullRequestBranch {
+	if p == nil {
+		return nil
+	}
+	return p.Base
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetBody() string {
+	if p == nil || p.Body == nil {
+		return ""
+	}
+	return *p.Body
+}
+
+// GetChangedFiles returns the ChangedFiles field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetChangedFiles() int {
+	if p == nil || p.ChangedFiles == nil {
+		return 0
+	}
+	return *p.ChangedFiles
+}
+
+// GetClosedAt returns the ClosedAt field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetClosedAt() time.Time {
+	if p == nil || p.ClosedAt == nil {
+		return time.Time{}
+	}
+	return *p.ClosedAt
+}
+
+// GetComments returns the Comments field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetComments() int {
+	if p == nil || p.Comments == nil {
+		return 0
+	}
+	return *p.Comments
+}
+
+// GetCommits returns the Commits field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetCommits() int {
+	if p == nil || p.Commits == nil {
+		return 0
+	}
+	return *p.Commits
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetCreatedAt() time.Time {
+	if p == nil || p.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *p.CreatedAt
+}
+
+// GetDeletions returns the Deletions field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetDeletions() int {
+	if p == nil || p.Deletions == nil {
+		return 0
+	}
+	return *p.Deletions
+}
+
+// GetDiffURL returns the DiffURL field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetDiffURL() string {
+	if p == nil || p.DiffURL == nil {
+		return ""
+	}
+	return *p.DiffURL
+}
+
+// GetHead returns the Head field.
+func (p *PullRequest) GetHead() *PullRequestBranch {
+	if p == nil {
+		return nil
+	}
+	return p.Head
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetHTMLURL() string {
+	if p == nil || p.HTMLURL == nil {
+		return ""
+	}
+	return *p.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetID() int64 {
+	if p == nil || p.ID == nil {
+		return 0
+	}
+	return *p.ID
+}
+
+// GetIssueURL returns the IssueURL field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetIssueURL() string {
+	if p == nil || p.IssueURL == nil {
+		return ""
+	}
+	return *p.IssueURL
+}
+
+// GetMaintainerCanModify returns the MaintainerCanModify field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetMaintainerCanModify() bool {
+	if p == nil || p.MaintainerCanModify == nil {
+		return false
+	}
+	return *p.MaintainerCanModify
+}
+
+// GetMergeable returns the Mergeable field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetMergeable() bool {
+	if p == nil || p.Mergeable == nil {
+		return false
+	}
+	return *p.Mergeable
+}
+
+// GetMergeableState returns the MergeableState field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetMergeableState() string {
+	if p == nil || p.MergeableState == nil {
+		return ""
+	}
+	return *p.MergeableState
+}
+
+// GetMergeCommitSHA returns the MergeCommitSHA field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetMergeCommitSHA() string {
+	if p == nil || p.MergeCommitSHA == nil {
+		return ""
+	}
+	return *p.MergeCommitSHA
+}
+
+// GetMerged returns the Merged field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetMerged() bool {
+	if p == nil || p.Merged == nil {
+		return false
+	}
+	return *p.Merged
+}
+
+// GetMergedAt returns the MergedAt field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetMergedAt() time.Time {
+	if p == nil || p.MergedAt == nil {
+		return time.Time{}
+	}
+	return *p.MergedAt
+}
+
+// GetMergedBy returns the MergedBy field.
+func (p *PullRequest) GetMergedBy() *User {
+	if p == nil {
+		return nil
+	}
+	return p.MergedBy
+}
+
+// GetMilestone returns the Milestone field.
+func (p *PullRequest) GetMilestone() *Milestone {
+	if p == nil {
+		return nil
+	}
+	return p.Milestone
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetNodeID() string {
+	if p == nil || p.NodeID == nil {
+		return ""
+	}
+	return *p.NodeID
+}
+
+// GetNumber returns the Number field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetNumber() int {
+	if p == nil || p.Number == nil {
+		return 0
+	}
+	return *p.Number
+}
+
+// GetPatchURL returns the PatchURL field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetPatchURL() string {
+	if p == nil || p.PatchURL == nil {
+		return ""
+	}
+	return *p.PatchURL
+}
+
+// GetReviewCommentsURL returns the ReviewCommentsURL field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetReviewCommentsURL() string {
+	if p == nil || p.ReviewCommentsURL == nil {
+		return ""
+	}
+	return *p.ReviewCommentsURL
+}
+
+// GetReviewCommentURL returns the ReviewCommentURL field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetReviewCommentURL() string {
+	if p == nil || p.ReviewCommentURL == nil {
+		return ""
+	}
+	return *p.ReviewCommentURL
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetState() string {
+	if p == nil || p.State == nil {
+		return ""
+	}
+	return *p.State
+}
+
+// GetStatusesURL returns the StatusesURL field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetStatusesURL() string {
+	if p == nil || p.StatusesURL == nil {
+		return ""
+	}
+	return *p.StatusesURL
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetTitle() string {
+	if p == nil || p.Title == nil {
+		return ""
+	}
+	return *p.Title
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetUpdatedAt() time.Time {
+	if p == nil || p.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *p.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (p *PullRequest) GetURL() string {
+	if p == nil || p.URL == nil {
+		return ""
+	}
+	return *p.URL
+}
+
+// GetUser returns the User field.
+func (p *PullRequest) GetUser() *User {
+	if p == nil {
+		return nil
+	}
+	return p.User
+}
+
+// GetLabel returns the Label field if it's non-nil, zero value otherwise.
+func (p *PullRequestBranch) GetLabel() string {
+	if p == nil || p.Label == nil {
+		return ""
+	}
+	return *p.Label
+}
+
+// GetRef returns the Ref field if it's non-nil, zero value otherwise.
+func (p *PullRequestBranch) GetRef() string {
+	if p == nil || p.Ref == nil {
+		return ""
+	}
+	return *p.Ref
+}
+
+// GetRepo returns the Repo field.
+func (p *PullRequestBranch) GetRepo() *Repository {
+	if p == nil {
+		return nil
+	}
+	return p.Repo
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (p *PullRequestBranch) GetSHA() string {
+	if p == nil || p.SHA == nil {
+		return ""
+	}
+	return *p.SHA
+}
+
+// GetUser returns the User field.
+func (p *PullRequestBranch) GetUser() *User {
+	if p == nil {
+		return nil
+	}
+	return p.User
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetBody() string {
+	if p == nil || p.Body == nil {
+		return ""
+	}
+	return *p.Body
+}
+
+// GetCommitID returns the CommitID field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetCommitID() string {
+	if p == nil || p.CommitID == nil {
+		return ""
+	}
+	return *p.CommitID
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetCreatedAt() time.Time {
+	if p == nil || p.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *p.CreatedAt
+}
+
+// GetDiffHunk returns the DiffHunk field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetDiffHunk() string {
+	if p == nil || p.DiffHunk == nil {
+		return ""
+	}
+	return *p.DiffHunk
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetHTMLURL() string {
+	if p == nil || p.HTMLURL == nil {
+		return ""
+	}
+	return *p.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetID() int64 {
+	if p == nil || p.ID == nil {
+		return 0
+	}
+	return *p.ID
+}
+
+// GetInReplyTo returns the InReplyTo field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetInReplyTo() int64 {
+	if p == nil || p.InReplyTo == nil {
+		return 0
+	}
+	return *p.InReplyTo
+}
+
+// GetOriginalCommitID returns the OriginalCommitID field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetOriginalCommitID() string {
+	if p == nil || p.OriginalCommitID == nil {
+		return ""
+	}
+	return *p.OriginalCommitID
+}
+
+// GetOriginalPosition returns the OriginalPosition field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetOriginalPosition() int {
+	if p == nil || p.OriginalPosition == nil {
+		return 0
+	}
+	return *p.OriginalPosition
+}
+
+// GetPath returns the Path field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetPath() string {
+	if p == nil || p.Path == nil {
+		return ""
+	}
+	return *p.Path
+}
+
+// GetPosition returns the Position field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetPosition() int {
+	if p == nil || p.Position == nil {
+		return 0
+	}
+	return *p.Position
+}
+
+// GetPullRequestURL returns the PullRequestURL field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetPullRequestURL() string {
+	if p == nil || p.PullRequestURL == nil {
+		return ""
+	}
+	return *p.PullRequestURL
+}
+
+// GetReactions returns the Reactions field.
+func (p *PullRequestComment) GetReactions() *Reactions {
+	if p == nil {
+		return nil
+	}
+	return p.Reactions
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetUpdatedAt() time.Time {
+	if p == nil || p.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *p.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetURL() string {
+	if p == nil || p.URL == nil {
+		return ""
+	}
+	return *p.URL
+}
+
+// GetUser returns the User field.
+func (p *PullRequestComment) GetUser() *User {
+	if p == nil {
+		return nil
+	}
+	return p.User
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (p *PullRequestEvent) GetAction() string {
+	if p == nil || p.Action == nil {
+		return ""
+	}
+	return *p.Action
+}
+
+// GetChanges returns the Changes field.
+func (p *PullRequestEvent) GetChanges() *EditChange {
+	if p == nil {
+		return nil
+	}
+	return p.Changes
+}
+
+// GetInstallation returns the Installation field.
+func (p *PullRequestEvent) GetInstallation() *Installation {
+	if p == nil {
+		return nil
+	}
+	return p.Installation
+}
+
+// GetNumber returns the Number field if it's non-nil, zero value otherwise.
+func (p *PullRequestEvent) GetNumber() int {
+	if p == nil || p.Number == nil {
+		return 0
+	}
+	return *p.Number
+}
+
+// GetPullRequest returns the PullRequest field.
+func (p *PullRequestEvent) GetPullRequest() *PullRequest {
+	if p == nil {
+		return nil
+	}
+	return p.PullRequest
+}
+
+// GetRepo returns the Repo field.
+func (p *PullRequestEvent) GetRepo() *Repository {
+	if p == nil {
+		return nil
+	}
+	return p.Repo
+}
+
+// GetSender returns the Sender field.
+func (p *PullRequestEvent) GetSender() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Sender
+}
+
+// GetDiffURL returns the DiffURL field if it's non-nil, zero value otherwise.
+func (p *PullRequestLinks) GetDiffURL() string {
+	if p == nil || p.DiffURL == nil {
+		return ""
+	}
+	return *p.DiffURL
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (p *PullRequestLinks) GetHTMLURL() string {
+	if p == nil || p.HTMLURL == nil {
+		return ""
+	}
+	return *p.HTMLURL
+}
+
+// GetPatchURL returns the PatchURL field if it's non-nil, zero value otherwise.
+func (p *PullRequestLinks) GetPatchURL() string {
+	if p == nil || p.PatchURL == nil {
+		return ""
+	}
+	return *p.PatchURL
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (p *PullRequestLinks) GetURL() string {
+	if p == nil || p.URL == nil {
+		return ""
+	}
+	return *p.URL
+}
+
+// GetMerged returns the Merged field if it's non-nil, zero value otherwise.
+func (p *PullRequestMergeResult) GetMerged() bool {
+	if p == nil || p.Merged == nil {
+		return false
+	}
+	return *p.Merged
+}
+
+// GetMessage returns the Message field if it's non-nil, zero value otherwise.
+func (p *PullRequestMergeResult) GetMessage() string {
+	if p == nil || p.Message == nil {
+		return ""
+	}
+	return *p.Message
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (p *PullRequestMergeResult) GetSHA() string {
+	if p == nil || p.SHA == nil {
+		return ""
+	}
+	return *p.SHA
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (p *PullRequestReview) GetBody() string {
+	if p == nil || p.Body == nil {
+		return ""
+	}
+	return *p.Body
+}
+
+// GetCommitID returns the CommitID field if it's non-nil, zero value otherwise.
+func (p *PullRequestReview) GetCommitID() string {
+	if p == nil || p.CommitID == nil {
+		return ""
+	}
+	return *p.CommitID
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (p *PullRequestReview) GetHTMLURL() string {
+	if p == nil || p.HTMLURL == nil {
+		return ""
+	}
+	return *p.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (p *PullRequestReview) GetID() int64 {
+	if p == nil || p.ID == nil {
+		return 0
+	}
+	return *p.ID
+}
+
+// GetPullRequestURL returns the PullRequestURL field if it's non-nil, zero value otherwise.
+func (p *PullRequestReview) GetPullRequestURL() string {
+	if p == nil || p.PullRequestURL == nil {
+		return ""
+	}
+	return *p.PullRequestURL
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (p *PullRequestReview) GetState() string {
+	if p == nil || p.State == nil {
+		return ""
+	}
+	return *p.State
+}
+
+// GetSubmittedAt returns the SubmittedAt field if it's non-nil, zero value otherwise.
+func (p *PullRequestReview) GetSubmittedAt() time.Time {
+	if p == nil || p.SubmittedAt == nil {
+		return time.Time{}
+	}
+	return *p.SubmittedAt
+}
+
+// GetUser returns the User field.
+func (p *PullRequestReview) GetUser() *User {
+	if p == nil {
+		return nil
+	}
+	return p.User
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (p *PullRequestReviewCommentEvent) GetAction() string {
+	if p == nil || p.Action == nil {
+		return ""
+	}
+	return *p.Action
+}
+
+// GetChanges returns the Changes field.
+func (p *PullRequestReviewCommentEvent) GetChanges() *EditChange {
+	if p == nil {
+		return nil
+	}
+	return p.Changes
+}
+
+// GetComment returns the Comment field.
+func (p *PullRequestReviewCommentEvent) GetComment() *PullRequestComment {
+	if p == nil {
+		return nil
+	}
+	return p.Comment
+}
+
+// GetInstallation returns the Installation field.
+func (p *PullRequestReviewCommentEvent) GetInstallation() *Installation {
+	if p == nil {
+		return nil
+	}
+	return p.Installation
+}
+
+// GetPullRequest returns the PullRequest field.
+func (p *PullRequestReviewCommentEvent) GetPullRequest() *PullRequest {
+	if p == nil {
+		return nil
+	}
+	return p.PullRequest
+}
+
+// GetRepo returns the Repo field.
+func (p *PullRequestReviewCommentEvent) GetRepo() *Repository {
+	if p == nil {
+		return nil
+	}
+	return p.Repo
+}
+
+// GetSender returns the Sender field.
+func (p *PullRequestReviewCommentEvent) GetSender() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Sender
+}
+
+// GetMessage returns the Message field if it's non-nil, zero value otherwise.
+func (p *PullRequestReviewDismissalRequest) GetMessage() string {
+	if p == nil || p.Message == nil {
+		return ""
+	}
+	return *p.Message
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (p *PullRequestReviewEvent) GetAction() string {
+	if p == nil || p.Action == nil {
+		return ""
+	}
+	return *p.Action
+}
+
+// GetInstallation returns the Installation field.
+func (p *PullRequestReviewEvent) GetInstallation() *Installation {
+	if p == nil {
+		return nil
+	}
+	return p.Installation
+}
+
+// GetOrganization returns the Organization field.
+func (p *PullRequestReviewEvent) GetOrganization() *Organization {
+	if p == nil {
+		return nil
+	}
+	return p.Organization
+}
+
+// GetPullRequest returns the PullRequest field.
+func (p *PullRequestReviewEvent) GetPullRequest() *PullRequest {
+	if p == nil {
+		return nil
+	}
+	return p.PullRequest
+}
+
+// GetRepo returns the Repo field.
+func (p *PullRequestReviewEvent) GetRepo() *Repository {
+	if p == nil {
+		return nil
+	}
+	return p.Repo
+}
+
+// GetReview returns the Review field.
+func (p *PullRequestReviewEvent) GetReview() *PullRequestReview {
+	if p == nil {
+		return nil
+	}
+	return p.Review
+}
+
+// GetSender returns the Sender field.
+func (p *PullRequestReviewEvent) GetSender() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Sender
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (p *PullRequestReviewRequest) GetBody() string {
+	if p == nil || p.Body == nil {
+		return ""
+	}
+	return *p.Body
+}
+
+// GetCommitID returns the CommitID field if it's non-nil, zero value otherwise.
+func (p *PullRequestReviewRequest) GetCommitID() string {
+	if p == nil || p.CommitID == nil {
+		return ""
+	}
+	return *p.CommitID
+}
+
+// GetEvent returns the Event field if it's non-nil, zero value otherwise.
+func (p *PullRequestReviewRequest) GetEvent() string {
+	if p == nil || p.Event == nil {
+		return ""
+	}
+	return *p.Event
+}
+
+// GetDismissalRestrictionsRequest returns the DismissalRestrictionsRequest field.
+func (p *PullRequestReviewsEnforcementRequest) GetDismissalRestrictionsRequest() *DismissalRestrictionsRequest {
+	if p == nil {
+		return nil
+	}
+	return p.DismissalRestrictionsRequest
+}
+
+// GetDismissalRestrictionsRequest returns the DismissalRestrictionsRequest field.
+func (p *PullRequestReviewsEnforcementUpdate) GetDismissalRestrictionsRequest() *DismissalRestrictionsRequest {
+	if p == nil {
+		return nil
+	}
+	return p.DismissalRestrictionsRequest
+}
+
+// GetDismissStaleReviews returns the DismissStaleReviews field if it's non-nil, zero value otherwise.
+func (p *PullRequestReviewsEnforcementUpdate) GetDismissStaleReviews() bool {
+	if p == nil || p.DismissStaleReviews == nil {
+		return false
+	}
+	return *p.DismissStaleReviews
+}
+
+// GetMergablePulls returns the MergablePulls field if it's non-nil, zero value otherwise.
+func (p *PullStats) GetMergablePulls() int {
+	if p == nil || p.MergablePulls == nil {
+		return 0
+	}
+	return *p.MergablePulls
+}
+
+// GetMergedPulls returns the MergedPulls field if it's non-nil, zero value otherwise.
+func (p *PullStats) GetMergedPulls() int {
+	if p == nil || p.MergedPulls == nil {
+		return 0
+	}
+	return *p.MergedPulls
+}
+
+// GetTotalPulls returns the TotalPulls field if it's non-nil, zero value otherwise.
+func (p *PullStats) GetTotalPulls() int {
+	if p == nil || p.TotalPulls == nil {
+		return 0
+	}
+	return *p.TotalPulls
+}
+
+// GetUnmergablePulls returns the UnmergablePulls field if it's non-nil, zero value otherwise.
+func (p *PullStats) GetUnmergablePulls() int {
+	if p == nil || p.UnmergablePulls == nil {
+		return 0
+	}
+	return *p.UnmergablePulls
+}
+
+// GetCommits returns the Commits field if it's non-nil, zero value otherwise.
+func (p *PunchCard) GetCommits() int {
+	if p == nil || p.Commits == nil {
+		return 0
+	}
+	return *p.Commits
+}
+
+// GetDay returns the Day field if it's non-nil, zero value otherwise.
+func (p *PunchCard) GetDay() int {
+	if p == nil || p.Day == nil {
+		return 0
+	}
+	return *p.Day
+}
+
+// GetHour returns the Hour field if it's non-nil, zero value otherwise.
+func (p *PunchCard) GetHour() int {
+	if p == nil || p.Hour == nil {
+		return 0
+	}
+	return *p.Hour
+}
+
+// GetAfter returns the After field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetAfter() string {
+	if p == nil || p.After == nil {
+		return ""
+	}
+	return *p.After
+}
+
+// GetBaseRef returns the BaseRef field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetBaseRef() string {
+	if p == nil || p.BaseRef == nil {
+		return ""
+	}
+	return *p.BaseRef
+}
+
+// GetBefore returns the Before field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetBefore() string {
+	if p == nil || p.Before == nil {
+		return ""
+	}
+	return *p.Before
+}
+
+// GetCompare returns the Compare field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetCompare() string {
+	if p == nil || p.Compare == nil {
+		return ""
+	}
+	return *p.Compare
+}
+
+// GetCreated returns the Created field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetCreated() bool {
+	if p == nil || p.Created == nil {
+		return false
+	}
+	return *p.Created
+}
+
+// GetDeleted returns the Deleted field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetDeleted() bool {
+	if p == nil || p.Deleted == nil {
+		return false
+	}
+	return *p.Deleted
+}
+
+// GetDistinctSize returns the DistinctSize field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetDistinctSize() int {
+	if p == nil || p.DistinctSize == nil {
+		return 0
+	}
+	return *p.DistinctSize
+}
+
+// GetForced returns the Forced field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetForced() bool {
+	if p == nil || p.Forced == nil {
+		return false
+	}
+	return *p.Forced
+}
+
+// GetHead returns the Head field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetHead() string {
+	if p == nil || p.Head == nil {
+		return ""
+	}
+	return *p.Head
+}
+
+// GetHeadCommit returns the HeadCommit field.
+func (p *PushEvent) GetHeadCommit() *PushEventCommit {
+	if p == nil {
+		return nil
+	}
+	return p.HeadCommit
+}
+
+// GetInstallation returns the Installation field.
+func (p *PushEvent) GetInstallation() *Installation {
+	if p == nil {
+		return nil
+	}
+	return p.Installation
+}
+
+// GetPusher returns the Pusher field.
+func (p *PushEvent) GetPusher() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Pusher
+}
+
+// GetPushID returns the PushID field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetPushID() int64 {
+	if p == nil || p.PushID == nil {
+		return 0
+	}
+	return *p.PushID
+}
+
+// GetRef returns the Ref field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetRef() string {
+	if p == nil || p.Ref == nil {
+		return ""
+	}
+	return *p.Ref
+}
+
+// GetRepo returns the Repo field.
+func (p *PushEvent) GetRepo() *PushEventRepository {
+	if p == nil {
+		return nil
+	}
+	return p.Repo
+}
+
+// GetSender returns the Sender field.
+func (p *PushEvent) GetSender() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Sender
+}
+
+// GetSize returns the Size field if it's non-nil, zero value otherwise.
+func (p *PushEvent) GetSize() int {
+	if p == nil || p.Size == nil {
+		return 0
+	}
+	return *p.Size
+}
+
+// GetAuthor returns the Author field.
+func (p *PushEventCommit) GetAuthor() *CommitAuthor {
+	if p == nil {
+		return nil
+	}
+	return p.Author
+}
+
+// GetCommitter returns the Committer field.
+func (p *PushEventCommit) GetCommitter() *CommitAuthor {
+	if p == nil {
+		return nil
+	}
+	return p.Committer
+}
+
+// GetDistinct returns the Distinct field if it's non-nil, zero value otherwise.
+func (p *PushEventCommit) GetDistinct() bool {
+	if p == nil || p.Distinct == nil {
+		return false
+	}
+	return *p.Distinct
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (p *PushEventCommit) GetID() string {
+	if p == nil || p.ID == nil {
+		return ""
+	}
+	return *p.ID
+}
+
+// GetMessage returns the Message field if it's non-nil, zero value otherwise.
+func (p *PushEventCommit) GetMessage() string {
+	if p == nil || p.Message == nil {
+		return ""
+	}
+	return *p.Message
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (p *PushEventCommit) GetSHA() string {
+	if p == nil || p.SHA == nil {
+		return ""
+	}
+	return *p.SHA
+}
+
+// GetTimestamp returns the Timestamp field if it's non-nil, zero value otherwise.
+func (p *PushEventCommit) GetTimestamp() Timestamp {
+	if p == nil || p.Timestamp == nil {
+		return Timestamp{}
+	}
+	return *p.Timestamp
+}
+
+// GetTreeID returns the TreeID field if it's non-nil, zero value otherwise.
+func (p *PushEventCommit) GetTreeID() string {
+	if p == nil || p.TreeID == nil {
+		return ""
+	}
+	return *p.TreeID
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (p *PushEventCommit) GetURL() string {
+	if p == nil || p.URL == nil {
+		return ""
+	}
+	return *p.URL
+}
+
+// GetEmail returns the Email field if it's non-nil, zero value otherwise.
+func (p *PushEventRepoOwner) GetEmail() string {
+	if p == nil || p.Email == nil {
+		return ""
+	}
+	return *p.Email
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (p *PushEventRepoOwner) GetName() string {
+	if p == nil || p.Name == nil {
+		return ""
+	}
+	return *p.Name
+}
+
+// GetArchiveURL returns the ArchiveURL field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetArchiveURL() string {
+	if p == nil || p.ArchiveURL == nil {
+		return ""
+	}
+	return *p.ArchiveURL
+}
+
+// GetCloneURL returns the CloneURL field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetCloneURL() string {
+	if p == nil || p.CloneURL == nil {
+		return ""
+	}
+	return *p.CloneURL
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetCreatedAt() Timestamp {
+	if p == nil || p.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.CreatedAt
+}
+
+// GetDefaultBranch returns the DefaultBranch field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetDefaultBranch() string {
+	if p == nil || p.DefaultBranch == nil {
+		return ""
+	}
+	return *p.DefaultBranch
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetDescription() string {
+	if p == nil || p.Description == nil {
+		return ""
+	}
+	return *p.Description
+}
+
+// GetFork returns the Fork field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetFork() bool {
+	if p == nil || p.Fork == nil {
+		return false
+	}
+	return *p.Fork
+}
+
+// GetForksCount returns the ForksCount field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetForksCount() int {
+	if p == nil || p.ForksCount == nil {
+		return 0
+	}
+	return *p.ForksCount
+}
+
+// GetFullName returns the FullName field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetFullName() string {
+	if p == nil || p.FullName == nil {
+		return ""
+	}
+	return *p.FullName
+}
+
+// GetGitURL returns the GitURL field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetGitURL() string {
+	if p == nil || p.GitURL == nil {
+		return ""
+	}
+	return *p.GitURL
+}
+
+// GetHasDownloads returns the HasDownloads field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetHasDownloads() bool {
+	if p == nil || p.HasDownloads == nil {
+		return false
+	}
+	return *p.HasDownloads
+}
+
+// GetHasIssues returns the HasIssues field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetHasIssues() bool {
+	if p == nil || p.HasIssues == nil {
+		return false
+	}
+	return *p.HasIssues
+}
+
+// GetHasPages returns the HasPages field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetHasPages() bool {
+	if p == nil || p.HasPages == nil {
+		return false
+	}
+	return *p.HasPages
+}
+
+// GetHasWiki returns the HasWiki field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetHasWiki() bool {
+	if p == nil || p.HasWiki == nil {
+		return false
+	}
+	return *p.HasWiki
+}
+
+// GetHomepage returns the Homepage field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetHomepage() string {
+	if p == nil || p.Homepage == nil {
+		return ""
+	}
+	return *p.Homepage
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetHTMLURL() string {
+	if p == nil || p.HTMLURL == nil {
+		return ""
+	}
+	return *p.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetID() int64 {
+	if p == nil || p.ID == nil {
+		return 0
+	}
+	return *p.ID
+}
+
+// GetLanguage returns the Language field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetLanguage() string {
+	if p == nil || p.Language == nil {
+		return ""
+	}
+	return *p.Language
+}
+
+// GetMasterBranch returns the MasterBranch field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetMasterBranch() string {
+	if p == nil || p.MasterBranch == nil {
+		return ""
+	}
+	return *p.MasterBranch
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetName() string {
+	if p == nil || p.Name == nil {
+		return ""
+	}
+	return *p.Name
+}
+
+// GetOpenIssuesCount returns the OpenIssuesCount field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetOpenIssuesCount() int {
+	if p == nil || p.OpenIssuesCount == nil {
+		return 0
+	}
+	return *p.OpenIssuesCount
+}
+
+// GetOrganization returns the Organization field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetOrganization() string {
+	if p == nil || p.Organization == nil {
+		return ""
+	}
+	return *p.Organization
+}
+
+// GetOwner returns the Owner field.
+func (p *PushEventRepository) GetOwner() *PushEventRepoOwner {
+	if p == nil {
+		return nil
+	}
+	return p.Owner
+}
+
+// GetPrivate returns the Private field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetPrivate() bool {
+	if p == nil || p.Private == nil {
+		return false
+	}
+	return *p.Private
+}
+
+// GetPushedAt returns the PushedAt field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetPushedAt() Timestamp {
+	if p == nil || p.PushedAt == nil {
+		return Timestamp{}
+	}
+	return *p.PushedAt
+}
+
+// GetSize returns the Size field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetSize() int {
+	if p == nil || p.Size == nil {
+		return 0
+	}
+	return *p.Size
+}
+
+// GetSSHURL returns the SSHURL field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetSSHURL() string {
+	if p == nil || p.SSHURL == nil {
+		return ""
+	}
+	return *p.SSHURL
+}
+
+// GetStargazersCount returns the StargazersCount field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetStargazersCount() int {
+	if p == nil || p.StargazersCount == nil {
+		return 0
+	}
+	return *p.StargazersCount
+}
+
+// GetStatusesURL returns the StatusesURL field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetStatusesURL() string {
+	if p == nil || p.StatusesURL == nil {
+		return ""
+	}
+	return *p.StatusesURL
+}
+
+// GetSVNURL returns the SVNURL field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetSVNURL() string {
+	if p == nil || p.SVNURL == nil {
+		return ""
+	}
+	return *p.SVNURL
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetUpdatedAt() Timestamp {
+	if p == nil || p.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetURL() string {
+	if p == nil || p.URL == nil {
+		return ""
+	}
+	return *p.URL
+}
+
+// GetWatchersCount returns the WatchersCount field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetWatchersCount() int {
+	if p == nil || p.WatchersCount == nil {
+		return 0
+	}
+	return *p.WatchersCount
+}
+
+// GetCore returns the Core field.
+func (r *RateLimits) GetCore() *Rate {
+	if r == nil {
+		return nil
+	}
+	return r.Core
+}
+
+// GetSearch returns the Search field.
+func (r *RateLimits) GetSearch() *Rate {
+	if r == nil {
+		return nil
+	}
+	return r.Search
+}
+
+// GetContent returns the Content field if it's non-nil, zero value otherwise.
+func (r *Reaction) GetContent() string {
+	if r == nil || r.Content == nil {
+		return ""
+	}
+	return *r.Content
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (r *Reaction) GetID() int64 {
+	if r == nil || r.ID == nil {
+		return 0
+	}
+	return *r.ID
+}
+
+// GetUser returns the User field.
+func (r *Reaction) GetUser() *User {
+	if r == nil {
+		return nil
+	}
+	return r.User
+}
+
+// GetConfused returns the Confused field if it's non-nil, zero value otherwise.
+func (r *Reactions) GetConfused() int {
+	if r == nil || r.Confused == nil {
+		return 0
+	}
+	return *r.Confused
+}
+
+// GetHeart returns the Heart field if it's non-nil, zero value otherwise.
+func (r *Reactions) GetHeart() int {
+	if r == nil || r.Heart == nil {
+		return 0
+	}
+	return *r.Heart
+}
+
+// GetHooray returns the Hooray field if it's non-nil, zero value otherwise.
+func (r *Reactions) GetHooray() int {
+	if r == nil || r.Hooray == nil {
+		return 0
+	}
+	return *r.Hooray
+}
+
+// GetLaugh returns the Laugh field if it's non-nil, zero value otherwise.
+func (r *Reactions) GetLaugh() int {
+	if r == nil || r.Laugh == nil {
+		return 0
+	}
+	return *r.Laugh
+}
+
+// GetMinusOne returns the MinusOne field if it's non-nil, zero value otherwise.
+func (r *Reactions) GetMinusOne() int {
+	if r == nil || r.MinusOne == nil {
+		return 0
+	}
+	return *r.MinusOne
+}
+
+// GetPlusOne returns the PlusOne field if it's non-nil, zero value otherwise.
+func (r *Reactions) GetPlusOne() int {
+	if r == nil || r.PlusOne == nil {
+		return 0
+	}
+	return *r.PlusOne
+}
+
+// GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise.
+func (r *Reactions) GetTotalCount() int {
+	if r == nil || r.TotalCount == nil {
+		return 0
+	}
+	return *r.TotalCount
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (r *Reactions) GetURL() string {
+	if r == nil || r.URL == nil {
+		return ""
+	}
+	return *r.URL
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (r *Reference) GetNodeID() string {
+	if r == nil || r.NodeID == nil {
+		return ""
+	}
+	return *r.NodeID
+}
+
+// GetObject returns the Object field.
+func (r *Reference) GetObject() *GitObject {
+	if r == nil {
+		return nil
+	}
+	return r.Object
+}
+
+// GetRef returns the Ref field if it's non-nil, zero value otherwise.
+func (r *Reference) GetRef() string {
+	if r == nil || r.Ref == nil {
+		return ""
+	}
+	return *r.Ref
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (r *Reference) GetURL() string {
+	if r == nil || r.URL == nil {
+		return ""
+	}
+	return *r.URL
+}
+
+// GetBrowserDownloadURL returns the BrowserDownloadURL field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetBrowserDownloadURL() string {
+	if r == nil || r.BrowserDownloadURL == nil {
+		return ""
+	}
+	return *r.BrowserDownloadURL
+}
+
+// GetContentType returns the ContentType field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetContentType() string {
+	if r == nil || r.ContentType == nil {
+		return ""
+	}
+	return *r.ContentType
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetCreatedAt() Timestamp {
+	if r == nil || r.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *r.CreatedAt
+}
+
+// GetDownloadCount returns the DownloadCount field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetDownloadCount() int {
+	if r == nil || r.DownloadCount == nil {
+		return 0
+	}
+	return *r.DownloadCount
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetID() int64 {
+	if r == nil || r.ID == nil {
+		return 0
+	}
+	return *r.ID
+}
+
+// GetLabel returns the Label field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetLabel() string {
+	if r == nil || r.Label == nil {
+		return ""
+	}
+	return *r.Label
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetName() string {
+	if r == nil || r.Name == nil {
+		return ""
+	}
+	return *r.Name
+}
+
+// GetSize returns the Size field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetSize() int {
+	if r == nil || r.Size == nil {
+		return 0
+	}
+	return *r.Size
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetState() string {
+	if r == nil || r.State == nil {
+		return ""
+	}
+	return *r.State
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetUpdatedAt() Timestamp {
+	if r == nil || r.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *r.UpdatedAt
+}
+
+// GetUploader returns the Uploader field.
+func (r *ReleaseAsset) GetUploader() *User {
+	if r == nil {
+		return nil
+	}
+	return r.Uploader
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetURL() string {
+	if r == nil || r.URL == nil {
+		return ""
+	}
+	return *r.URL
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (r *ReleaseEvent) GetAction() string {
+	if r == nil || r.Action == nil {
+		return ""
+	}
+	return *r.Action
+}
+
+// GetInstallation returns the Installation field.
+func (r *ReleaseEvent) GetInstallation() *Installation {
+	if r == nil {
+		return nil
+	}
+	return r.Installation
+}
+
+// GetRelease returns the Release field.
+func (r *ReleaseEvent) GetRelease() *RepositoryRelease {
+	if r == nil {
+		return nil
+	}
+	return r.Release
+}
+
+// GetRepo returns the Repo field.
+func (r *ReleaseEvent) GetRepo() *Repository {
+	if r == nil {
+		return nil
+	}
+	return r.Repo
+}
+
+// GetSender returns the Sender field.
+func (r *ReleaseEvent) GetSender() *User {
+	if r == nil {
+		return nil
+	}
+	return r.Sender
+}
+
+// GetFrom returns the From field if it's non-nil, zero value otherwise.
+func (r *Rename) GetFrom() string {
+	if r == nil || r.From == nil {
+		return ""
+	}
+	return *r.From
+}
+
+// GetTo returns the To field if it's non-nil, zero value otherwise.
+func (r *Rename) GetTo() string {
+	if r == nil || r.To == nil {
+		return ""
+	}
+	return *r.To
+}
+
+// GetIncompleteResults returns the IncompleteResults field if it's non-nil, zero value otherwise.
+func (r *RepositoriesSearchResult) GetIncompleteResults() bool {
+	if r == nil || r.IncompleteResults == nil {
+		return false
+	}
+	return *r.IncompleteResults
+}
+
+// GetTotal returns the Total field if it's non-nil, zero value otherwise.
+func (r *RepositoriesSearchResult) GetTotal() int {
+	if r == nil || r.Total == nil {
+		return 0
+	}
+	return *r.Total
+}
+
+// GetAllowMergeCommit returns the AllowMergeCommit field if it's non-nil, zero value otherwise.
+func (r *Repository) GetAllowMergeCommit() bool {
+	if r == nil || r.AllowMergeCommit == nil {
+		return false
+	}
+	return *r.AllowMergeCommit
+}
+
+// GetAllowRebaseMerge returns the AllowRebaseMerge field if it's non-nil, zero value otherwise.
+func (r *Repository) GetAllowRebaseMerge() bool {
+	if r == nil || r.AllowRebaseMerge == nil {
+		return false
+	}
+	return *r.AllowRebaseMerge
+}
+
+// GetAllowSquashMerge returns the AllowSquashMerge field if it's non-nil, zero value otherwise.
+func (r *Repository) GetAllowSquashMerge() bool {
+	if r == nil || r.AllowSquashMerge == nil {
+		return false
+	}
+	return *r.AllowSquashMerge
+}
+
+// GetArchived returns the Archived field if it's non-nil, zero value otherwise.
+func (r *Repository) GetArchived() bool {
+	if r == nil || r.Archived == nil {
+		return false
+	}
+	return *r.Archived
+}
+
+// GetArchiveURL returns the ArchiveURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetArchiveURL() string {
+	if r == nil || r.ArchiveURL == nil {
+		return ""
+	}
+	return *r.ArchiveURL
+}
+
+// GetAssigneesURL returns the AssigneesURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetAssigneesURL() string {
+	if r == nil || r.AssigneesURL == nil {
+		return ""
+	}
+	return *r.AssigneesURL
+}
+
+// GetAutoInit returns the AutoInit field if it's non-nil, zero value otherwise.
+func (r *Repository) GetAutoInit() bool {
+	if r == nil || r.AutoInit == nil {
+		return false
+	}
+	return *r.AutoInit
+}
+
+// GetBlobsURL returns the BlobsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetBlobsURL() string {
+	if r == nil || r.BlobsURL == nil {
+		return ""
+	}
+	return *r.BlobsURL
+}
+
+// GetBranchesURL returns the BranchesURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetBranchesURL() string {
+	if r == nil || r.BranchesURL == nil {
+		return ""
+	}
+	return *r.BranchesURL
+}
+
+// GetCloneURL returns the CloneURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetCloneURL() string {
+	if r == nil || r.CloneURL == nil {
+		return ""
+	}
+	return *r.CloneURL
+}
+
+// GetCodeOfConduct returns the CodeOfConduct field.
+func (r *Repository) GetCodeOfConduct() *CodeOfConduct {
+	if r == nil {
+		return nil
+	}
+	return r.CodeOfConduct
+}
+
+// GetCollaboratorsURL returns the CollaboratorsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetCollaboratorsURL() string {
+	if r == nil || r.CollaboratorsURL == nil {
+		return ""
+	}
+	return *r.CollaboratorsURL
+}
+
+// GetCommentsURL returns the CommentsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetCommentsURL() string {
+	if r == nil || r.CommentsURL == nil {
+		return ""
+	}
+	return *r.CommentsURL
+}
+
+// GetCommitsURL returns the CommitsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetCommitsURL() string {
+	if r == nil || r.CommitsURL == nil {
+		return ""
+	}
+	return *r.CommitsURL
+}
+
+// GetCompareURL returns the CompareURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetCompareURL() string {
+	if r == nil || r.CompareURL == nil {
+		return ""
+	}
+	return *r.CompareURL
+}
+
+// GetContentsURL returns the ContentsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetContentsURL() string {
+	if r == nil || r.ContentsURL == nil {
+		return ""
+	}
+	return *r.ContentsURL
+}
+
+// GetContributorsURL returns the ContributorsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetContributorsURL() string {
+	if r == nil || r.ContributorsURL == nil {
+		return ""
+	}
+	return *r.ContributorsURL
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (r *Repository) GetCreatedAt() Timestamp {
+	if r == nil || r.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *r.CreatedAt
+}
+
+// GetDefaultBranch returns the DefaultBranch field if it's non-nil, zero value otherwise.
+func (r *Repository) GetDefaultBranch() string {
+	if r == nil || r.DefaultBranch == nil {
+		return ""
+	}
+	return *r.DefaultBranch
+}
+
+// GetDeploymentsURL returns the DeploymentsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetDeploymentsURL() string {
+	if r == nil || r.DeploymentsURL == nil {
+		return ""
+	}
+	return *r.DeploymentsURL
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (r *Repository) GetDescription() string {
+	if r == nil || r.Description == nil {
+		return ""
+	}
+	return *r.Description
+}
+
+// GetDownloadsURL returns the DownloadsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetDownloadsURL() string {
+	if r == nil || r.DownloadsURL == nil {
+		return ""
+	}
+	return *r.DownloadsURL
+}
+
+// GetEventsURL returns the EventsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetEventsURL() string {
+	if r == nil || r.EventsURL == nil {
+		return ""
+	}
+	return *r.EventsURL
+}
+
+// GetFork returns the Fork field if it's non-nil, zero value otherwise.
+func (r *Repository) GetFork() bool {
+	if r == nil || r.Fork == nil {
+		return false
+	}
+	return *r.Fork
+}
+
+// GetForksCount returns the ForksCount field if it's non-nil, zero value otherwise.
+func (r *Repository) GetForksCount() int {
+	if r == nil || r.ForksCount == nil {
+		return 0
+	}
+	return *r.ForksCount
+}
+
+// GetForksURL returns the ForksURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetForksURL() string {
+	if r == nil || r.ForksURL == nil {
+		return ""
+	}
+	return *r.ForksURL
+}
+
+// GetFullName returns the FullName field if it's non-nil, zero value otherwise.
+func (r *Repository) GetFullName() string {
+	if r == nil || r.FullName == nil {
+		return ""
+	}
+	return *r.FullName
+}
+
+// GetGitCommitsURL returns the GitCommitsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetGitCommitsURL() string {
+	if r == nil || r.GitCommitsURL == nil {
+		return ""
+	}
+	return *r.GitCommitsURL
+}
+
+// GetGitignoreTemplate returns the GitignoreTemplate field if it's non-nil, zero value otherwise.
+func (r *Repository) GetGitignoreTemplate() string {
+	if r == nil || r.GitignoreTemplate == nil {
+		return ""
+	}
+	return *r.GitignoreTemplate
+}
+
+// GetGitRefsURL returns the GitRefsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetGitRefsURL() string {
+	if r == nil || r.GitRefsURL == nil {
+		return ""
+	}
+	return *r.GitRefsURL
+}
+
+// GetGitTagsURL returns the GitTagsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetGitTagsURL() string {
+	if r == nil || r.GitTagsURL == nil {
+		return ""
+	}
+	return *r.GitTagsURL
+}
+
+// GetGitURL returns the GitURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetGitURL() string {
+	if r == nil || r.GitURL == nil {
+		return ""
+	}
+	return *r.GitURL
+}
+
+// GetHasDownloads returns the HasDownloads field if it's non-nil, zero value otherwise.
+func (r *Repository) GetHasDownloads() bool {
+	if r == nil || r.HasDownloads == nil {
+		return false
+	}
+	return *r.HasDownloads
+}
+
+// GetHasIssues returns the HasIssues field if it's non-nil, zero value otherwise.
+func (r *Repository) GetHasIssues() bool {
+	if r == nil || r.HasIssues == nil {
+		return false
+	}
+	return *r.HasIssues
+}
+
+// GetHasPages returns the HasPages field if it's non-nil, zero value otherwise.
+func (r *Repository) GetHasPages() bool {
+	if r == nil || r.HasPages == nil {
+		return false
+	}
+	return *r.HasPages
+}
+
+// GetHasProjects returns the HasProjects field if it's non-nil, zero value otherwise.
+func (r *Repository) GetHasProjects() bool {
+	if r == nil || r.HasProjects == nil {
+		return false
+	}
+	return *r.HasProjects
+}
+
+// GetHasWiki returns the HasWiki field if it's non-nil, zero value otherwise.
+func (r *Repository) GetHasWiki() bool {
+	if r == nil || r.HasWiki == nil {
+		return false
+	}
+	return *r.HasWiki
+}
+
+// GetHomepage returns the Homepage field if it's non-nil, zero value otherwise.
+func (r *Repository) GetHomepage() string {
+	if r == nil || r.Homepage == nil {
+		return ""
+	}
+	return *r.Homepage
+}
+
+// GetHooksURL returns the HooksURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetHooksURL() string {
+	if r == nil || r.HooksURL == nil {
+		return ""
+	}
+	return *r.HooksURL
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetHTMLURL() string {
+	if r == nil || r.HTMLURL == nil {
+		return ""
+	}
+	return *r.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (r *Repository) GetID() int64 {
+	if r == nil || r.ID == nil {
+		return 0
+	}
+	return *r.ID
+}
+
+// GetIssueCommentURL returns the IssueCommentURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetIssueCommentURL() string {
+	if r == nil || r.IssueCommentURL == nil {
+		return ""
+	}
+	return *r.IssueCommentURL
+}
+
+// GetIssueEventsURL returns the IssueEventsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetIssueEventsURL() string {
+	if r == nil || r.IssueEventsURL == nil {
+		return ""
+	}
+	return *r.IssueEventsURL
+}
+
+// GetIssuesURL returns the IssuesURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetIssuesURL() string {
+	if r == nil || r.IssuesURL == nil {
+		return ""
+	}
+	return *r.IssuesURL
+}
+
+// GetKeysURL returns the KeysURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetKeysURL() string {
+	if r == nil || r.KeysURL == nil {
+		return ""
+	}
+	return *r.KeysURL
+}
+
+// GetLabelsURL returns the LabelsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetLabelsURL() string {
+	if r == nil || r.LabelsURL == nil {
+		return ""
+	}
+	return *r.LabelsURL
+}
+
+// GetLanguage returns the Language field if it's non-nil, zero value otherwise.
+func (r *Repository) GetLanguage() string {
+	if r == nil || r.Language == nil {
+		return ""
+	}
+	return *r.Language
+}
+
+// GetLanguagesURL returns the LanguagesURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetLanguagesURL() string {
+	if r == nil || r.LanguagesURL == nil {
+		return ""
+	}
+	return *r.LanguagesURL
+}
+
+// GetLicense returns the License field.
+func (r *Repository) GetLicense() *License {
+	if r == nil {
+		return nil
+	}
+	return r.License
+}
+
+// GetLicenseTemplate returns the LicenseTemplate field if it's non-nil, zero value otherwise.
+func (r *Repository) GetLicenseTemplate() string {
+	if r == nil || r.LicenseTemplate == nil {
+		return ""
+	}
+	return *r.LicenseTemplate
+}
+
+// GetMasterBranch returns the MasterBranch field if it's non-nil, zero value otherwise.
+func (r *Repository) GetMasterBranch() string {
+	if r == nil || r.MasterBranch == nil {
+		return ""
+	}
+	return *r.MasterBranch
+}
+
+// GetMergesURL returns the MergesURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetMergesURL() string {
+	if r == nil || r.MergesURL == nil {
+		return ""
+	}
+	return *r.MergesURL
+}
+
+// GetMilestonesURL returns the MilestonesURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetMilestonesURL() string {
+	if r == nil || r.MilestonesURL == nil {
+		return ""
+	}
+	return *r.MilestonesURL
+}
+
+// GetMirrorURL returns the MirrorURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetMirrorURL() string {
+	if r == nil || r.MirrorURL == nil {
+		return ""
+	}
+	return *r.MirrorURL
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (r *Repository) GetName() string {
+	if r == nil || r.Name == nil {
+		return ""
+	}
+	return *r.Name
+}
+
+// GetNetworkCount returns the NetworkCount field if it's non-nil, zero value otherwise.
+func (r *Repository) GetNetworkCount() int {
+	if r == nil || r.NetworkCount == nil {
+		return 0
+	}
+	return *r.NetworkCount
+}
+
+// GetNotificationsURL returns the NotificationsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetNotificationsURL() string {
+	if r == nil || r.NotificationsURL == nil {
+		return ""
+	}
+	return *r.NotificationsURL
+}
+
+// GetOpenIssuesCount returns the OpenIssuesCount field if it's non-nil, zero value otherwise.
+func (r *Repository) GetOpenIssuesCount() int {
+	if r == nil || r.OpenIssuesCount == nil {
+		return 0
+	}
+	return *r.OpenIssuesCount
+}
+
+// GetOrganization returns the Organization field.
+func (r *Repository) GetOrganization() *Organization {
+	if r == nil {
+		return nil
+	}
+	return r.Organization
+}
+
+// GetOwner returns the Owner field.
+func (r *Repository) GetOwner() *User {
+	if r == nil {
+		return nil
+	}
+	return r.Owner
+}
+
+// GetParent returns the Parent field.
+func (r *Repository) GetParent() *Repository {
+	if r == nil {
+		return nil
+	}
+	return r.Parent
+}
+
+// GetPermissions returns the Permissions field if it's non-nil, zero value otherwise.
+func (r *Repository) GetPermissions() map[string]bool {
+	if r == nil || r.Permissions == nil {
+		return map[string]bool{}
+	}
+	return *r.Permissions
+}
+
+// GetPrivate returns the Private field if it's non-nil, zero value otherwise.
+func (r *Repository) GetPrivate() bool {
+	if r == nil || r.Private == nil {
+		return false
+	}
+	return *r.Private
+}
+
+// GetPullsURL returns the PullsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetPullsURL() string {
+	if r == nil || r.PullsURL == nil {
+		return ""
+	}
+	return *r.PullsURL
+}
+
+// GetPushedAt returns the PushedAt field if it's non-nil, zero value otherwise.
+func (r *Repository) GetPushedAt() Timestamp {
+	if r == nil || r.PushedAt == nil {
+		return Timestamp{}
+	}
+	return *r.PushedAt
+}
+
+// GetReleasesURL returns the ReleasesURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetReleasesURL() string {
+	if r == nil || r.ReleasesURL == nil {
+		return ""
+	}
+	return *r.ReleasesURL
+}
+
+// GetSize returns the Size field if it's non-nil, zero value otherwise.
+func (r *Repository) GetSize() int {
+	if r == nil || r.Size == nil {
+		return 0
+	}
+	return *r.Size
+}
+
+// GetSource returns the Source field.
+func (r *Repository) GetSource() *Repository {
+	if r == nil {
+		return nil
+	}
+	return r.Source
+}
+
+// GetSSHURL returns the SSHURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetSSHURL() string {
+	if r == nil || r.SSHURL == nil {
+		return ""
+	}
+	return *r.SSHURL
+}
+
+// GetStargazersCount returns the StargazersCount field if it's non-nil, zero value otherwise.
+func (r *Repository) GetStargazersCount() int {
+	if r == nil || r.StargazersCount == nil {
+		return 0
+	}
+	return *r.StargazersCount
+}
+
+// GetStargazersURL returns the StargazersURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetStargazersURL() string {
+	if r == nil || r.StargazersURL == nil {
+		return ""
+	}
+	return *r.StargazersURL
+}
+
+// GetStatusesURL returns the StatusesURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetStatusesURL() string {
+	if r == nil || r.StatusesURL == nil {
+		return ""
+	}
+	return *r.StatusesURL
+}
+
+// GetSubscribersCount returns the SubscribersCount field if it's non-nil, zero value otherwise.
+func (r *Repository) GetSubscribersCount() int {
+	if r == nil || r.SubscribersCount == nil {
+		return 0
+	}
+	return *r.SubscribersCount
+}
+
+// GetSubscribersURL returns the SubscribersURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetSubscribersURL() string {
+	if r == nil || r.SubscribersURL == nil {
+		return ""
+	}
+	return *r.SubscribersURL
+}
+
+// GetSubscriptionURL returns the SubscriptionURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetSubscriptionURL() string {
+	if r == nil || r.SubscriptionURL == nil {
+		return ""
+	}
+	return *r.SubscriptionURL
+}
+
+// GetSVNURL returns the SVNURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetSVNURL() string {
+	if r == nil || r.SVNURL == nil {
+		return ""
+	}
+	return *r.SVNURL
+}
+
+// GetTagsURL returns the TagsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetTagsURL() string {
+	if r == nil || r.TagsURL == nil {
+		return ""
+	}
+	return *r.TagsURL
+}
+
+// GetTeamID returns the TeamID field if it's non-nil, zero value otherwise.
+func (r *Repository) GetTeamID() int64 {
+	if r == nil || r.TeamID == nil {
+		return 0
+	}
+	return *r.TeamID
+}
+
+// GetTeamsURL returns the TeamsURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetTeamsURL() string {
+	if r == nil || r.TeamsURL == nil {
+		return ""
+	}
+	return *r.TeamsURL
+}
+
+// GetTreesURL returns the TreesURL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetTreesURL() string {
+	if r == nil || r.TreesURL == nil {
+		return ""
+	}
+	return *r.TreesURL
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (r *Repository) GetUpdatedAt() Timestamp {
+	if r == nil || r.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *r.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (r *Repository) GetURL() string {
+	if r == nil || r.URL == nil {
+		return ""
+	}
+	return *r.URL
+}
+
+// GetWatchersCount returns the WatchersCount field if it's non-nil, zero value otherwise.
+func (r *Repository) GetWatchersCount() int {
+	if r == nil || r.WatchersCount == nil {
+		return 0
+	}
+	return *r.WatchersCount
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (r *RepositoryComment) GetBody() string {
+	if r == nil || r.Body == nil {
+		return ""
+	}
+	return *r.Body
+}
+
+// GetCommitID returns the CommitID field if it's non-nil, zero value otherwise.
+func (r *RepositoryComment) GetCommitID() string {
+	if r == nil || r.CommitID == nil {
+		return ""
+	}
+	return *r.CommitID
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (r *RepositoryComment) GetCreatedAt() time.Time {
+	if r == nil || r.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *r.CreatedAt
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryComment) GetHTMLURL() string {
+	if r == nil || r.HTMLURL == nil {
+		return ""
+	}
+	return *r.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (r *RepositoryComment) GetID() int64 {
+	if r == nil || r.ID == nil {
+		return 0
+	}
+	return *r.ID
+}
+
+// GetPath returns the Path field if it's non-nil, zero value otherwise.
+func (r *RepositoryComment) GetPath() string {
+	if r == nil || r.Path == nil {
+		return ""
+	}
+	return *r.Path
+}
+
+// GetPosition returns the Position field if it's non-nil, zero value otherwise.
+func (r *RepositoryComment) GetPosition() int {
+	if r == nil || r.Position == nil {
+		return 0
+	}
+	return *r.Position
+}
+
+// GetReactions returns the Reactions field.
+func (r *RepositoryComment) GetReactions() *Reactions {
+	if r == nil {
+		return nil
+	}
+	return r.Reactions
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (r *RepositoryComment) GetUpdatedAt() time.Time {
+	if r == nil || r.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *r.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (r *RepositoryComment) GetURL() string {
+	if r == nil || r.URL == nil {
+		return ""
+	}
+	return *r.URL
+}
+
+// GetUser returns the User field.
+func (r *RepositoryComment) GetUser() *User {
+	if r == nil {
+		return nil
+	}
+	return r.User
+}
+
+// GetAuthor returns the Author field.
+func (r *RepositoryCommit) GetAuthor() *User {
+	if r == nil {
+		return nil
+	}
+	return r.Author
+}
+
+// GetCommentsURL returns the CommentsURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryCommit) GetCommentsURL() string {
+	if r == nil || r.CommentsURL == nil {
+		return ""
+	}
+	return *r.CommentsURL
+}
+
+// GetCommit returns the Commit field.
+func (r *RepositoryCommit) GetCommit() *Commit {
+	if r == nil {
+		return nil
+	}
+	return r.Commit
+}
+
+// GetCommitter returns the Committer field.
+func (r *RepositoryCommit) GetCommitter() *User {
+	if r == nil {
+		return nil
+	}
+	return r.Committer
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryCommit) GetHTMLURL() string {
+	if r == nil || r.HTMLURL == nil {
+		return ""
+	}
+	return *r.HTMLURL
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (r *RepositoryCommit) GetSHA() string {
+	if r == nil || r.SHA == nil {
+		return ""
+	}
+	return *r.SHA
+}
+
+// GetStats returns the Stats field.
+func (r *RepositoryCommit) GetStats() *CommitStats {
+	if r == nil {
+		return nil
+	}
+	return r.Stats
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (r *RepositoryCommit) GetURL() string {
+	if r == nil || r.URL == nil {
+		return ""
+	}
+	return *r.URL
+}
+
+// GetDownloadURL returns the DownloadURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryContent) GetDownloadURL() string {
+	if r == nil || r.DownloadURL == nil {
+		return ""
+	}
+	return *r.DownloadURL
+}
+
+// GetEncoding returns the Encoding field if it's non-nil, zero value otherwise.
+func (r *RepositoryContent) GetEncoding() string {
+	if r == nil || r.Encoding == nil {
+		return ""
+	}
+	return *r.Encoding
+}
+
+// GetGitURL returns the GitURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryContent) GetGitURL() string {
+	if r == nil || r.GitURL == nil {
+		return ""
+	}
+	return *r.GitURL
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryContent) GetHTMLURL() string {
+	if r == nil || r.HTMLURL == nil {
+		return ""
+	}
+	return *r.HTMLURL
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (r *RepositoryContent) GetName() string {
+	if r == nil || r.Name == nil {
+		return ""
+	}
+	return *r.Name
+}
+
+// GetPath returns the Path field if it's non-nil, zero value otherwise.
+func (r *RepositoryContent) GetPath() string {
+	if r == nil || r.Path == nil {
+		return ""
+	}
+	return *r.Path
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (r *RepositoryContent) GetSHA() string {
+	if r == nil || r.SHA == nil {
+		return ""
+	}
+	return *r.SHA
+}
+
+// GetSize returns the Size field if it's non-nil, zero value otherwise.
+func (r *RepositoryContent) GetSize() int {
+	if r == nil || r.Size == nil {
+		return 0
+	}
+	return *r.Size
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (r *RepositoryContent) GetType() string {
+	if r == nil || r.Type == nil {
+		return ""
+	}
+	return *r.Type
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (r *RepositoryContent) GetURL() string {
+	if r == nil || r.URL == nil {
+		return ""
+	}
+	return *r.URL
+}
+
+// GetAuthor returns the Author field.
+func (r *RepositoryContentFileOptions) GetAuthor() *CommitAuthor {
+	if r == nil {
+		return nil
+	}
+	return r.Author
+}
+
+// GetBranch returns the Branch field if it's non-nil, zero value otherwise.
+func (r *RepositoryContentFileOptions) GetBranch() string {
+	if r == nil || r.Branch == nil {
+		return ""
+	}
+	return *r.Branch
+}
+
+// GetCommitter returns the Committer field.
+func (r *RepositoryContentFileOptions) GetCommitter() *CommitAuthor {
+	if r == nil {
+		return nil
+	}
+	return r.Committer
+}
+
+// GetMessage returns the Message field if it's non-nil, zero value otherwise.
+func (r *RepositoryContentFileOptions) GetMessage() string {
+	if r == nil || r.Message == nil {
+		return ""
+	}
+	return *r.Message
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (r *RepositoryContentFileOptions) GetSHA() string {
+	if r == nil || r.SHA == nil {
+		return ""
+	}
+	return *r.SHA
+}
+
+// GetContent returns the Content field.
+func (r *RepositoryContentResponse) GetContent() *RepositoryContent {
+	if r == nil {
+		return nil
+	}
+	return r.Content
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (r *RepositoryEvent) GetAction() string {
+	if r == nil || r.Action == nil {
+		return ""
+	}
+	return *r.Action
+}
+
+// GetInstallation returns the Installation field.
+func (r *RepositoryEvent) GetInstallation() *Installation {
+	if r == nil {
+		return nil
+	}
+	return r.Installation
+}
+
+// GetOrg returns the Org field.
+func (r *RepositoryEvent) GetOrg() *Organization {
+	if r == nil {
+		return nil
+	}
+	return r.Org
+}
+
+// GetRepo returns the Repo field.
+func (r *RepositoryEvent) GetRepo() *Repository {
+	if r == nil {
+		return nil
+	}
+	return r.Repo
+}
+
+// GetSender returns the Sender field.
+func (r *RepositoryEvent) GetSender() *User {
+	if r == nil {
+		return nil
+	}
+	return r.Sender
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (r *RepositoryInvitation) GetCreatedAt() Timestamp {
+	if r == nil || r.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *r.CreatedAt
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryInvitation) GetHTMLURL() string {
+	if r == nil || r.HTMLURL == nil {
+		return ""
+	}
+	return *r.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (r *RepositoryInvitation) GetID() int64 {
+	if r == nil || r.ID == nil {
+		return 0
+	}
+	return *r.ID
+}
+
+// GetInvitee returns the Invitee field.
+func (r *RepositoryInvitation) GetInvitee() *User {
+	if r == nil {
+		return nil
+	}
+	return r.Invitee
+}
+
+// GetInviter returns the Inviter field.
+func (r *RepositoryInvitation) GetInviter() *User {
+	if r == nil {
+		return nil
+	}
+	return r.Inviter
+}
+
+// GetPermissions returns the Permissions field if it's non-nil, zero value otherwise.
+func (r *RepositoryInvitation) GetPermissions() string {
+	if r == nil || r.Permissions == nil {
+		return ""
+	}
+	return *r.Permissions
+}
+
+// GetRepo returns the Repo field.
+func (r *RepositoryInvitation) GetRepo() *Repository {
+	if r == nil {
+		return nil
+	}
+	return r.Repo
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (r *RepositoryInvitation) GetURL() string {
+	if r == nil || r.URL == nil {
+		return ""
+	}
+	return *r.URL
+}
+
+// GetContent returns the Content field if it's non-nil, zero value otherwise.
+func (r *RepositoryLicense) GetContent() string {
+	if r == nil || r.Content == nil {
+		return ""
+	}
+	return *r.Content
+}
+
+// GetDownloadURL returns the DownloadURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryLicense) GetDownloadURL() string {
+	if r == nil || r.DownloadURL == nil {
+		return ""
+	}
+	return *r.DownloadURL
+}
+
+// GetEncoding returns the Encoding field if it's non-nil, zero value otherwise.
+func (r *RepositoryLicense) GetEncoding() string {
+	if r == nil || r.Encoding == nil {
+		return ""
+	}
+	return *r.Encoding
+}
+
+// GetGitURL returns the GitURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryLicense) GetGitURL() string {
+	if r == nil || r.GitURL == nil {
+		return ""
+	}
+	return *r.GitURL
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryLicense) GetHTMLURL() string {
+	if r == nil || r.HTMLURL == nil {
+		return ""
+	}
+	return *r.HTMLURL
+}
+
+// GetLicense returns the License field.
+func (r *RepositoryLicense) GetLicense() *License {
+	if r == nil {
+		return nil
+	}
+	return r.License
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (r *RepositoryLicense) GetName() string {
+	if r == nil || r.Name == nil {
+		return ""
+	}
+	return *r.Name
+}
+
+// GetPath returns the Path field if it's non-nil, zero value otherwise.
+func (r *RepositoryLicense) GetPath() string {
+	if r == nil || r.Path == nil {
+		return ""
+	}
+	return *r.Path
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (r *RepositoryLicense) GetSHA() string {
+	if r == nil || r.SHA == nil {
+		return ""
+	}
+	return *r.SHA
+}
+
+// GetSize returns the Size field if it's non-nil, zero value otherwise.
+func (r *RepositoryLicense) GetSize() int {
+	if r == nil || r.Size == nil {
+		return 0
+	}
+	return *r.Size
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (r *RepositoryLicense) GetType() string {
+	if r == nil || r.Type == nil {
+		return ""
+	}
+	return *r.Type
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (r *RepositoryLicense) GetURL() string {
+	if r == nil || r.URL == nil {
+		return ""
+	}
+	return *r.URL
+}
+
+// GetBase returns the Base field if it's non-nil, zero value otherwise.
+func (r *RepositoryMergeRequest) GetBase() string {
+	if r == nil || r.Base == nil {
+		return ""
+	}
+	return *r.Base
+}
+
+// GetCommitMessage returns the CommitMessage field if it's non-nil, zero value otherwise.
+func (r *RepositoryMergeRequest) GetCommitMessage() string {
+	if r == nil || r.CommitMessage == nil {
+		return ""
+	}
+	return *r.CommitMessage
+}
+
+// GetHead returns the Head field if it's non-nil, zero value otherwise.
+func (r *RepositoryMergeRequest) GetHead() string {
+	if r == nil || r.Head == nil {
+		return ""
+	}
+	return *r.Head
+}
+
+// GetPermission returns the Permission field if it's non-nil, zero value otherwise.
+func (r *RepositoryPermissionLevel) GetPermission() string {
+	if r == nil || r.Permission == nil {
+		return ""
+	}
+	return *r.Permission
+}
+
+// GetUser returns the User field.
+func (r *RepositoryPermissionLevel) GetUser() *User {
+	if r == nil {
+		return nil
+	}
+	return r.User
+}
+
+// GetAssetsURL returns the AssetsURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetAssetsURL() string {
+	if r == nil || r.AssetsURL == nil {
+		return ""
+	}
+	return *r.AssetsURL
+}
+
+// GetAuthor returns the Author field.
+func (r *RepositoryRelease) GetAuthor() *User {
+	if r == nil {
+		return nil
+	}
+	return r.Author
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetBody() string {
+	if r == nil || r.Body == nil {
+		return ""
+	}
+	return *r.Body
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetCreatedAt() Timestamp {
+	if r == nil || r.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *r.CreatedAt
+}
+
+// GetDraft returns the Draft field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetDraft() bool {
+	if r == nil || r.Draft == nil {
+		return false
+	}
+	return *r.Draft
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetHTMLURL() string {
+	if r == nil || r.HTMLURL == nil {
+		return ""
+	}
+	return *r.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetID() int64 {
+	if r == nil || r.ID == nil {
+		return 0
+	}
+	return *r.ID
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetName() string {
+	if r == nil || r.Name == nil {
+		return ""
+	}
+	return *r.Name
+}
+
+// GetPrerelease returns the Prerelease field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetPrerelease() bool {
+	if r == nil || r.Prerelease == nil {
+		return false
+	}
+	return *r.Prerelease
+}
+
+// GetPublishedAt returns the PublishedAt field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetPublishedAt() Timestamp {
+	if r == nil || r.PublishedAt == nil {
+		return Timestamp{}
+	}
+	return *r.PublishedAt
+}
+
+// GetTagName returns the TagName field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetTagName() string {
+	if r == nil || r.TagName == nil {
+		return ""
+	}
+	return *r.TagName
+}
+
+// GetTarballURL returns the TarballURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetTarballURL() string {
+	if r == nil || r.TarballURL == nil {
+		return ""
+	}
+	return *r.TarballURL
+}
+
+// GetTargetCommitish returns the TargetCommitish field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetTargetCommitish() string {
+	if r == nil || r.TargetCommitish == nil {
+		return ""
+	}
+	return *r.TargetCommitish
+}
+
+// GetUploadURL returns the UploadURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetUploadURL() string {
+	if r == nil || r.UploadURL == nil {
+		return ""
+	}
+	return *r.UploadURL
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetURL() string {
+	if r == nil || r.URL == nil {
+		return ""
+	}
+	return *r.URL
+}
+
+// GetZipballURL returns the ZipballURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetZipballURL() string {
+	if r == nil || r.ZipballURL == nil {
+		return ""
+	}
+	return *r.ZipballURL
+}
+
+// GetCommit returns the Commit field.
+func (r *RepositoryTag) GetCommit() *Commit {
+	if r == nil {
+		return nil
+	}
+	return r.Commit
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (r *RepositoryTag) GetName() string {
+	if r == nil || r.Name == nil {
+		return ""
+	}
+	return *r.Name
+}
+
+// GetTarballURL returns the TarballURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryTag) GetTarballURL() string {
+	if r == nil || r.TarballURL == nil {
+		return ""
+	}
+	return *r.TarballURL
+}
+
+// GetZipballURL returns the ZipballURL field if it's non-nil, zero value otherwise.
+func (r *RepositoryTag) GetZipballURL() string {
+	if r == nil || r.ZipballURL == nil {
+		return ""
+	}
+	return *r.ZipballURL
+}
+
+// GetForkRepos returns the ForkRepos field if it's non-nil, zero value otherwise.
+func (r *RepoStats) GetForkRepos() int {
+	if r == nil || r.ForkRepos == nil {
+		return 0
+	}
+	return *r.ForkRepos
+}
+
+// GetOrgRepos returns the OrgRepos field if it's non-nil, zero value otherwise.
+func (r *RepoStats) GetOrgRepos() int {
+	if r == nil || r.OrgRepos == nil {
+		return 0
+	}
+	return *r.OrgRepos
+}
+
+// GetRootRepos returns the RootRepos field if it's non-nil, zero value otherwise.
+func (r *RepoStats) GetRootRepos() int {
+	if r == nil || r.RootRepos == nil {
+		return 0
+	}
+	return *r.RootRepos
+}
+
+// GetTotalPushes returns the TotalPushes field if it's non-nil, zero value otherwise.
+func (r *RepoStats) GetTotalPushes() int {
+	if r == nil || r.TotalPushes == nil {
+		return 0
+	}
+	return *r.TotalPushes
+}
+
+// GetTotalRepos returns the TotalRepos field if it's non-nil, zero value otherwise.
+func (r *RepoStats) GetTotalRepos() int {
+	if r == nil || r.TotalRepos == nil {
+		return 0
+	}
+	return *r.TotalRepos
+}
+
+// GetTotalWikis returns the TotalWikis field if it's non-nil, zero value otherwise.
+func (r *RepoStats) GetTotalWikis() int {
+	if r == nil || r.TotalWikis == nil {
+		return 0
+	}
+	return *r.TotalWikis
+}
+
+// GetContext returns the Context field if it's non-nil, zero value otherwise.
+func (r *RepoStatus) GetContext() string {
+	if r == nil || r.Context == nil {
+		return ""
+	}
+	return *r.Context
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (r *RepoStatus) GetCreatedAt() time.Time {
+	if r == nil || r.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *r.CreatedAt
+}
+
+// GetCreator returns the Creator field.
+func (r *RepoStatus) GetCreator() *User {
+	if r == nil {
+		return nil
+	}
+	return r.Creator
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (r *RepoStatus) GetDescription() string {
+	if r == nil || r.Description == nil {
+		return ""
+	}
+	return *r.Description
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (r *RepoStatus) GetID() int64 {
+	if r == nil || r.ID == nil {
+		return 0
+	}
+	return *r.ID
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (r *RepoStatus) GetState() string {
+	if r == nil || r.State == nil {
+		return ""
+	}
+	return *r.State
+}
+
+// GetTargetURL returns the TargetURL field if it's non-nil, zero value otherwise.
+func (r *RepoStatus) GetTargetURL() string {
+	if r == nil || r.TargetURL == nil {
+		return ""
+	}
+	return *r.TargetURL
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (r *RepoStatus) GetUpdatedAt() time.Time {
+	if r == nil || r.UpdatedAt == nil {
+		return time.Time{}
+	}
+	return *r.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (r *RepoStatus) GetURL() string {
+	if r == nil || r.URL == nil {
+		return ""
+	}
+	return *r.URL
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (s *ServiceHook) GetName() string {
+	if s == nil || s.Name == nil {
+		return ""
+	}
+	return *s.Name
+}
+
+// GetPayload returns the Payload field if it's non-nil, zero value otherwise.
+func (s *SignatureVerification) GetPayload() string {
+	if s == nil || s.Payload == nil {
+		return ""
+	}
+	return *s.Payload
+}
+
+// GetReason returns the Reason field if it's non-nil, zero value otherwise.
+func (s *SignatureVerification) GetReason() string {
+	if s == nil || s.Reason == nil {
+		return ""
+	}
+	return *s.Reason
+}
+
+// GetSignature returns the Signature field if it's non-nil, zero value otherwise.
+func (s *SignatureVerification) GetSignature() string {
+	if s == nil || s.Signature == nil {
+		return ""
+	}
+	return *s.Signature
+}
+
+// GetVerified returns the Verified field if it's non-nil, zero value otherwise.
+func (s *SignatureVerification) GetVerified() bool {
+	if s == nil || s.Verified == nil {
+		return false
+	}
+	return *s.Verified
+}
+
+// GetActor returns the Actor field.
+func (s *Source) GetActor() *User {
+	if s == nil {
+		return nil
+	}
+	return s.Actor
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (s *Source) GetID() int64 {
+	if s == nil || s.ID == nil {
+		return 0
+	}
+	return *s.ID
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (s *Source) GetURL() string {
+	if s == nil || s.URL == nil {
+		return ""
+	}
+	return *s.URL
+}
+
+// GetEmail returns the Email field if it's non-nil, zero value otherwise.
+func (s *SourceImportAuthor) GetEmail() string {
+	if s == nil || s.Email == nil {
+		return ""
+	}
+	return *s.Email
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (s *SourceImportAuthor) GetID() int64 {
+	if s == nil || s.ID == nil {
+		return 0
+	}
+	return *s.ID
+}
+
+// GetImportURL returns the ImportURL field if it's non-nil, zero value otherwise.
+func (s *SourceImportAuthor) GetImportURL() string {
+	if s == nil || s.ImportURL == nil {
+		return ""
+	}
+	return *s.ImportURL
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (s *SourceImportAuthor) GetName() string {
+	if s == nil || s.Name == nil {
+		return ""
+	}
+	return *s.Name
+}
+
+// GetRemoteID returns the RemoteID field if it's non-nil, zero value otherwise.
+func (s *SourceImportAuthor) GetRemoteID() string {
+	if s == nil || s.RemoteID == nil {
+		return ""
+	}
+	return *s.RemoteID
+}
+
+// GetRemoteName returns the RemoteName field if it's non-nil, zero value otherwise.
+func (s *SourceImportAuthor) GetRemoteName() string {
+	if s == nil || s.RemoteName == nil {
+		return ""
+	}
+	return *s.RemoteName
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (s *SourceImportAuthor) GetURL() string {
+	if s == nil || s.URL == nil {
+		return ""
+	}
+	return *s.URL
+}
+
+// GetStarredAt returns the StarredAt field if it's non-nil, zero value otherwise.
+func (s *Stargazer) GetStarredAt() Timestamp {
+	if s == nil || s.StarredAt == nil {
+		return Timestamp{}
+	}
+	return *s.StarredAt
+}
+
+// GetUser returns the User field.
+func (s *Stargazer) GetUser() *User {
+	if s == nil {
+		return nil
+	}
+	return s.User
+}
+
+// GetRepository returns the Repository field.
+func (s *StarredRepository) GetRepository() *Repository {
+	if s == nil {
+		return nil
+	}
+	return s.Repository
+}
+
+// GetStarredAt returns the StarredAt field if it's non-nil, zero value otherwise.
+func (s *StarredRepository) GetStarredAt() Timestamp {
+	if s == nil || s.StarredAt == nil {
+		return Timestamp{}
+	}
+	return *s.StarredAt
+}
+
+// GetCommit returns the Commit field.
+func (s *StatusEvent) GetCommit() *RepositoryCommit {
+	if s == nil {
+		return nil
+	}
+	return s.Commit
+}
+
+// GetContext returns the Context field if it's non-nil, zero value otherwise.
+func (s *StatusEvent) GetContext() string {
+	if s == nil || s.Context == nil {
+		return ""
+	}
+	return *s.Context
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (s *StatusEvent) GetCreatedAt() Timestamp {
+	if s == nil || s.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *s.CreatedAt
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (s *StatusEvent) GetDescription() string {
+	if s == nil || s.Description == nil {
+		return ""
+	}
+	return *s.Description
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (s *StatusEvent) GetID() int64 {
+	if s == nil || s.ID == nil {
+		return 0
+	}
+	return *s.ID
+}
+
+// GetInstallation returns the Installation field.
+func (s *StatusEvent) GetInstallation() *Installation {
+	if s == nil {
+		return nil
+	}
+	return s.Installation
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (s *StatusEvent) GetName() string {
+	if s == nil || s.Name == nil {
+		return ""
+	}
+	return *s.Name
+}
+
+// GetRepo returns the Repo field.
+func (s *StatusEvent) GetRepo() *Repository {
+	if s == nil {
+		return nil
+	}
+	return s.Repo
+}
+
+// GetSender returns the Sender field.
+func (s *StatusEvent) GetSender() *User {
+	if s == nil {
+		return nil
+	}
+	return s.Sender
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (s *StatusEvent) GetSHA() string {
+	if s == nil || s.SHA == nil {
+		return ""
+	}
+	return *s.SHA
+}
+
+// GetState returns the State field if it's non-nil, zero value otherwise.
+func (s *StatusEvent) GetState() string {
+	if s == nil || s.State == nil {
+		return ""
+	}
+	return *s.State
+}
+
+// GetTargetURL returns the TargetURL field if it's non-nil, zero value otherwise.
+func (s *StatusEvent) GetTargetURL() string {
+	if s == nil || s.TargetURL == nil {
+		return ""
+	}
+	return *s.TargetURL
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (s *StatusEvent) GetUpdatedAt() Timestamp {
+	if s == nil || s.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *s.UpdatedAt
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (s *Subscription) GetCreatedAt() Timestamp {
+	if s == nil || s.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *s.CreatedAt
+}
+
+// GetIgnored returns the Ignored field if it's non-nil, zero value otherwise.
+func (s *Subscription) GetIgnored() bool {
+	if s == nil || s.Ignored == nil {
+		return false
+	}
+	return *s.Ignored
+}
+
+// GetReason returns the Reason field if it's non-nil, zero value otherwise.
+func (s *Subscription) GetReason() string {
+	if s == nil || s.Reason == nil {
+		return ""
+	}
+	return *s.Reason
+}
+
+// GetRepositoryURL returns the RepositoryURL field if it's non-nil, zero value otherwise.
+func (s *Subscription) GetRepositoryURL() string {
+	if s == nil || s.RepositoryURL == nil {
+		return ""
+	}
+	return *s.RepositoryURL
+}
+
+// GetSubscribed returns the Subscribed field if it's non-nil, zero value otherwise.
+func (s *Subscription) GetSubscribed() bool {
+	if s == nil || s.Subscribed == nil {
+		return false
+	}
+	return *s.Subscribed
+}
+
+// GetThreadURL returns the ThreadURL field if it's non-nil, zero value otherwise.
+func (s *Subscription) GetThreadURL() string {
+	if s == nil || s.ThreadURL == nil {
+		return ""
+	}
+	return *s.ThreadURL
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (s *Subscription) GetURL() string {
+	if s == nil || s.URL == nil {
+		return ""
+	}
+	return *s.URL
+}
+
+// GetMessage returns the Message field if it's non-nil, zero value otherwise.
+func (t *Tag) GetMessage() string {
+	if t == nil || t.Message == nil {
+		return ""
+	}
+	return *t.Message
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (t *Tag) GetNodeID() string {
+	if t == nil || t.NodeID == nil {
+		return ""
+	}
+	return *t.NodeID
+}
+
+// GetObject returns the Object field.
+func (t *Tag) GetObject() *GitObject {
+	if t == nil {
+		return nil
+	}
+	return t.Object
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (t *Tag) GetSHA() string {
+	if t == nil || t.SHA == nil {
+		return ""
+	}
+	return *t.SHA
+}
+
+// GetTag returns the Tag field if it's non-nil, zero value otherwise.
+func (t *Tag) GetTag() string {
+	if t == nil || t.Tag == nil {
+		return ""
+	}
+	return *t.Tag
+}
+
+// GetTagger returns the Tagger field.
+func (t *Tag) GetTagger() *CommitAuthor {
+	if t == nil {
+		return nil
+	}
+	return t.Tagger
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (t *Tag) GetURL() string {
+	if t == nil || t.URL == nil {
+		return ""
+	}
+	return *t.URL
+}
+
+// GetVerification returns the Verification field.
+func (t *Tag) GetVerification() *SignatureVerification {
+	if t == nil {
+		return nil
+	}
+	return t.Verification
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (t *Team) GetDescription() string {
+	if t == nil || t.Description == nil {
+		return ""
+	}
+	return *t.Description
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (t *Team) GetID() int64 {
+	if t == nil || t.ID == nil {
+		return 0
+	}
+	return *t.ID
+}
+
+// GetLDAPDN returns the LDAPDN field if it's non-nil, zero value otherwise.
+func (t *Team) GetLDAPDN() string {
+	if t == nil || t.LDAPDN == nil {
+		return ""
+	}
+	return *t.LDAPDN
+}
+
+// GetMembersCount returns the MembersCount field if it's non-nil, zero value otherwise.
+func (t *Team) GetMembersCount() int {
+	if t == nil || t.MembersCount == nil {
+		return 0
+	}
+	return *t.MembersCount
+}
+
+// GetMembersURL returns the MembersURL field if it's non-nil, zero value otherwise.
+func (t *Team) GetMembersURL() string {
+	if t == nil || t.MembersURL == nil {
+		return ""
+	}
+	return *t.MembersURL
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (t *Team) GetName() string {
+	if t == nil || t.Name == nil {
+		return ""
+	}
+	return *t.Name
+}
+
+// GetOrganization returns the Organization field.
+func (t *Team) GetOrganization() *Organization {
+	if t == nil {
+		return nil
+	}
+	return t.Organization
+}
+
+// GetParent returns the Parent field.
+func (t *Team) GetParent() *Team {
+	if t == nil {
+		return nil
+	}
+	return t.Parent
+}
+
+// GetPermission returns the Permission field if it's non-nil, zero value otherwise.
+func (t *Team) GetPermission() string {
+	if t == nil || t.Permission == nil {
+		return ""
+	}
+	return *t.Permission
+}
+
+// GetPrivacy returns the Privacy field if it's non-nil, zero value otherwise.
+func (t *Team) GetPrivacy() string {
+	if t == nil || t.Privacy == nil {
+		return ""
+	}
+	return *t.Privacy
+}
+
+// GetReposCount returns the ReposCount field if it's non-nil, zero value otherwise.
+func (t *Team) GetReposCount() int {
+	if t == nil || t.ReposCount == nil {
+		return 0
+	}
+	return *t.ReposCount
+}
+
+// GetRepositoriesURL returns the RepositoriesURL field if it's non-nil, zero value otherwise.
+func (t *Team) GetRepositoriesURL() string {
+	if t == nil || t.RepositoriesURL == nil {
+		return ""
+	}
+	return *t.RepositoriesURL
+}
+
+// GetSlug returns the Slug field if it's non-nil, zero value otherwise.
+func (t *Team) GetSlug() string {
+	if t == nil || t.Slug == nil {
+		return ""
+	}
+	return *t.Slug
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (t *Team) GetURL() string {
+	if t == nil || t.URL == nil {
+		return ""
+	}
+	return *t.URL
+}
+
+// GetInstallation returns the Installation field.
+func (t *TeamAddEvent) GetInstallation() *Installation {
+	if t == nil {
+		return nil
+	}
+	return t.Installation
+}
+
+// GetOrg returns the Org field.
+func (t *TeamAddEvent) GetOrg() *Organization {
+	if t == nil {
+		return nil
+	}
+	return t.Org
+}
+
+// GetRepo returns the Repo field.
+func (t *TeamAddEvent) GetRepo() *Repository {
+	if t == nil {
+		return nil
+	}
+	return t.Repo
+}
+
+// GetSender returns the Sender field.
+func (t *TeamAddEvent) GetSender() *User {
+	if t == nil {
+		return nil
+	}
+	return t.Sender
+}
+
+// GetTeam returns the Team field.
+func (t *TeamAddEvent) GetTeam() *Team {
+	if t == nil {
+		return nil
+	}
+	return t.Team
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (t *TeamEvent) GetAction() string {
+	if t == nil || t.Action == nil {
+		return ""
+	}
+	return *t.Action
+}
+
+// GetChanges returns the Changes field.
+func (t *TeamEvent) GetChanges() *TeamChange {
+	if t == nil {
+		return nil
+	}
+	return t.Changes
+}
+
+// GetInstallation returns the Installation field.
+func (t *TeamEvent) GetInstallation() *Installation {
+	if t == nil {
+		return nil
+	}
+	return t.Installation
+}
+
+// GetOrg returns the Org field.
+func (t *TeamEvent) GetOrg() *Organization {
+	if t == nil {
+		return nil
+	}
+	return t.Org
+}
+
+// GetRepo returns the Repo field.
+func (t *TeamEvent) GetRepo() *Repository {
+	if t == nil {
+		return nil
+	}
+	return t.Repo
+}
+
+// GetSender returns the Sender field.
+func (t *TeamEvent) GetSender() *User {
+	if t == nil {
+		return nil
+	}
+	return t.Sender
+}
+
+// GetTeam returns the Team field.
+func (t *TeamEvent) GetTeam() *Team {
+	if t == nil {
+		return nil
+	}
+	return t.Team
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (t *TeamLDAPMapping) GetDescription() string {
+	if t == nil || t.Description == nil {
+		return ""
+	}
+	return *t.Description
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (t *TeamLDAPMapping) GetID() int64 {
+	if t == nil || t.ID == nil {
+		return 0
+	}
+	return *t.ID
+}
+
+// GetLDAPDN returns the LDAPDN field if it's non-nil, zero value otherwise.
+func (t *TeamLDAPMapping) GetLDAPDN() string {
+	if t == nil || t.LDAPDN == nil {
+		return ""
+	}
+	return *t.LDAPDN
+}
+
+// GetMembersURL returns the MembersURL field if it's non-nil, zero value otherwise.
+func (t *TeamLDAPMapping) GetMembersURL() string {
+	if t == nil || t.MembersURL == nil {
+		return ""
+	}
+	return *t.MembersURL
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (t *TeamLDAPMapping) GetName() string {
+	if t == nil || t.Name == nil {
+		return ""
+	}
+	return *t.Name
+}
+
+// GetPermission returns the Permission field if it's non-nil, zero value otherwise.
+func (t *TeamLDAPMapping) GetPermission() string {
+	if t == nil || t.Permission == nil {
+		return ""
+	}
+	return *t.Permission
+}
+
+// GetPrivacy returns the Privacy field if it's non-nil, zero value otherwise.
+func (t *TeamLDAPMapping) GetPrivacy() string {
+	if t == nil || t.Privacy == nil {
+		return ""
+	}
+	return *t.Privacy
+}
+
+// GetRepositoriesURL returns the RepositoriesURL field if it's non-nil, zero value otherwise.
+func (t *TeamLDAPMapping) GetRepositoriesURL() string {
+	if t == nil || t.RepositoriesURL == nil {
+		return ""
+	}
+	return *t.RepositoriesURL
+}
+
+// GetSlug returns the Slug field if it's non-nil, zero value otherwise.
+func (t *TeamLDAPMapping) GetSlug() string {
+	if t == nil || t.Slug == nil {
+		return ""
+	}
+	return *t.Slug
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (t *TeamLDAPMapping) GetURL() string {
+	if t == nil || t.URL == nil {
+		return ""
+	}
+	return *t.URL
+}
+
+// GetFragment returns the Fragment field if it's non-nil, zero value otherwise.
+func (t *TextMatch) GetFragment() string {
+	if t == nil || t.Fragment == nil {
+		return ""
+	}
+	return *t.Fragment
+}
+
+// GetObjectType returns the ObjectType field if it's non-nil, zero value otherwise.
+func (t *TextMatch) GetObjectType() string {
+	if t == nil || t.ObjectType == nil {
+		return ""
+	}
+	return *t.ObjectType
+}
+
+// GetObjectURL returns the ObjectURL field if it's non-nil, zero value otherwise.
+func (t *TextMatch) GetObjectURL() string {
+	if t == nil || t.ObjectURL == nil {
+		return ""
+	}
+	return *t.ObjectURL
+}
+
+// GetProperty returns the Property field if it's non-nil, zero value otherwise.
+func (t *TextMatch) GetProperty() string {
+	if t == nil || t.Property == nil {
+		return ""
+	}
+	return *t.Property
+}
+
+// GetActor returns the Actor field.
+func (t *Timeline) GetActor() *User {
+	if t == nil {
+		return nil
+	}
+	return t.Actor
+}
+
+// GetAssignee returns the Assignee field.
+func (t *Timeline) GetAssignee() *User {
+	if t == nil {
+		return nil
+	}
+	return t.Assignee
+}
+
+// GetCommitID returns the CommitID field if it's non-nil, zero value otherwise.
+func (t *Timeline) GetCommitID() string {
+	if t == nil || t.CommitID == nil {
+		return ""
+	}
+	return *t.CommitID
+}
+
+// GetCommitURL returns the CommitURL field if it's non-nil, zero value otherwise.
+func (t *Timeline) GetCommitURL() string {
+	if t == nil || t.CommitURL == nil {
+		return ""
+	}
+	return *t.CommitURL
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (t *Timeline) GetCreatedAt() time.Time {
+	if t == nil || t.CreatedAt == nil {
+		return time.Time{}
+	}
+	return *t.CreatedAt
+}
+
+// GetEvent returns the Event field if it's non-nil, zero value otherwise.
+func (t *Timeline) GetEvent() string {
+	if t == nil || t.Event == nil {
+		return ""
+	}
+	return *t.Event
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (t *Timeline) GetID() int64 {
+	if t == nil || t.ID == nil {
+		return 0
+	}
+	return *t.ID
+}
+
+// GetLabel returns the Label field.
+func (t *Timeline) GetLabel() *Label {
+	if t == nil {
+		return nil
+	}
+	return t.Label
+}
+
+// GetMilestone returns the Milestone field.
+func (t *Timeline) GetMilestone() *Milestone {
+	if t == nil {
+		return nil
+	}
+	return t.Milestone
+}
+
+// GetRename returns the Rename field.
+func (t *Timeline) GetRename() *Rename {
+	if t == nil {
+		return nil
+	}
+	return t.Rename
+}
+
+// GetSource returns the Source field.
+func (t *Timeline) GetSource() *Source {
+	if t == nil {
+		return nil
+	}
+	return t.Source
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (t *Timeline) GetURL() string {
+	if t == nil || t.URL == nil {
+		return ""
+	}
+	return *t.URL
+}
+
+// GetCount returns the Count field if it's non-nil, zero value otherwise.
+func (t *TrafficClones) GetCount() int {
+	if t == nil || t.Count == nil {
+		return 0
+	}
+	return *t.Count
+}
+
+// GetUniques returns the Uniques field if it's non-nil, zero value otherwise.
+func (t *TrafficClones) GetUniques() int {
+	if t == nil || t.Uniques == nil {
+		return 0
+	}
+	return *t.Uniques
+}
+
+// GetCount returns the Count field if it's non-nil, zero value otherwise.
+func (t *TrafficData) GetCount() int {
+	if t == nil || t.Count == nil {
+		return 0
+	}
+	return *t.Count
+}
+
+// GetTimestamp returns the Timestamp field if it's non-nil, zero value otherwise.
+func (t *TrafficData) GetTimestamp() Timestamp {
+	if t == nil || t.Timestamp == nil {
+		return Timestamp{}
+	}
+	return *t.Timestamp
+}
+
+// GetUniques returns the Uniques field if it's non-nil, zero value otherwise.
+func (t *TrafficData) GetUniques() int {
+	if t == nil || t.Uniques == nil {
+		return 0
+	}
+	return *t.Uniques
+}
+
+// GetCount returns the Count field if it's non-nil, zero value otherwise.
+func (t *TrafficPath) GetCount() int {
+	if t == nil || t.Count == nil {
+		return 0
+	}
+	return *t.Count
+}
+
+// GetPath returns the Path field if it's non-nil, zero value otherwise.
+func (t *TrafficPath) GetPath() string {
+	if t == nil || t.Path == nil {
+		return ""
+	}
+	return *t.Path
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (t *TrafficPath) GetTitle() string {
+	if t == nil || t.Title == nil {
+		return ""
+	}
+	return *t.Title
+}
+
+// GetUniques returns the Uniques field if it's non-nil, zero value otherwise.
+func (t *TrafficPath) GetUniques() int {
+	if t == nil || t.Uniques == nil {
+		return 0
+	}
+	return *t.Uniques
+}
+
+// GetCount returns the Count field if it's non-nil, zero value otherwise.
+func (t *TrafficReferrer) GetCount() int {
+	if t == nil || t.Count == nil {
+		return 0
+	}
+	return *t.Count
+}
+
+// GetReferrer returns the Referrer field if it's non-nil, zero value otherwise.
+func (t *TrafficReferrer) GetReferrer() string {
+	if t == nil || t.Referrer == nil {
+		return ""
+	}
+	return *t.Referrer
+}
+
+// GetUniques returns the Uniques field if it's non-nil, zero value otherwise.
+func (t *TrafficReferrer) GetUniques() int {
+	if t == nil || t.Uniques == nil {
+		return 0
+	}
+	return *t.Uniques
+}
+
+// GetCount returns the Count field if it's non-nil, zero value otherwise.
+func (t *TrafficViews) GetCount() int {
+	if t == nil || t.Count == nil {
+		return 0
+	}
+	return *t.Count
+}
+
+// GetUniques returns the Uniques field if it's non-nil, zero value otherwise.
+func (t *TrafficViews) GetUniques() int {
+	if t == nil || t.Uniques == nil {
+		return 0
+	}
+	return *t.Uniques
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (t *Tree) GetSHA() string {
+	if t == nil || t.SHA == nil {
+		return ""
+	}
+	return *t.SHA
+}
+
+// GetContent returns the Content field if it's non-nil, zero value otherwise.
+func (t *TreeEntry) GetContent() string {
+	if t == nil || t.Content == nil {
+		return ""
+	}
+	return *t.Content
+}
+
+// GetMode returns the Mode field if it's non-nil, zero value otherwise.
+func (t *TreeEntry) GetMode() string {
+	if t == nil || t.Mode == nil {
+		return ""
+	}
+	return *t.Mode
+}
+
+// GetPath returns the Path field if it's non-nil, zero value otherwise.
+func (t *TreeEntry) GetPath() string {
+	if t == nil || t.Path == nil {
+		return ""
+	}
+	return *t.Path
+}
+
+// GetSHA returns the SHA field if it's non-nil, zero value otherwise.
+func (t *TreeEntry) GetSHA() string {
+	if t == nil || t.SHA == nil {
+		return ""
+	}
+	return *t.SHA
+}
+
+// GetSize returns the Size field if it's non-nil, zero value otherwise.
+func (t *TreeEntry) GetSize() int {
+	if t == nil || t.Size == nil {
+		return 0
+	}
+	return *t.Size
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (t *TreeEntry) GetType() string {
+	if t == nil || t.Type == nil {
+		return ""
+	}
+	return *t.Type
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (t *TreeEntry) GetURL() string {
+	if t == nil || t.URL == nil {
+		return ""
+	}
+	return *t.URL
+}
+
+// GetAvatarURL returns the AvatarURL field if it's non-nil, zero value otherwise.
+func (u *User) GetAvatarURL() string {
+	if u == nil || u.AvatarURL == nil {
+		return ""
+	}
+	return *u.AvatarURL
+}
+
+// GetBio returns the Bio field if it's non-nil, zero value otherwise.
+func (u *User) GetBio() string {
+	if u == nil || u.Bio == nil {
+		return ""
+	}
+	return *u.Bio
+}
+
+// GetBlog returns the Blog field if it's non-nil, zero value otherwise.
+func (u *User) GetBlog() string {
+	if u == nil || u.Blog == nil {
+		return ""
+	}
+	return *u.Blog
+}
+
+// GetCollaborators returns the Collaborators field if it's non-nil, zero value otherwise.
+func (u *User) GetCollaborators() int {
+	if u == nil || u.Collaborators == nil {
+		return 0
+	}
+	return *u.Collaborators
+}
+
+// GetCompany returns the Company field if it's non-nil, zero value otherwise.
+func (u *User) GetCompany() string {
+	if u == nil || u.Company == nil {
+		return ""
+	}
+	return *u.Company
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (u *User) GetCreatedAt() Timestamp {
+	if u == nil || u.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *u.CreatedAt
+}
+
+// GetDiskUsage returns the DiskUsage field if it's non-nil, zero value otherwise.
+func (u *User) GetDiskUsage() int {
+	if u == nil || u.DiskUsage == nil {
+		return 0
+	}
+	return *u.DiskUsage
+}
+
+// GetEmail returns the Email field if it's non-nil, zero value otherwise.
+func (u *User) GetEmail() string {
+	if u == nil || u.Email == nil {
+		return ""
+	}
+	return *u.Email
+}
+
+// GetEventsURL returns the EventsURL field if it's non-nil, zero value otherwise.
+func (u *User) GetEventsURL() string {
+	if u == nil || u.EventsURL == nil {
+		return ""
+	}
+	return *u.EventsURL
+}
+
+// GetFollowers returns the Followers field if it's non-nil, zero value otherwise.
+func (u *User) GetFollowers() int {
+	if u == nil || u.Followers == nil {
+		return 0
+	}
+	return *u.Followers
+}
+
+// GetFollowersURL returns the FollowersURL field if it's non-nil, zero value otherwise.
+func (u *User) GetFollowersURL() string {
+	if u == nil || u.FollowersURL == nil {
+		return ""
+	}
+	return *u.FollowersURL
+}
+
+// GetFollowing returns the Following field if it's non-nil, zero value otherwise.
+func (u *User) GetFollowing() int {
+	if u == nil || u.Following == nil {
+		return 0
+	}
+	return *u.Following
+}
+
+// GetFollowingURL returns the FollowingURL field if it's non-nil, zero value otherwise.
+func (u *User) GetFollowingURL() string {
+	if u == nil || u.FollowingURL == nil {
+		return ""
+	}
+	return *u.FollowingURL
+}
+
+// GetGistsURL returns the GistsURL field if it's non-nil, zero value otherwise.
+func (u *User) GetGistsURL() string {
+	if u == nil || u.GistsURL == nil {
+		return ""
+	}
+	return *u.GistsURL
+}
+
+// GetGravatarID returns the GravatarID field if it's non-nil, zero value otherwise.
+func (u *User) GetGravatarID() string {
+	if u == nil || u.GravatarID == nil {
+		return ""
+	}
+	return *u.GravatarID
+}
+
+// GetHireable returns the Hireable field if it's non-nil, zero value otherwise.
+func (u *User) GetHireable() bool {
+	if u == nil || u.Hireable == nil {
+		return false
+	}
+	return *u.Hireable
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (u *User) GetHTMLURL() string {
+	if u == nil || u.HTMLURL == nil {
+		return ""
+	}
+	return *u.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (u *User) GetID() int64 {
+	if u == nil || u.ID == nil {
+		return 0
+	}
+	return *u.ID
+}
+
+// GetLocation returns the Location field if it's non-nil, zero value otherwise.
+func (u *User) GetLocation() string {
+	if u == nil || u.Location == nil {
+		return ""
+	}
+	return *u.Location
+}
+
+// GetLogin returns the Login field if it's non-nil, zero value otherwise.
+func (u *User) GetLogin() string {
+	if u == nil || u.Login == nil {
+		return ""
+	}
+	return *u.Login
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (u *User) GetName() string {
+	if u == nil || u.Name == nil {
+		return ""
+	}
+	return *u.Name
+}
+
+// GetOrganizationsURL returns the OrganizationsURL field if it's non-nil, zero value otherwise.
+func (u *User) GetOrganizationsURL() string {
+	if u == nil || u.OrganizationsURL == nil {
+		return ""
+	}
+	return *u.OrganizationsURL
+}
+
+// GetOwnedPrivateRepos returns the OwnedPrivateRepos field if it's non-nil, zero value otherwise.
+func (u *User) GetOwnedPrivateRepos() int {
+	if u == nil || u.OwnedPrivateRepos == nil {
+		return 0
+	}
+	return *u.OwnedPrivateRepos
+}
+
+// GetPermissions returns the Permissions field if it's non-nil, zero value otherwise.
+func (u *User) GetPermissions() map[string]bool {
+	if u == nil || u.Permissions == nil {
+		return map[string]bool{}
+	}
+	return *u.Permissions
+}
+
+// GetPlan returns the Plan field.
+func (u *User) GetPlan() *Plan {
+	if u == nil {
+		return nil
+	}
+	return u.Plan
+}
+
+// GetPrivateGists returns the PrivateGists field if it's non-nil, zero value otherwise.
+func (u *User) GetPrivateGists() int {
+	if u == nil || u.PrivateGists == nil {
+		return 0
+	}
+	return *u.PrivateGists
+}
+
+// GetPublicGists returns the PublicGists field if it's non-nil, zero value otherwise.
+func (u *User) GetPublicGists() int {
+	if u == nil || u.PublicGists == nil {
+		return 0
+	}
+	return *u.PublicGists
+}
+
+// GetPublicRepos returns the PublicRepos field if it's non-nil, zero value otherwise.
+func (u *User) GetPublicRepos() int {
+	if u == nil || u.PublicRepos == nil {
+		return 0
+	}
+	return *u.PublicRepos
+}
+
+// GetReceivedEventsURL returns the ReceivedEventsURL field if it's non-nil, zero value otherwise.
+func (u *User) GetReceivedEventsURL() string {
+	if u == nil || u.ReceivedEventsURL == nil {
+		return ""
+	}
+	return *u.ReceivedEventsURL
+}
+
+// GetReposURL returns the ReposURL field if it's non-nil, zero value otherwise.
+func (u *User) GetReposURL() string {
+	if u == nil || u.ReposURL == nil {
+		return ""
+	}
+	return *u.ReposURL
+}
+
+// GetSiteAdmin returns the SiteAdmin field if it's non-nil, zero value otherwise.
+func (u *User) GetSiteAdmin() bool {
+	if u == nil || u.SiteAdmin == nil {
+		return false
+	}
+	return *u.SiteAdmin
+}
+
+// GetStarredURL returns the StarredURL field if it's non-nil, zero value otherwise.
+func (u *User) GetStarredURL() string {
+	if u == nil || u.StarredURL == nil {
+		return ""
+	}
+	return *u.StarredURL
+}
+
+// GetSubscriptionsURL returns the SubscriptionsURL field if it's non-nil, zero value otherwise.
+func (u *User) GetSubscriptionsURL() string {
+	if u == nil || u.SubscriptionsURL == nil {
+		return ""
+	}
+	return *u.SubscriptionsURL
+}
+
+// GetSuspendedAt returns the SuspendedAt field if it's non-nil, zero value otherwise.
+func (u *User) GetSuspendedAt() Timestamp {
+	if u == nil || u.SuspendedAt == nil {
+		return Timestamp{}
+	}
+	return *u.SuspendedAt
+}
+
+// GetTotalPrivateRepos returns the TotalPrivateRepos field if it's non-nil, zero value otherwise.
+func (u *User) GetTotalPrivateRepos() int {
+	if u == nil || u.TotalPrivateRepos == nil {
+		return 0
+	}
+	return *u.TotalPrivateRepos
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (u *User) GetType() string {
+	if u == nil || u.Type == nil {
+		return ""
+	}
+	return *u.Type
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (u *User) GetUpdatedAt() Timestamp {
+	if u == nil || u.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *u.UpdatedAt
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (u *User) GetURL() string {
+	if u == nil || u.URL == nil {
+		return ""
+	}
+	return *u.URL
+}
+
+// GetEmail returns the Email field if it's non-nil, zero value otherwise.
+func (u *UserEmail) GetEmail() string {
+	if u == nil || u.Email == nil {
+		return ""
+	}
+	return *u.Email
+}
+
+// GetPrimary returns the Primary field if it's non-nil, zero value otherwise.
+func (u *UserEmail) GetPrimary() bool {
+	if u == nil || u.Primary == nil {
+		return false
+	}
+	return *u.Primary
+}
+
+// GetVerified returns the Verified field if it's non-nil, zero value otherwise.
+func (u *UserEmail) GetVerified() bool {
+	if u == nil || u.Verified == nil {
+		return false
+	}
+	return *u.Verified
+}
+
+// GetAvatarURL returns the AvatarURL field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetAvatarURL() string {
+	if u == nil || u.AvatarURL == nil {
+		return ""
+	}
+	return *u.AvatarURL
+}
+
+// GetEventsURL returns the EventsURL field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetEventsURL() string {
+	if u == nil || u.EventsURL == nil {
+		return ""
+	}
+	return *u.EventsURL
+}
+
+// GetFollowersURL returns the FollowersURL field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetFollowersURL() string {
+	if u == nil || u.FollowersURL == nil {
+		return ""
+	}
+	return *u.FollowersURL
+}
+
+// GetFollowingURL returns the FollowingURL field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetFollowingURL() string {
+	if u == nil || u.FollowingURL == nil {
+		return ""
+	}
+	return *u.FollowingURL
+}
+
+// GetGistsURL returns the GistsURL field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetGistsURL() string {
+	if u == nil || u.GistsURL == nil {
+		return ""
+	}
+	return *u.GistsURL
+}
+
+// GetGravatarID returns the GravatarID field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetGravatarID() string {
+	if u == nil || u.GravatarID == nil {
+		return ""
+	}
+	return *u.GravatarID
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetID() int64 {
+	if u == nil || u.ID == nil {
+		return 0
+	}
+	return *u.ID
+}
+
+// GetLDAPDN returns the LDAPDN field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetLDAPDN() string {
+	if u == nil || u.LDAPDN == nil {
+		return ""
+	}
+	return *u.LDAPDN
+}
+
+// GetLogin returns the Login field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetLogin() string {
+	if u == nil || u.Login == nil {
+		return ""
+	}
+	return *u.Login
+}
+
+// GetOrganizationsURL returns the OrganizationsURL field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetOrganizationsURL() string {
+	if u == nil || u.OrganizationsURL == nil {
+		return ""
+	}
+	return *u.OrganizationsURL
+}
+
+// GetReceivedEventsURL returns the ReceivedEventsURL field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetReceivedEventsURL() string {
+	if u == nil || u.ReceivedEventsURL == nil {
+		return ""
+	}
+	return *u.ReceivedEventsURL
+}
+
+// GetReposURL returns the ReposURL field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetReposURL() string {
+	if u == nil || u.ReposURL == nil {
+		return ""
+	}
+	return *u.ReposURL
+}
+
+// GetSiteAdmin returns the SiteAdmin field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetSiteAdmin() bool {
+	if u == nil || u.SiteAdmin == nil {
+		return false
+	}
+	return *u.SiteAdmin
+}
+
+// GetStarredURL returns the StarredURL field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetStarredURL() string {
+	if u == nil || u.StarredURL == nil {
+		return ""
+	}
+	return *u.StarredURL
+}
+
+// GetSubscriptionsURL returns the SubscriptionsURL field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetSubscriptionsURL() string {
+	if u == nil || u.SubscriptionsURL == nil {
+		return ""
+	}
+	return *u.SubscriptionsURL
+}
+
+// GetType returns the Type field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetType() string {
+	if u == nil || u.Type == nil {
+		return ""
+	}
+	return *u.Type
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (u *UserLDAPMapping) GetURL() string {
+	if u == nil || u.URL == nil {
+		return ""
+	}
+	return *u.URL
+}
+
+// GetIncompleteResults returns the IncompleteResults field if it's non-nil, zero value otherwise.
+func (u *UsersSearchResult) GetIncompleteResults() bool {
+	if u == nil || u.IncompleteResults == nil {
+		return false
+	}
+	return *u.IncompleteResults
+}
+
+// GetTotal returns the Total field if it's non-nil, zero value otherwise.
+func (u *UsersSearchResult) GetTotal() int {
+	if u == nil || u.Total == nil {
+		return 0
+	}
+	return *u.Total
+}
+
+// GetAdminUsers returns the AdminUsers field if it's non-nil, zero value otherwise.
+func (u *UserStats) GetAdminUsers() int {
+	if u == nil || u.AdminUsers == nil {
+		return 0
+	}
+	return *u.AdminUsers
+}
+
+// GetSuspendedUsers returns the SuspendedUsers field if it's non-nil, zero value otherwise.
+func (u *UserStats) GetSuspendedUsers() int {
+	if u == nil || u.SuspendedUsers == nil {
+		return 0
+	}
+	return *u.SuspendedUsers
+}
+
+// GetTotalUsers returns the TotalUsers field if it's non-nil, zero value otherwise.
+func (u *UserStats) GetTotalUsers() int {
+	if u == nil || u.TotalUsers == nil {
+		return 0
+	}
+	return *u.TotalUsers
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (w *WatchEvent) GetAction() string {
+	if w == nil || w.Action == nil {
+		return ""
+	}
+	return *w.Action
+}
+
+// GetInstallation returns the Installation field.
+func (w *WatchEvent) GetInstallation() *Installation {
+	if w == nil {
+		return nil
+	}
+	return w.Installation
+}
+
+// GetRepo returns the Repo field.
+func (w *WatchEvent) GetRepo() *Repository {
+	if w == nil {
+		return nil
+	}
+	return w.Repo
+}
+
+// GetSender returns the Sender field.
+func (w *WatchEvent) GetSender() *User {
+	if w == nil {
+		return nil
+	}
+	return w.Sender
+}
+
+// GetEmail returns the Email field if it's non-nil, zero value otherwise.
+func (w *WebHookAuthor) GetEmail() string {
+	if w == nil || w.Email == nil {
+		return ""
+	}
+	return *w.Email
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (w *WebHookAuthor) GetName() string {
+	if w == nil || w.Name == nil {
+		return ""
+	}
+	return *w.Name
+}
+
+// GetUsername returns the Username field if it's non-nil, zero value otherwise.
+func (w *WebHookAuthor) GetUsername() string {
+	if w == nil || w.Username == nil {
+		return ""
+	}
+	return *w.Username
+}
+
+// GetAuthor returns the Author field.
+func (w *WebHookCommit) GetAuthor() *WebHookAuthor {
+	if w == nil {
+		return nil
+	}
+	return w.Author
+}
+
+// GetCommitter returns the Committer field.
+func (w *WebHookCommit) GetCommitter() *WebHookAuthor {
+	if w == nil {
+		return nil
+	}
+	return w.Committer
+}
+
+// GetDistinct returns the Distinct field if it's non-nil, zero value otherwise.
+func (w *WebHookCommit) GetDistinct() bool {
+	if w == nil || w.Distinct == nil {
+		return false
+	}
+	return *w.Distinct
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (w *WebHookCommit) GetID() string {
+	if w == nil || w.ID == nil {
+		return ""
+	}
+	return *w.ID
+}
+
+// GetMessage returns the Message field if it's non-nil, zero value otherwise.
+func (w *WebHookCommit) GetMessage() string {
+	if w == nil || w.Message == nil {
+		return ""
+	}
+	return *w.Message
+}
+
+// GetTimestamp returns the Timestamp field if it's non-nil, zero value otherwise.
+func (w *WebHookCommit) GetTimestamp() time.Time {
+	if w == nil || w.Timestamp == nil {
+		return time.Time{}
+	}
+	return *w.Timestamp
+}
+
+// GetAfter returns the After field if it's non-nil, zero value otherwise.
+func (w *WebHookPayload) GetAfter() string {
+	if w == nil || w.After == nil {
+		return ""
+	}
+	return *w.After
+}
+
+// GetBefore returns the Before field if it's non-nil, zero value otherwise.
+func (w *WebHookPayload) GetBefore() string {
+	if w == nil || w.Before == nil {
+		return ""
+	}
+	return *w.Before
+}
+
+// GetCompare returns the Compare field if it's non-nil, zero value otherwise.
+func (w *WebHookPayload) GetCompare() string {
+	if w == nil || w.Compare == nil {
+		return ""
+	}
+	return *w.Compare
+}
+
+// GetCreated returns the Created field if it's non-nil, zero value otherwise.
+func (w *WebHookPayload) GetCreated() bool {
+	if w == nil || w.Created == nil {
+		return false
+	}
+	return *w.Created
+}
+
+// GetDeleted returns the Deleted field if it's non-nil, zero value otherwise.
+func (w *WebHookPayload) GetDeleted() bool {
+	if w == nil || w.Deleted == nil {
+		return false
+	}
+	return *w.Deleted
+}
+
+// GetForced returns the Forced field if it's non-nil, zero value otherwise.
+func (w *WebHookPayload) GetForced() bool {
+	if w == nil || w.Forced == nil {
+		return false
+	}
+	return *w.Forced
+}
+
+// GetHeadCommit returns the HeadCommit field.
+func (w *WebHookPayload) GetHeadCommit() *WebHookCommit {
+	if w == nil {
+		return nil
+	}
+	return w.HeadCommit
+}
+
+// GetPusher returns the Pusher field.
+func (w *WebHookPayload) GetPusher() *User {
+	if w == nil {
+		return nil
+	}
+	return w.Pusher
+}
+
+// GetRef returns the Ref field if it's non-nil, zero value otherwise.
+func (w *WebHookPayload) GetRef() string {
+	if w == nil || w.Ref == nil {
+		return ""
+	}
+	return *w.Ref
+}
+
+// GetRepo returns the Repo field.
+func (w *WebHookPayload) GetRepo() *Repository {
+	if w == nil {
+		return nil
+	}
+	return w.Repo
+}
+
+// GetSender returns the Sender field.
+func (w *WebHookPayload) GetSender() *User {
+	if w == nil {
+		return nil
+	}
+	return w.Sender
+}
+
+// GetTotal returns the Total field if it's non-nil, zero value otherwise.
+func (w *WeeklyCommitActivity) GetTotal() int {
+	if w == nil || w.Total == nil {
+		return 0
+	}
+	return *w.Total
+}
+
+// GetWeek returns the Week field if it's non-nil, zero value otherwise.
+func (w *WeeklyCommitActivity) GetWeek() Timestamp {
+	if w == nil || w.Week == nil {
+		return Timestamp{}
+	}
+	return *w.Week
+}
+
+// GetAdditions returns the Additions field if it's non-nil, zero value otherwise.
+func (w *WeeklyStats) GetAdditions() int {
+	if w == nil || w.Additions == nil {
+		return 0
+	}
+	return *w.Additions
+}
+
+// GetCommits returns the Commits field if it's non-nil, zero value otherwise.
+func (w *WeeklyStats) GetCommits() int {
+	if w == nil || w.Commits == nil {
+		return 0
+	}
+	return *w.Commits
+}
+
+// GetDeletions returns the Deletions field if it's non-nil, zero value otherwise.
+func (w *WeeklyStats) GetDeletions() int {
+	if w == nil || w.Deletions == nil {
+		return 0
+	}
+	return *w.Deletions
+}
+
+// GetWeek returns the Week field if it's non-nil, zero value otherwise.
+func (w *WeeklyStats) GetWeek() Timestamp {
+	if w == nil || w.Week == nil {
+		return Timestamp{}
+	}
+	return *w.Week
+}

+ 980 - 0
vendor/github.com/google/go-github/github/github.go

@@ -0,0 +1,980 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:generate go run gen-accessors.go
+
+package github
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+	"reflect"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/google/go-querystring/query"
+)
+
+const (
+	libraryVersion = "15"
+	defaultBaseURL = "https://api.github.com/"
+	uploadBaseURL  = "https://uploads.github.com/"
+	userAgent      = "go-github/" + libraryVersion
+
+	headerRateLimit     = "X-RateLimit-Limit"
+	headerRateRemaining = "X-RateLimit-Remaining"
+	headerRateReset     = "X-RateLimit-Reset"
+	headerOTP           = "X-GitHub-OTP"
+
+	mediaTypeV3                = "application/vnd.github.v3+json"
+	defaultMediaType           = "application/octet-stream"
+	mediaTypeV3SHA             = "application/vnd.github.v3.sha"
+	mediaTypeV3Diff            = "application/vnd.github.v3.diff"
+	mediaTypeV3Patch           = "application/vnd.github.v3.patch"
+	mediaTypeOrgPermissionRepo = "application/vnd.github.v3.repository+json"
+
+	// Media Type values to access preview APIs
+
+	// https://developer.github.com/changes/2015-03-09-licenses-api/
+	mediaTypeLicensesPreview = "application/vnd.github.drax-preview+json"
+
+	// https://developer.github.com/changes/2014-12-09-new-attributes-for-stars-api/
+	mediaTypeStarringPreview = "application/vnd.github.v3.star+json"
+
+	// https://developer.github.com/changes/2015-11-11-protected-branches-api/
+	mediaTypeProtectedBranchesPreview = "application/vnd.github.loki-preview+json"
+
+	// https://help.github.com/enterprise/2.4/admin/guides/migrations/exporting-the-github-com-organization-s-repositories/
+	mediaTypeMigrationsPreview = "application/vnd.github.wyandotte-preview+json"
+
+	// https://developer.github.com/changes/2016-04-06-deployment-and-deployment-status-enhancements/
+	mediaTypeDeploymentStatusPreview = "application/vnd.github.ant-man-preview+json"
+
+	// https://developer.github.com/changes/2016-02-19-source-import-preview-api/
+	mediaTypeImportPreview = "application/vnd.github.barred-rock-preview"
+
+	// https://developer.github.com/changes/2016-05-12-reactions-api-preview/
+	mediaTypeReactionsPreview = "application/vnd.github.squirrel-girl-preview"
+
+	// https://developer.github.com/changes/2016-04-04-git-signing-api-preview/
+	mediaTypeGitSigningPreview = "application/vnd.github.cryptographer-preview+json"
+
+	// https://developer.github.com/changes/2016-05-23-timeline-preview-api/
+	mediaTypeTimelinePreview = "application/vnd.github.mockingbird-preview+json"
+
+	// https://developer.github.com/changes/2016-06-14-repository-invitations/
+	mediaTypeRepositoryInvitationsPreview = "application/vnd.github.swamp-thing-preview+json"
+
+	// https://developer.github.com/changes/2016-07-06-github-pages-preiew-api/
+	mediaTypePagesPreview = "application/vnd.github.mister-fantastic-preview+json"
+
+	// https://developer.github.com/changes/2016-09-14-projects-api/
+	mediaTypeProjectsPreview = "application/vnd.github.inertia-preview+json"
+
+	// https://developer.github.com/changes/2016-09-14-Integrations-Early-Access/
+	mediaTypeIntegrationPreview = "application/vnd.github.machine-man-preview+json"
+
+	// https://developer.github.com/changes/2017-01-05-commit-search-api/
+	mediaTypeCommitSearchPreview = "application/vnd.github.cloak-preview+json"
+
+	// https://developer.github.com/changes/2017-02-28-user-blocking-apis-and-webhook/
+	mediaTypeBlockUsersPreview = "application/vnd.github.giant-sentry-fist-preview+json"
+
+	// https://developer.github.com/changes/2017-02-09-community-health/
+	mediaTypeRepositoryCommunityHealthMetricsPreview = "application/vnd.github.black-panther-preview+json"
+
+	// https://developer.github.com/changes/2017-05-23-coc-api/
+	mediaTypeCodesOfConductPreview = "application/vnd.github.scarlet-witch-preview+json"
+
+	// https://developer.github.com/changes/2017-07-17-update-topics-on-repositories/
+	mediaTypeTopicsPreview = "application/vnd.github.mercy-preview+json"
+
+	// https://developer.github.com/changes/2017-07-26-team-review-request-thor-preview/
+	mediaTypeTeamReviewPreview = "application/vnd.github.thor-preview+json"
+
+	// https://developer.github.com/v3/apps/marketplace/
+	mediaTypeMarketplacePreview = "application/vnd.github.valkyrie-preview+json"
+
+	// https://developer.github.com/changes/2017-08-30-preview-nested-teams/
+	mediaTypeNestedTeamsPreview = "application/vnd.github.hellcat-preview+json"
+
+	// https://developer.github.com/changes/2017-11-09-repository-transfer-api-preview/
+	mediaTypeRepositoryTransferPreview = "application/vnd.github.nightshade-preview+json"
+
+	// https://developer.github.com/changes/2017-12-19-graphql-node-id/
+	mediaTypeGraphQLNodeIDPreview = "application/vnd.github.jean-grey-preview+json"
+)
+
+// A Client manages communication with the GitHub API.
+type Client struct {
+	clientMu sync.Mutex   // clientMu protects the client during calls that modify the CheckRedirect func.
+	client   *http.Client // HTTP client used to communicate with the API.
+
+	// Base URL for API requests. Defaults to the public GitHub API, but can be
+	// set to a domain endpoint to use with GitHub Enterprise. BaseURL should
+	// always be specified with a trailing slash.
+	BaseURL *url.URL
+
+	// Base URL for uploading files.
+	UploadURL *url.URL
+
+	// User agent used when communicating with the GitHub API.
+	UserAgent string
+
+	rateMu     sync.Mutex
+	rateLimits [categories]Rate // Rate limits for the client as determined by the most recent API calls.
+
+	common service // Reuse a single struct instead of allocating one for each service on the heap.
+
+	// Services used for talking to different parts of the GitHub API.
+	Activity       *ActivityService
+	Admin          *AdminService
+	Apps           *AppsService
+	Authorizations *AuthorizationsService
+	Gists          *GistsService
+	Git            *GitService
+	Gitignores     *GitignoresService
+	Issues         *IssuesService
+	Licenses       *LicensesService
+	Marketplace    *MarketplaceService
+	Migrations     *MigrationService
+	Organizations  *OrganizationsService
+	Projects       *ProjectsService
+	PullRequests   *PullRequestsService
+	Reactions      *ReactionsService
+	Repositories   *RepositoriesService
+	Search         *SearchService
+	Users          *UsersService
+}
+
+type service struct {
+	client *Client
+}
+
+// ListOptions specifies the optional parameters to various List methods that
+// support pagination.
+type ListOptions struct {
+	// For paginated result sets, page of results to retrieve.
+	Page int `url:"page,omitempty"`
+
+	// For paginated result sets, the number of results to include per page.
+	PerPage int `url:"per_page,omitempty"`
+}
+
+// UploadOptions specifies the parameters to methods that support uploads.
+type UploadOptions struct {
+	Name string `url:"name,omitempty"`
+}
+
+// RawType represents type of raw format of a request instead of JSON.
+type RawType uint8
+
+const (
+	// Diff format.
+	Diff RawType = 1 + iota
+	// Patch format.
+	Patch
+)
+
+// RawOptions specifies parameters when user wants to get raw format of
+// a response instead of JSON.
+type RawOptions struct {
+	Type RawType
+}
+
+// addOptions adds the parameters in opt as URL query parameters to s. opt
+// must be a struct whose fields may contain "url" tags.
+func addOptions(s string, opt interface{}) (string, error) {
+	v := reflect.ValueOf(opt)
+	if v.Kind() == reflect.Ptr && v.IsNil() {
+		return s, nil
+	}
+
+	u, err := url.Parse(s)
+	if err != nil {
+		return s, err
+	}
+
+	qs, err := query.Values(opt)
+	if err != nil {
+		return s, err
+	}
+
+	u.RawQuery = qs.Encode()
+	return u.String(), nil
+}
+
+// NewClient returns a new GitHub API client. If a nil httpClient is
+// provided, http.DefaultClient will be used. To use API methods which require
+// authentication, provide an http.Client that will perform the authentication
+// for you (such as that provided by the golang.org/x/oauth2 library).
+func NewClient(httpClient *http.Client) *Client {
+	if httpClient == nil {
+		httpClient = http.DefaultClient
+	}
+	baseURL, _ := url.Parse(defaultBaseURL)
+	uploadURL, _ := url.Parse(uploadBaseURL)
+
+	c := &Client{client: httpClient, BaseURL: baseURL, UserAgent: userAgent, UploadURL: uploadURL}
+	c.common.client = c
+	c.Activity = (*ActivityService)(&c.common)
+	c.Admin = (*AdminService)(&c.common)
+	c.Apps = (*AppsService)(&c.common)
+	c.Authorizations = (*AuthorizationsService)(&c.common)
+	c.Gists = (*GistsService)(&c.common)
+	c.Git = (*GitService)(&c.common)
+	c.Gitignores = (*GitignoresService)(&c.common)
+	c.Issues = (*IssuesService)(&c.common)
+	c.Licenses = (*LicensesService)(&c.common)
+	c.Marketplace = &MarketplaceService{client: c}
+	c.Migrations = (*MigrationService)(&c.common)
+	c.Organizations = (*OrganizationsService)(&c.common)
+	c.Projects = (*ProjectsService)(&c.common)
+	c.PullRequests = (*PullRequestsService)(&c.common)
+	c.Reactions = (*ReactionsService)(&c.common)
+	c.Repositories = (*RepositoriesService)(&c.common)
+	c.Search = (*SearchService)(&c.common)
+	c.Users = (*UsersService)(&c.common)
+	return c
+}
+
+// NewEnterpriseClient returns a new GitHub API client with provided
+// base URL and upload URL (often the same URL).
+// If either URL does not have a trailing slash, one is added automatically.
+// If a nil httpClient is provided, http.DefaultClient will be used.
+//
+// Note that NewEnterpriseClient is a convenience helper only;
+// its behavior is equivalent to using NewClient, followed by setting
+// the BaseURL and UploadURL fields.
+func NewEnterpriseClient(baseURL, uploadURL string, httpClient *http.Client) (*Client, error) {
+	baseEndpoint, err := url.Parse(baseURL)
+	if err != nil {
+		return nil, err
+	}
+	if !strings.HasSuffix(baseEndpoint.Path, "/") {
+		baseEndpoint.Path += "/"
+	}
+
+	uploadEndpoint, err := url.Parse(uploadURL)
+	if err != nil {
+		return nil, err
+	}
+	if !strings.HasSuffix(uploadEndpoint.Path, "/") {
+		uploadEndpoint.Path += "/"
+	}
+
+	c := NewClient(httpClient)
+	c.BaseURL = baseEndpoint
+	c.UploadURL = uploadEndpoint
+	return c, nil
+}
+
+// NewRequest creates an API request. A relative URL can be provided in urlStr,
+// in which case it is resolved relative to the BaseURL of the Client.
+// Relative URLs should always be specified without a preceding slash. If
+// specified, the value pointed to by body is JSON encoded and included as the
+// request body.
+func (c *Client) NewRequest(method, urlStr string, body interface{}) (*http.Request, error) {
+	if !strings.HasSuffix(c.BaseURL.Path, "/") {
+		return nil, fmt.Errorf("BaseURL must have a trailing slash, but %q does not", c.BaseURL)
+	}
+	u, err := c.BaseURL.Parse(urlStr)
+	if err != nil {
+		return nil, err
+	}
+
+	var buf io.ReadWriter
+	if body != nil {
+		buf = new(bytes.Buffer)
+		enc := json.NewEncoder(buf)
+		enc.SetEscapeHTML(false)
+		err := enc.Encode(body)
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	req, err := http.NewRequest(method, u.String(), buf)
+	if err != nil {
+		return nil, err
+	}
+
+	if body != nil {
+		req.Header.Set("Content-Type", "application/json")
+	}
+	req.Header.Set("Accept", mediaTypeV3)
+	if c.UserAgent != "" {
+		req.Header.Set("User-Agent", c.UserAgent)
+	}
+	return req, nil
+}
+
+// NewUploadRequest creates an upload request. A relative URL can be provided in
+// urlStr, in which case it is resolved relative to the UploadURL of the Client.
+// Relative URLs should always be specified without a preceding slash.
+func (c *Client) NewUploadRequest(urlStr string, reader io.Reader, size int64, mediaType string) (*http.Request, error) {
+	if !strings.HasSuffix(c.UploadURL.Path, "/") {
+		return nil, fmt.Errorf("UploadURL must have a trailing slash, but %q does not", c.UploadURL)
+	}
+	u, err := c.UploadURL.Parse(urlStr)
+	if err != nil {
+		return nil, err
+	}
+
+	req, err := http.NewRequest("POST", u.String(), reader)
+	if err != nil {
+		return nil, err
+	}
+	req.ContentLength = size
+
+	if mediaType == "" {
+		mediaType = defaultMediaType
+	}
+	req.Header.Set("Content-Type", mediaType)
+	req.Header.Set("Accept", mediaTypeV3)
+	req.Header.Set("User-Agent", c.UserAgent)
+	return req, nil
+}
+
+// Response is a GitHub API response. This wraps the standard http.Response
+// returned from GitHub and provides convenient access to things like
+// pagination links.
+type Response struct {
+	*http.Response
+
+	// These fields provide the page values for paginating through a set of
+	// results. Any or all of these may be set to the zero value for
+	// responses that are not part of a paginated set, or for which there
+	// are no additional pages.
+
+	NextPage  int
+	PrevPage  int
+	FirstPage int
+	LastPage  int
+
+	Rate
+}
+
+// newResponse creates a new Response for the provided http.Response.
+// r must not be nil.
+func newResponse(r *http.Response) *Response {
+	response := &Response{Response: r}
+	response.populatePageValues()
+	response.Rate = parseRate(r)
+	return response
+}
+
+// populatePageValues parses the HTTP Link response headers and populates the
+// various pagination link values in the Response.
+func (r *Response) populatePageValues() {
+	if links, ok := r.Response.Header["Link"]; ok && len(links) > 0 {
+		for _, link := range strings.Split(links[0], ",") {
+			segments := strings.Split(strings.TrimSpace(link), ";")
+
+			// link must at least have href and rel
+			if len(segments) < 2 {
+				continue
+			}
+
+			// ensure href is properly formatted
+			if !strings.HasPrefix(segments[0], "<") || !strings.HasSuffix(segments[0], ">") {
+				continue
+			}
+
+			// try to pull out page parameter
+			url, err := url.Parse(segments[0][1 : len(segments[0])-1])
+			if err != nil {
+				continue
+			}
+			page := url.Query().Get("page")
+			if page == "" {
+				continue
+			}
+
+			for _, segment := range segments[1:] {
+				switch strings.TrimSpace(segment) {
+				case `rel="next"`:
+					r.NextPage, _ = strconv.Atoi(page)
+				case `rel="prev"`:
+					r.PrevPage, _ = strconv.Atoi(page)
+				case `rel="first"`:
+					r.FirstPage, _ = strconv.Atoi(page)
+				case `rel="last"`:
+					r.LastPage, _ = strconv.Atoi(page)
+				}
+
+			}
+		}
+	}
+}
+
+// parseRate parses the rate related headers.
+func parseRate(r *http.Response) Rate {
+	var rate Rate
+	if limit := r.Header.Get(headerRateLimit); limit != "" {
+		rate.Limit, _ = strconv.Atoi(limit)
+	}
+	if remaining := r.Header.Get(headerRateRemaining); remaining != "" {
+		rate.Remaining, _ = strconv.Atoi(remaining)
+	}
+	if reset := r.Header.Get(headerRateReset); reset != "" {
+		if v, _ := strconv.ParseInt(reset, 10, 64); v != 0 {
+			rate.Reset = Timestamp{time.Unix(v, 0)}
+		}
+	}
+	return rate
+}
+
+// Do sends an API request and returns the API response. The API response is
+// JSON decoded and stored in the value pointed to by v, or returned as an
+// error if an API error has occurred. If v implements the io.Writer
+// interface, the raw response body will be written to v, without attempting to
+// first decode it. If rate limit is exceeded and reset time is in the future,
+// Do returns *RateLimitError immediately without making a network API call.
+//
+// The provided ctx must be non-nil. If it is canceled or times out,
+// ctx.Err() will be returned.
+func (c *Client) Do(ctx context.Context, req *http.Request, v interface{}) (*Response, error) {
+	req = withContext(ctx, req)
+
+	rateLimitCategory := category(req.URL.Path)
+
+	// If we've hit rate limit, don't make further requests before Reset time.
+	if err := c.checkRateLimitBeforeDo(req, rateLimitCategory); err != nil {
+		return &Response{
+			Response: err.Response,
+			Rate:     err.Rate,
+		}, err
+	}
+
+	resp, err := c.client.Do(req)
+	if err != nil {
+		// If we got an error, and the context has been canceled,
+		// the context's error is probably more useful.
+		select {
+		case <-ctx.Done():
+			return nil, ctx.Err()
+		default:
+		}
+
+		// If the error type is *url.Error, sanitize its URL before returning.
+		if e, ok := err.(*url.Error); ok {
+			if url, err := url.Parse(e.URL); err == nil {
+				e.URL = sanitizeURL(url).String()
+				return nil, e
+			}
+		}
+
+		return nil, err
+	}
+
+	defer func() {
+		// Drain up to 512 bytes and close the body to let the Transport reuse the connection
+		io.CopyN(ioutil.Discard, resp.Body, 512)
+		resp.Body.Close()
+	}()
+
+	response := newResponse(resp)
+
+	c.rateMu.Lock()
+	c.rateLimits[rateLimitCategory] = response.Rate
+	c.rateMu.Unlock()
+
+	err = CheckResponse(resp)
+	if err != nil {
+		// even though there was an error, we still return the response
+		// in case the caller wants to inspect it further
+		return response, err
+	}
+
+	if v != nil {
+		if w, ok := v.(io.Writer); ok {
+			io.Copy(w, resp.Body)
+		} else {
+			err = json.NewDecoder(resp.Body).Decode(v)
+			if err == io.EOF {
+				err = nil // ignore EOF errors caused by empty response body
+			}
+		}
+	}
+
+	return response, err
+}
+
+// checkRateLimitBeforeDo does not make any network calls, but uses existing knowledge from
+// current client state in order to quickly check if *RateLimitError can be immediately returned
+// from Client.Do, and if so, returns it so that Client.Do can skip making a network API call unnecessarily.
+// Otherwise it returns nil, and Client.Do should proceed normally.
+func (c *Client) checkRateLimitBeforeDo(req *http.Request, rateLimitCategory rateLimitCategory) *RateLimitError {
+	c.rateMu.Lock()
+	rate := c.rateLimits[rateLimitCategory]
+	c.rateMu.Unlock()
+	if !rate.Reset.Time.IsZero() && rate.Remaining == 0 && time.Now().Before(rate.Reset.Time) {
+		// Create a fake response.
+		resp := &http.Response{
+			Status:     http.StatusText(http.StatusForbidden),
+			StatusCode: http.StatusForbidden,
+			Request:    req,
+			Header:     make(http.Header),
+			Body:       ioutil.NopCloser(strings.NewReader("")),
+		}
+		return &RateLimitError{
+			Rate:     rate,
+			Response: resp,
+			Message:  fmt.Sprintf("API rate limit of %v still exceeded until %v, not making remote request.", rate.Limit, rate.Reset.Time),
+		}
+	}
+
+	return nil
+}
+
+/*
+An ErrorResponse reports one or more errors caused by an API request.
+
+GitHub API docs: https://developer.github.com/v3/#client-errors
+*/
+type ErrorResponse struct {
+	Response *http.Response // HTTP response that caused this error
+	Message  string         `json:"message"` // error message
+	Errors   []Error        `json:"errors"`  // more detail on individual errors
+	// Block is only populated on certain types of errors such as code 451.
+	// See https://developer.github.com/changes/2016-03-17-the-451-status-code-is-now-supported/
+	// for more information.
+	Block *struct {
+		Reason    string     `json:"reason,omitempty"`
+		CreatedAt *Timestamp `json:"created_at,omitempty"`
+	} `json:"block,omitempty"`
+	// Most errors will also include a documentation_url field pointing
+	// to some content that might help you resolve the error, see
+	// https://developer.github.com/v3/#client-errors
+	DocumentationURL string `json:"documentation_url,omitempty"`
+}
+
+func (r *ErrorResponse) Error() string {
+	return fmt.Sprintf("%v %v: %d %v %+v",
+		r.Response.Request.Method, sanitizeURL(r.Response.Request.URL),
+		r.Response.StatusCode, r.Message, r.Errors)
+}
+
+// TwoFactorAuthError occurs when using HTTP Basic Authentication for a user
+// that has two-factor authentication enabled. The request can be reattempted
+// by providing a one-time password in the request.
+type TwoFactorAuthError ErrorResponse
+
+func (r *TwoFactorAuthError) Error() string { return (*ErrorResponse)(r).Error() }
+
+// RateLimitError occurs when GitHub returns 403 Forbidden response with a rate limit
+// remaining value of 0, and error message starts with "API rate limit exceeded for ".
+type RateLimitError struct {
+	Rate     Rate           // Rate specifies last known rate limit for the client
+	Response *http.Response // HTTP response that caused this error
+	Message  string         `json:"message"` // error message
+}
+
+func (r *RateLimitError) Error() string {
+	return fmt.Sprintf("%v %v: %d %v %v",
+		r.Response.Request.Method, sanitizeURL(r.Response.Request.URL),
+		r.Response.StatusCode, r.Message, formatRateReset(r.Rate.Reset.Time.Sub(time.Now())))
+}
+
+// AcceptedError occurs when GitHub returns 202 Accepted response with an
+// empty body, which means a job was scheduled on the GitHub side to process
+// the information needed and cache it.
+// Technically, 202 Accepted is not a real error, it's just used to
+// indicate that results are not ready yet, but should be available soon.
+// The request can be repeated after some time.
+type AcceptedError struct{}
+
+func (*AcceptedError) Error() string {
+	return "job scheduled on GitHub side; try again later"
+}
+
+// AbuseRateLimitError occurs when GitHub returns 403 Forbidden response with the
+// "documentation_url" field value equal to "https://developer.github.com/v3/#abuse-rate-limits".
+type AbuseRateLimitError struct {
+	Response *http.Response // HTTP response that caused this error
+	Message  string         `json:"message"` // error message
+
+	// RetryAfter is provided with some abuse rate limit errors. If present,
+	// it is the amount of time that the client should wait before retrying.
+	// Otherwise, the client should try again later (after an unspecified amount of time).
+	RetryAfter *time.Duration
+}
+
+func (r *AbuseRateLimitError) Error() string {
+	return fmt.Sprintf("%v %v: %d %v",
+		r.Response.Request.Method, sanitizeURL(r.Response.Request.URL),
+		r.Response.StatusCode, r.Message)
+}
+
+// sanitizeURL redacts the client_secret parameter from the URL which may be
+// exposed to the user.
+func sanitizeURL(uri *url.URL) *url.URL {
+	if uri == nil {
+		return nil
+	}
+	params := uri.Query()
+	if len(params.Get("client_secret")) > 0 {
+		params.Set("client_secret", "REDACTED")
+		uri.RawQuery = params.Encode()
+	}
+	return uri
+}
+
+/*
+An Error reports more details on an individual error in an ErrorResponse.
+These are the possible validation error codes:
+
+    missing:
+        resource does not exist
+    missing_field:
+        a required field on a resource has not been set
+    invalid:
+        the formatting of a field is invalid
+    already_exists:
+        another resource has the same valid as this field
+    custom:
+        some resources return this (e.g. github.User.CreateKey()), additional
+        information is set in the Message field of the Error
+
+GitHub API docs: https://developer.github.com/v3/#client-errors
+*/
+type Error struct {
+	Resource string `json:"resource"` // resource on which the error occurred
+	Field    string `json:"field"`    // field on which the error occurred
+	Code     string `json:"code"`     // validation error code
+	Message  string `json:"message"`  // Message describing the error. Errors with Code == "custom" will always have this set.
+}
+
+func (e *Error) Error() string {
+	return fmt.Sprintf("%v error caused by %v field on %v resource",
+		e.Code, e.Field, e.Resource)
+}
+
+// CheckResponse checks the API response for errors, and returns them if
+// present. A response is considered an error if it has a status code outside
+// the 200 range or equal to 202 Accepted.
+// API error responses are expected to have either no response
+// body, or a JSON response body that maps to ErrorResponse. Any other
+// response body will be silently ignored.
+//
+// The error type will be *RateLimitError for rate limit exceeded errors,
+// *AcceptedError for 202 Accepted status codes,
+// and *TwoFactorAuthError for two-factor authentication errors.
+func CheckResponse(r *http.Response) error {
+	if r.StatusCode == http.StatusAccepted {
+		return &AcceptedError{}
+	}
+	if c := r.StatusCode; 200 <= c && c <= 299 {
+		return nil
+	}
+	errorResponse := &ErrorResponse{Response: r}
+	data, err := ioutil.ReadAll(r.Body)
+	if err == nil && data != nil {
+		json.Unmarshal(data, errorResponse)
+	}
+	switch {
+	case r.StatusCode == http.StatusUnauthorized && strings.HasPrefix(r.Header.Get(headerOTP), "required"):
+		return (*TwoFactorAuthError)(errorResponse)
+	case r.StatusCode == http.StatusForbidden && r.Header.Get(headerRateRemaining) == "0" && strings.HasPrefix(errorResponse.Message, "API rate limit exceeded for "):
+		return &RateLimitError{
+			Rate:     parseRate(r),
+			Response: errorResponse.Response,
+			Message:  errorResponse.Message,
+		}
+	case r.StatusCode == http.StatusForbidden && errorResponse.DocumentationURL == "https://developer.github.com/v3/#abuse-rate-limits":
+		abuseRateLimitError := &AbuseRateLimitError{
+			Response: errorResponse.Response,
+			Message:  errorResponse.Message,
+		}
+		if v := r.Header["Retry-After"]; len(v) > 0 {
+			// According to GitHub support, the "Retry-After" header value will be
+			// an integer which represents the number of seconds that one should
+			// wait before resuming making requests.
+			retryAfterSeconds, _ := strconv.ParseInt(v[0], 10, 64) // Error handling is noop.
+			retryAfter := time.Duration(retryAfterSeconds) * time.Second
+			abuseRateLimitError.RetryAfter = &retryAfter
+		}
+		return abuseRateLimitError
+	default:
+		return errorResponse
+	}
+}
+
+// parseBoolResponse determines the boolean result from a GitHub API response.
+// Several GitHub API methods return boolean responses indicated by the HTTP
+// status code in the response (true indicated by a 204, false indicated by a
+// 404). This helper function will determine that result and hide the 404
+// error if present. Any other error will be returned through as-is.
+func parseBoolResponse(err error) (bool, error) {
+	if err == nil {
+		return true, nil
+	}
+
+	if err, ok := err.(*ErrorResponse); ok && err.Response.StatusCode == http.StatusNotFound {
+		// Simply false. In this one case, we do not pass the error through.
+		return false, nil
+	}
+
+	// some other real error occurred
+	return false, err
+}
+
+// Rate represents the rate limit for the current client.
+type Rate struct {
+	// The number of requests per hour the client is currently limited to.
+	Limit int `json:"limit"`
+
+	// The number of remaining requests the client can make this hour.
+	Remaining int `json:"remaining"`
+
+	// The time at which the current rate limit will reset.
+	Reset Timestamp `json:"reset"`
+}
+
+func (r Rate) String() string {
+	return Stringify(r)
+}
+
+// RateLimits represents the rate limits for the current client.
+type RateLimits struct {
+	// The rate limit for non-search API requests. Unauthenticated
+	// requests are limited to 60 per hour. Authenticated requests are
+	// limited to 5,000 per hour.
+	//
+	// GitHub API docs: https://developer.github.com/v3/#rate-limiting
+	Core *Rate `json:"core"`
+
+	// The rate limit for search API requests. Unauthenticated requests
+	// are limited to 10 requests per minutes. Authenticated requests are
+	// limited to 30 per minute.
+	//
+	// GitHub API docs: https://developer.github.com/v3/search/#rate-limit
+	Search *Rate `json:"search"`
+}
+
+func (r RateLimits) String() string {
+	return Stringify(r)
+}
+
+type rateLimitCategory uint8
+
+const (
+	coreCategory rateLimitCategory = iota
+	searchCategory
+
+	categories // An array of this length will be able to contain all rate limit categories.
+)
+
+// category returns the rate limit category of the endpoint, determined by Request.URL.Path.
+func category(path string) rateLimitCategory {
+	switch {
+	default:
+		return coreCategory
+	case strings.HasPrefix(path, "/search/"):
+		return searchCategory
+	}
+}
+
+// RateLimits returns the rate limits for the current client.
+func (c *Client) RateLimits(ctx context.Context) (*RateLimits, *Response, error) {
+	req, err := c.NewRequest("GET", "rate_limit", nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	response := new(struct {
+		Resources *RateLimits `json:"resources"`
+	})
+	resp, err := c.Do(ctx, req, response)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	if response.Resources != nil {
+		c.rateMu.Lock()
+		if response.Resources.Core != nil {
+			c.rateLimits[coreCategory] = *response.Resources.Core
+		}
+		if response.Resources.Search != nil {
+			c.rateLimits[searchCategory] = *response.Resources.Search
+		}
+		c.rateMu.Unlock()
+	}
+
+	return response.Resources, resp, nil
+}
+
+/*
+UnauthenticatedRateLimitedTransport allows you to make unauthenticated calls
+that need to use a higher rate limit associated with your OAuth application.
+
+	t := &github.UnauthenticatedRateLimitedTransport{
+		ClientID:     "your app's client ID",
+		ClientSecret: "your app's client secret",
+	}
+	client := github.NewClient(t.Client())
+
+This will append the querystring params client_id=xxx&client_secret=yyy to all
+requests.
+
+See https://developer.github.com/v3/#unauthenticated-rate-limited-requests for
+more information.
+*/
+type UnauthenticatedRateLimitedTransport struct {
+	// ClientID is the GitHub OAuth client ID of the current application, which
+	// can be found by selecting its entry in the list at
+	// https://github.com/settings/applications.
+	ClientID string
+
+	// ClientSecret is the GitHub OAuth client secret of the current
+	// application.
+	ClientSecret string
+
+	// Transport is the underlying HTTP transport to use when making requests.
+	// It will default to http.DefaultTransport if nil.
+	Transport http.RoundTripper
+}
+
+// RoundTrip implements the RoundTripper interface.
+func (t *UnauthenticatedRateLimitedTransport) RoundTrip(req *http.Request) (*http.Response, error) {
+	if t.ClientID == "" {
+		return nil, errors.New("t.ClientID is empty")
+	}
+	if t.ClientSecret == "" {
+		return nil, errors.New("t.ClientSecret is empty")
+	}
+
+	// To set extra querystring params, we must make a copy of the Request so
+	// that we don't modify the Request we were given. This is required by the
+	// specification of http.RoundTripper.
+	//
+	// Since we are going to modify only req.URL here, we only need a deep copy
+	// of req.URL.
+	req2 := new(http.Request)
+	*req2 = *req
+	req2.URL = new(url.URL)
+	*req2.URL = *req.URL
+
+	q := req2.URL.Query()
+	q.Set("client_id", t.ClientID)
+	q.Set("client_secret", t.ClientSecret)
+	req2.URL.RawQuery = q.Encode()
+
+	// Make the HTTP request.
+	return t.transport().RoundTrip(req2)
+}
+
+// Client returns an *http.Client that makes requests which are subject to the
+// rate limit of your OAuth application.
+func (t *UnauthenticatedRateLimitedTransport) Client() *http.Client {
+	return &http.Client{Transport: t}
+}
+
+func (t *UnauthenticatedRateLimitedTransport) transport() http.RoundTripper {
+	if t.Transport != nil {
+		return t.Transport
+	}
+	return http.DefaultTransport
+}
+
+// BasicAuthTransport is an http.RoundTripper that authenticates all requests
+// using HTTP Basic Authentication with the provided username and password. It
+// additionally supports users who have two-factor authentication enabled on
+// their GitHub account.
+type BasicAuthTransport struct {
+	Username string // GitHub username
+	Password string // GitHub password
+	OTP      string // one-time password for users with two-factor auth enabled
+
+	// Transport is the underlying HTTP transport to use when making requests.
+	// It will default to http.DefaultTransport if nil.
+	Transport http.RoundTripper
+}
+
+// RoundTrip implements the RoundTripper interface.
+func (t *BasicAuthTransport) RoundTrip(req *http.Request) (*http.Response, error) {
+	// To set extra headers, we must make a copy of the Request so
+	// that we don't modify the Request we were given. This is required by the
+	// specification of http.RoundTripper.
+	//
+	// Since we are going to modify only req.Header here, we only need a deep copy
+	// of req.Header.
+	req2 := new(http.Request)
+	*req2 = *req
+	req2.Header = make(http.Header, len(req.Header))
+	for k, s := range req.Header {
+		req2.Header[k] = append([]string(nil), s...)
+	}
+
+	req2.SetBasicAuth(t.Username, t.Password)
+	if t.OTP != "" {
+		req2.Header.Set(headerOTP, t.OTP)
+	}
+	return t.transport().RoundTrip(req2)
+}
+
+// Client returns an *http.Client that makes requests that are authenticated
+// using HTTP Basic Authentication.
+func (t *BasicAuthTransport) Client() *http.Client {
+	return &http.Client{Transport: t}
+}
+
+func (t *BasicAuthTransport) transport() http.RoundTripper {
+	if t.Transport != nil {
+		return t.Transport
+	}
+	return http.DefaultTransport
+}
+
+// formatRateReset formats d to look like "[rate reset in 2s]" or
+// "[rate reset in 87m02s]" for the positive durations. And like "[rate limit was reset 87m02s ago]"
+// for the negative cases.
+func formatRateReset(d time.Duration) string {
+	isNegative := d < 0
+	if isNegative {
+		d *= -1
+	}
+	secondsTotal := int(0.5 + d.Seconds())
+	minutes := secondsTotal / 60
+	seconds := secondsTotal - minutes*60
+
+	var timeString string
+	if minutes > 0 {
+		timeString = fmt.Sprintf("%dm%02ds", minutes, seconds)
+	} else {
+		timeString = fmt.Sprintf("%ds", seconds)
+	}
+
+	if isNegative {
+		return fmt.Sprintf("[rate limit was reset %v ago]", timeString)
+	}
+	return fmt.Sprintf("[rate reset in %v]", timeString)
+}
+
+// Bool is a helper routine that allocates a new bool value
+// to store v and returns a pointer to it.
+func Bool(v bool) *bool { return &v }
+
+// Int is a helper routine that allocates a new int value
+// to store v and returns a pointer to it.
+func Int(v int) *int { return &v }
+
+// Int64 is a helper routine that allocates a new int64 value
+// to store v and returns a pointer to it.
+func Int64(v int64) *int64 { return &v }
+
+// String is a helper routine that allocates a new string value
+// to store v and returns a pointer to it.
+func String(v string) *string { return &v }

+ 64 - 0
vendor/github.com/google/go-github/github/gitignore.go

@@ -0,0 +1,64 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// GitignoresService provides access to the gitignore related functions in the
+// GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/gitignore/
+type GitignoresService service
+
+// Gitignore represents a .gitignore file as returned by the GitHub API.
+type Gitignore struct {
+	Name   *string `json:"name,omitempty"`
+	Source *string `json:"source,omitempty"`
+}
+
+func (g Gitignore) String() string {
+	return Stringify(g)
+}
+
+// List all available Gitignore templates.
+//
+// GitHub API docs: https://developer.github.com/v3/gitignore/#listing-available-templates
+func (s GitignoresService) List(ctx context.Context) ([]string, *Response, error) {
+	req, err := s.client.NewRequest("GET", "gitignore/templates", nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var availableTemplates []string
+	resp, err := s.client.Do(ctx, req, &availableTemplates)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return availableTemplates, resp, nil
+}
+
+// Get a Gitignore by name.
+//
+// GitHub API docs: https://developer.github.com/v3/gitignore/#get-a-single-template
+func (s GitignoresService) Get(ctx context.Context, name string) (*Gitignore, *Response, error) {
+	u := fmt.Sprintf("gitignore/templates/%v", name)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	gitignore := new(Gitignore)
+	resp, err := s.client.Do(ctx, req, gitignore)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return gitignore, resp, nil
+}

+ 330 - 0
vendor/github.com/google/go-github/github/issues.go

@@ -0,0 +1,330 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"strings"
+	"time"
+)
+
+// IssuesService handles communication with the issue related
+// methods of the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/
+type IssuesService service
+
+// Issue represents a GitHub issue on a repository.
+//
+// Note: As far as the GitHub API is concerned, every pull request is an issue,
+// but not every issue is a pull request. Some endpoints, events, and webhooks
+// may also return pull requests via this struct. If PullRequestLinks is nil,
+// this is an issue, and if PullRequestLinks is not nil, this is a pull request.
+// The IsPullRequest helper method can be used to check that.
+type Issue struct {
+	ID               *int64            `json:"id,omitempty"`
+	Number           *int              `json:"number,omitempty"`
+	State            *string           `json:"state,omitempty"`
+	Locked           *bool             `json:"locked,omitempty"`
+	Title            *string           `json:"title,omitempty"`
+	Body             *string           `json:"body,omitempty"`
+	User             *User             `json:"user,omitempty"`
+	Labels           []Label           `json:"labels,omitempty"`
+	Assignee         *User             `json:"assignee,omitempty"`
+	Comments         *int              `json:"comments,omitempty"`
+	ClosedAt         *time.Time        `json:"closed_at,omitempty"`
+	CreatedAt        *time.Time        `json:"created_at,omitempty"`
+	UpdatedAt        *time.Time        `json:"updated_at,omitempty"`
+	ClosedBy         *User             `json:"closed_by,omitempty"`
+	URL              *string           `json:"url,omitempty"`
+	HTMLURL          *string           `json:"html_url,omitempty"`
+	CommentsURL      *string           `json:"comments_url,omitempty"`
+	EventsURL        *string           `json:"events_url,omitempty"`
+	LabelsURL        *string           `json:"labels_url,omitempty"`
+	RepositoryURL    *string           `json:"repository_url,omitempty"`
+	Milestone        *Milestone        `json:"milestone,omitempty"`
+	PullRequestLinks *PullRequestLinks `json:"pull_request,omitempty"`
+	Repository       *Repository       `json:"repository,omitempty"`
+	Reactions        *Reactions        `json:"reactions,omitempty"`
+	Assignees        []*User           `json:"assignees,omitempty"`
+	NodeID           *string           `json:"node_id,omitempty"`
+
+	// TextMatches is only populated from search results that request text matches
+	// See: search.go and https://developer.github.com/v3/search/#text-match-metadata
+	TextMatches []TextMatch `json:"text_matches,omitempty"`
+}
+
+func (i Issue) String() string {
+	return Stringify(i)
+}
+
+// IsPullRequest reports whether the issue is also a pull request. It uses the
+// method recommended by GitHub's API documentation, which is to check whether
+// PullRequestLinks is non-nil.
+func (i Issue) IsPullRequest() bool {
+	return i.PullRequestLinks != nil
+}
+
+// IssueRequest represents a request to create/edit an issue.
+// It is separate from Issue above because otherwise Labels
+// and Assignee fail to serialize to the correct JSON.
+type IssueRequest struct {
+	Title     *string   `json:"title,omitempty"`
+	Body      *string   `json:"body,omitempty"`
+	Labels    *[]string `json:"labels,omitempty"`
+	Assignee  *string   `json:"assignee,omitempty"`
+	State     *string   `json:"state,omitempty"`
+	Milestone *int      `json:"milestone,omitempty"`
+	Assignees *[]string `json:"assignees,omitempty"`
+}
+
+// IssueListOptions specifies the optional parameters to the IssuesService.List
+// and IssuesService.ListByOrg methods.
+type IssueListOptions struct {
+	// Filter specifies which issues to list. Possible values are: assigned,
+	// created, mentioned, subscribed, all. Default is "assigned".
+	Filter string `url:"filter,omitempty"`
+
+	// State filters issues based on their state. Possible values are: open,
+	// closed, all. Default is "open".
+	State string `url:"state,omitempty"`
+
+	// Labels filters issues based on their label.
+	Labels []string `url:"labels,comma,omitempty"`
+
+	// Sort specifies how to sort issues. Possible values are: created, updated,
+	// and comments. Default value is "created".
+	Sort string `url:"sort,omitempty"`
+
+	// Direction in which to sort issues. Possible values are: asc, desc.
+	// Default is "desc".
+	Direction string `url:"direction,omitempty"`
+
+	// Since filters issues by time.
+	Since time.Time `url:"since,omitempty"`
+
+	ListOptions
+}
+
+// PullRequestLinks object is added to the Issue object when it's an issue included
+// in the IssueCommentEvent webhook payload, if the webhook is fired by a comment on a PR.
+type PullRequestLinks struct {
+	URL      *string `json:"url,omitempty"`
+	HTMLURL  *string `json:"html_url,omitempty"`
+	DiffURL  *string `json:"diff_url,omitempty"`
+	PatchURL *string `json:"patch_url,omitempty"`
+}
+
+// List the issues for the authenticated user. If all is true, list issues
+// across all the user's visible repositories including owned, member, and
+// organization repositories; if false, list only owned and member
+// repositories.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/#list-issues
+func (s *IssuesService) List(ctx context.Context, all bool, opt *IssueListOptions) ([]*Issue, *Response, error) {
+	var u string
+	if all {
+		u = "issues"
+	} else {
+		u = "user/issues"
+	}
+	return s.listIssues(ctx, u, opt)
+}
+
+// ListByOrg fetches the issues in the specified organization for the
+// authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/#list-issues
+func (s *IssuesService) ListByOrg(ctx context.Context, org string, opt *IssueListOptions) ([]*Issue, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/issues", org)
+	return s.listIssues(ctx, u, opt)
+}
+
+func (s *IssuesService) listIssues(ctx context.Context, u string, opt *IssueListOptions) ([]*Issue, *Response, error) {
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	var issues []*Issue
+	resp, err := s.client.Do(ctx, req, &issues)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return issues, resp, nil
+}
+
+// IssueListByRepoOptions specifies the optional parameters to the
+// IssuesService.ListByRepo method.
+type IssueListByRepoOptions struct {
+	// Milestone limits issues for the specified milestone. Possible values are
+	// a milestone number, "none" for issues with no milestone, "*" for issues
+	// with any milestone.
+	Milestone string `url:"milestone,omitempty"`
+
+	// State filters issues based on their state. Possible values are: open,
+	// closed, all. Default is "open".
+	State string `url:"state,omitempty"`
+
+	// Assignee filters issues based on their assignee. Possible values are a
+	// user name, "none" for issues that are not assigned, "*" for issues with
+	// any assigned user.
+	Assignee string `url:"assignee,omitempty"`
+
+	// Creator filters issues based on their creator.
+	Creator string `url:"creator,omitempty"`
+
+	// Mentioned filters issues to those mentioned a specific user.
+	Mentioned string `url:"mentioned,omitempty"`
+
+	// Labels filters issues based on their label.
+	Labels []string `url:"labels,omitempty,comma"`
+
+	// Sort specifies how to sort issues. Possible values are: created, updated,
+	// and comments. Default value is "created".
+	Sort string `url:"sort,omitempty"`
+
+	// Direction in which to sort issues. Possible values are: asc, desc.
+	// Default is "desc".
+	Direction string `url:"direction,omitempty"`
+
+	// Since filters issues by time.
+	Since time.Time `url:"since,omitempty"`
+
+	ListOptions
+}
+
+// ListByRepo lists the issues for the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/#list-issues-for-a-repository
+func (s *IssuesService) ListByRepo(ctx context.Context, owner string, repo string, opt *IssueListByRepoOptions) ([]*Issue, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	var issues []*Issue
+	resp, err := s.client.Do(ctx, req, &issues)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return issues, resp, nil
+}
+
+// Get a single issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/#get-a-single-issue
+func (s *IssuesService) Get(ctx context.Context, owner string, repo string, number int) (*Issue, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%d", owner, repo, number)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	issue := new(Issue)
+	resp, err := s.client.Do(ctx, req, issue)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return issue, resp, nil
+}
+
+// Create a new issue on the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/#create-an-issue
+func (s *IssuesService) Create(ctx context.Context, owner string, repo string, issue *IssueRequest) (*Issue, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues", owner, repo)
+	req, err := s.client.NewRequest("POST", u, issue)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	i := new(Issue)
+	resp, err := s.client.Do(ctx, req, i)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return i, resp, nil
+}
+
+// Edit an issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/#edit-an-issue
+func (s *IssuesService) Edit(ctx context.Context, owner string, repo string, number int, issue *IssueRequest) (*Issue, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%d", owner, repo, number)
+	req, err := s.client.NewRequest("PATCH", u, issue)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	i := new(Issue)
+	resp, err := s.client.Do(ctx, req, i)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return i, resp, nil
+}
+
+// Lock an issue's conversation.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/#lock-an-issue
+func (s *IssuesService) Lock(ctx context.Context, owner string, repo string, number int) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%d/lock", owner, repo, number)
+	req, err := s.client.NewRequest("PUT", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// Unlock an issue's conversation.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/#unlock-an-issue
+func (s *IssuesService) Unlock(ctx context.Context, owner string, repo string, number int) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%d/lock", owner, repo, number)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}

+ 85 - 0
vendor/github.com/google/go-github/github/issues_assignees.go

@@ -0,0 +1,85 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ListAssignees fetches all available assignees (owners and collaborators) to
+// which issues may be assigned.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/assignees/#list-assignees
+func (s *IssuesService) ListAssignees(ctx context.Context, owner, repo string, opt *ListOptions) ([]*User, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/assignees", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+	var assignees []*User
+	resp, err := s.client.Do(ctx, req, &assignees)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return assignees, resp, nil
+}
+
+// IsAssignee checks if a user is an assignee for the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/assignees/#check-assignee
+func (s *IssuesService) IsAssignee(ctx context.Context, owner, repo, user string) (bool, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/assignees/%v", owner, repo, user)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return false, nil, err
+	}
+	resp, err := s.client.Do(ctx, req, nil)
+	assignee, err := parseBoolResponse(err)
+	return assignee, resp, err
+}
+
+// AddAssignees adds the provided GitHub users as assignees to the issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/assignees/#add-assignees-to-an-issue
+func (s *IssuesService) AddAssignees(ctx context.Context, owner, repo string, number int, assignees []string) (*Issue, *Response, error) {
+	users := &struct {
+		Assignees []string `json:"assignees,omitempty"`
+	}{Assignees: assignees}
+	u := fmt.Sprintf("repos/%v/%v/issues/%v/assignees", owner, repo, number)
+	req, err := s.client.NewRequest("POST", u, users)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	issue := &Issue{}
+	resp, err := s.client.Do(ctx, req, issue)
+	return issue, resp, err
+}
+
+// RemoveAssignees removes the provided GitHub users as assignees from the issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/assignees/#remove-assignees-from-an-issue
+func (s *IssuesService) RemoveAssignees(ctx context.Context, owner, repo string, number int, assignees []string) (*Issue, *Response, error) {
+	users := &struct {
+		Assignees []string `json:"assignees,omitempty"`
+	}{Assignees: assignees}
+	u := fmt.Sprintf("repos/%v/%v/issues/%v/assignees", owner, repo, number)
+	req, err := s.client.NewRequest("DELETE", u, users)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	issue := &Issue{}
+	resp, err := s.client.Do(ctx, req, issue)
+	return issue, resp, err
+}

+ 148 - 0
vendor/github.com/google/go-github/github/issues_comments.go

@@ -0,0 +1,148 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// IssueComment represents a comment left on an issue.
+type IssueComment struct {
+	ID        *int64     `json:"id,omitempty"`
+	Body      *string    `json:"body,omitempty"`
+	User      *User      `json:"user,omitempty"`
+	Reactions *Reactions `json:"reactions,omitempty"`
+	CreatedAt *time.Time `json:"created_at,omitempty"`
+	UpdatedAt *time.Time `json:"updated_at,omitempty"`
+	URL       *string    `json:"url,omitempty"`
+	HTMLURL   *string    `json:"html_url,omitempty"`
+	IssueURL  *string    `json:"issue_url,omitempty"`
+}
+
+func (i IssueComment) String() string {
+	return Stringify(i)
+}
+
+// IssueListCommentsOptions specifies the optional parameters to the
+// IssuesService.ListComments method.
+type IssueListCommentsOptions struct {
+	// Sort specifies how to sort comments. Possible values are: created, updated.
+	Sort string `url:"sort,omitempty"`
+
+	// Direction in which to sort comments. Possible values are: asc, desc.
+	Direction string `url:"direction,omitempty"`
+
+	// Since filters comments by time.
+	Since time.Time `url:"since,omitempty"`
+
+	ListOptions
+}
+
+// ListComments lists all comments on the specified issue. Specifying an issue
+// number of 0 will return all comments on all issues for the repository.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/comments/#list-comments-on-an-issue
+func (s *IssuesService) ListComments(ctx context.Context, owner string, repo string, number int, opt *IssueListCommentsOptions) ([]*IssueComment, *Response, error) {
+	var u string
+	if number == 0 {
+		u = fmt.Sprintf("repos/%v/%v/issues/comments", owner, repo)
+	} else {
+		u = fmt.Sprintf("repos/%v/%v/issues/%d/comments", owner, repo, number)
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	var comments []*IssueComment
+	resp, err := s.client.Do(ctx, req, &comments)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return comments, resp, nil
+}
+
+// GetComment fetches the specified issue comment.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/comments/#get-a-single-comment
+func (s *IssuesService) GetComment(ctx context.Context, owner string, repo string, id int) (*IssueComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/comments/%d", owner, repo, id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	comment := new(IssueComment)
+	resp, err := s.client.Do(ctx, req, comment)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return comment, resp, nil
+}
+
+// CreateComment creates a new comment on the specified issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/comments/#create-a-comment
+func (s *IssuesService) CreateComment(ctx context.Context, owner string, repo string, number int, comment *IssueComment) (*IssueComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%d/comments", owner, repo, number)
+	req, err := s.client.NewRequest("POST", u, comment)
+	if err != nil {
+		return nil, nil, err
+	}
+	c := new(IssueComment)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// EditComment updates an issue comment.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/comments/#edit-a-comment
+func (s *IssuesService) EditComment(ctx context.Context, owner string, repo string, id int, comment *IssueComment) (*IssueComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/comments/%d", owner, repo, id)
+	req, err := s.client.NewRequest("PATCH", u, comment)
+	if err != nil {
+		return nil, nil, err
+	}
+	c := new(IssueComment)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// DeleteComment deletes an issue comment.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/comments/#delete-a-comment
+func (s *IssuesService) DeleteComment(ctx context.Context, owner string, repo string, id int) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/comments/%d", owner, repo, id)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}

+ 151 - 0
vendor/github.com/google/go-github/github/issues_events.go

@@ -0,0 +1,151 @@
+// Copyright 2014 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// IssueEvent represents an event that occurred around an Issue or Pull Request.
+type IssueEvent struct {
+	ID  *int64  `json:"id,omitempty"`
+	URL *string `json:"url,omitempty"`
+
+	// The User that generated this event.
+	Actor *User `json:"actor,omitempty"`
+
+	// Event identifies the actual type of Event that occurred. Possible
+	// values are:
+	//
+	//     closed
+	//       The Actor closed the issue.
+	//       If the issue was closed by commit message, CommitID holds the SHA1 hash of the commit.
+	//
+	//     merged
+	//       The Actor merged into master a branch containing a commit mentioning the issue.
+	//       CommitID holds the SHA1 of the merge commit.
+	//
+	//     referenced
+	//       The Actor committed to master a commit mentioning the issue in its commit message.
+	//       CommitID holds the SHA1 of the commit.
+	//
+	//     reopened, locked, unlocked
+	//       The Actor did that to the issue.
+	//
+	//     renamed
+	//       The Actor changed the issue title from Rename.From to Rename.To.
+	//
+	//     mentioned
+	//       Someone unspecified @mentioned the Actor [sic] in an issue comment body.
+	//
+	//     assigned, unassigned
+	//       The Assigner assigned the issue to or removed the assignment from the Assignee.
+	//
+	//     labeled, unlabeled
+	//       The Actor added or removed the Label from the issue.
+	//
+	//     milestoned, demilestoned
+	//       The Actor added or removed the issue from the Milestone.
+	//
+	//     subscribed, unsubscribed
+	//       The Actor subscribed to or unsubscribed from notifications for an issue.
+	//
+	//     head_ref_deleted, head_ref_restored
+	//       The pull request’s branch was deleted or restored.
+	//
+	Event *string `json:"event,omitempty"`
+
+	CreatedAt *time.Time `json:"created_at,omitempty"`
+	Issue     *Issue     `json:"issue,omitempty"`
+
+	// Only present on certain events; see above.
+	Assignee  *User      `json:"assignee,omitempty"`
+	Assigner  *User      `json:"assigner,omitempty"`
+	CommitID  *string    `json:"commit_id,omitempty"`
+	Milestone *Milestone `json:"milestone,omitempty"`
+	Label     *Label     `json:"label,omitempty"`
+	Rename    *Rename    `json:"rename,omitempty"`
+}
+
+// ListIssueEvents lists events for the specified issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/events/#list-events-for-an-issue
+func (s *IssuesService) ListIssueEvents(ctx context.Context, owner, repo string, number int, opt *ListOptions) ([]*IssueEvent, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%v/events", owner, repo, number)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var events []*IssueEvent
+	resp, err := s.client.Do(ctx, req, &events)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return events, resp, nil
+}
+
+// ListRepositoryEvents lists events for the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/events/#list-events-for-a-repository
+func (s *IssuesService) ListRepositoryEvents(ctx context.Context, owner, repo string, opt *ListOptions) ([]*IssueEvent, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/events", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var events []*IssueEvent
+	resp, err := s.client.Do(ctx, req, &events)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return events, resp, nil
+}
+
+// GetEvent returns the specified issue event.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/events/#get-a-single-event
+func (s *IssuesService) GetEvent(ctx context.Context, owner, repo string, id int64) (*IssueEvent, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/events/%v", owner, repo, id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	event := new(IssueEvent)
+	resp, err := s.client.Do(ctx, req, event)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return event, resp, nil
+}
+
+// Rename contains details for 'renamed' events.
+type Rename struct {
+	From *string `json:"from,omitempty"`
+	To   *string `json:"to,omitempty"`
+}
+
+func (r Rename) String() string {
+	return Stringify(r)
+}

+ 251 - 0
vendor/github.com/google/go-github/github/issues_labels.go

@@ -0,0 +1,251 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// Label represents a GitHub label on an Issue
+type Label struct {
+	ID     *int64  `json:"id,omitempty"`
+	URL    *string `json:"url,omitempty"`
+	Name   *string `json:"name,omitempty"`
+	Color  *string `json:"color,omitempty"`
+	NodeID *string `json:"node_id,omitempty"`
+}
+
+func (l Label) String() string {
+	return Stringify(l)
+}
+
+// ListLabels lists all labels for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/labels/#list-all-labels-for-this-repository
+func (s *IssuesService) ListLabels(ctx context.Context, owner string, repo string, opt *ListOptions) ([]*Label, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/labels", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	var labels []*Label
+	resp, err := s.client.Do(ctx, req, &labels)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return labels, resp, nil
+}
+
+// GetLabel gets a single label.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/labels/#get-a-single-label
+func (s *IssuesService) GetLabel(ctx context.Context, owner string, repo string, name string) (*Label, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/labels/%v", owner, repo, name)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	label := new(Label)
+	resp, err := s.client.Do(ctx, req, label)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return label, resp, nil
+}
+
+// CreateLabel creates a new label on the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/labels/#create-a-label
+func (s *IssuesService) CreateLabel(ctx context.Context, owner string, repo string, label *Label) (*Label, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/labels", owner, repo)
+	req, err := s.client.NewRequest("POST", u, label)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	l := new(Label)
+	resp, err := s.client.Do(ctx, req, l)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return l, resp, nil
+}
+
+// EditLabel edits a label.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/labels/#update-a-label
+func (s *IssuesService) EditLabel(ctx context.Context, owner string, repo string, name string, label *Label) (*Label, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/labels/%v", owner, repo, name)
+	req, err := s.client.NewRequest("PATCH", u, label)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	l := new(Label)
+	resp, err := s.client.Do(ctx, req, l)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return l, resp, nil
+}
+
+// DeleteLabel deletes a label.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/labels/#delete-a-label
+func (s *IssuesService) DeleteLabel(ctx context.Context, owner string, repo string, name string) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/labels/%v", owner, repo, name)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
+
+// ListLabelsByIssue lists all labels for an issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/labels/#list-labels-on-an-issue
+func (s *IssuesService) ListLabelsByIssue(ctx context.Context, owner string, repo string, number int, opt *ListOptions) ([]*Label, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	var labels []*Label
+	resp, err := s.client.Do(ctx, req, &labels)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return labels, resp, nil
+}
+
+// AddLabelsToIssue adds labels to an issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/labels/#add-labels-to-an-issue
+func (s *IssuesService) AddLabelsToIssue(ctx context.Context, owner string, repo string, number int, labels []string) ([]*Label, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number)
+	req, err := s.client.NewRequest("POST", u, labels)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	var l []*Label
+	resp, err := s.client.Do(ctx, req, &l)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return l, resp, nil
+}
+
+// RemoveLabelForIssue removes a label for an issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/labels/#remove-a-label-from-an-issue
+func (s *IssuesService) RemoveLabelForIssue(ctx context.Context, owner string, repo string, number int, label string) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%d/labels/%v", owner, repo, number, label)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
+
+// ReplaceLabelsForIssue replaces all labels for an issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/labels/#replace-all-labels-for-an-issue
+func (s *IssuesService) ReplaceLabelsForIssue(ctx context.Context, owner string, repo string, number int, labels []string) ([]*Label, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number)
+	req, err := s.client.NewRequest("PUT", u, labels)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	var l []*Label
+	resp, err := s.client.Do(ctx, req, &l)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return l, resp, nil
+}
+
+// RemoveLabelsForIssue removes all labels for an issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/labels/#remove-all-labels-from-an-issue
+func (s *IssuesService) RemoveLabelsForIssue(ctx context.Context, owner string, repo string, number int) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
+
+// ListLabelsForMilestone lists labels for every issue in a milestone.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/labels/#get-labels-for-every-issue-in-a-milestone
+func (s *IssuesService) ListLabelsForMilestone(ctx context.Context, owner string, repo string, number int, opt *ListOptions) ([]*Label, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/milestones/%d/labels", owner, repo, number)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	var labels []*Label
+	resp, err := s.client.Do(ctx, req, &labels)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return labels, resp, nil
+}

+ 160 - 0
vendor/github.com/google/go-github/github/issues_milestones.go

@@ -0,0 +1,160 @@
+// Copyright 2014 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// Milestone represents a GitHub repository milestone.
+type Milestone struct {
+	URL          *string    `json:"url,omitempty"`
+	HTMLURL      *string    `json:"html_url,omitempty"`
+	LabelsURL    *string    `json:"labels_url,omitempty"`
+	ID           *int64     `json:"id,omitempty"`
+	Number       *int       `json:"number,omitempty"`
+	State        *string    `json:"state,omitempty"`
+	Title        *string    `json:"title,omitempty"`
+	Description  *string    `json:"description,omitempty"`
+	Creator      *User      `json:"creator,omitempty"`
+	OpenIssues   *int       `json:"open_issues,omitempty"`
+	ClosedIssues *int       `json:"closed_issues,omitempty"`
+	CreatedAt    *time.Time `json:"created_at,omitempty"`
+	UpdatedAt    *time.Time `json:"updated_at,omitempty"`
+	ClosedAt     *time.Time `json:"closed_at,omitempty"`
+	DueOn        *time.Time `json:"due_on,omitempty"`
+	NodeID       *string    `json:"node_id,omitempty"`
+}
+
+func (m Milestone) String() string {
+	return Stringify(m)
+}
+
+// MilestoneListOptions specifies the optional parameters to the
+// IssuesService.ListMilestones method.
+type MilestoneListOptions struct {
+	// State filters milestones based on their state. Possible values are:
+	// open, closed, all. Default is "open".
+	State string `url:"state,omitempty"`
+
+	// Sort specifies how to sort milestones. Possible values are: due_on, completeness.
+	// Default value is "due_on".
+	Sort string `url:"sort,omitempty"`
+
+	// Direction in which to sort milestones. Possible values are: asc, desc.
+	// Default is "asc".
+	Direction string `url:"direction,omitempty"`
+
+	ListOptions
+}
+
+// ListMilestones lists all milestones for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/milestones/#list-milestones-for-a-repository
+func (s *IssuesService) ListMilestones(ctx context.Context, owner string, repo string, opt *MilestoneListOptions) ([]*Milestone, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/milestones", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	var milestones []*Milestone
+	resp, err := s.client.Do(ctx, req, &milestones)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return milestones, resp, nil
+}
+
+// GetMilestone gets a single milestone.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/milestones/#get-a-single-milestone
+func (s *IssuesService) GetMilestone(ctx context.Context, owner string, repo string, number int) (*Milestone, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/milestones/%d", owner, repo, number)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	milestone := new(Milestone)
+	resp, err := s.client.Do(ctx, req, milestone)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return milestone, resp, nil
+}
+
+// CreateMilestone creates a new milestone on the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/milestones/#create-a-milestone
+func (s *IssuesService) CreateMilestone(ctx context.Context, owner string, repo string, milestone *Milestone) (*Milestone, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/milestones", owner, repo)
+	req, err := s.client.NewRequest("POST", u, milestone)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	m := new(Milestone)
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// EditMilestone edits a milestone.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/milestones/#update-a-milestone
+func (s *IssuesService) EditMilestone(ctx context.Context, owner string, repo string, number int, milestone *Milestone) (*Milestone, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/milestones/%d", owner, repo, number)
+	req, err := s.client.NewRequest("PATCH", u, milestone)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	m := new(Milestone)
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// DeleteMilestone deletes a milestone.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/milestones/#delete-a-milestone
+func (s *IssuesService) DeleteMilestone(ctx context.Context, owner string, repo string, number int) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/milestones/%d", owner, repo, number)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}

+ 149 - 0
vendor/github.com/google/go-github/github/issues_timeline.go

@@ -0,0 +1,149 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// Timeline represents an event that occurred around an Issue or Pull Request.
+//
+// It is similar to an IssueEvent but may contain more information.
+// GitHub API docs: https://developer.github.com/v3/issues/timeline/
+type Timeline struct {
+	ID        *int64  `json:"id,omitempty"`
+	URL       *string `json:"url,omitempty"`
+	CommitURL *string `json:"commit_url,omitempty"`
+
+	// The User object that generated the event.
+	Actor *User `json:"actor,omitempty"`
+
+	// Event identifies the actual type of Event that occurred. Possible values
+	// are:
+	//
+	//     assigned
+	//       The issue was assigned to the assignee.
+	//
+	//     closed
+	//       The issue was closed by the actor. When the commit_id is present, it
+	//       identifies the commit that closed the issue using "closes / fixes #NN"
+	//       syntax.
+	//
+	//     commented
+	//       A comment was added to the issue.
+	//
+	//     committed
+	//       A commit was added to the pull request's 'HEAD' branch. Only provided
+	//       for pull requests.
+	//
+	//     cross-referenced
+	//       The issue was referenced from another issue. The 'source' attribute
+	//       contains the 'id', 'actor', and 'url' of the reference's source.
+	//
+	//     demilestoned
+	//       The issue was removed from a milestone.
+	//
+	//     head_ref_deleted
+	//       The pull request's branch was deleted.
+	//
+	//     head_ref_restored
+	//       The pull request's branch was restored.
+	//
+	//     labeled
+	//       A label was added to the issue.
+	//
+	//     locked
+	//       The issue was locked by the actor.
+	//
+	//     mentioned
+	//       The actor was @mentioned in an issue body.
+	//
+	//     merged
+	//       The issue was merged by the actor. The 'commit_id' attribute is the
+	//       SHA1 of the HEAD commit that was merged.
+	//
+	//     milestoned
+	//       The issue was added to a milestone.
+	//
+	//     referenced
+	//       The issue was referenced from a commit message. The 'commit_id'
+	//       attribute is the commit SHA1 of where that happened.
+	//
+	//     renamed
+	//       The issue title was changed.
+	//
+	//     reopened
+	//       The issue was reopened by the actor.
+	//
+	//     subscribed
+	//       The actor subscribed to receive notifications for an issue.
+	//
+	//     unassigned
+	//       The assignee was unassigned from the issue.
+	//
+	//     unlabeled
+	//       A label was removed from the issue.
+	//
+	//     unlocked
+	//       The issue was unlocked by the actor.
+	//
+	//     unsubscribed
+	//       The actor unsubscribed to stop receiving notifications for an issue.
+	//
+	Event *string `json:"event,omitempty"`
+
+	// The string SHA of a commit that referenced this Issue or Pull Request.
+	CommitID *string `json:"commit_id,omitempty"`
+	// The timestamp indicating when the event occurred.
+	CreatedAt *time.Time `json:"created_at,omitempty"`
+	// The Label object including `name` and `color` attributes. Only provided for
+	// 'labeled' and 'unlabeled' events.
+	Label *Label `json:"label,omitempty"`
+	// The User object which was assigned to (or unassigned from) this Issue or
+	// Pull Request. Only provided for 'assigned' and 'unassigned' events.
+	Assignee *User `json:"assignee,omitempty"`
+	// The Milestone object including a 'title' attribute.
+	// Only provided for 'milestoned' and 'demilestoned' events.
+	Milestone *Milestone `json:"milestone,omitempty"`
+	// The 'id', 'actor', and 'url' for the source of a reference from another issue.
+	// Only provided for 'cross-referenced' events.
+	Source *Source `json:"source,omitempty"`
+	// An object containing rename details including 'from' and 'to' attributes.
+	// Only provided for 'renamed' events.
+	Rename *Rename `json:"rename,omitempty"`
+}
+
+// Source represents a reference's source.
+type Source struct {
+	ID    *int64  `json:"id,omitempty"`
+	URL   *string `json:"url,omitempty"`
+	Actor *User   `json:"actor,omitempty"`
+}
+
+// ListIssueTimeline lists events for the specified issue.
+//
+// GitHub API docs: https://developer.github.com/v3/issues/timeline/#list-events-for-an-issue
+func (s *IssuesService) ListIssueTimeline(ctx context.Context, owner, repo string, number int, opt *ListOptions) ([]*Timeline, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%v/timeline", owner, repo, number)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeTimelinePreview)
+
+	var events []*Timeline
+	resp, err := s.client.Do(ctx, req, &events)
+	return events, resp, err
+}

+ 103 - 0
vendor/github.com/google/go-github/github/licenses.go

@@ -0,0 +1,103 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// LicensesService handles communication with the license related
+// methods of the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/licenses/
+type LicensesService service
+
+// RepositoryLicense represents the license for a repository.
+type RepositoryLicense struct {
+	Name *string `json:"name,omitempty"`
+	Path *string `json:"path,omitempty"`
+
+	SHA         *string  `json:"sha,omitempty"`
+	Size        *int     `json:"size,omitempty"`
+	URL         *string  `json:"url,omitempty"`
+	HTMLURL     *string  `json:"html_url,omitempty"`
+	GitURL      *string  `json:"git_url,omitempty"`
+	DownloadURL *string  `json:"download_url,omitempty"`
+	Type        *string  `json:"type,omitempty"`
+	Content     *string  `json:"content,omitempty"`
+	Encoding    *string  `json:"encoding,omitempty"`
+	License     *License `json:"license,omitempty"`
+}
+
+func (l RepositoryLicense) String() string {
+	return Stringify(l)
+}
+
+// License represents an open source license.
+type License struct {
+	Key  *string `json:"key,omitempty"`
+	Name *string `json:"name,omitempty"`
+	URL  *string `json:"url,omitempty"`
+
+	SPDXID         *string   `json:"spdx_id,omitempty"`
+	HTMLURL        *string   `json:"html_url,omitempty"`
+	Featured       *bool     `json:"featured,omitempty"`
+	Description    *string   `json:"description,omitempty"`
+	Implementation *string   `json:"implementation,omitempty"`
+	Permissions    *[]string `json:"permissions,omitempty"`
+	Conditions     *[]string `json:"conditions,omitempty"`
+	Limitations    *[]string `json:"limitations,omitempty"`
+	Body           *string   `json:"body,omitempty"`
+}
+
+func (l License) String() string {
+	return Stringify(l)
+}
+
+// List popular open source licenses.
+//
+// GitHub API docs: https://developer.github.com/v3/licenses/#list-all-licenses
+func (s *LicensesService) List(ctx context.Context) ([]*License, *Response, error) {
+	req, err := s.client.NewRequest("GET", "licenses", nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeLicensesPreview)
+
+	var licenses []*License
+	resp, err := s.client.Do(ctx, req, &licenses)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return licenses, resp, nil
+}
+
+// Get extended metadata for one license.
+//
+// GitHub API docs: https://developer.github.com/v3/licenses/#get-an-individual-license
+func (s *LicensesService) Get(ctx context.Context, licenseName string) (*License, *Response, error) {
+	u := fmt.Sprintf("licenses/%s", licenseName)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeLicensesPreview)
+
+	license := new(License)
+	resp, err := s.client.Do(ctx, req, license)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return license, resp, nil
+}

+ 245 - 0
vendor/github.com/google/go-github/github/messages.go

@@ -0,0 +1,245 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file provides functions for validating payloads from GitHub Webhooks.
+// GitHub API docs: https://developer.github.com/webhooks/securing/#validating-payloads-from-github
+
+package github
+
+import (
+	"crypto/hmac"
+	"crypto/sha1"
+	"crypto/sha256"
+	"crypto/sha512"
+	"encoding/hex"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"hash"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+	"strings"
+)
+
+const (
+	// sha1Prefix is the prefix used by GitHub before the HMAC hexdigest.
+	sha1Prefix = "sha1"
+	// sha256Prefix and sha512Prefix are provided for future compatibility.
+	sha256Prefix = "sha256"
+	sha512Prefix = "sha512"
+	// signatureHeader is the GitHub header key used to pass the HMAC hexdigest.
+	signatureHeader = "X-Hub-Signature"
+	// eventTypeHeader is the GitHub header key used to pass the event type.
+	eventTypeHeader = "X-Github-Event"
+	// deliveryIDHeader is the GitHub header key used to pass the unique ID for the webhook event.
+	deliveryIDHeader = "X-Github-Delivery"
+)
+
+var (
+	// eventTypeMapping maps webhooks types to their corresponding go-github struct types.
+	eventTypeMapping = map[string]string{
+		"commit_comment":              "CommitCommentEvent",
+		"create":                      "CreateEvent",
+		"delete":                      "DeleteEvent",
+		"deployment":                  "DeploymentEvent",
+		"deployment_status":           "DeploymentStatusEvent",
+		"fork":                        "ForkEvent",
+		"gollum":                      "GollumEvent",
+		"installation":                "InstallationEvent",
+		"installation_repositories":   "InstallationRepositoriesEvent",
+		"issue_comment":               "IssueCommentEvent",
+		"issues":                      "IssuesEvent",
+		"label":                       "LabelEvent",
+		"marketplace_purchase":        "MarketplacePurchaseEvent",
+		"member":                      "MemberEvent",
+		"membership":                  "MembershipEvent",
+		"milestone":                   "MilestoneEvent",
+		"organization":                "OrganizationEvent",
+		"org_block":                   "OrgBlockEvent",
+		"page_build":                  "PageBuildEvent",
+		"ping":                        "PingEvent",
+		"project":                     "ProjectEvent",
+		"project_card":                "ProjectCardEvent",
+		"project_column":              "ProjectColumnEvent",
+		"public":                      "PublicEvent",
+		"pull_request_review":         "PullRequestReviewEvent",
+		"pull_request_review_comment": "PullRequestReviewCommentEvent",
+		"pull_request":                "PullRequestEvent",
+		"push":                        "PushEvent",
+		"repository":                  "RepositoryEvent",
+		"release":                     "ReleaseEvent",
+		"status":                      "StatusEvent",
+		"team":                        "TeamEvent",
+		"team_add":                    "TeamAddEvent",
+		"watch":                       "WatchEvent",
+	}
+)
+
+// genMAC generates the HMAC signature for a message provided the secret key
+// and hashFunc.
+func genMAC(message, key []byte, hashFunc func() hash.Hash) []byte {
+	mac := hmac.New(hashFunc, key)
+	mac.Write(message)
+	return mac.Sum(nil)
+}
+
+// checkMAC reports whether messageMAC is a valid HMAC tag for message.
+func checkMAC(message, messageMAC, key []byte, hashFunc func() hash.Hash) bool {
+	expectedMAC := genMAC(message, key, hashFunc)
+	return hmac.Equal(messageMAC, expectedMAC)
+}
+
+// messageMAC returns the hex-decoded HMAC tag from the signature and its
+// corresponding hash function.
+func messageMAC(signature string) ([]byte, func() hash.Hash, error) {
+	if signature == "" {
+		return nil, nil, errors.New("missing signature")
+	}
+	sigParts := strings.SplitN(signature, "=", 2)
+	if len(sigParts) != 2 {
+		return nil, nil, fmt.Errorf("error parsing signature %q", signature)
+	}
+
+	var hashFunc func() hash.Hash
+	switch sigParts[0] {
+	case sha1Prefix:
+		hashFunc = sha1.New
+	case sha256Prefix:
+		hashFunc = sha256.New
+	case sha512Prefix:
+		hashFunc = sha512.New
+	default:
+		return nil, nil, fmt.Errorf("unknown hash type prefix: %q", sigParts[0])
+	}
+
+	buf, err := hex.DecodeString(sigParts[1])
+	if err != nil {
+		return nil, nil, fmt.Errorf("error decoding signature %q: %v", signature, err)
+	}
+	return buf, hashFunc, nil
+}
+
+// ValidatePayload validates an incoming GitHub Webhook event request
+// and returns the (JSON) payload.
+// The Content-Type header of the payload can be "application/json" or "application/x-www-form-urlencoded".
+// If the Content-Type is neither then an error is returned.
+// secretKey is the GitHub Webhook secret message.
+//
+// Example usage:
+//
+//     func (s *GitHubEventMonitor) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+//       payload, err := github.ValidatePayload(r, s.webhookSecretKey)
+//       if err != nil { ... }
+//       // Process payload...
+//     }
+//
+func ValidatePayload(r *http.Request, secretKey []byte) (payload []byte, err error) {
+	var body []byte // Raw body that GitHub uses to calculate the signature.
+
+	switch ct := r.Header.Get("Content-Type"); ct {
+	case "application/json":
+		var err error
+		if body, err = ioutil.ReadAll(r.Body); err != nil {
+			return nil, err
+		}
+
+		// If the content type is application/json,
+		// the JSON payload is just the original body.
+		payload = body
+
+	case "application/x-www-form-urlencoded":
+		// payloadFormParam is the name of the form parameter that the JSON payload
+		// will be in if a webhook has its content type set to application/x-www-form-urlencoded.
+		const payloadFormParam = "payload"
+
+		var err error
+		if body, err = ioutil.ReadAll(r.Body); err != nil {
+			return nil, err
+		}
+
+		// If the content type is application/x-www-form-urlencoded,
+		// the JSON payload will be under the "payload" form param.
+		form, err := url.ParseQuery(string(body))
+		if err != nil {
+			return nil, err
+		}
+		payload = []byte(form.Get(payloadFormParam))
+
+	default:
+		return nil, fmt.Errorf("Webhook request has unsupported Content-Type %q", ct)
+	}
+
+	sig := r.Header.Get(signatureHeader)
+	if err := validateSignature(sig, body, secretKey); err != nil {
+		return nil, err
+	}
+	return payload, nil
+}
+
+// validateSignature validates the signature for the given payload.
+// signature is the GitHub hash signature delivered in the X-Hub-Signature header.
+// payload is the JSON payload sent by GitHub Webhooks.
+// secretKey is the GitHub Webhook secret message.
+//
+// GitHub API docs: https://developer.github.com/webhooks/securing/#validating-payloads-from-github
+func validateSignature(signature string, payload, secretKey []byte) error {
+	messageMAC, hashFunc, err := messageMAC(signature)
+	if err != nil {
+		return err
+	}
+	if !checkMAC(payload, messageMAC, secretKey, hashFunc) {
+		return errors.New("payload signature check failed")
+	}
+	return nil
+}
+
+// WebHookType returns the event type of webhook request r.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/hooks/#webhook-headers
+func WebHookType(r *http.Request) string {
+	return r.Header.Get(eventTypeHeader)
+}
+
+// DeliveryID returns the unique delivery ID of webhook request r.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/hooks/#webhook-headers
+func DeliveryID(r *http.Request) string {
+	return r.Header.Get(deliveryIDHeader)
+}
+
+// ParseWebHook parses the event payload. For recognized event types, a
+// value of the corresponding struct type will be returned (as returned
+// by Event.ParsePayload()). An error will be returned for unrecognized event
+// types.
+//
+// Example usage:
+//
+//     func (s *GitHubEventMonitor) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+//       payload, err := github.ValidatePayload(r, s.webhookSecretKey)
+//       if err != nil { ... }
+//       event, err := github.ParseWebHook(github.WebHookType(r), payload)
+//       if err != nil { ... }
+//       switch event := event.(type) {
+//       case *github.CommitCommentEvent:
+//           processCommitCommentEvent(event)
+//       case *github.CreateEvent:
+//           processCreateEvent(event)
+//       ...
+//       }
+//     }
+//
+func ParseWebHook(messageType string, payload []byte) (interface{}, error) {
+	eventType, ok := eventTypeMapping[messageType]
+	if !ok {
+		return nil, fmt.Errorf("unknown X-Github-Event in message: %v", messageType)
+	}
+
+	event := Event{
+		Type:       &eventType,
+		RawPayload: (*json.RawMessage)(&payload),
+	}
+	return event.ParsePayload()
+}

+ 224 - 0
vendor/github.com/google/go-github/github/migrations.go

@@ -0,0 +1,224 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"net/http"
+	"strings"
+)
+
+// MigrationService provides access to the migration related functions
+// in the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/
+type MigrationService service
+
+// Migration represents a GitHub migration (archival).
+type Migration struct {
+	ID   *int64  `json:"id,omitempty"`
+	GUID *string `json:"guid,omitempty"`
+	// State is the current state of a migration.
+	// Possible values are:
+	//     "pending" which means the migration hasn't started yet,
+	//     "exporting" which means the migration is in progress,
+	//     "exported" which means the migration finished successfully, or
+	//     "failed" which means the migration failed.
+	State *string `json:"state,omitempty"`
+	// LockRepositories indicates whether repositories are locked (to prevent
+	// manipulation) while migrating data.
+	LockRepositories *bool `json:"lock_repositories,omitempty"`
+	// ExcludeAttachments indicates whether attachments should be excluded from
+	// the migration (to reduce migration archive file size).
+	ExcludeAttachments *bool         `json:"exclude_attachments,omitempty"`
+	URL                *string       `json:"url,omitempty"`
+	CreatedAt          *string       `json:"created_at,omitempty"`
+	UpdatedAt          *string       `json:"updated_at,omitempty"`
+	Repositories       []*Repository `json:"repositories,omitempty"`
+}
+
+func (m Migration) String() string {
+	return Stringify(m)
+}
+
+// MigrationOptions specifies the optional parameters to Migration methods.
+type MigrationOptions struct {
+	// LockRepositories indicates whether repositories should be locked (to prevent
+	// manipulation) while migrating data.
+	LockRepositories bool
+
+	// ExcludeAttachments indicates whether attachments should be excluded from
+	// the migration (to reduce migration archive file size).
+	ExcludeAttachments bool
+}
+
+// startMigration represents the body of a StartMigration request.
+type startMigration struct {
+	// Repositories is a slice of repository names to migrate.
+	Repositories []string `json:"repositories,omitempty"`
+
+	// LockRepositories indicates whether repositories should be locked (to prevent
+	// manipulation) while migrating data.
+	LockRepositories *bool `json:"lock_repositories,omitempty"`
+
+	// ExcludeAttachments indicates whether attachments should be excluded from
+	// the migration (to reduce migration archive file size).
+	ExcludeAttachments *bool `json:"exclude_attachments,omitempty"`
+}
+
+// StartMigration starts the generation of a migration archive.
+// repos is a slice of repository names to migrate.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/migrations/#start-a-migration
+func (s *MigrationService) StartMigration(ctx context.Context, org string, repos []string, opt *MigrationOptions) (*Migration, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/migrations", org)
+
+	body := &startMigration{Repositories: repos}
+	if opt != nil {
+		body.LockRepositories = Bool(opt.LockRepositories)
+		body.ExcludeAttachments = Bool(opt.ExcludeAttachments)
+	}
+
+	req, err := s.client.NewRequest("POST", u, body)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMigrationsPreview)
+
+	m := &Migration{}
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// ListMigrations lists the most recent migrations.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/migrations/#get-a-list-of-migrations
+func (s *MigrationService) ListMigrations(ctx context.Context, org string) ([]*Migration, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/migrations", org)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMigrationsPreview)
+
+	var m []*Migration
+	resp, err := s.client.Do(ctx, req, &m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// MigrationStatus gets the status of a specific migration archive.
+// id is the migration ID.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/migrations/#get-the-status-of-a-migration
+func (s *MigrationService) MigrationStatus(ctx context.Context, org string, id int64) (*Migration, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/migrations/%v", org, id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMigrationsPreview)
+
+	m := &Migration{}
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// MigrationArchiveURL fetches a migration archive URL.
+// id is the migration ID.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/migrations/#download-a-migration-archive
+func (s *MigrationService) MigrationArchiveURL(ctx context.Context, org string, id int64) (url string, err error) {
+	u := fmt.Sprintf("orgs/%v/migrations/%v/archive", org, id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return "", err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMigrationsPreview)
+
+	s.client.clientMu.Lock()
+	defer s.client.clientMu.Unlock()
+
+	// Disable the redirect mechanism because AWS fails if the GitHub auth token is provided.
+	var loc string
+	saveRedirect := s.client.client.CheckRedirect
+	s.client.client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
+		loc = req.URL.String()
+		return errors.New("disable redirect")
+	}
+	defer func() { s.client.client.CheckRedirect = saveRedirect }()
+
+	_, err = s.client.Do(ctx, req, nil) // expect error from disable redirect
+	if err == nil {
+		return "", errors.New("expected redirect, none provided")
+	}
+	if !strings.Contains(err.Error(), "disable redirect") {
+		return "", err
+	}
+	return loc, nil
+}
+
+// DeleteMigration deletes a previous migration archive.
+// id is the migration ID.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/migrations/#delete-a-migration-archive
+func (s *MigrationService) DeleteMigration(ctx context.Context, org string, id int64) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/migrations/%v/archive", org, id)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMigrationsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// UnlockRepo unlocks a repository that was locked for migration.
+// id is the migration ID.
+// You should unlock each migrated repository and delete them when the migration
+// is complete and you no longer need the source data.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/migrations/#unlock-a-repository
+func (s *MigrationService) UnlockRepo(ctx context.Context, org string, id int64, repo string) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/migrations/%v/repos/%v/lock", org, id, repo)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMigrationsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}

+ 329 - 0
vendor/github.com/google/go-github/github/migrations_source_import.go

@@ -0,0 +1,329 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// Import represents a repository import request.
+type Import struct {
+	// The URL of the originating repository.
+	VCSURL *string `json:"vcs_url,omitempty"`
+	// The originating VCS type. Can be one of 'subversion', 'git',
+	// 'mercurial', or 'tfvc'. Without this parameter, the import job will
+	// take additional time to detect the VCS type before beginning the
+	// import. This detection step will be reflected in the response.
+	VCS *string `json:"vcs,omitempty"`
+	// VCSUsername and VCSPassword are only used for StartImport calls that
+	// are importing a password-protected repository.
+	VCSUsername *string `json:"vcs_username,omitempty"`
+	VCSPassword *string `json:"vcs_password,omitempty"`
+	// For a tfvc import, the name of the project that is being imported.
+	TFVCProject *string `json:"tfvc_project,omitempty"`
+
+	// LFS related fields that may be preset in the Import Progress response
+
+	// Describes whether the import has been opted in or out of using Git
+	// LFS. The value can be 'opt_in', 'opt_out', or 'undecided' if no
+	// action has been taken.
+	UseLFS *string `json:"use_lfs,omitempty"`
+	// Describes whether files larger than 100MB were found during the
+	// importing step.
+	HasLargeFiles *bool `json:"has_large_files,omitempty"`
+	// The total size in gigabytes of files larger than 100MB found in the
+	// originating repository.
+	LargeFilesSize *int `json:"large_files_size,omitempty"`
+	// The total number of files larger than 100MB found in the originating
+	// repository. To see a list of these files, call LargeFiles.
+	LargeFilesCount *int `json:"large_files_count,omitempty"`
+
+	// Identifies the current status of an import. An import that does not
+	// have errors will progress through these steps:
+	//
+	//     detecting - the "detection" step of the import is in progress
+	//         because the request did not include a VCS parameter. The
+	//         import is identifying the type of source control present at
+	//         the URL.
+	//     importing - the "raw" step of the import is in progress. This is
+	//         where commit data is fetched from the original repository.
+	//         The import progress response will include CommitCount (the
+	//         total number of raw commits that will be imported) and
+	//         Percent (0 - 100, the current progress through the import).
+	//     mapping - the "rewrite" step of the import is in progress. This
+	//         is where SVN branches are converted to Git branches, and
+	//         where author updates are applied. The import progress
+	//         response does not include progress information.
+	//     pushing - the "push" step of the import is in progress. This is
+	//         where the importer updates the repository on GitHub. The
+	//         import progress response will include PushPercent, which is
+	//         the percent value reported by git push when it is "Writing
+	//         objects".
+	//     complete - the import is complete, and the repository is ready
+	//         on GitHub.
+	//
+	// If there are problems, you will see one of these in the status field:
+	//
+	//     auth_failed - the import requires authentication in order to
+	//         connect to the original repository. Make an UpdateImport
+	//         request, and include VCSUsername and VCSPassword.
+	//     error - the import encountered an error. The import progress
+	//         response will include the FailedStep and an error message.
+	//         Contact GitHub support for more information.
+	//     detection_needs_auth - the importer requires authentication for
+	//         the originating repository to continue detection. Make an
+	//         UpdatImport request, and include VCSUsername and
+	//         VCSPassword.
+	//     detection_found_nothing - the importer didn't recognize any
+	//         source control at the URL.
+	//     detection_found_multiple - the importer found several projects
+	//         or repositories at the provided URL. When this is the case,
+	//         the Import Progress response will also include a
+	//         ProjectChoices field with the possible project choices as
+	//         values. Make an UpdateImport request, and include VCS and
+	//         (if applicable) TFVCProject.
+	Status        *string `json:"status,omitempty"`
+	CommitCount   *int    `json:"commit_count,omitempty"`
+	StatusText    *string `json:"status_text,omitempty"`
+	AuthorsCount  *int    `json:"authors_count,omitempty"`
+	Percent       *int    `json:"percent,omitempty"`
+	PushPercent   *int    `json:"push_percent,omitempty"`
+	URL           *string `json:"url,omitempty"`
+	HTMLURL       *string `json:"html_url,omitempty"`
+	AuthorsURL    *string `json:"authors_url,omitempty"`
+	RepositoryURL *string `json:"repository_url,omitempty"`
+	Message       *string `json:"message,omitempty"`
+	FailedStep    *string `json:"failed_step,omitempty"`
+
+	// Human readable display name, provided when the Import appears as
+	// part of ProjectChoices.
+	HumanName *string `json:"human_name,omitempty"`
+
+	// When the importer finds several projects or repositories at the
+	// provided URLs, this will identify the available choices. Call
+	// UpdateImport with the selected Import value.
+	ProjectChoices []Import `json:"project_choices,omitempty"`
+}
+
+func (i Import) String() string {
+	return Stringify(i)
+}
+
+// SourceImportAuthor identifies an author imported from a source repository.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#get-commit-authors
+type SourceImportAuthor struct {
+	ID         *int64  `json:"id,omitempty"`
+	RemoteID   *string `json:"remote_id,omitempty"`
+	RemoteName *string `json:"remote_name,omitempty"`
+	Email      *string `json:"email,omitempty"`
+	Name       *string `json:"name,omitempty"`
+	URL        *string `json:"url,omitempty"`
+	ImportURL  *string `json:"import_url,omitempty"`
+}
+
+func (a SourceImportAuthor) String() string {
+	return Stringify(a)
+}
+
+// LargeFile identifies a file larger than 100MB found during a repository import.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#get-large-files
+type LargeFile struct {
+	RefName *string `json:"ref_name,omitempty"`
+	Path    *string `json:"path,omitempty"`
+	OID     *string `json:"oid,omitempty"`
+	Size    *int    `json:"size,omitempty"`
+}
+
+func (f LargeFile) String() string {
+	return Stringify(f)
+}
+
+// StartImport initiates a repository import.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#start-an-import
+func (s *MigrationService) StartImport(ctx context.Context, owner, repo string, in *Import) (*Import, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/import", owner, repo)
+	req, err := s.client.NewRequest("PUT", u, in)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeImportPreview)
+
+	out := new(Import)
+	resp, err := s.client.Do(ctx, req, out)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return out, resp, nil
+}
+
+// ImportProgress queries for the status and progress of an ongoing repository import.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#get-import-progress
+func (s *MigrationService) ImportProgress(ctx context.Context, owner, repo string) (*Import, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/import", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeImportPreview)
+
+	out := new(Import)
+	resp, err := s.client.Do(ctx, req, out)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return out, resp, nil
+}
+
+// UpdateImport initiates a repository import.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#update-existing-import
+func (s *MigrationService) UpdateImport(ctx context.Context, owner, repo string, in *Import) (*Import, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/import", owner, repo)
+	req, err := s.client.NewRequest("PATCH", u, in)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeImportPreview)
+
+	out := new(Import)
+	resp, err := s.client.Do(ctx, req, out)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return out, resp, nil
+}
+
+// CommitAuthors gets the authors mapped from the original repository.
+//
+// Each type of source control system represents authors in a different way.
+// For example, a Git commit author has a display name and an email address,
+// but a Subversion commit author just has a username. The GitHub Importer will
+// make the author information valid, but the author might not be correct. For
+// example, it will change the bare Subversion username "hubot" into something
+// like "hubot <hubot@12341234-abab-fefe-8787-fedcba987654>".
+//
+// This method and MapCommitAuthor allow you to provide correct Git author
+// information.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#get-commit-authors
+func (s *MigrationService) CommitAuthors(ctx context.Context, owner, repo string) ([]*SourceImportAuthor, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/import/authors", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeImportPreview)
+
+	var authors []*SourceImportAuthor
+	resp, err := s.client.Do(ctx, req, &authors)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return authors, resp, nil
+}
+
+// MapCommitAuthor updates an author's identity for the import. Your
+// application can continue updating authors any time before you push new
+// commits to the repository.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#map-a-commit-author
+func (s *MigrationService) MapCommitAuthor(ctx context.Context, owner, repo string, id int64, author *SourceImportAuthor) (*SourceImportAuthor, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/import/authors/%v", owner, repo, id)
+	req, err := s.client.NewRequest("PATCH", u, author)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeImportPreview)
+
+	out := new(SourceImportAuthor)
+	resp, err := s.client.Do(ctx, req, out)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return out, resp, nil
+}
+
+// SetLFSPreference sets whether imported repositories should use Git LFS for
+// files larger than 100MB. Only the UseLFS field on the provided Import is
+// used.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#set-git-lfs-preference
+func (s *MigrationService) SetLFSPreference(ctx context.Context, owner, repo string, in *Import) (*Import, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/import/lfs", owner, repo)
+	req, err := s.client.NewRequest("PATCH", u, in)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeImportPreview)
+
+	out := new(Import)
+	resp, err := s.client.Do(ctx, req, out)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return out, resp, nil
+}
+
+// LargeFiles lists files larger than 100MB found during the import.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#get-large-files
+func (s *MigrationService) LargeFiles(ctx context.Context, owner, repo string) ([]*LargeFile, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/import/large_files", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeImportPreview)
+
+	var files []*LargeFile
+	resp, err := s.client.Do(ctx, req, &files)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return files, resp, nil
+}
+
+// CancelImport stops an import for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#cancel-an-import
+func (s *MigrationService) CancelImport(ctx context.Context, owner, repo string) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/import", owner, repo)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeImportPreview)
+
+	return s.client.Do(ctx, req, nil)
+}

+ 253 - 0
vendor/github.com/google/go-github/github/misc.go

@@ -0,0 +1,253 @@
+// Copyright 2014 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"net/url"
+)
+
+// MarkdownOptions specifies optional parameters to the Markdown method.
+type MarkdownOptions struct {
+	// Mode identifies the rendering mode. Possible values are:
+	//   markdown - render a document as plain Markdown, just like
+	//   README files are rendered.
+	//
+	//   gfm - to render a document as user-content, e.g. like user
+	//   comments or issues are rendered. In GFM mode, hard line breaks are
+	//   always taken into account, and issue and user mentions are linked
+	//   accordingly.
+	//
+	// Default is "markdown".
+	Mode string
+
+	// Context identifies the repository context. Only taken into account
+	// when rendering as "gfm".
+	Context string
+}
+
+type markdownRequest struct {
+	Text    *string `json:"text,omitempty"`
+	Mode    *string `json:"mode,omitempty"`
+	Context *string `json:"context,omitempty"`
+}
+
+// Markdown renders an arbitrary Markdown document.
+//
+// GitHub API docs: https://developer.github.com/v3/markdown/
+func (c *Client) Markdown(ctx context.Context, text string, opt *MarkdownOptions) (string, *Response, error) {
+	request := &markdownRequest{Text: String(text)}
+	if opt != nil {
+		if opt.Mode != "" {
+			request.Mode = String(opt.Mode)
+		}
+		if opt.Context != "" {
+			request.Context = String(opt.Context)
+		}
+	}
+
+	req, err := c.NewRequest("POST", "markdown", request)
+	if err != nil {
+		return "", nil, err
+	}
+
+	buf := new(bytes.Buffer)
+	resp, err := c.Do(ctx, req, buf)
+	if err != nil {
+		return "", resp, err
+	}
+
+	return buf.String(), resp, nil
+}
+
+// ListEmojis returns the emojis available to use on GitHub.
+//
+// GitHub API docs: https://developer.github.com/v3/emojis/
+func (c *Client) ListEmojis(ctx context.Context) (map[string]string, *Response, error) {
+	req, err := c.NewRequest("GET", "emojis", nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var emoji map[string]string
+	resp, err := c.Do(ctx, req, &emoji)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return emoji, resp, nil
+}
+
+// CodeOfConduct represents a code of conduct.
+type CodeOfConduct struct {
+	Name *string `json:"name,omitempty"`
+	Key  *string `json:"key,omitempty"`
+	URL  *string `json:"url,omitempty"`
+	Body *string `json:"body,omitempty"`
+}
+
+func (c *CodeOfConduct) String() string {
+	return Stringify(c)
+}
+
+// ListCodesOfConduct returns all codes of conduct.
+//
+// GitHub API docs: https://developer.github.com/v3/codes_of_conduct/#list-all-codes-of-conduct
+func (c *Client) ListCodesOfConduct(ctx context.Context) ([]*CodeOfConduct, *Response, error) {
+	req, err := c.NewRequest("GET", "codes_of_conduct", nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeCodesOfConductPreview)
+
+	var cs []*CodeOfConduct
+	resp, err := c.Do(ctx, req, &cs)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return cs, resp, nil
+}
+
+// GetCodeOfConduct returns an individual code of conduct.
+//
+// https://developer.github.com/v3/codes_of_conduct/#get-an-individual-code-of-conduct
+func (c *Client) GetCodeOfConduct(ctx context.Context, key string) (*CodeOfConduct, *Response, error) {
+	u := fmt.Sprintf("codes_of_conduct/%s", key)
+	req, err := c.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeCodesOfConductPreview)
+
+	coc := new(CodeOfConduct)
+	resp, err := c.Do(ctx, req, coc)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return coc, resp, nil
+}
+
+// APIMeta represents metadata about the GitHub API.
+type APIMeta struct {
+	// An Array of IP addresses in CIDR format specifying the addresses
+	// that incoming service hooks will originate from on GitHub.com.
+	Hooks []string `json:"hooks,omitempty"`
+
+	// An Array of IP addresses in CIDR format specifying the Git servers
+	// for GitHub.com.
+	Git []string `json:"git,omitempty"`
+
+	// Whether authentication with username and password is supported.
+	// (GitHub Enterprise instances using CAS or OAuth for authentication
+	// will return false. Features like Basic Authentication with a
+	// username and password, sudo mode, and two-factor authentication are
+	// not supported on these servers.)
+	VerifiablePasswordAuthentication *bool `json:"verifiable_password_authentication,omitempty"`
+
+	// An array of IP addresses in CIDR format specifying the addresses
+	// which serve GitHub Pages websites.
+	Pages []string `json:"pages,omitempty"`
+}
+
+// APIMeta returns information about GitHub.com, the service. Or, if you access
+// this endpoint on your organization’s GitHub Enterprise installation, this
+// endpoint provides information about that installation.
+//
+// GitHub API docs: https://developer.github.com/v3/meta/
+func (c *Client) APIMeta(ctx context.Context) (*APIMeta, *Response, error) {
+	req, err := c.NewRequest("GET", "meta", nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	meta := new(APIMeta)
+	resp, err := c.Do(ctx, req, meta)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return meta, resp, nil
+}
+
+// Octocat returns an ASCII art octocat with the specified message in a speech
+// bubble. If message is empty, a random zen phrase is used.
+func (c *Client) Octocat(ctx context.Context, message string) (string, *Response, error) {
+	u := "octocat"
+	if message != "" {
+		u = fmt.Sprintf("%s?s=%s", u, url.QueryEscape(message))
+	}
+
+	req, err := c.NewRequest("GET", u, nil)
+	if err != nil {
+		return "", nil, err
+	}
+
+	buf := new(bytes.Buffer)
+	resp, err := c.Do(ctx, req, buf)
+	if err != nil {
+		return "", resp, err
+	}
+
+	return buf.String(), resp, nil
+}
+
+// Zen returns a random line from The Zen of GitHub.
+//
+// see also: http://warpspire.com/posts/taste/
+func (c *Client) Zen(ctx context.Context) (string, *Response, error) {
+	req, err := c.NewRequest("GET", "zen", nil)
+	if err != nil {
+		return "", nil, err
+	}
+
+	buf := new(bytes.Buffer)
+	resp, err := c.Do(ctx, req, buf)
+	if err != nil {
+		return "", resp, err
+	}
+
+	return buf.String(), resp, nil
+}
+
+// ServiceHook represents a hook that has configuration settings, a list of
+// available events, and default events.
+type ServiceHook struct {
+	Name            *string    `json:"name,omitempty"`
+	Events          []string   `json:"events,omitempty"`
+	SupportedEvents []string   `json:"supported_events,omitempty"`
+	Schema          [][]string `json:"schema,omitempty"`
+}
+
+func (s *ServiceHook) String() string {
+	return Stringify(s)
+}
+
+// ListServiceHooks lists all of the available service hooks.
+//
+// GitHub API docs: https://developer.github.com/webhooks/#services
+func (c *Client) ListServiceHooks(ctx context.Context) ([]*ServiceHook, *Response, error) {
+	u := "hooks"
+	req, err := c.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var hooks []*ServiceHook
+	resp, err := c.Do(ctx, req, &hooks)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return hooks, resp, nil
+}

+ 209 - 0
vendor/github.com/google/go-github/github/orgs.go

@@ -0,0 +1,209 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// OrganizationsService provides access to the organization related functions
+// in the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/
+type OrganizationsService service
+
+// Organization represents a GitHub organization account.
+type Organization struct {
+	Login             *string    `json:"login,omitempty"`
+	ID                *int64     `json:"id,omitempty"`
+	AvatarURL         *string    `json:"avatar_url,omitempty"`
+	HTMLURL           *string    `json:"html_url,omitempty"`
+	Name              *string    `json:"name,omitempty"`
+	Company           *string    `json:"company,omitempty"`
+	Blog              *string    `json:"blog,omitempty"`
+	Location          *string    `json:"location,omitempty"`
+	Email             *string    `json:"email,omitempty"`
+	Description       *string    `json:"description,omitempty"`
+	PublicRepos       *int       `json:"public_repos,omitempty"`
+	PublicGists       *int       `json:"public_gists,omitempty"`
+	Followers         *int       `json:"followers,omitempty"`
+	Following         *int       `json:"following,omitempty"`
+	CreatedAt         *time.Time `json:"created_at,omitempty"`
+	UpdatedAt         *time.Time `json:"updated_at,omitempty"`
+	TotalPrivateRepos *int       `json:"total_private_repos,omitempty"`
+	OwnedPrivateRepos *int       `json:"owned_private_repos,omitempty"`
+	PrivateGists      *int       `json:"private_gists,omitempty"`
+	DiskUsage         *int       `json:"disk_usage,omitempty"`
+	Collaborators     *int       `json:"collaborators,omitempty"`
+	BillingEmail      *string    `json:"billing_email,omitempty"`
+	Type              *string    `json:"type,omitempty"`
+	Plan              *Plan      `json:"plan,omitempty"`
+	NodeID            *string    `json:"node_id,omitempty"`
+
+	// API URLs
+	URL              *string `json:"url,omitempty"`
+	EventsURL        *string `json:"events_url,omitempty"`
+	HooksURL         *string `json:"hooks_url,omitempty"`
+	IssuesURL        *string `json:"issues_url,omitempty"`
+	MembersURL       *string `json:"members_url,omitempty"`
+	PublicMembersURL *string `json:"public_members_url,omitempty"`
+	ReposURL         *string `json:"repos_url,omitempty"`
+}
+
+func (o Organization) String() string {
+	return Stringify(o)
+}
+
+// Plan represents the payment plan for an account. See plans at https://github.com/plans.
+type Plan struct {
+	Name          *string `json:"name,omitempty"`
+	Space         *int    `json:"space,omitempty"`
+	Collaborators *int    `json:"collaborators,omitempty"`
+	PrivateRepos  *int    `json:"private_repos,omitempty"`
+}
+
+func (p Plan) String() string {
+	return Stringify(p)
+}
+
+// OrganizationsListOptions specifies the optional parameters to the
+// OrganizationsService.ListAll method.
+type OrganizationsListOptions struct {
+	// Since filters Organizations by ID.
+	Since int `url:"since,omitempty"`
+
+	ListOptions
+}
+
+// ListAll lists all organizations, in the order that they were created on GitHub.
+//
+// Note: Pagination is powered exclusively by the since parameter. To continue
+// listing the next set of organizations, use the ID of the last-returned organization
+// as the opts.Since parameter for the next call.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/#list-all-organizations
+func (s *OrganizationsService) ListAll(ctx context.Context, opt *OrganizationsListOptions) ([]*Organization, *Response, error) {
+	u, err := addOptions("organizations", opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	orgs := []*Organization{}
+	resp, err := s.client.Do(ctx, req, &orgs)
+	if err != nil {
+		return nil, resp, err
+	}
+	return orgs, resp, nil
+}
+
+// List the organizations for a user. Passing the empty string will list
+// organizations for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/#list-user-organizations
+func (s *OrganizationsService) List(ctx context.Context, user string, opt *ListOptions) ([]*Organization, *Response, error) {
+	var u string
+	if user != "" {
+		u = fmt.Sprintf("users/%v/orgs", user)
+	} else {
+		u = "user/orgs"
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	var orgs []*Organization
+	resp, err := s.client.Do(ctx, req, &orgs)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return orgs, resp, nil
+}
+
+// Get fetches an organization by name.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/#get-an-organization
+func (s *OrganizationsService) Get(ctx context.Context, org string) (*Organization, *Response, error) {
+	u := fmt.Sprintf("orgs/%v", org)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	organization := new(Organization)
+	resp, err := s.client.Do(ctx, req, organization)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return organization, resp, nil
+}
+
+// GetByID fetches an organization.
+//
+// Note: GetByID uses the undocumented GitHub API endpoint /organizations/:id.
+func (s *OrganizationsService) GetByID(ctx context.Context, id int64) (*Organization, *Response, error) {
+	u := fmt.Sprintf("organizations/%d", id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	organization := new(Organization)
+	resp, err := s.client.Do(ctx, req, organization)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return organization, resp, nil
+}
+
+// Edit an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/#edit-an-organization
+func (s *OrganizationsService) Edit(ctx context.Context, name string, org *Organization) (*Organization, *Response, error) {
+	u := fmt.Sprintf("orgs/%v", name)
+	req, err := s.client.NewRequest("PATCH", u, org)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	o := new(Organization)
+	resp, err := s.client.Do(ctx, req, o)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return o, resp, nil
+}

+ 107 - 0
vendor/github.com/google/go-github/github/orgs_hooks.go

@@ -0,0 +1,107 @@
+// Copyright 2015 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ListHooks lists all Hooks for the specified organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#list-hooks
+func (s *OrganizationsService) ListHooks(ctx context.Context, org string, opt *ListOptions) ([]*Hook, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/hooks", org)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var hooks []*Hook
+	resp, err := s.client.Do(ctx, req, &hooks)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return hooks, resp, nil
+}
+
+// GetHook returns a single specified Hook.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#get-single-hook
+func (s *OrganizationsService) GetHook(ctx context.Context, org string, id int) (*Hook, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/hooks/%d", org, id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+	hook := new(Hook)
+	resp, err := s.client.Do(ctx, req, hook)
+	return hook, resp, err
+}
+
+// CreateHook creates a Hook for the specified org.
+// Name and Config are required fields.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#create-a-hook
+func (s *OrganizationsService) CreateHook(ctx context.Context, org string, hook *Hook) (*Hook, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/hooks", org)
+	req, err := s.client.NewRequest("POST", u, hook)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	h := new(Hook)
+	resp, err := s.client.Do(ctx, req, h)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return h, resp, nil
+}
+
+// EditHook updates a specified Hook.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#edit-a-hook
+func (s *OrganizationsService) EditHook(ctx context.Context, org string, id int, hook *Hook) (*Hook, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/hooks/%d", org, id)
+	req, err := s.client.NewRequest("PATCH", u, hook)
+	if err != nil {
+		return nil, nil, err
+	}
+	h := new(Hook)
+	resp, err := s.client.Do(ctx, req, h)
+	return h, resp, err
+}
+
+// PingHook triggers a 'ping' event to be sent to the Hook.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#ping-a-hook
+func (s *OrganizationsService) PingHook(ctx context.Context, org string, id int) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/hooks/%d/pings", org, id)
+	req, err := s.client.NewRequest("POST", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
+
+// DeleteHook deletes a specified Hook.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#delete-a-hook
+func (s *OrganizationsService) DeleteHook(ctx context.Context, org string, id int) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/hooks/%d", org, id)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}

+ 299 - 0
vendor/github.com/google/go-github/github/orgs_members.go

@@ -0,0 +1,299 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// Membership represents the status of a user's membership in an organization or team.
+type Membership struct {
+	URL *string `json:"url,omitempty"`
+
+	// State is the user's status within the organization or team.
+	// Possible values are: "active", "pending"
+	State *string `json:"state,omitempty"`
+
+	// Role identifies the user's role within the organization or team.
+	// Possible values for organization membership:
+	//     member - non-owner organization member
+	//     admin - organization owner
+	//
+	// Possible values for team membership are:
+	//     member - a normal member of the team
+	//     maintainer - a team maintainer. Able to add/remove other team
+	//                  members, promote other team members to team
+	//                  maintainer, and edit the team’s name and description
+	Role *string `json:"role,omitempty"`
+
+	// For organization membership, the API URL of the organization.
+	OrganizationURL *string `json:"organization_url,omitempty"`
+
+	// For organization membership, the organization the membership is for.
+	Organization *Organization `json:"organization,omitempty"`
+
+	// For organization membership, the user the membership is for.
+	User *User `json:"user,omitempty"`
+}
+
+func (m Membership) String() string {
+	return Stringify(m)
+}
+
+// ListMembersOptions specifies optional parameters to the
+// OrganizationsService.ListMembers method.
+type ListMembersOptions struct {
+	// If true (or if the authenticated user is not an owner of the
+	// organization), list only publicly visible members.
+	PublicOnly bool `url:"-"`
+
+	// Filter members returned in the list. Possible values are:
+	// 2fa_disabled, all. Default is "all".
+	Filter string `url:"filter,omitempty"`
+
+	// Role filters members returned by their role in the organization.
+	// Possible values are:
+	//     all - all members of the organization, regardless of role
+	//     admin - organization owners
+	//     member - non-organization members
+	//
+	// Default is "all".
+	Role string `url:"role,omitempty"`
+
+	ListOptions
+}
+
+// ListMembers lists the members for an organization. If the authenticated
+// user is an owner of the organization, this will return both concealed and
+// public members, otherwise it will only return public members.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#members-list
+func (s *OrganizationsService) ListMembers(ctx context.Context, org string, opt *ListMembersOptions) ([]*User, *Response, error) {
+	var u string
+	if opt != nil && opt.PublicOnly {
+		u = fmt.Sprintf("orgs/%v/public_members", org)
+	} else {
+		u = fmt.Sprintf("orgs/%v/members", org)
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var members []*User
+	resp, err := s.client.Do(ctx, req, &members)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return members, resp, nil
+}
+
+// IsMember checks if a user is a member of an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#check-membership
+func (s *OrganizationsService) IsMember(ctx context.Context, org, user string) (bool, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/members/%v", org, user)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return false, nil, err
+	}
+
+	resp, err := s.client.Do(ctx, req, nil)
+	member, err := parseBoolResponse(err)
+	return member, resp, err
+}
+
+// IsPublicMember checks if a user is a public member of an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#check-public-membership
+func (s *OrganizationsService) IsPublicMember(ctx context.Context, org, user string) (bool, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/public_members/%v", org, user)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return false, nil, err
+	}
+
+	resp, err := s.client.Do(ctx, req, nil)
+	member, err := parseBoolResponse(err)
+	return member, resp, err
+}
+
+// RemoveMember removes a user from all teams of an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#remove-a-member
+func (s *OrganizationsService) RemoveMember(ctx context.Context, org, user string) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/members/%v", org, user)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// PublicizeMembership publicizes a user's membership in an organization. (A
+// user cannot publicize the membership for another user.)
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#publicize-a-users-membership
+func (s *OrganizationsService) PublicizeMembership(ctx context.Context, org, user string) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/public_members/%v", org, user)
+	req, err := s.client.NewRequest("PUT", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ConcealMembership conceals a user's membership in an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#conceal-a-users-membership
+func (s *OrganizationsService) ConcealMembership(ctx context.Context, org, user string) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/public_members/%v", org, user)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ListOrgMembershipsOptions specifies optional parameters to the
+// OrganizationsService.ListOrgMemberships method.
+type ListOrgMembershipsOptions struct {
+	// Filter memberships to include only those with the specified state.
+	// Possible values are: "active", "pending".
+	State string `url:"state,omitempty"`
+
+	ListOptions
+}
+
+// ListOrgMemberships lists the organization memberships for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#list-your-organization-memberships
+func (s *OrganizationsService) ListOrgMemberships(ctx context.Context, opt *ListOrgMembershipsOptions) ([]*Membership, *Response, error) {
+	u := "user/memberships/orgs"
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var memberships []*Membership
+	resp, err := s.client.Do(ctx, req, &memberships)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return memberships, resp, nil
+}
+
+// GetOrgMembership gets the membership for a user in a specified organization.
+// Passing an empty string for user will get the membership for the
+// authenticated user.
+//
+// GitHub API docs:
+// https://developer.github.com/v3/orgs/members/#get-organization-membership
+// https://developer.github.com/v3/orgs/members/#get-your-organization-membership
+func (s *OrganizationsService) GetOrgMembership(ctx context.Context, user, org string) (*Membership, *Response, error) {
+	var u string
+	if user != "" {
+		u = fmt.Sprintf("orgs/%v/memberships/%v", org, user)
+	} else {
+		u = fmt.Sprintf("user/memberships/orgs/%v", org)
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	membership := new(Membership)
+	resp, err := s.client.Do(ctx, req, membership)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return membership, resp, nil
+}
+
+// EditOrgMembership edits the membership for user in specified organization.
+// Passing an empty string for user will edit the membership for the
+// authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#add-or-update-organization-membership
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#edit-your-organization-membership
+func (s *OrganizationsService) EditOrgMembership(ctx context.Context, user, org string, membership *Membership) (*Membership, *Response, error) {
+	var u, method string
+	if user != "" {
+		u = fmt.Sprintf("orgs/%v/memberships/%v", org, user)
+		method = "PUT"
+	} else {
+		u = fmt.Sprintf("user/memberships/orgs/%v", org)
+		method = "PATCH"
+	}
+
+	req, err := s.client.NewRequest(method, u, membership)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	m := new(Membership)
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// RemoveOrgMembership removes user from the specified organization. If the
+// user has been invited to the organization, this will cancel their invitation.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#remove-organization-membership
+func (s *OrganizationsService) RemoveOrgMembership(ctx context.Context, user, org string) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/memberships/%v", org, user)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ListPendingOrgInvitations returns a list of pending invitations.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#list-pending-organization-invitations
+func (s *OrganizationsService) ListPendingOrgInvitations(ctx context.Context, org string, opt *ListOptions) ([]*Invitation, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/invitations", org)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var pendingInvitations []*Invitation
+	resp, err := s.client.Do(ctx, req, &pendingInvitations)
+	if err != nil {
+		return nil, resp, err
+	}
+	return pendingInvitations, resp, nil
+}

+ 81 - 0
vendor/github.com/google/go-github/github/orgs_outside_collaborators.go

@@ -0,0 +1,81 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ListOutsideCollaboratorsOptions specifies optional parameters to the
+// OrganizationsService.ListOutsideCollaborators method.
+type ListOutsideCollaboratorsOptions struct {
+	// Filter outside collaborators returned in the list. Possible values are:
+	// 2fa_disabled, all.  Default is "all".
+	Filter string `url:"filter,omitempty"`
+
+	ListOptions
+}
+
+// ListOutsideCollaborators lists outside collaborators of organization's repositories.
+// This will only work if the authenticated
+// user is an owner of the organization.
+//
+// Warning: The API may change without advance notice during the preview period.
+// Preview features are not supported for production use.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/outside_collaborators/#list-outside-collaborators
+func (s *OrganizationsService) ListOutsideCollaborators(ctx context.Context, org string, opt *ListOutsideCollaboratorsOptions) ([]*User, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/outside_collaborators", org)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var members []*User
+	resp, err := s.client.Do(ctx, req, &members)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return members, resp, nil
+}
+
+// RemoveOutsideCollaborator removes a user from the list of outside collaborators;
+// consequently, removing them from all the organization's repositories.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/outside_collaborators/#remove-outside-collaborator
+func (s *OrganizationsService) RemoveOutsideCollaborator(ctx context.Context, org string, user string) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/outside_collaborators/%v", org, user)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ConvertMemberToOutsideCollaborator reduces the permission level of a member of the
+// organization to that of an outside collaborator. Therefore, they will only
+// have access to the repositories that their current team membership allows.
+// Responses for converting a non-member or the last owner to an outside collaborator
+// are listed in GitHub API docs.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/outside_collaborators/#convert-member-to-outside-collaborator
+func (s *OrganizationsService) ConvertMemberToOutsideCollaborator(ctx context.Context, org string, user string) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/outside_collaborators/%v", org, user)
+	req, err := s.client.NewRequest("PUT", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}

+ 60 - 0
vendor/github.com/google/go-github/github/orgs_projects.go

@@ -0,0 +1,60 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ListProjects lists the projects for an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/#list-organization-projects
+func (s *OrganizationsService) ListProjects(ctx context.Context, org string, opt *ProjectListOptions) ([]*Project, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/projects", org)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	var projects []*Project
+	resp, err := s.client.Do(ctx, req, &projects)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return projects, resp, nil
+}
+
+// CreateProject creates a GitHub Project for the specified organization.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/#create-an-organization-project
+func (s *OrganizationsService) CreateProject(ctx context.Context, org string, opt *ProjectOptions) (*Project, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/projects", org)
+	req, err := s.client.NewRequest("POST", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	project := &Project{}
+	resp, err := s.client.Do(ctx, req, project)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return project, resp, nil
+}

+ 512 - 0
vendor/github.com/google/go-github/github/orgs_teams.go

@@ -0,0 +1,512 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"strings"
+	"time"
+)
+
+// Team represents a team within a GitHub organization. Teams are used to
+// manage access to an organization's repositories.
+type Team struct {
+	ID          *int64  `json:"id,omitempty"`
+	Name        *string `json:"name,omitempty"`
+	Description *string `json:"description,omitempty"`
+	URL         *string `json:"url,omitempty"`
+	Slug        *string `json:"slug,omitempty"`
+
+	// Permission specifies the default permission for repositories owned by the team.
+	Permission *string `json:"permission,omitempty"`
+
+	// Privacy identifies the level of privacy this team should have.
+	// Possible values are:
+	//     secret - only visible to organization owners and members of this team
+	//     closed - visible to all members of this organization
+	// Default is "secret".
+	Privacy *string `json:"privacy,omitempty"`
+
+	MembersCount    *int          `json:"members_count,omitempty"`
+	ReposCount      *int          `json:"repos_count,omitempty"`
+	Organization    *Organization `json:"organization,omitempty"`
+	MembersURL      *string       `json:"members_url,omitempty"`
+	RepositoriesURL *string       `json:"repositories_url,omitempty"`
+	Parent          *Team         `json:"parent,omitempty"`
+
+	// LDAPDN is only available in GitHub Enterprise and when the team
+	// membership is synchronized with LDAP.
+	LDAPDN *string `json:"ldap_dn,omitempty"`
+}
+
+func (t Team) String() string {
+	return Stringify(t)
+}
+
+// Invitation represents a team member's invitation status.
+type Invitation struct {
+	ID    *int64  `json:"id,omitempty"`
+	Login *string `json:"login,omitempty"`
+	Email *string `json:"email,omitempty"`
+	// Role can be one of the values - 'direct_member', 'admin', 'billing_manager', 'hiring_manager', or 'reinstate'.
+	Role      *string    `json:"role,omitempty"`
+	CreatedAt *time.Time `json:"created_at,omitempty"`
+	Inviter   *User      `json:"inviter,omitempty"`
+}
+
+func (i Invitation) String() string {
+	return Stringify(i)
+}
+
+// ListTeams lists all of the teams for an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/teams/#list-teams
+func (s *OrganizationsService) ListTeams(ctx context.Context, org string, opt *ListOptions) ([]*Team, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/teams", org)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	var teams []*Team
+	resp, err := s.client.Do(ctx, req, &teams)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return teams, resp, nil
+}
+
+// GetTeam fetches a team by ID.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/teams/#get-team
+func (s *OrganizationsService) GetTeam(ctx context.Context, team int64) (*Team, *Response, error) {
+	u := fmt.Sprintf("teams/%v", team)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	t := new(Team)
+	resp, err := s.client.Do(ctx, req, t)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return t, resp, nil
+}
+
+// NewTeam represents a team to be created or modified.
+type NewTeam struct {
+	Name         string   `json:"name"` // Name of the team. (Required.)
+	Description  *string  `json:"description,omitempty"`
+	Maintainers  []string `json:"maintainers,omitempty"`
+	RepoNames    []string `json:"repo_names,omitempty"`
+	ParentTeamID *int64   `json:"parent_team_id,omitempty"`
+
+	// Deprecated: Permission is deprecated when creating or editing a team in an org
+	// using the new GitHub permission model. It no longer identifies the
+	// permission a team has on its repos, but only specifies the default
+	// permission a repo is initially added with. Avoid confusion by
+	// specifying a permission value when calling AddTeamRepo.
+	Permission *string `json:"permission,omitempty"`
+
+	// Privacy identifies the level of privacy this team should have.
+	// Possible values are:
+	//     secret - only visible to organization owners and members of this team
+	//     closed - visible to all members of this organization
+	// Default is "secret".
+	Privacy *string `json:"privacy,omitempty"`
+
+	// LDAPDN may be used in GitHub Enterprise when the team membership
+	// is synchronized with LDAP.
+	LDAPDN *string `json:"ldap_dn,omitempty"`
+}
+
+func (s NewTeam) String() string {
+	return Stringify(s)
+}
+
+// CreateTeam creates a new team within an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/teams/#create-team
+func (s *OrganizationsService) CreateTeam(ctx context.Context, org string, team *NewTeam) (*Team, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/teams", org)
+	req, err := s.client.NewRequest("POST", u, team)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	t := new(Team)
+	resp, err := s.client.Do(ctx, req, t)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return t, resp, nil
+}
+
+// EditTeam edits a team.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/teams/#edit-team
+func (s *OrganizationsService) EditTeam(ctx context.Context, id int64, team *NewTeam) (*Team, *Response, error) {
+	u := fmt.Sprintf("teams/%v", id)
+	req, err := s.client.NewRequest("PATCH", u, team)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	t := new(Team)
+	resp, err := s.client.Do(ctx, req, t)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return t, resp, nil
+}
+
+// DeleteTeam deletes a team.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/teams/#delete-team
+func (s *OrganizationsService) DeleteTeam(ctx context.Context, team int64) (*Response, error) {
+	u := fmt.Sprintf("teams/%v", team)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// OrganizationListTeamMembersOptions specifies the optional parameters to the
+// OrganizationsService.ListTeamMembers method.
+type OrganizationListTeamMembersOptions struct {
+	// Role filters members returned by their role in the team. Possible
+	// values are "all", "member", "maintainer". Default is "all".
+	Role string `url:"role,omitempty"`
+
+	ListOptions
+}
+
+// ListChildTeams lists child teams for a team.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/teams/#list-child-teams
+func (s *OrganizationsService) ListChildTeams(ctx context.Context, teamID int64, opt *ListOptions) ([]*Team, *Response, error) {
+	u := fmt.Sprintf("teams/%v/teams", teamID)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	var teams []*Team
+	resp, err := s.client.Do(ctx, req, &teams)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return teams, resp, nil
+}
+
+// ListTeamMembers lists all of the users who are members of the specified
+// team.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/teams/#list-team-members
+func (s *OrganizationsService) ListTeamMembers(ctx context.Context, team int64, opt *OrganizationListTeamMembersOptions) ([]*User, *Response, error) {
+	u := fmt.Sprintf("teams/%v/members", team)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	var members []*User
+	resp, err := s.client.Do(ctx, req, &members)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return members, resp, nil
+}
+
+// IsTeamMember checks if a user is a member of the specified team.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/teams/#get-team-member
+//
+// Deprecated: This API has been marked as deprecated in the Github API docs,
+// OrganizationsService.GetTeamMembership method should be used instead.
+func (s *OrganizationsService) IsTeamMember(ctx context.Context, team int64, user string) (bool, *Response, error) {
+	u := fmt.Sprintf("teams/%v/members/%v", team, user)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return false, nil, err
+	}
+
+	resp, err := s.client.Do(ctx, req, nil)
+	member, err := parseBoolResponse(err)
+	return member, resp, err
+}
+
+// ListTeamRepos lists the repositories that the specified team has access to.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/teams/#list-team-repos
+func (s *OrganizationsService) ListTeamRepos(ctx context.Context, team int64, opt *ListOptions) ([]*Repository, *Response, error) {
+	u := fmt.Sprintf("teams/%v/repos", team)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when topics API fully launches.
+	headers := []string{mediaTypeTopicsPreview, mediaTypeNestedTeamsPreview}
+	req.Header.Set("Accept", strings.Join(headers, ", "))
+
+	var repos []*Repository
+	resp, err := s.client.Do(ctx, req, &repos)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repos, resp, nil
+}
+
+// IsTeamRepo checks if a team manages the specified repository. If the
+// repository is managed by team, a Repository is returned which includes the
+// permissions team has for that repo.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/teams/#check-if-a-team-manages-a-repository
+func (s *OrganizationsService) IsTeamRepo(ctx context.Context, team int64, owner string, repo string) (*Repository, *Response, error) {
+	u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	headers := []string{mediaTypeOrgPermissionRepo, mediaTypeNestedTeamsPreview}
+	req.Header.Set("Accept", strings.Join(headers, ", "))
+
+	repository := new(Repository)
+	resp, err := s.client.Do(ctx, req, repository)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repository, resp, nil
+}
+
+// OrganizationAddTeamRepoOptions specifies the optional parameters to the
+// OrganizationsService.AddTeamRepo method.
+type OrganizationAddTeamRepoOptions struct {
+	// Permission specifies the permission to grant the team on this repository.
+	// Possible values are:
+	//     pull - team members can pull, but not push to or administer this repository
+	//     push - team members can pull and push, but not administer this repository
+	//     admin - team members can pull, push and administer this repository
+	//
+	// If not specified, the team's permission attribute will be used.
+	Permission string `json:"permission,omitempty"`
+}
+
+// AddTeamRepo adds a repository to be managed by the specified team. The
+// specified repository must be owned by the organization to which the team
+// belongs, or a direct fork of a repository owned by the organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/teams/#add-team-repo
+func (s *OrganizationsService) AddTeamRepo(ctx context.Context, team int64, owner string, repo string, opt *OrganizationAddTeamRepoOptions) (*Response, error) {
+	u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo)
+	req, err := s.client.NewRequest("PUT", u, opt)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// RemoveTeamRepo removes a repository from being managed by the specified
+// team. Note that this does not delete the repository, it just removes it
+// from the team.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/teams/#remove-team-repo
+func (s *OrganizationsService) RemoveTeamRepo(ctx context.Context, team int64, owner string, repo string) (*Response, error) {
+	u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ListUserTeams lists a user's teams
+// GitHub API docs: https://developer.github.com/v3/orgs/teams/#list-user-teams
+func (s *OrganizationsService) ListUserTeams(ctx context.Context, opt *ListOptions) ([]*Team, *Response, error) {
+	u := "user/teams"
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	var teams []*Team
+	resp, err := s.client.Do(ctx, req, &teams)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return teams, resp, nil
+}
+
+// GetTeamMembership returns the membership status for a user in a team.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/teams/#get-team-membership
+func (s *OrganizationsService) GetTeamMembership(ctx context.Context, team int64, user string) (*Membership, *Response, error) {
+	u := fmt.Sprintf("teams/%v/memberships/%v", team, user)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	t := new(Membership)
+	resp, err := s.client.Do(ctx, req, t)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return t, resp, nil
+}
+
+// OrganizationAddTeamMembershipOptions does stuff specifies the optional
+// parameters to the OrganizationsService.AddTeamMembership method.
+type OrganizationAddTeamMembershipOptions struct {
+	// Role specifies the role the user should have in the team. Possible
+	// values are:
+	//     member - a normal member of the team
+	//     maintainer - a team maintainer. Able to add/remove other team
+	//                  members, promote other team members to team
+	//                  maintainer, and edit the team’s name and description
+	//
+	// Default value is "member".
+	Role string `json:"role,omitempty"`
+}
+
+// AddTeamMembership adds or invites a user to a team.
+//
+// In order to add a membership between a user and a team, the authenticated
+// user must have 'admin' permissions to the team or be an owner of the
+// organization that the team is associated with.
+//
+// If the user is already a part of the team's organization (meaning they're on
+// at least one other team in the organization), this endpoint will add the
+// user to the team.
+//
+// If the user is completely unaffiliated with the team's organization (meaning
+// they're on none of the organization's teams), this endpoint will send an
+// invitation to the user via email. This newly-created membership will be in
+// the "pending" state until the user accepts the invitation, at which point
+// the membership will transition to the "active" state and the user will be
+// added as a member of the team.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/teams/#add-team-membership
+func (s *OrganizationsService) AddTeamMembership(ctx context.Context, team int64, user string, opt *OrganizationAddTeamMembershipOptions) (*Membership, *Response, error) {
+	u := fmt.Sprintf("teams/%v/memberships/%v", team, user)
+	req, err := s.client.NewRequest("PUT", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	t := new(Membership)
+	resp, err := s.client.Do(ctx, req, t)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return t, resp, nil
+}
+
+// RemoveTeamMembership removes a user from a team.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/teams/#remove-team-membership
+func (s *OrganizationsService) RemoveTeamMembership(ctx context.Context, team int64, user string) (*Response, error) {
+	u := fmt.Sprintf("teams/%v/memberships/%v", team, user)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ListPendingTeamInvitations get pending invitaion list in team.
+// Warning: The API may change without advance notice during the preview period.
+// Preview features are not supported for production use.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/teams/#list-pending-team-invitations
+func (s *OrganizationsService) ListPendingTeamInvitations(ctx context.Context, team int64, opt *ListOptions) ([]*Invitation, *Response, error) {
+	u := fmt.Sprintf("teams/%v/invitations", team)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var pendingInvitations []*Invitation
+	resp, err := s.client.Do(ctx, req, &pendingInvitations)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return pendingInvitations, resp, nil
+}

+ 91 - 0
vendor/github.com/google/go-github/github/orgs_users_blocking.go

@@ -0,0 +1,91 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ListBlockedUsers lists all the users blocked by an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#list-blocked-users
+func (s *OrganizationsService) ListBlockedUsers(ctx context.Context, org string, opt *ListOptions) ([]*User, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/blocks", org)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeBlockUsersPreview)
+
+	var blockedUsers []*User
+	resp, err := s.client.Do(ctx, req, &blockedUsers)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return blockedUsers, resp, nil
+}
+
+// IsBlocked reports whether specified user is blocked from an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#check-whether-a-user-is-blocked-from-an-organization
+func (s *OrganizationsService) IsBlocked(ctx context.Context, org string, user string) (bool, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/blocks/%v", org, user)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return false, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeBlockUsersPreview)
+
+	resp, err := s.client.Do(ctx, req, nil)
+	isBlocked, err := parseBoolResponse(err)
+	return isBlocked, resp, err
+}
+
+// BlockUser blocks specified user from an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#block-a-user
+func (s *OrganizationsService) BlockUser(ctx context.Context, org string, user string) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/blocks/%v", org, user)
+
+	req, err := s.client.NewRequest("PUT", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeBlockUsersPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// UnblockUser unblocks specified user from an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/blocking/#unblock-a-user
+func (s *OrganizationsService) UnblockUser(ctx context.Context, org string, user string) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/blocks/%v", org, user)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeBlockUsersPreview)
+
+	return s.client.Do(ctx, req, nil)
+}

+ 431 - 0
vendor/github.com/google/go-github/github/projects.go

@@ -0,0 +1,431 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ProjectsService provides access to the projects functions in the
+// GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/
+type ProjectsService service
+
+// Project represents a GitHub Project.
+type Project struct {
+	ID        *int64     `json:"id,omitempty"`
+	URL       *string    `json:"url,omitempty"`
+	OwnerURL  *string    `json:"owner_url,omitempty"`
+	Name      *string    `json:"name,omitempty"`
+	Body      *string    `json:"body,omitempty"`
+	Number    *int       `json:"number,omitempty"`
+	CreatedAt *Timestamp `json:"created_at,omitempty"`
+	UpdatedAt *Timestamp `json:"updated_at,omitempty"`
+
+	// The User object that generated the project.
+	Creator *User `json:"creator,omitempty"`
+}
+
+func (p Project) String() string {
+	return Stringify(p)
+}
+
+// GetProject gets a GitHub Project for a repo.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/#get-a-project
+func (s *ProjectsService) GetProject(ctx context.Context, id int64) (*Project, *Response, error) {
+	u := fmt.Sprintf("projects/%v", id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	project := &Project{}
+	resp, err := s.client.Do(ctx, req, project)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return project, resp, nil
+}
+
+// ProjectOptions specifies the parameters to the
+// RepositoriesService.CreateProject and
+// ProjectsService.UpdateProject methods.
+type ProjectOptions struct {
+	// The name of the project. (Required for creation; optional for update.)
+	Name string `json:"name,omitempty"`
+	// The body of the project. (Optional.)
+	Body string `json:"body,omitempty"`
+
+	// The following field(s) are only applicable for update.
+	// They should be left with zero values for creation.
+
+	// State of the project. Either "open" or "closed". (Optional.)
+	State string `json:"state,omitempty"`
+}
+
+// UpdateProject updates a repository project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/#update-a-project
+func (s *ProjectsService) UpdateProject(ctx context.Context, id int64, opt *ProjectOptions) (*Project, *Response, error) {
+	u := fmt.Sprintf("projects/%v", id)
+	req, err := s.client.NewRequest("PATCH", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	project := &Project{}
+	resp, err := s.client.Do(ctx, req, project)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return project, resp, nil
+}
+
+// DeleteProject deletes a GitHub Project from a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/#delete-a-project
+func (s *ProjectsService) DeleteProject(ctx context.Context, id int64) (*Response, error) {
+	u := fmt.Sprintf("projects/%v", id)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ProjectColumn represents a column of a GitHub Project.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/projects/
+type ProjectColumn struct {
+	ID         *int64     `json:"id,omitempty"`
+	Name       *string    `json:"name,omitempty"`
+	ProjectURL *string    `json:"project_url,omitempty"`
+	CreatedAt  *Timestamp `json:"created_at,omitempty"`
+	UpdatedAt  *Timestamp `json:"updated_at,omitempty"`
+}
+
+// ListProjectColumns lists the columns of a GitHub Project for a repo.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/columns/#list-project-columns
+func (s *ProjectsService) ListProjectColumns(ctx context.Context, projectID int64, opt *ListOptions) ([]*ProjectColumn, *Response, error) {
+	u := fmt.Sprintf("projects/%v/columns", projectID)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	columns := []*ProjectColumn{}
+	resp, err := s.client.Do(ctx, req, &columns)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return columns, resp, nil
+}
+
+// GetProjectColumn gets a column of a GitHub Project for a repo.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/columns/#get-a-project-column
+func (s *ProjectsService) GetProjectColumn(ctx context.Context, id int64) (*ProjectColumn, *Response, error) {
+	u := fmt.Sprintf("projects/columns/%v", id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	column := &ProjectColumn{}
+	resp, err := s.client.Do(ctx, req, column)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return column, resp, nil
+}
+
+// ProjectColumnOptions specifies the parameters to the
+// ProjectsService.CreateProjectColumn and
+// ProjectsService.UpdateProjectColumn methods.
+type ProjectColumnOptions struct {
+	// The name of the project column. (Required for creation and update.)
+	Name string `json:"name"`
+}
+
+// CreateProjectColumn creates a column for the specified (by number) project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/columns/#create-a-project-column
+func (s *ProjectsService) CreateProjectColumn(ctx context.Context, projectID int64, opt *ProjectColumnOptions) (*ProjectColumn, *Response, error) {
+	u := fmt.Sprintf("projects/%v/columns", projectID)
+	req, err := s.client.NewRequest("POST", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	column := &ProjectColumn{}
+	resp, err := s.client.Do(ctx, req, column)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return column, resp, nil
+}
+
+// UpdateProjectColumn updates a column of a GitHub Project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/columns/#update-a-project-column
+func (s *ProjectsService) UpdateProjectColumn(ctx context.Context, columnID int64, opt *ProjectColumnOptions) (*ProjectColumn, *Response, error) {
+	u := fmt.Sprintf("projects/columns/%v", columnID)
+	req, err := s.client.NewRequest("PATCH", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	column := &ProjectColumn{}
+	resp, err := s.client.Do(ctx, req, column)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return column, resp, nil
+}
+
+// DeleteProjectColumn deletes a column from a GitHub Project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/columns/#delete-a-project-column
+func (s *ProjectsService) DeleteProjectColumn(ctx context.Context, columnID int64) (*Response, error) {
+	u := fmt.Sprintf("projects/columns/%v", columnID)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ProjectColumnMoveOptions specifies the parameters to the
+// ProjectsService.MoveProjectColumn method.
+type ProjectColumnMoveOptions struct {
+	// Position can be one of "first", "last", or "after:<column-id>", where
+	// <column-id> is the ID of a column in the same project. (Required.)
+	Position string `json:"position"`
+}
+
+// MoveProjectColumn moves a column within a GitHub Project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/columns/#move-a-project-column
+func (s *ProjectsService) MoveProjectColumn(ctx context.Context, columnID int64, opt *ProjectColumnMoveOptions) (*Response, error) {
+	u := fmt.Sprintf("projects/columns/%v/moves", columnID)
+	req, err := s.client.NewRequest("POST", u, opt)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ProjectCard represents a card in a column of a GitHub Project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/cards/#get-a-project-card
+type ProjectCard struct {
+	URL        *string    `json:"url,omitempty"`
+	ColumnURL  *string    `json:"column_url,omitempty"`
+	ContentURL *string    `json:"content_url,omitempty"`
+	ID         *int64     `json:"id,omitempty"`
+	Note       *string    `json:"note,omitempty"`
+	Creator    *User      `json:"creator,omitempty"`
+	CreatedAt  *Timestamp `json:"created_at,omitempty"`
+	UpdatedAt  *Timestamp `json:"updated_at,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	ColumnID *int64 `json:"column_id,omitempty"`
+}
+
+// ListProjectCards lists the cards in a column of a GitHub Project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/cards/#list-project-cards
+func (s *ProjectsService) ListProjectCards(ctx context.Context, columnID int64, opt *ListOptions) ([]*ProjectCard, *Response, error) {
+	u := fmt.Sprintf("projects/columns/%v/cards", columnID)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	cards := []*ProjectCard{}
+	resp, err := s.client.Do(ctx, req, &cards)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return cards, resp, nil
+}
+
+// GetProjectCard gets a card in a column of a GitHub Project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/cards/#get-a-project-card
+func (s *ProjectsService) GetProjectCard(ctx context.Context, columnID int64) (*ProjectCard, *Response, error) {
+	u := fmt.Sprintf("projects/columns/cards/%v", columnID)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	card := &ProjectCard{}
+	resp, err := s.client.Do(ctx, req, card)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return card, resp, nil
+}
+
+// ProjectCardOptions specifies the parameters to the
+// ProjectsService.CreateProjectCard and
+// ProjectsService.UpdateProjectCard methods.
+type ProjectCardOptions struct {
+	// The note of the card. Note and ContentID are mutually exclusive.
+	Note string `json:"note,omitempty"`
+	// The ID (not Number) of the Issue to associate with this card.
+	// Note and ContentID are mutually exclusive.
+	ContentID int64 `json:"content_id,omitempty"`
+	// The type of content to associate with this card. Possible values are: "Issue".
+	ContentType string `json:"content_type,omitempty"`
+}
+
+// CreateProjectCard creates a card in the specified column of a GitHub Project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/cards/#create-a-project-card
+func (s *ProjectsService) CreateProjectCard(ctx context.Context, columnID int64, opt *ProjectCardOptions) (*ProjectCard, *Response, error) {
+	u := fmt.Sprintf("projects/columns/%v/cards", columnID)
+	req, err := s.client.NewRequest("POST", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	card := &ProjectCard{}
+	resp, err := s.client.Do(ctx, req, card)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return card, resp, nil
+}
+
+// UpdateProjectCard updates a card of a GitHub Project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/cards/#update-a-project-card
+func (s *ProjectsService) UpdateProjectCard(ctx context.Context, cardID int64, opt *ProjectCardOptions) (*ProjectCard, *Response, error) {
+	u := fmt.Sprintf("projects/columns/cards/%v", cardID)
+	req, err := s.client.NewRequest("PATCH", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	card := &ProjectCard{}
+	resp, err := s.client.Do(ctx, req, card)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return card, resp, nil
+}
+
+// DeleteProjectCard deletes a card from a GitHub Project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/cards/#delete-a-project-card
+func (s *ProjectsService) DeleteProjectCard(ctx context.Context, cardID int64) (*Response, error) {
+	u := fmt.Sprintf("projects/columns/cards/%v", cardID)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// ProjectCardMoveOptions specifies the parameters to the
+// ProjectsService.MoveProjectCard method.
+type ProjectCardMoveOptions struct {
+	// Position can be one of "top", "bottom", or "after:<card-id>", where
+	// <card-id> is the ID of a card in the same project.
+	Position string `json:"position"`
+	// ColumnID is the ID of a column in the same project. Note that ColumnID
+	// is required when using Position "after:<card-id>" when that card is in
+	// another column; otherwise it is optional.
+	ColumnID int64 `json:"column_id,omitempty"`
+}
+
+// MoveProjectCard moves a card within a GitHub Project.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/cards/#move-a-project-card
+func (s *ProjectsService) MoveProjectCard(ctx context.Context, cardID int64, opt *ProjectCardMoveOptions) (*Response, error) {
+	u := fmt.Sprintf("projects/columns/cards/%v/moves", cardID)
+	req, err := s.client.NewRequest("POST", u, opt)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}

+ 371 - 0
vendor/github.com/google/go-github/github/pulls.go

@@ -0,0 +1,371 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"time"
+)
+
+// PullRequestsService handles communication with the pull request related
+// methods of the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/
+type PullRequestsService service
+
+// PullRequest represents a GitHub pull request on a repository.
+type PullRequest struct {
+	ID                  *int64     `json:"id,omitempty"`
+	Number              *int       `json:"number,omitempty"`
+	State               *string    `json:"state,omitempty"`
+	Title               *string    `json:"title,omitempty"`
+	Body                *string    `json:"body,omitempty"`
+	CreatedAt           *time.Time `json:"created_at,omitempty"`
+	UpdatedAt           *time.Time `json:"updated_at,omitempty"`
+	ClosedAt            *time.Time `json:"closed_at,omitempty"`
+	MergedAt            *time.Time `json:"merged_at,omitempty"`
+	User                *User      `json:"user,omitempty"`
+	Merged              *bool      `json:"merged,omitempty"`
+	Mergeable           *bool      `json:"mergeable,omitempty"`
+	MergeableState      *string    `json:"mergeable_state,omitempty"`
+	MergedBy            *User      `json:"merged_by,omitempty"`
+	MergeCommitSHA      *string    `json:"merge_commit_sha,omitempty"`
+	Comments            *int       `json:"comments,omitempty"`
+	Commits             *int       `json:"commits,omitempty"`
+	Additions           *int       `json:"additions,omitempty"`
+	Deletions           *int       `json:"deletions,omitempty"`
+	ChangedFiles        *int       `json:"changed_files,omitempty"`
+	URL                 *string    `json:"url,omitempty"`
+	HTMLURL             *string    `json:"html_url,omitempty"`
+	IssueURL            *string    `json:"issue_url,omitempty"`
+	StatusesURL         *string    `json:"statuses_url,omitempty"`
+	DiffURL             *string    `json:"diff_url,omitempty"`
+	PatchURL            *string    `json:"patch_url,omitempty"`
+	ReviewCommentsURL   *string    `json:"review_comments_url,omitempty"`
+	ReviewCommentURL    *string    `json:"review_comment_url,omitempty"`
+	Assignee            *User      `json:"assignee,omitempty"`
+	Assignees           []*User    `json:"assignees,omitempty"`
+	Milestone           *Milestone `json:"milestone,omitempty"`
+	MaintainerCanModify *bool      `json:"maintainer_can_modify,omitempty"`
+	AuthorAssociation   *string    `json:"author_association,omitempty"`
+	NodeID              *string    `json:"node_id,omitempty"`
+
+	Head *PullRequestBranch `json:"head,omitempty"`
+	Base *PullRequestBranch `json:"base,omitempty"`
+}
+
+func (p PullRequest) String() string {
+	return Stringify(p)
+}
+
+// PullRequestBranch represents a base or head branch in a GitHub pull request.
+type PullRequestBranch struct {
+	Label *string     `json:"label,omitempty"`
+	Ref   *string     `json:"ref,omitempty"`
+	SHA   *string     `json:"sha,omitempty"`
+	Repo  *Repository `json:"repo,omitempty"`
+	User  *User       `json:"user,omitempty"`
+}
+
+// PullRequestListOptions specifies the optional parameters to the
+// PullRequestsService.List method.
+type PullRequestListOptions struct {
+	// State filters pull requests based on their state. Possible values are:
+	// open, closed. Default is "open".
+	State string `url:"state,omitempty"`
+
+	// Head filters pull requests by head user and branch name in the format of:
+	// "user:ref-name".
+	Head string `url:"head,omitempty"`
+
+	// Base filters pull requests by base branch name.
+	Base string `url:"base,omitempty"`
+
+	// Sort specifies how to sort pull requests. Possible values are: created,
+	// updated, popularity, long-running. Default is "created".
+	Sort string `url:"sort,omitempty"`
+
+	// Direction in which to sort pull requests. Possible values are: asc, desc.
+	// If Sort is "created" or not specified, Default is "desc", otherwise Default
+	// is "asc"
+	Direction string `url:"direction,omitempty"`
+
+	ListOptions
+}
+
+// List the pull requests for the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/#list-pull-requests
+func (s *PullRequestsService) List(ctx context.Context, owner string, repo string, opt *PullRequestListOptions) ([]*PullRequest, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	var pulls []*PullRequest
+	resp, err := s.client.Do(ctx, req, &pulls)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return pulls, resp, nil
+}
+
+// Get a single pull request.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/#get-a-single-pull-request
+func (s *PullRequestsService) Get(ctx context.Context, owner string, repo string, number int) (*PullRequest, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	pull := new(PullRequest)
+	resp, err := s.client.Do(ctx, req, pull)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return pull, resp, nil
+}
+
+// GetRaw gets a single pull request in raw (diff or patch) format.
+func (s *PullRequestsService) GetRaw(ctx context.Context, owner string, repo string, number int, opt RawOptions) (string, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return "", nil, err
+	}
+
+	switch opt.Type {
+	case Diff:
+		req.Header.Set("Accept", mediaTypeV3Diff)
+	case Patch:
+		req.Header.Set("Accept", mediaTypeV3Patch)
+	default:
+		return "", nil, fmt.Errorf("unsupported raw type %d", opt.Type)
+	}
+
+	var buf bytes.Buffer
+	resp, err := s.client.Do(ctx, req, &buf)
+	if err != nil {
+		return "", resp, err
+	}
+
+	return buf.String(), resp, nil
+}
+
+// NewPullRequest represents a new pull request to be created.
+type NewPullRequest struct {
+	Title               *string `json:"title,omitempty"`
+	Head                *string `json:"head,omitempty"`
+	Base                *string `json:"base,omitempty"`
+	Body                *string `json:"body,omitempty"`
+	Issue               *int    `json:"issue,omitempty"`
+	MaintainerCanModify *bool   `json:"maintainer_can_modify,omitempty"`
+}
+
+// Create a new pull request on the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/#create-a-pull-request
+func (s *PullRequestsService) Create(ctx context.Context, owner string, repo string, pull *NewPullRequest) (*PullRequest, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls", owner, repo)
+	req, err := s.client.NewRequest("POST", u, pull)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	p := new(PullRequest)
+	resp, err := s.client.Do(ctx, req, p)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return p, resp, nil
+}
+
+type pullRequestUpdate struct {
+	Title               *string `json:"title,omitempty"`
+	Body                *string `json:"body,omitempty"`
+	State               *string `json:"state,omitempty"`
+	Base                *string `json:"base,omitempty"`
+	MaintainerCanModify *bool   `json:"maintainer_can_modify,omitempty"`
+}
+
+// Edit a pull request.
+// pull must not be nil.
+//
+// The following fields are editable: Title, Body, State, Base.Ref and MaintainerCanModify.
+// Base.Ref updates the base branch of the pull request.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/#update-a-pull-request
+func (s *PullRequestsService) Edit(ctx context.Context, owner string, repo string, number int, pull *PullRequest) (*PullRequest, *Response, error) {
+	if pull == nil {
+		return nil, nil, fmt.Errorf("pull must be provided")
+	}
+
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number)
+
+	update := &pullRequestUpdate{
+		Title:               pull.Title,
+		Body:                pull.Body,
+		State:               pull.State,
+		MaintainerCanModify: pull.MaintainerCanModify,
+	}
+	if pull.Base != nil {
+		update.Base = pull.Base.Ref
+	}
+
+	req, err := s.client.NewRequest("PATCH", u, update)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	p := new(PullRequest)
+	resp, err := s.client.Do(ctx, req, p)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return p, resp, nil
+}
+
+// ListCommits lists the commits in a pull request.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/#list-commits-on-a-pull-request
+func (s *PullRequestsService) ListCommits(ctx context.Context, owner string, repo string, number int, opt *ListOptions) ([]*RepositoryCommit, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/commits", owner, repo, number)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGitSigningPreview)
+
+	var commits []*RepositoryCommit
+	resp, err := s.client.Do(ctx, req, &commits)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return commits, resp, nil
+}
+
+// ListFiles lists the files in a pull request.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/#list-pull-requests-files
+func (s *PullRequestsService) ListFiles(ctx context.Context, owner string, repo string, number int, opt *ListOptions) ([]*CommitFile, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/files", owner, repo, number)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var commitFiles []*CommitFile
+	resp, err := s.client.Do(ctx, req, &commitFiles)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return commitFiles, resp, nil
+}
+
+// IsMerged checks if a pull request has been merged.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/#get-if-a-pull-request-has-been-merged
+func (s *PullRequestsService) IsMerged(ctx context.Context, owner string, repo string, number int) (bool, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/merge", owner, repo, number)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return false, nil, err
+	}
+
+	resp, err := s.client.Do(ctx, req, nil)
+	merged, err := parseBoolResponse(err)
+	return merged, resp, err
+}
+
+// PullRequestMergeResult represents the result of merging a pull request.
+type PullRequestMergeResult struct {
+	SHA     *string `json:"sha,omitempty"`
+	Merged  *bool   `json:"merged,omitempty"`
+	Message *string `json:"message,omitempty"`
+}
+
+// PullRequestOptions lets you define how a pull request will be merged.
+type PullRequestOptions struct {
+	CommitTitle string // Extra detail to append to automatic commit message. (Optional.)
+	SHA         string // SHA that pull request head must match to allow merge. (Optional.)
+
+	// The merge method to use. Possible values include: "merge", "squash", and "rebase" with the default being merge. (Optional.)
+	MergeMethod string
+}
+
+type pullRequestMergeRequest struct {
+	CommitMessage string `json:"commit_message"`
+	CommitTitle   string `json:"commit_title,omitempty"`
+	MergeMethod   string `json:"merge_method,omitempty"`
+	SHA           string `json:"sha,omitempty"`
+}
+
+// Merge a pull request (Merge Button™).
+// commitMessage is the title for the automatic commit message.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-buttontrade
+func (s *PullRequestsService) Merge(ctx context.Context, owner string, repo string, number int, commitMessage string, options *PullRequestOptions) (*PullRequestMergeResult, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/merge", owner, repo, number)
+
+	pullRequestBody := &pullRequestMergeRequest{CommitMessage: commitMessage}
+	if options != nil {
+		pullRequestBody.CommitTitle = options.CommitTitle
+		pullRequestBody.MergeMethod = options.MergeMethod
+		pullRequestBody.SHA = options.SHA
+	}
+	req, err := s.client.NewRequest("PUT", u, pullRequestBody)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	mergeResult := new(PullRequestMergeResult)
+	resp, err := s.client.Do(ctx, req, mergeResult)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return mergeResult, resp, nil
+}

+ 157 - 0
vendor/github.com/google/go-github/github/pulls_comments.go

@@ -0,0 +1,157 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// PullRequestComment represents a comment left on a pull request.
+type PullRequestComment struct {
+	ID               *int64     `json:"id,omitempty"`
+	InReplyTo        *int64     `json:"in_reply_to,omitempty"`
+	Body             *string    `json:"body,omitempty"`
+	Path             *string    `json:"path,omitempty"`
+	DiffHunk         *string    `json:"diff_hunk,omitempty"`
+	Position         *int       `json:"position,omitempty"`
+	OriginalPosition *int       `json:"original_position,omitempty"`
+	CommitID         *string    `json:"commit_id,omitempty"`
+	OriginalCommitID *string    `json:"original_commit_id,omitempty"`
+	User             *User      `json:"user,omitempty"`
+	Reactions        *Reactions `json:"reactions,omitempty"`
+	CreatedAt        *time.Time `json:"created_at,omitempty"`
+	UpdatedAt        *time.Time `json:"updated_at,omitempty"`
+	URL              *string    `json:"url,omitempty"`
+	HTMLURL          *string    `json:"html_url,omitempty"`
+	PullRequestURL   *string    `json:"pull_request_url,omitempty"`
+}
+
+func (p PullRequestComment) String() string {
+	return Stringify(p)
+}
+
+// PullRequestListCommentsOptions specifies the optional parameters to the
+// PullRequestsService.ListComments method.
+type PullRequestListCommentsOptions struct {
+	// Sort specifies how to sort comments. Possible values are: created, updated.
+	Sort string `url:"sort,omitempty"`
+
+	// Direction in which to sort comments. Possible values are: asc, desc.
+	Direction string `url:"direction,omitempty"`
+
+	// Since filters comments by time.
+	Since time.Time `url:"since,omitempty"`
+
+	ListOptions
+}
+
+// ListComments lists all comments on the specified pull request. Specifying a
+// pull request number of 0 will return all comments on all pull requests for
+// the repository.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/comments/#list-comments-on-a-pull-request
+func (s *PullRequestsService) ListComments(ctx context.Context, owner string, repo string, number int, opt *PullRequestListCommentsOptions) ([]*PullRequestComment, *Response, error) {
+	var u string
+	if number == 0 {
+		u = fmt.Sprintf("repos/%v/%v/pulls/comments", owner, repo)
+	} else {
+		u = fmt.Sprintf("repos/%v/%v/pulls/%d/comments", owner, repo, number)
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	var comments []*PullRequestComment
+	resp, err := s.client.Do(ctx, req, &comments)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return comments, resp, nil
+}
+
+// GetComment fetches the specified pull request comment.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/comments/#get-a-single-comment
+func (s *PullRequestsService) GetComment(ctx context.Context, owner string, repo string, number int) (*PullRequestComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/comments/%d", owner, repo, number)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	comment := new(PullRequestComment)
+	resp, err := s.client.Do(ctx, req, comment)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return comment, resp, nil
+}
+
+// CreateComment creates a new comment on the specified pull request.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/comments/#create-a-comment
+func (s *PullRequestsService) CreateComment(ctx context.Context, owner string, repo string, number int, comment *PullRequestComment) (*PullRequestComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/comments", owner, repo, number)
+	req, err := s.client.NewRequest("POST", u, comment)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	c := new(PullRequestComment)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// EditComment updates a pull request comment.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/comments/#edit-a-comment
+func (s *PullRequestsService) EditComment(ctx context.Context, owner string, repo string, number int, comment *PullRequestComment) (*PullRequestComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/comments/%d", owner, repo, number)
+	req, err := s.client.NewRequest("PATCH", u, comment)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	c := new(PullRequestComment)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// DeleteComment deletes a pull request comment.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/comments/#delete-a-comment
+func (s *PullRequestsService) DeleteComment(ctx context.Context, owner string, repo string, number int) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/comments/%d", owner, repo, number)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}

+ 88 - 0
vendor/github.com/google/go-github/github/pulls_reviewers.go

@@ -0,0 +1,88 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ReviewersRequest specifies users and teams for a pull request review request.
+type ReviewersRequest struct {
+	Reviewers     []string `json:"reviewers,omitempty"`
+	TeamReviewers []string `json:"team_reviewers,omitempty"`
+}
+
+// Reviewers represents reviewers of a pull request.
+type Reviewers struct {
+	Users []*User `json:"users,omitempty"`
+	Teams []*Team `json:"teams,omitempty"`
+}
+
+// RequestReviewers creates a review request for the provided reviewers for the specified pull request.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/review_requests/#create-a-review-request
+func (s *PullRequestsService) RequestReviewers(ctx context.Context, owner, repo string, number int, reviewers ReviewersRequest) (*PullRequest, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/pulls/%d/requested_reviewers", owner, repo, number)
+	req, err := s.client.NewRequest("POST", u, &reviewers)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeTeamReviewPreview)
+
+	r := new(PullRequest)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// ListReviewers lists reviewers whose reviews have been requested on the specified pull request.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/review_requests/#list-review-requests
+func (s *PullRequestsService) ListReviewers(ctx context.Context, owner, repo string, number int, opt *ListOptions) (*Reviewers, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/requested_reviewers", owner, repo, number)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeTeamReviewPreview)
+
+	reviewers := new(Reviewers)
+	resp, err := s.client.Do(ctx, req, reviewers)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return reviewers, resp, nil
+}
+
+// RemoveReviewers removes the review request for the provided reviewers for the specified pull request.
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/review_requests/#delete-a-review-request
+func (s *PullRequestsService) RemoveReviewers(ctx context.Context, owner, repo string, number int, reviewers ReviewersRequest) (*Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/pulls/%d/requested_reviewers", owner, repo, number)
+	req, err := s.client.NewRequest("DELETE", u, &reviewers)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeTeamReviewPreview)
+
+	return s.client.Do(ctx, req, nil)
+}

+ 236 - 0
vendor/github.com/google/go-github/github/pulls_reviews.go

@@ -0,0 +1,236 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// PullRequestReview represents a review of a pull request.
+type PullRequestReview struct {
+	ID             *int64     `json:"id,omitempty"`
+	User           *User      `json:"user,omitempty"`
+	Body           *string    `json:"body,omitempty"`
+	SubmittedAt    *time.Time `json:"submitted_at,omitempty"`
+	CommitID       *string    `json:"commit_id,omitempty"`
+	HTMLURL        *string    `json:"html_url,omitempty"`
+	PullRequestURL *string    `json:"pull_request_url,omitempty"`
+	State          *string    `json:"state,omitempty"`
+}
+
+func (p PullRequestReview) String() string {
+	return Stringify(p)
+}
+
+// DraftReviewComment represents a comment part of the review.
+type DraftReviewComment struct {
+	Path     *string `json:"path,omitempty"`
+	Position *int    `json:"position,omitempty"`
+	Body     *string `json:"body,omitempty"`
+}
+
+func (c DraftReviewComment) String() string {
+	return Stringify(c)
+}
+
+// PullRequestReviewRequest represents a request to create a review.
+type PullRequestReviewRequest struct {
+	CommitID *string               `json:"commit_id,omitempty"`
+	Body     *string               `json:"body,omitempty"`
+	Event    *string               `json:"event,omitempty"`
+	Comments []*DraftReviewComment `json:"comments,omitempty"`
+}
+
+func (r PullRequestReviewRequest) String() string {
+	return Stringify(r)
+}
+
+// PullRequestReviewDismissalRequest represents a request to dismiss a review.
+type PullRequestReviewDismissalRequest struct {
+	Message *string `json:"message,omitempty"`
+}
+
+func (r PullRequestReviewDismissalRequest) String() string {
+	return Stringify(r)
+}
+
+// ListReviews lists all reviews on the specified pull request.
+//
+// TODO: Follow up with GitHub support about an issue with this method's
+// returned error format and remove this comment once it's fixed.
+// Read more about it here - https://github.com/google/go-github/issues/540
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#list-reviews-on-a-pull-request
+func (s *PullRequestsService) ListReviews(ctx context.Context, owner, repo string, number int, opt *ListOptions) ([]*PullRequestReview, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews", owner, repo, number)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var reviews []*PullRequestReview
+	resp, err := s.client.Do(ctx, req, &reviews)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return reviews, resp, nil
+}
+
+// GetReview fetches the specified pull request review.
+//
+// TODO: Follow up with GitHub support about an issue with this method's
+// returned error format and remove this comment once it's fixed.
+// Read more about it here - https://github.com/google/go-github/issues/540
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#get-a-single-review
+func (s *PullRequestsService) GetReview(ctx context.Context, owner, repo string, number, reviewID int64) (*PullRequestReview, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d", owner, repo, number, reviewID)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	review := new(PullRequestReview)
+	resp, err := s.client.Do(ctx, req, review)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return review, resp, nil
+}
+
+// DeletePendingReview deletes the specified pull request pending review.
+//
+// TODO: Follow up with GitHub support about an issue with this method's
+// returned error format and remove this comment once it's fixed.
+// Read more about it here - https://github.com/google/go-github/issues/540
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#delete-a-pending-review
+func (s *PullRequestsService) DeletePendingReview(ctx context.Context, owner, repo string, number, reviewID int64) (*PullRequestReview, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d", owner, repo, number, reviewID)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	review := new(PullRequestReview)
+	resp, err := s.client.Do(ctx, req, review)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return review, resp, nil
+}
+
+// ListReviewComments lists all the comments for the specified review.
+//
+// TODO: Follow up with GitHub support about an issue with this method's
+// returned error format and remove this comment once it's fixed.
+// Read more about it here - https://github.com/google/go-github/issues/540
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#get-comments-for-a-single-review
+func (s *PullRequestsService) ListReviewComments(ctx context.Context, owner, repo string, number, reviewID int64, opt *ListOptions) ([]*PullRequestComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d/comments", owner, repo, number, reviewID)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var comments []*PullRequestComment
+	resp, err := s.client.Do(ctx, req, &comments)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return comments, resp, nil
+}
+
+// CreateReview creates a new review on the specified pull request.
+//
+// TODO: Follow up with GitHub support about an issue with this method's
+// returned error format and remove this comment once it's fixed.
+// Read more about it here - https://github.com/google/go-github/issues/540
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#create-a-pull-request-review
+func (s *PullRequestsService) CreateReview(ctx context.Context, owner, repo string, number int, review *PullRequestReviewRequest) (*PullRequestReview, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews", owner, repo, number)
+
+	req, err := s.client.NewRequest("POST", u, review)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r := new(PullRequestReview)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// SubmitReview submits a specified review on the specified pull request.
+//
+// TODO: Follow up with GitHub support about an issue with this method's
+// returned error format and remove this comment once it's fixed.
+// Read more about it here - https://github.com/google/go-github/issues/540
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#submit-a-pull-request-review
+func (s *PullRequestsService) SubmitReview(ctx context.Context, owner, repo string, number, reviewID int64, review *PullRequestReviewRequest) (*PullRequestReview, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d/events", owner, repo, number, reviewID)
+
+	req, err := s.client.NewRequest("POST", u, review)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r := new(PullRequestReview)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// DismissReview dismisses a specified review on the specified pull request.
+//
+// TODO: Follow up with GitHub support about an issue with this method's
+// returned error format and remove this comment once it's fixed.
+// Read more about it here - https://github.com/google/go-github/issues/540
+//
+// GitHub API docs: https://developer.github.com/v3/pulls/reviews/#dismiss-a-pull-request-review
+func (s *PullRequestsService) DismissReview(ctx context.Context, owner, repo string, number, reviewID int64, review *PullRequestReviewDismissalRequest) (*PullRequestReview, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/%d/reviews/%d/dismissals", owner, repo, number, reviewID)
+
+	req, err := s.client.NewRequest("PUT", u, review)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r := new(PullRequestReview)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}

+ 273 - 0
vendor/github.com/google/go-github/github/reactions.go

@@ -0,0 +1,273 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ReactionsService provides access to the reactions-related functions in the
+// GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/reactions/
+type ReactionsService service
+
+// Reaction represents a GitHub reaction.
+type Reaction struct {
+	// ID is the Reaction ID.
+	ID   *int64 `json:"id,omitempty"`
+	User *User  `json:"user,omitempty"`
+	// Content is the type of reaction.
+	// Possible values are:
+	//     "+1", "-1", "laugh", "confused", "heart", "hooray".
+	Content *string `json:"content,omitempty"`
+}
+
+// Reactions represents a summary of GitHub reactions.
+type Reactions struct {
+	TotalCount *int    `json:"total_count,omitempty"`
+	PlusOne    *int    `json:"+1,omitempty"`
+	MinusOne   *int    `json:"-1,omitempty"`
+	Laugh      *int    `json:"laugh,omitempty"`
+	Confused   *int    `json:"confused,omitempty"`
+	Heart      *int    `json:"heart,omitempty"`
+	Hooray     *int    `json:"hooray,omitempty"`
+	URL        *string `json:"url,omitempty"`
+}
+
+func (r Reaction) String() string {
+	return Stringify(r)
+}
+
+// ListCommentReactions lists the reactions for a commit comment.
+//
+// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-commit-comment
+func (s *ReactionsService) ListCommentReactions(ctx context.Context, owner, repo string, id int64, opt *ListOptions) ([]*Reaction, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions", owner, repo, id)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	var m []*Reaction
+	resp, err := s.client.Do(ctx, req, &m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// CreateCommentReaction creates a reaction for a commit comment.
+// Note that if you have already created a reaction of type content, the
+// previously created reaction will be returned with Status: 200 OK.
+//
+// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-commit-comment
+func (s ReactionsService) CreateCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions", owner, repo, id)
+
+	body := &Reaction{Content: String(content)}
+	req, err := s.client.NewRequest("POST", u, body)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	m := &Reaction{}
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// ListIssueReactions lists the reactions for an issue.
+//
+// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue
+func (s *ReactionsService) ListIssueReactions(ctx context.Context, owner, repo string, number int, opt *ListOptions) ([]*Reaction, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%v/reactions", owner, repo, number)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	var m []*Reaction
+	resp, err := s.client.Do(ctx, req, &m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// CreateIssueReaction creates a reaction for an issue.
+// Note that if you have already created a reaction of type content, the
+// previously created reaction will be returned with Status: 200 OK.
+//
+// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-an-issue
+func (s ReactionsService) CreateIssueReaction(ctx context.Context, owner, repo string, number int, content string) (*Reaction, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%v/reactions", owner, repo, number)
+
+	body := &Reaction{Content: String(content)}
+	req, err := s.client.NewRequest("POST", u, body)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	m := &Reaction{}
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// ListIssueCommentReactions lists the reactions for an issue comment.
+//
+// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue-comment
+func (s *ReactionsService) ListIssueCommentReactions(ctx context.Context, owner, repo string, id int64, opt *ListOptions) ([]*Reaction, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/comments/%v/reactions", owner, repo, id)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	var m []*Reaction
+	resp, err := s.client.Do(ctx, req, &m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// CreateIssueCommentReaction creates a reaction for an issue comment.
+// Note that if you have already created a reaction of type content, the
+// previously created reaction will be returned with Status: 200 OK.
+//
+// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-an-issue-comment
+func (s ReactionsService) CreateIssueCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/comments/%v/reactions", owner, repo, id)
+
+	body := &Reaction{Content: String(content)}
+	req, err := s.client.NewRequest("POST", u, body)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	m := &Reaction{}
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// ListPullRequestCommentReactions lists the reactions for a pull request review comment.
+//
+// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue-comment
+func (s *ReactionsService) ListPullRequestCommentReactions(ctx context.Context, owner, repo string, id int64, opt *ListOptions) ([]*Reaction, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions", owner, repo, id)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	var m []*Reaction
+	resp, err := s.client.Do(ctx, req, &m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// CreatePullRequestCommentReaction creates a reaction for a pull request review comment.
+// Note that if you have already created a reaction of type content, the
+// previously created reaction will be returned with Status: 200 OK.
+//
+// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-an-issue-comment
+func (s ReactionsService) CreatePullRequestCommentReaction(ctx context.Context, owner, repo string, id int64, content string) (*Reaction, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions", owner, repo, id)
+
+	body := &Reaction{Content: String(content)}
+	req, err := s.client.NewRequest("POST", u, body)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	m := &Reaction{}
+	resp, err := s.client.Do(ctx, req, m)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return m, resp, nil
+}
+
+// DeleteReaction deletes a reaction.
+//
+// GitHub API docs: https://developer.github.com/v3/reaction/reactions/#delete-a-reaction-archive
+func (s *ReactionsService) DeleteReaction(ctx context.Context, id int64) (*Response, error) {
+	u := fmt.Sprintf("reactions/%v", id)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}

+ 1076 - 0
vendor/github.com/google/go-github/github/repos.go

@@ -0,0 +1,1076 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"strings"
+)
+
+// RepositoriesService handles communication with the repository related
+// methods of the GitHub API.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/
+type RepositoriesService service
+
+// Repository represents a GitHub repository.
+type Repository struct {
+	ID               *int64           `json:"id,omitempty"`
+	Owner            *User            `json:"owner,omitempty"`
+	Name             *string          `json:"name,omitempty"`
+	FullName         *string          `json:"full_name,omitempty"`
+	Description      *string          `json:"description,omitempty"`
+	Homepage         *string          `json:"homepage,omitempty"`
+	CodeOfConduct    *CodeOfConduct   `json:"code_of_conduct,omitempty"`
+	DefaultBranch    *string          `json:"default_branch,omitempty"`
+	MasterBranch     *string          `json:"master_branch,omitempty"`
+	CreatedAt        *Timestamp       `json:"created_at,omitempty"`
+	PushedAt         *Timestamp       `json:"pushed_at,omitempty"`
+	UpdatedAt        *Timestamp       `json:"updated_at,omitempty"`
+	HTMLURL          *string          `json:"html_url,omitempty"`
+	CloneURL         *string          `json:"clone_url,omitempty"`
+	GitURL           *string          `json:"git_url,omitempty"`
+	MirrorURL        *string          `json:"mirror_url,omitempty"`
+	SSHURL           *string          `json:"ssh_url,omitempty"`
+	SVNURL           *string          `json:"svn_url,omitempty"`
+	Language         *string          `json:"language,omitempty"`
+	Fork             *bool            `json:"fork,omitempty"`
+	ForksCount       *int             `json:"forks_count,omitempty"`
+	NetworkCount     *int             `json:"network_count,omitempty"`
+	OpenIssuesCount  *int             `json:"open_issues_count,omitempty"`
+	StargazersCount  *int             `json:"stargazers_count,omitempty"`
+	SubscribersCount *int             `json:"subscribers_count,omitempty"`
+	WatchersCount    *int             `json:"watchers_count,omitempty"`
+	Size             *int             `json:"size,omitempty"`
+	AutoInit         *bool            `json:"auto_init,omitempty"`
+	Parent           *Repository      `json:"parent,omitempty"`
+	Source           *Repository      `json:"source,omitempty"`
+	Organization     *Organization    `json:"organization,omitempty"`
+	Permissions      *map[string]bool `json:"permissions,omitempty"`
+	AllowRebaseMerge *bool            `json:"allow_rebase_merge,omitempty"`
+	AllowSquashMerge *bool            `json:"allow_squash_merge,omitempty"`
+	AllowMergeCommit *bool            `json:"allow_merge_commit,omitempty"`
+	Topics           []string         `json:"topics,omitempty"`
+
+	// Only provided when using RepositoriesService.Get while in preview
+	License *License `json:"license,omitempty"`
+
+	// Additional mutable fields when creating and editing a repository
+	Private           *bool   `json:"private,omitempty"`
+	HasIssues         *bool   `json:"has_issues,omitempty"`
+	HasWiki           *bool   `json:"has_wiki,omitempty"`
+	HasPages          *bool   `json:"has_pages,omitempty"`
+	HasProjects       *bool   `json:"has_projects,omitempty"`
+	HasDownloads      *bool   `json:"has_downloads,omitempty"`
+	LicenseTemplate   *string `json:"license_template,omitempty"`
+	GitignoreTemplate *string `json:"gitignore_template,omitempty"`
+	Archived          *bool   `json:"archived,omitempty"`
+
+	// Creating an organization repository. Required for non-owners.
+	TeamID *int64 `json:"team_id,omitempty"`
+
+	// API URLs
+	URL              *string `json:"url,omitempty"`
+	ArchiveURL       *string `json:"archive_url,omitempty"`
+	AssigneesURL     *string `json:"assignees_url,omitempty"`
+	BlobsURL         *string `json:"blobs_url,omitempty"`
+	BranchesURL      *string `json:"branches_url,omitempty"`
+	CollaboratorsURL *string `json:"collaborators_url,omitempty"`
+	CommentsURL      *string `json:"comments_url,omitempty"`
+	CommitsURL       *string `json:"commits_url,omitempty"`
+	CompareURL       *string `json:"compare_url,omitempty"`
+	ContentsURL      *string `json:"contents_url,omitempty"`
+	ContributorsURL  *string `json:"contributors_url,omitempty"`
+	DeploymentsURL   *string `json:"deployments_url,omitempty"`
+	DownloadsURL     *string `json:"downloads_url,omitempty"`
+	EventsURL        *string `json:"events_url,omitempty"`
+	ForksURL         *string `json:"forks_url,omitempty"`
+	GitCommitsURL    *string `json:"git_commits_url,omitempty"`
+	GitRefsURL       *string `json:"git_refs_url,omitempty"`
+	GitTagsURL       *string `json:"git_tags_url,omitempty"`
+	HooksURL         *string `json:"hooks_url,omitempty"`
+	IssueCommentURL  *string `json:"issue_comment_url,omitempty"`
+	IssueEventsURL   *string `json:"issue_events_url,omitempty"`
+	IssuesURL        *string `json:"issues_url,omitempty"`
+	KeysURL          *string `json:"keys_url,omitempty"`
+	LabelsURL        *string `json:"labels_url,omitempty"`
+	LanguagesURL     *string `json:"languages_url,omitempty"`
+	MergesURL        *string `json:"merges_url,omitempty"`
+	MilestonesURL    *string `json:"milestones_url,omitempty"`
+	NotificationsURL *string `json:"notifications_url,omitempty"`
+	PullsURL         *string `json:"pulls_url,omitempty"`
+	ReleasesURL      *string `json:"releases_url,omitempty"`
+	StargazersURL    *string `json:"stargazers_url,omitempty"`
+	StatusesURL      *string `json:"statuses_url,omitempty"`
+	SubscribersURL   *string `json:"subscribers_url,omitempty"`
+	SubscriptionURL  *string `json:"subscription_url,omitempty"`
+	TagsURL          *string `json:"tags_url,omitempty"`
+	TreesURL         *string `json:"trees_url,omitempty"`
+	TeamsURL         *string `json:"teams_url,omitempty"`
+
+	// TextMatches is only populated from search results that request text matches
+	// See: search.go and https://developer.github.com/v3/search/#text-match-metadata
+	TextMatches []TextMatch `json:"text_matches,omitempty"`
+}
+
+func (r Repository) String() string {
+	return Stringify(r)
+}
+
+// RepositoryListOptions specifies the optional parameters to the
+// RepositoriesService.List method.
+type RepositoryListOptions struct {
+	// Visibility of repositories to list. Can be one of all, public, or private.
+	// Default: all
+	Visibility string `url:"visibility,omitempty"`
+
+	// List repos of given affiliation[s].
+	// Comma-separated list of values. Can include:
+	// * owner: Repositories that are owned by the authenticated user.
+	// * collaborator: Repositories that the user has been added to as a
+	//   collaborator.
+	// * organization_member: Repositories that the user has access to through
+	//   being a member of an organization. This includes every repository on
+	//   every team that the user is on.
+	// Default: owner,collaborator,organization_member
+	Affiliation string `url:"affiliation,omitempty"`
+
+	// Type of repositories to list.
+	// Can be one of all, owner, public, private, member. Default: all
+	// Will cause a 422 error if used in the same request as visibility or
+	// affiliation.
+	Type string `url:"type,omitempty"`
+
+	// How to sort the repository list. Can be one of created, updated, pushed,
+	// full_name. Default: full_name
+	Sort string `url:"sort,omitempty"`
+
+	// Direction in which to sort repositories. Can be one of asc or desc.
+	// Default: when using full_name: asc; otherwise desc
+	Direction string `url:"direction,omitempty"`
+
+	ListOptions
+}
+
+// List the repositories for a user. Passing the empty string will list
+// repositories for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#list-user-repositories
+func (s *RepositoriesService) List(ctx context.Context, user string, opt *RepositoryListOptions) ([]*Repository, *Response, error) {
+	var u string
+	if user != "" {
+		u = fmt.Sprintf("users/%v/repos", user)
+	} else {
+		u = "user/repos"
+	}
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeLicensesPreview, mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	var repos []*Repository
+	resp, err := s.client.Do(ctx, req, &repos)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repos, resp, nil
+}
+
+// RepositoryListByOrgOptions specifies the optional parameters to the
+// RepositoriesService.ListByOrg method.
+type RepositoryListByOrgOptions struct {
+	// Type of repositories to list. Possible values are: all, public, private,
+	// forks, sources, member. Default is "all".
+	Type string `url:"type,omitempty"`
+
+	ListOptions
+}
+
+// ListByOrg lists the repositories for an organization.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#list-organization-repositories
+func (s *RepositoriesService) ListByOrg(ctx context.Context, org string, opt *RepositoryListByOrgOptions) ([]*Repository, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/repos", org)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeLicensesPreview, mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	var repos []*Repository
+	resp, err := s.client.Do(ctx, req, &repos)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repos, resp, nil
+}
+
+// RepositoryListAllOptions specifies the optional parameters to the
+// RepositoriesService.ListAll method.
+type RepositoryListAllOptions struct {
+	// ID of the last repository seen
+	Since int64 `url:"since,omitempty"`
+}
+
+// ListAll lists all GitHub repositories in the order that they were created.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#list-all-public-repositories
+func (s *RepositoriesService) ListAll(ctx context.Context, opt *RepositoryListAllOptions) ([]*Repository, *Response, error) {
+	u, err := addOptions("repositories", opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var repos []*Repository
+	resp, err := s.client.Do(ctx, req, &repos)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repos, resp, nil
+}
+
+// Create a new repository. If an organization is specified, the new
+// repository will be created under that org. If the empty string is
+// specified, it will be created for the authenticated user.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#create
+func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repository) (*Repository, *Response, error) {
+	var u string
+	if org != "" {
+		u = fmt.Sprintf("orgs/%v/repos", org)
+	} else {
+		u = "user/repos"
+	}
+
+	req, err := s.client.NewRequest("POST", u, repo)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r := new(Repository)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// Get fetches a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#get
+func (s *RepositoriesService) Get(ctx context.Context, owner, repo string) (*Repository, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when the license support fully launches
+	// https://developer.github.com/v3/licenses/#get-a-repositorys-license
+	acceptHeaders := []string{mediaTypeLicensesPreview, mediaTypeCodesOfConductPreview, mediaTypeTopicsPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	repository := new(Repository)
+	resp, err := s.client.Do(ctx, req, repository)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repository, resp, nil
+}
+
+// GetCodeOfConduct gets the contents of a repository's code of conduct.
+//
+// GitHub API docs: https://developer.github.com/v3/codes_of_conduct/#get-the-contents-of-a-repositorys-code-of-conduct
+func (s *RepositoriesService) GetCodeOfConduct(ctx context.Context, owner, repo string) (*CodeOfConduct, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/community/code_of_conduct", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeCodesOfConductPreview)
+
+	coc := new(CodeOfConduct)
+	resp, err := s.client.Do(ctx, req, coc)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return coc, resp, nil
+}
+
+// GetByID fetches a repository.
+//
+// Note: GetByID uses the undocumented GitHub API endpoint /repositories/:id.
+func (s *RepositoriesService) GetByID(ctx context.Context, id int64) (*Repository, *Response, error) {
+	u := fmt.Sprintf("repositories/%d", id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when the license support fully launches
+	// https://developer.github.com/v3/licenses/#get-a-repositorys-license
+	req.Header.Set("Accept", mediaTypeLicensesPreview)
+
+	repository := new(Repository)
+	resp, err := s.client.Do(ctx, req, repository)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repository, resp, nil
+}
+
+// Edit updates a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#edit
+func (s *RepositoriesService) Edit(ctx context.Context, owner, repo string, repository *Repository) (*Repository, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v", owner, repo)
+	req, err := s.client.NewRequest("PATCH", u, repository)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r := new(Repository)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// Delete a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#delete-a-repository
+func (s *RepositoriesService) Delete(ctx context.Context, owner, repo string) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v", owner, repo)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// Contributor represents a repository contributor
+type Contributor struct {
+	Login             *string `json:"login,omitempty"`
+	ID                *int64  `json:"id,omitempty"`
+	AvatarURL         *string `json:"avatar_url,omitempty"`
+	GravatarID        *string `json:"gravatar_id,omitempty"`
+	URL               *string `json:"url,omitempty"`
+	HTMLURL           *string `json:"html_url,omitempty"`
+	FollowersURL      *string `json:"followers_url,omitempty"`
+	FollowingURL      *string `json:"following_url,omitempty"`
+	GistsURL          *string `json:"gists_url,omitempty"`
+	StarredURL        *string `json:"starred_url,omitempty"`
+	SubscriptionsURL  *string `json:"subscriptions_url,omitempty"`
+	OrganizationsURL  *string `json:"organizations_url,omitempty"`
+	ReposURL          *string `json:"repos_url,omitempty"`
+	EventsURL         *string `json:"events_url,omitempty"`
+	ReceivedEventsURL *string `json:"received_events_url,omitempty"`
+	Type              *string `json:"type,omitempty"`
+	SiteAdmin         *bool   `json:"site_admin,omitempty"`
+	Contributions     *int    `json:"contributions,omitempty"`
+}
+
+// ListContributorsOptions specifies the optional parameters to the
+// RepositoriesService.ListContributors method.
+type ListContributorsOptions struct {
+	// Include anonymous contributors in results or not
+	Anon string `url:"anon,omitempty"`
+
+	ListOptions
+}
+
+// ListContributors lists contributors for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#list-contributors
+func (s *RepositoriesService) ListContributors(ctx context.Context, owner string, repository string, opt *ListContributorsOptions) ([]*Contributor, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/contributors", owner, repository)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var contributor []*Contributor
+	resp, err := s.client.Do(ctx, req, &contributor)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	return contributor, resp, nil
+}
+
+// ListLanguages lists languages for the specified repository. The returned map
+// specifies the languages and the number of bytes of code written in that
+// language. For example:
+//
+//     {
+//       "C": 78769,
+//       "Python": 7769
+//     }
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#list-languages
+func (s *RepositoriesService) ListLanguages(ctx context.Context, owner string, repo string) (map[string]int, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/languages", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	languages := make(map[string]int)
+	resp, err := s.client.Do(ctx, req, &languages)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return languages, resp, nil
+}
+
+// ListTeams lists the teams for the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#list-teams
+func (s *RepositoriesService) ListTeams(ctx context.Context, owner string, repo string, opt *ListOptions) ([]*Team, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/teams", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	var teams []*Team
+	resp, err := s.client.Do(ctx, req, &teams)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return teams, resp, nil
+}
+
+// RepositoryTag represents a repository tag.
+type RepositoryTag struct {
+	Name       *string `json:"name,omitempty"`
+	Commit     *Commit `json:"commit,omitempty"`
+	ZipballURL *string `json:"zipball_url,omitempty"`
+	TarballURL *string `json:"tarball_url,omitempty"`
+}
+
+// ListTags lists tags for the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#list-tags
+func (s *RepositoriesService) ListTags(ctx context.Context, owner string, repo string, opt *ListOptions) ([]*RepositoryTag, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/tags", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var tags []*RepositoryTag
+	resp, err := s.client.Do(ctx, req, &tags)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return tags, resp, nil
+}
+
+// Branch represents a repository branch
+type Branch struct {
+	Name      *string           `json:"name,omitempty"`
+	Commit    *RepositoryCommit `json:"commit,omitempty"`
+	Protected *bool             `json:"protected,omitempty"`
+}
+
+// Protection represents a repository branch's protection.
+type Protection struct {
+	RequiredStatusChecks       *RequiredStatusChecks          `json:"required_status_checks"`
+	RequiredPullRequestReviews *PullRequestReviewsEnforcement `json:"required_pull_request_reviews"`
+	EnforceAdmins              *AdminEnforcement              `json:"enforce_admins"`
+	Restrictions               *BranchRestrictions            `json:"restrictions"`
+}
+
+// ProtectionRequest represents a request to create/edit a branch's protection.
+type ProtectionRequest struct {
+	RequiredStatusChecks       *RequiredStatusChecks                 `json:"required_status_checks"`
+	RequiredPullRequestReviews *PullRequestReviewsEnforcementRequest `json:"required_pull_request_reviews"`
+	EnforceAdmins              bool                                  `json:"enforce_admins"`
+	Restrictions               *BranchRestrictionsRequest            `json:"restrictions"`
+}
+
+// RequiredStatusChecks represents the protection status of a individual branch.
+type RequiredStatusChecks struct {
+	// Require branches to be up to date before merging. (Required.)
+	Strict bool `json:"strict"`
+	// The list of status checks to require in order to merge into this
+	// branch. (Required; use []string{} instead of nil for empty list.)
+	Contexts []string `json:"contexts"`
+}
+
+// PullRequestReviewsEnforcement represents the pull request reviews enforcement of a protected branch.
+type PullRequestReviewsEnforcement struct {
+	// Specifies which users and teams can dismiss pull request reviews.
+	DismissalRestrictions DismissalRestrictions `json:"dismissal_restrictions"`
+	// Specifies if approved reviews are dismissed automatically, when a new commit is pushed.
+	DismissStaleReviews bool `json:"dismiss_stale_reviews"`
+	// RequireCodeOwnerReviews specifies if an approved review is required in pull requests including files with a designated code owner.
+	RequireCodeOwnerReviews bool `json:"require_code_owner_reviews"`
+}
+
+// PullRequestReviewsEnforcementRequest represents request to set the pull request review
+// enforcement of a protected branch. It is separate from PullRequestReviewsEnforcement above
+// because the request structure is different from the response structure.
+type PullRequestReviewsEnforcementRequest struct {
+	// Specifies which users and teams should be allowed to dismiss pull request reviews. Can be nil to disable the restrictions.
+	DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions"`
+	// Specifies if approved reviews can be dismissed automatically, when a new commit is pushed. (Required)
+	DismissStaleReviews bool `json:"dismiss_stale_reviews"`
+	// RequireCodeOwnerReviews specifies if an approved review is required in pull requests including files with a designated code owner.
+	RequireCodeOwnerReviews bool `json:"require_code_owner_reviews"`
+}
+
+// MarshalJSON implements the json.Marshaler interface.
+// Converts nil value of PullRequestReviewsEnforcementRequest.DismissalRestrictionsRequest to empty array
+func (req PullRequestReviewsEnforcementRequest) MarshalJSON() ([]byte, error) {
+	if req.DismissalRestrictionsRequest == nil {
+		newReq := struct {
+			R []interface{} `json:"dismissal_restrictions"`
+			D bool          `json:"dismiss_stale_reviews"`
+			O bool          `json:"require_code_owner_reviews"`
+		}{
+			R: []interface{}{},
+			D: req.DismissStaleReviews,
+			O: req.RequireCodeOwnerReviews,
+		}
+		return json.Marshal(newReq)
+	}
+	newReq := struct {
+		R *DismissalRestrictionsRequest `json:"dismissal_restrictions"`
+		D bool                          `json:"dismiss_stale_reviews"`
+		O bool                          `json:"require_code_owner_reviews"`
+	}{
+		R: req.DismissalRestrictionsRequest,
+		D: req.DismissStaleReviews,
+		O: req.RequireCodeOwnerReviews,
+	}
+	return json.Marshal(newReq)
+}
+
+// PullRequestReviewsEnforcementUpdate represents request to patch the pull request review
+// enforcement of a protected branch. It is separate from PullRequestReviewsEnforcementRequest above
+// because the patch request does not require all fields to be initialized.
+type PullRequestReviewsEnforcementUpdate struct {
+	// Specifies which users and teams can dismiss pull request reviews. Can be omitted.
+	DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions,omitempty"`
+	// Specifies if approved reviews can be dismissed automatically, when a new commit is pushed. Can be omitted.
+	DismissStaleReviews *bool `json:"dismiss_stale_reviews,omitempty"`
+	// RequireCodeOwnerReviews specifies if an approved review is required in pull requests including files with a designated code owner.
+	RequireCodeOwnerReviews bool `json:"require_code_owner_reviews,omitempty"`
+}
+
+// AdminEnforcement represents the configuration to enforce required status checks for repository administrators.
+type AdminEnforcement struct {
+	URL     *string `json:"url,omitempty"`
+	Enabled bool    `json:"enabled"`
+}
+
+// BranchRestrictions represents the restriction that only certain users or
+// teams may push to a branch.
+type BranchRestrictions struct {
+	// The list of user logins with push access.
+	Users []*User `json:"users"`
+	// The list of team slugs with push access.
+	Teams []*Team `json:"teams"`
+}
+
+// BranchRestrictionsRequest represents the request to create/edit the
+// restriction that only certain users or teams may push to a branch. It is
+// separate from BranchRestrictions above because the request structure is
+// different from the response structure.
+type BranchRestrictionsRequest struct {
+	// The list of user logins with push access. (Required; use []string{} instead of nil for empty list.)
+	Users []string `json:"users"`
+	// The list of team slugs with push access. (Required; use []string{} instead of nil for empty list.)
+	Teams []string `json:"teams"`
+}
+
+// DismissalRestrictions specifies which users and teams can dismiss pull request reviews.
+type DismissalRestrictions struct {
+	// The list of users who can dimiss pull request reviews.
+	Users []*User `json:"users"`
+	// The list of teams which can dismiss pull request reviews.
+	Teams []*Team `json:"teams"`
+}
+
+// DismissalRestrictionsRequest represents the request to create/edit the
+// restriction to allows only specific users or teams to dimiss pull request reviews. It is
+// separate from DismissalRestrictions above because the request structure is
+// different from the response structure.
+type DismissalRestrictionsRequest struct {
+	// The list of user logins who can dismiss pull request reviews. (Required; use []string{} instead of nil for empty list.)
+	Users []string `json:"users"`
+	// The list of team slugs which can dismiss pull request reviews. (Required; use []string{} instead of nil for empty list.)
+	Teams []string `json:"teams"`
+}
+
+// ListBranches lists branches for the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#list-branches
+func (s *RepositoriesService) ListBranches(ctx context.Context, owner string, repo string, opt *ListOptions) ([]*Branch, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeProtectedBranchesPreview)
+
+	var branches []*Branch
+	resp, err := s.client.Do(ctx, req, &branches)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return branches, resp, nil
+}
+
+// GetBranch gets the specified branch for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#get-branch
+func (s *RepositoriesService) GetBranch(ctx context.Context, owner, repo, branch string) (*Branch, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v", owner, repo, branch)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeProtectedBranchesPreview)
+
+	b := new(Branch)
+	resp, err := s.client.Do(ctx, req, b)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return b, resp, nil
+}
+
+// GetBranchProtection gets the protection of a given branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-branch-protection
+func (s *RepositoriesService) GetBranchProtection(ctx context.Context, owner, repo, branch string) (*Protection, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection", owner, repo, branch)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeProtectedBranchesPreview)
+
+	p := new(Protection)
+	resp, err := s.client.Do(ctx, req, p)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return p, resp, nil
+}
+
+// GetRequiredStatusChecks gets the required status checks for a given protected branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-required-status-checks-of-protected-branch
+func (s *RepositoriesService) GetRequiredStatusChecks(ctx context.Context, owner, repo, branch string) (*RequiredStatusChecks, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks", owner, repo, branch)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeProtectedBranchesPreview)
+
+	p := new(RequiredStatusChecks)
+	resp, err := s.client.Do(ctx, req, p)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return p, resp, nil
+}
+
+// ListRequiredStatusChecksContexts lists the required status checks contexts for a given protected branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#list-required-status-checks-contexts-of-protected-branch
+func (s *RepositoriesService) ListRequiredStatusChecksContexts(ctx context.Context, owner, repo, branch string) (contexts []string, resp *Response, err error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_status_checks/contexts", owner, repo, branch)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeProtectedBranchesPreview)
+
+	resp, err = s.client.Do(ctx, req, &contexts)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return contexts, resp, nil
+}
+
+// UpdateBranchProtection updates the protection of a given branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-branch-protection
+func (s *RepositoriesService) UpdateBranchProtection(ctx context.Context, owner, repo, branch string, preq *ProtectionRequest) (*Protection, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection", owner, repo, branch)
+	req, err := s.client.NewRequest("PUT", u, preq)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeProtectedBranchesPreview)
+
+	p := new(Protection)
+	resp, err := s.client.Do(ctx, req, p)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return p, resp, nil
+}
+
+// RemoveBranchProtection removes the protection of a given branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-branch-protection
+func (s *RepositoriesService) RemoveBranchProtection(ctx context.Context, owner, repo, branch string) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection", owner, repo, branch)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeProtectedBranchesPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// License gets the contents of a repository's license if one is detected.
+//
+// GitHub API docs: https://developer.github.com/v3/licenses/#get-the-contents-of-a-repositorys-license
+func (s *RepositoriesService) License(ctx context.Context, owner, repo string) (*RepositoryLicense, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/license", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r := &RepositoryLicense{}
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// GetPullRequestReviewEnforcement gets pull request review enforcement of a protected branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-pull-request-review-enforcement-of-protected-branch
+func (s *RepositoriesService) GetPullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string) (*PullRequestReviewsEnforcement, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeProtectedBranchesPreview)
+
+	r := new(PullRequestReviewsEnforcement)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// UpdatePullRequestReviewEnforcement patches pull request review enforcement of a protected branch.
+// It requires admin access and branch protection to be enabled.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-pull-request-review-enforcement-of-protected-branch
+func (s *RepositoriesService) UpdatePullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string, patch *PullRequestReviewsEnforcementUpdate) (*PullRequestReviewsEnforcement, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch)
+	req, err := s.client.NewRequest("PATCH", u, patch)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeProtectedBranchesPreview)
+
+	r := new(PullRequestReviewsEnforcement)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, err
+}
+
+// DisableDismissalRestrictions disables dismissal restrictions of a protected branch.
+// It requires admin access and branch protection to be enabled.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#update-pull-request-review-enforcement-of-protected-branch
+func (s *RepositoriesService) DisableDismissalRestrictions(ctx context.Context, owner, repo, branch string) (*PullRequestReviewsEnforcement, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch)
+
+	data := struct {
+		R []interface{} `json:"dismissal_restrictions"`
+	}{[]interface{}{}}
+
+	req, err := s.client.NewRequest("PATCH", u, data)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeProtectedBranchesPreview)
+
+	r := new(PullRequestReviewsEnforcement)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, err
+}
+
+// RemovePullRequestReviewEnforcement removes pull request enforcement of a protected branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-pull-request-review-enforcement-of-protected-branch
+func (s *RepositoriesService) RemovePullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeProtectedBranchesPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// GetAdminEnforcement gets admin enforcement information of a protected branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-admin-enforcement-of-protected-branch
+func (s *RepositoriesService) GetAdminEnforcement(ctx context.Context, owner, repo, branch string) (*AdminEnforcement, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeProtectedBranchesPreview)
+
+	r := new(AdminEnforcement)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
+// AddAdminEnforcement adds admin enforcement to a protected branch.
+// It requires admin access and branch protection to be enabled.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#add-admin-enforcement-of-protected-branch
+func (s *RepositoriesService) AddAdminEnforcement(ctx context.Context, owner, repo, branch string) (*AdminEnforcement, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch)
+	req, err := s.client.NewRequest("POST", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeProtectedBranchesPreview)
+
+	r := new(AdminEnforcement)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, err
+}
+
+// RemoveAdminEnforcement removes admin enforcement from a protected branch.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-admin-enforcement-of-protected-branch
+func (s *RepositoriesService) RemoveAdminEnforcement(ctx context.Context, owner, repo, branch string) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/enforce_admins", owner, repo, branch)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches
+	req.Header.Set("Accept", mediaTypeProtectedBranchesPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// repositoryTopics represents a collection of repository topics.
+type repositoryTopics struct {
+	Names []string `json:"names"`
+}
+
+// ListAllTopics lists topics for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#list-all-topics-for-a-repository
+func (s *RepositoriesService) ListAllTopics(ctx context.Context, owner, repo string) ([]string, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/topics", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeTopicsPreview)
+
+	topics := new(repositoryTopics)
+	resp, err := s.client.Do(ctx, req, topics)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return topics.Names, resp, nil
+}
+
+// ReplaceAllTopics replaces topics for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#replace-all-topics-for-a-repository
+func (s *RepositoriesService) ReplaceAllTopics(ctx context.Context, owner, repo string, topics []string) ([]string, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/topics", owner, repo)
+	t := &repositoryTopics{
+		Names: topics,
+	}
+	if t.Names == nil {
+		t.Names = []string{}
+	}
+	req, err := s.client.NewRequest("PUT", u, t)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeTopicsPreview)
+
+	t = new(repositoryTopics)
+	resp, err := s.client.Do(ctx, req, t)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return t.Names, resp, nil
+}
+
+// TransferRequest represents a request to transfer a repository.
+type TransferRequest struct {
+	NewOwner string  `json:"new_owner"`
+	TeamID   []int64 `json:"team_id,omitempty"`
+}
+
+// Transfer transfers a repository from one account or organization to another.
+//
+// This method might return an *AcceptedError and a status code of
+// 202. This is because this is the status that GitHub returns to signify that
+// it has now scheduled the transfer of the repository in a background task.
+// A follow up request, after a delay of a second or so, should result
+// in a successful request.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#transfer-a-repository
+func (s *RepositoriesService) Transfer(ctx context.Context, owner, repo string, transfer TransferRequest) (*Repository, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/transfer", owner, repo)
+
+	req, err := s.client.NewRequest("POST", u, &transfer)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeRepositoryTransferPreview)
+
+	r := new(Repository)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}

+ 140 - 0
vendor/github.com/google/go-github/github/repos_collaborators.go

@@ -0,0 +1,140 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ListCollaboratorsOptions specifies the optional parameters to the
+// RepositoriesService.ListCollaborators method.
+type ListCollaboratorsOptions struct {
+	// Affiliation specifies how collaborators should be filtered by their affiliation.
+	// Possible values are:
+	//     outside - All outside collaborators of an organization-owned repository
+	//     direct - All collaborators with permissions to an organization-owned repository,
+	//              regardless of organization membership status
+	//     all - All collaborators the authenticated user can see
+	//
+	// Default value is "all".
+	Affiliation string `url:"affiliation,omitempty"`
+
+	ListOptions
+}
+
+// ListCollaborators lists the GitHub users that have access to the repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#list-collaborators
+func (s *RepositoriesService) ListCollaborators(ctx context.Context, owner, repo string, opt *ListCollaboratorsOptions) ([]*User, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/collaborators", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
+
+	var users []*User
+	resp, err := s.client.Do(ctx, req, &users)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return users, resp, nil
+}
+
+// IsCollaborator checks whether the specified GitHub user has collaborator
+// access to the given repo.
+// Note: This will return false if the user is not a collaborator OR the user
+// is not a GitHub user.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#get
+func (s *RepositoriesService) IsCollaborator(ctx context.Context, owner, repo, user string) (bool, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return false, nil, err
+	}
+
+	resp, err := s.client.Do(ctx, req, nil)
+	isCollab, err := parseBoolResponse(err)
+	return isCollab, resp, err
+}
+
+// RepositoryPermissionLevel represents the permission level an organization
+// member has for a given repository.
+type RepositoryPermissionLevel struct {
+	// Possible values: "admin", "write", "read", "none"
+	Permission *string `json:"permission,omitempty"`
+
+	User *User `json:"user,omitempty"`
+}
+
+// GetPermissionLevel retrieves the specific permission level a collaborator has for a given repository.
+// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#review-a-users-permission-level
+func (s *RepositoriesService) GetPermissionLevel(ctx context.Context, owner, repo, user string) (*RepositoryPermissionLevel, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/collaborators/%v/permission", owner, repo, user)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	rpl := new(RepositoryPermissionLevel)
+	resp, err := s.client.Do(ctx, req, rpl)
+	if err != nil {
+		return nil, resp, err
+	}
+	return rpl, resp, nil
+}
+
+// RepositoryAddCollaboratorOptions specifies the optional parameters to the
+// RepositoriesService.AddCollaborator method.
+type RepositoryAddCollaboratorOptions struct {
+	// Permission specifies the permission to grant the user on this repository.
+	// Possible values are:
+	//     pull - team members can pull, but not push to or administer this repository
+	//     push - team members can pull and push, but not administer this repository
+	//     admin - team members can pull, push and administer this repository
+	//
+	// Default value is "push". This option is only valid for organization-owned repositories.
+	Permission string `json:"permission,omitempty"`
+}
+
+// AddCollaborator sends an invitation to the specified GitHub user
+// to become a collaborator to the given repo.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#add-user-as-a-collaborator
+func (s *RepositoriesService) AddCollaborator(ctx context.Context, owner, repo, user string, opt *RepositoryAddCollaboratorOptions) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user)
+	req, err := s.client.NewRequest("PUT", u, opt)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeRepositoryInvitationsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// RemoveCollaborator removes the specified GitHub user as collaborator from the given repo.
+// Note: Does not return error if a valid user that is not a collaborator is removed.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#remove-collaborator
+func (s *RepositoriesService) RemoveCollaborator(ctx context.Context, owner, repo, user string) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}

+ 161 - 0
vendor/github.com/google/go-github/github/repos_comments.go

@@ -0,0 +1,161 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// RepositoryComment represents a comment for a commit, file, or line in a repository.
+type RepositoryComment struct {
+	HTMLURL   *string    `json:"html_url,omitempty"`
+	URL       *string    `json:"url,omitempty"`
+	ID        *int64     `json:"id,omitempty"`
+	CommitID  *string    `json:"commit_id,omitempty"`
+	User      *User      `json:"user,omitempty"`
+	Reactions *Reactions `json:"reactions,omitempty"`
+	CreatedAt *time.Time `json:"created_at,omitempty"`
+	UpdatedAt *time.Time `json:"updated_at,omitempty"`
+
+	// User-mutable fields
+	Body *string `json:"body"`
+	// User-initialized fields
+	Path     *string `json:"path,omitempty"`
+	Position *int    `json:"position,omitempty"`
+}
+
+func (r RepositoryComment) String() string {
+	return Stringify(r)
+}
+
+// ListComments lists all the comments for the repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/comments/#list-commit-comments-for-a-repository
+func (s *RepositoriesService) ListComments(ctx context.Context, owner, repo string, opt *ListOptions) ([]*RepositoryComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/comments", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	var comments []*RepositoryComment
+	resp, err := s.client.Do(ctx, req, &comments)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return comments, resp, nil
+}
+
+// ListCommitComments lists all the comments for a given commit SHA.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/comments/#list-comments-for-a-single-commit
+func (s *RepositoriesService) ListCommitComments(ctx context.Context, owner, repo, sha string, opt *ListOptions) ([]*RepositoryComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/commits/%v/comments", owner, repo, sha)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	var comments []*RepositoryComment
+	resp, err := s.client.Do(ctx, req, &comments)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return comments, resp, nil
+}
+
+// CreateComment creates a comment for the given commit.
+// Note: GitHub allows for comments to be created for non-existing files and positions.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/comments/#create-a-commit-comment
+func (s *RepositoriesService) CreateComment(ctx context.Context, owner, repo, sha string, comment *RepositoryComment) (*RepositoryComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/commits/%v/comments", owner, repo, sha)
+	req, err := s.client.NewRequest("POST", u, comment)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	c := new(RepositoryComment)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// GetComment gets a single comment from a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/comments/#get-a-single-commit-comment
+func (s *RepositoriesService) GetComment(ctx context.Context, owner, repo string, id int64) (*RepositoryComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/comments/%v", owner, repo, id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeReactionsPreview)
+
+	c := new(RepositoryComment)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// UpdateComment updates the body of a single comment.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/comments/#update-a-commit-comment
+func (s *RepositoriesService) UpdateComment(ctx context.Context, owner, repo string, id int64, comment *RepositoryComment) (*RepositoryComment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/comments/%v", owner, repo, id)
+	req, err := s.client.NewRequest("PATCH", u, comment)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	c := new(RepositoryComment)
+	resp, err := s.client.Do(ctx, req, c)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return c, resp, nil
+}
+
+// DeleteComment deletes a single comment from a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/comments/#delete-a-commit-comment
+func (s *RepositoriesService) DeleteComment(ctx context.Context, owner, repo string, id int64) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/comments/%v", owner, repo, id)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}

+ 237 - 0
vendor/github.com/google/go-github/github/repos_commits.go

@@ -0,0 +1,237 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"time"
+)
+
+// RepositoryCommit represents a commit in a repo.
+// Note that it's wrapping a Commit, so author/committer information is in two places,
+// but contain different details about them: in RepositoryCommit "github details", in Commit - "git details".
+type RepositoryCommit struct {
+	SHA         *string  `json:"sha,omitempty"`
+	Commit      *Commit  `json:"commit,omitempty"`
+	Author      *User    `json:"author,omitempty"`
+	Committer   *User    `json:"committer,omitempty"`
+	Parents     []Commit `json:"parents,omitempty"`
+	HTMLURL     *string  `json:"html_url,omitempty"`
+	URL         *string  `json:"url,omitempty"`
+	CommentsURL *string  `json:"comments_url,omitempty"`
+
+	// Details about how many changes were made in this commit. Only filled in during GetCommit!
+	Stats *CommitStats `json:"stats,omitempty"`
+	// Details about which files, and how this commit touched. Only filled in during GetCommit!
+	Files []CommitFile `json:"files,omitempty"`
+}
+
+func (r RepositoryCommit) String() string {
+	return Stringify(r)
+}
+
+// CommitStats represents the number of additions / deletions from a file in a given RepositoryCommit or GistCommit.
+type CommitStats struct {
+	Additions *int `json:"additions,omitempty"`
+	Deletions *int `json:"deletions,omitempty"`
+	Total     *int `json:"total,omitempty"`
+}
+
+func (c CommitStats) String() string {
+	return Stringify(c)
+}
+
+// CommitFile represents a file modified in a commit.
+type CommitFile struct {
+	SHA         *string `json:"sha,omitempty"`
+	Filename    *string `json:"filename,omitempty"`
+	Additions   *int    `json:"additions,omitempty"`
+	Deletions   *int    `json:"deletions,omitempty"`
+	Changes     *int    `json:"changes,omitempty"`
+	Status      *string `json:"status,omitempty"`
+	Patch       *string `json:"patch,omitempty"`
+	BlobURL     *string `json:"blob_url,omitempty"`
+	RawURL      *string `json:"raw_url,omitempty"`
+	ContentsURL *string `json:"contents_url,omitempty"`
+}
+
+func (c CommitFile) String() string {
+	return Stringify(c)
+}
+
+// CommitsComparison is the result of comparing two commits.
+// See CompareCommits() for details.
+type CommitsComparison struct {
+	BaseCommit      *RepositoryCommit `json:"base_commit,omitempty"`
+	MergeBaseCommit *RepositoryCommit `json:"merge_base_commit,omitempty"`
+
+	// Head can be 'behind' or 'ahead'
+	Status       *string `json:"status,omitempty"`
+	AheadBy      *int    `json:"ahead_by,omitempty"`
+	BehindBy     *int    `json:"behind_by,omitempty"`
+	TotalCommits *int    `json:"total_commits,omitempty"`
+
+	Commits []RepositoryCommit `json:"commits,omitempty"`
+
+	Files []CommitFile `json:"files,omitempty"`
+
+	HTMLURL      *string `json:"html_url,omitempty"`
+	PermalinkURL *string `json:"permalink_url,omitempty"`
+	DiffURL      *string `json:"diff_url,omitempty"`
+	PatchURL     *string `json:"patch_url,omitempty"`
+	URL          *string `json:"url,omitempty"` // API URL.
+}
+
+func (c CommitsComparison) String() string {
+	return Stringify(c)
+}
+
+// CommitsListOptions specifies the optional parameters to the
+// RepositoriesService.ListCommits method.
+type CommitsListOptions struct {
+	// SHA or branch to start listing Commits from.
+	SHA string `url:"sha,omitempty"`
+
+	// Path that should be touched by the returned Commits.
+	Path string `url:"path,omitempty"`
+
+	// Author of by which to filter Commits.
+	Author string `url:"author,omitempty"`
+
+	// Since when should Commits be included in the response.
+	Since time.Time `url:"since,omitempty"`
+
+	// Until when should Commits be included in the response.
+	Until time.Time `url:"until,omitempty"`
+
+	ListOptions
+}
+
+// ListCommits lists the commits of a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/commits/#list
+func (s *RepositoriesService) ListCommits(ctx context.Context, owner, repo string, opt *CommitsListOptions) ([]*RepositoryCommit, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/commits", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGitSigningPreview)
+
+	var commits []*RepositoryCommit
+	resp, err := s.client.Do(ctx, req, &commits)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return commits, resp, nil
+}
+
+// GetCommit fetches the specified commit, including all details about it.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/commits/#get-a-single-commit
+// See also: https://developer.github.com/v3/git/commits/#get-a-single-commit provides the same functionality
+func (s *RepositoriesService) GetCommit(ctx context.Context, owner, repo, sha string) (*RepositoryCommit, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, sha)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGitSigningPreview)
+
+	commit := new(RepositoryCommit)
+	resp, err := s.client.Do(ctx, req, commit)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return commit, resp, nil
+}
+
+// GetCommitRaw fetches the specified commit in raw (diff or patch) format.
+func (s *RepositoriesService) GetCommitRaw(ctx context.Context, owner string, repo string, sha string, opt RawOptions) (string, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, sha)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return "", nil, err
+	}
+
+	switch opt.Type {
+	case Diff:
+		req.Header.Set("Accept", mediaTypeV3Diff)
+	case Patch:
+		req.Header.Set("Accept", mediaTypeV3Patch)
+	default:
+		return "", nil, fmt.Errorf("unsupported raw type %d", opt.Type)
+	}
+
+	var buf bytes.Buffer
+	resp, err := s.client.Do(ctx, req, &buf)
+	if err != nil {
+		return "", resp, err
+	}
+
+	return buf.String(), resp, nil
+}
+
+// GetCommitSHA1 gets the SHA-1 of a commit reference. If a last-known SHA1 is
+// supplied and no new commits have occurred, a 304 Unmodified response is returned.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/commits/#get-the-sha-1-of-a-commit-reference
+func (s *RepositoriesService) GetCommitSHA1(ctx context.Context, owner, repo, ref, lastSHA string) (string, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, ref)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return "", nil, err
+	}
+	if lastSHA != "" {
+		req.Header.Set("If-None-Match", `"`+lastSHA+`"`)
+	}
+
+	req.Header.Set("Accept", mediaTypeV3SHA)
+
+	var buf bytes.Buffer
+	resp, err := s.client.Do(ctx, req, &buf)
+	if err != nil {
+		return "", resp, err
+	}
+
+	return buf.String(), resp, nil
+}
+
+// CompareCommits compares a range of commits with each other.
+// todo: support media formats - https://github.com/google/go-github/issues/6
+//
+// GitHub API docs: https://developer.github.com/v3/repos/commits/index.html#compare-two-commits
+func (s *RepositoriesService) CompareCommits(ctx context.Context, owner, repo string, base, head string) (*CommitsComparison, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/compare/%v...%v", owner, repo, base, head)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	comp := new(CommitsComparison)
+	resp, err := s.client.Do(ctx, req, comp)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return comp, resp, nil
+}

+ 57 - 0
vendor/github.com/google/go-github/github/repos_community_health.go

@@ -0,0 +1,57 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// Metric represents the different fields for one file in community health files.
+type Metric struct {
+	Name    *string `json:"name"`
+	Key     *string `json:"key"`
+	URL     *string `json:"url"`
+	HTMLURL *string `json:"html_url"`
+}
+
+// CommunityHealthFiles represents the different files in the community health metrics response.
+type CommunityHealthFiles struct {
+	CodeOfConduct *Metric `json:"code_of_conduct"`
+	Contributing  *Metric `json:"contributing"`
+	License       *Metric `json:"license"`
+	Readme        *Metric `json:"readme"`
+}
+
+// CommunityHealthMetrics represents a response containing the community metrics of a repository.
+type CommunityHealthMetrics struct {
+	HealthPercentage *int                  `json:"health_percentage"`
+	Files            *CommunityHealthFiles `json:"files"`
+	UpdatedAt        *time.Time            `json:"updated_at"`
+}
+
+// GetCommunityHealthMetrics retrieves all the community health  metrics for a  repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/community/#retrieve-community-health-metrics
+func (s *RepositoriesService) GetCommunityHealthMetrics(ctx context.Context, owner, repo string) (*CommunityHealthMetrics, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/community/profile", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeRepositoryCommunityHealthMetricsPreview)
+
+	metrics := &CommunityHealthMetrics{}
+	resp, err := s.client.Do(ctx, req, metrics)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return metrics, resp, nil
+}

+ 266 - 0
vendor/github.com/google/go-github/github/repos_contents.go

@@ -0,0 +1,266 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Repository contents API methods.
+// GitHub API docs: https://developer.github.com/v3/repos/contents/
+
+package github
+
+import (
+	"context"
+	"encoding/base64"
+	"encoding/json"
+	"fmt"
+	"io"
+	"net/http"
+	"net/url"
+	"path"
+)
+
+// RepositoryContent represents a file or directory in a github repository.
+type RepositoryContent struct {
+	Type     *string `json:"type,omitempty"`
+	Encoding *string `json:"encoding,omitempty"`
+	Size     *int    `json:"size,omitempty"`
+	Name     *string `json:"name,omitempty"`
+	Path     *string `json:"path,omitempty"`
+	// Content contains the actual file content, which may be encoded.
+	// Callers should call GetContent which will decode the content if
+	// necessary.
+	Content     *string `json:"content,omitempty"`
+	SHA         *string `json:"sha,omitempty"`
+	URL         *string `json:"url,omitempty"`
+	GitURL      *string `json:"git_url,omitempty"`
+	HTMLURL     *string `json:"html_url,omitempty"`
+	DownloadURL *string `json:"download_url,omitempty"`
+}
+
+// RepositoryContentResponse holds the parsed response from CreateFile, UpdateFile, and DeleteFile.
+type RepositoryContentResponse struct {
+	Content *RepositoryContent `json:"content,omitempty"`
+	Commit  `json:"commit,omitempty"`
+}
+
+// RepositoryContentFileOptions specifies optional parameters for CreateFile, UpdateFile, and DeleteFile.
+type RepositoryContentFileOptions struct {
+	Message   *string       `json:"message,omitempty"`
+	Content   []byte        `json:"content,omitempty"` // unencoded
+	SHA       *string       `json:"sha,omitempty"`
+	Branch    *string       `json:"branch,omitempty"`
+	Author    *CommitAuthor `json:"author,omitempty"`
+	Committer *CommitAuthor `json:"committer,omitempty"`
+}
+
+// RepositoryContentGetOptions represents an optional ref parameter, which can be a SHA,
+// branch, or tag
+type RepositoryContentGetOptions struct {
+	Ref string `url:"ref,omitempty"`
+}
+
+// String converts RepositoryContent to a string. It's primarily for testing.
+func (r RepositoryContent) String() string {
+	return Stringify(r)
+}
+
+// GetContent returns the content of r, decoding it if necessary.
+func (r *RepositoryContent) GetContent() (string, error) {
+	var encoding string
+	if r.Encoding != nil {
+		encoding = *r.Encoding
+	}
+
+	switch encoding {
+	case "base64":
+		c, err := base64.StdEncoding.DecodeString(*r.Content)
+		return string(c), err
+	case "":
+		if r.Content == nil {
+			return "", nil
+		}
+		return *r.Content, nil
+	default:
+		return "", fmt.Errorf("unsupported content encoding: %v", encoding)
+	}
+}
+
+// GetReadme gets the Readme file for the repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/contents/#get-the-readme
+func (s *RepositoriesService) GetReadme(ctx context.Context, owner, repo string, opt *RepositoryContentGetOptions) (*RepositoryContent, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/readme", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+	readme := new(RepositoryContent)
+	resp, err := s.client.Do(ctx, req, readme)
+	if err != nil {
+		return nil, resp, err
+	}
+	return readme, resp, nil
+}
+
+// DownloadContents returns an io.ReadCloser that reads the contents of the
+// specified file. This function will work with files of any size, as opposed
+// to GetContents which is limited to 1 Mb files. It is the caller's
+// responsibility to close the ReadCloser.
+func (s *RepositoriesService) DownloadContents(ctx context.Context, owner, repo, filepath string, opt *RepositoryContentGetOptions) (io.ReadCloser, error) {
+	dir := path.Dir(filepath)
+	filename := path.Base(filepath)
+	_, dirContents, _, err := s.GetContents(ctx, owner, repo, dir, opt)
+	if err != nil {
+		return nil, err
+	}
+	for _, contents := range dirContents {
+		if *contents.Name == filename {
+			if contents.DownloadURL == nil || *contents.DownloadURL == "" {
+				return nil, fmt.Errorf("No download link found for %s", filepath)
+			}
+			resp, err := s.client.client.Get(*contents.DownloadURL)
+			if err != nil {
+				return nil, err
+			}
+			return resp.Body, nil
+		}
+	}
+	return nil, fmt.Errorf("No file named %s found in %s", filename, dir)
+}
+
+// GetContents can return either the metadata and content of a single file
+// (when path references a file) or the metadata of all the files and/or
+// subdirectories of a directory (when path references a directory). To make it
+// easy to distinguish between both result types and to mimic the API as much
+// as possible, both result types will be returned but only one will contain a
+// value and the other will be nil.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/contents/#get-contents
+func (s *RepositoriesService) GetContents(ctx context.Context, owner, repo, path string, opt *RepositoryContentGetOptions) (fileContent *RepositoryContent, directoryContent []*RepositoryContent, resp *Response, err error) {
+	escapedPath := (&url.URL{Path: path}).String()
+	u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, escapedPath)
+	u, err = addOptions(u, opt)
+	if err != nil {
+		return nil, nil, nil, err
+	}
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, nil, err
+	}
+	var rawJSON json.RawMessage
+	resp, err = s.client.Do(ctx, req, &rawJSON)
+	if err != nil {
+		return nil, nil, resp, err
+	}
+	fileUnmarshalError := json.Unmarshal(rawJSON, &fileContent)
+	if fileUnmarshalError == nil {
+		return fileContent, nil, resp, nil
+	}
+	directoryUnmarshalError := json.Unmarshal(rawJSON, &directoryContent)
+	if directoryUnmarshalError == nil {
+		return nil, directoryContent, resp, nil
+	}
+	return nil, nil, resp, fmt.Errorf("unmarshalling failed for both file and directory content: %s and %s", fileUnmarshalError, directoryUnmarshalError)
+}
+
+// CreateFile creates a new file in a repository at the given path and returns
+// the commit and file metadata.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/contents/#create-a-file
+func (s *RepositoriesService) CreateFile(ctx context.Context, owner, repo, path string, opt *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path)
+	req, err := s.client.NewRequest("PUT", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+	createResponse := new(RepositoryContentResponse)
+	resp, err := s.client.Do(ctx, req, createResponse)
+	if err != nil {
+		return nil, resp, err
+	}
+	return createResponse, resp, nil
+}
+
+// UpdateFile updates a file in a repository at the given path and returns the
+// commit and file metadata. Requires the blob SHA of the file being updated.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/contents/#update-a-file
+func (s *RepositoriesService) UpdateFile(ctx context.Context, owner, repo, path string, opt *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path)
+	req, err := s.client.NewRequest("PUT", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+	updateResponse := new(RepositoryContentResponse)
+	resp, err := s.client.Do(ctx, req, updateResponse)
+	if err != nil {
+		return nil, resp, err
+	}
+	return updateResponse, resp, nil
+}
+
+// DeleteFile deletes a file from a repository and returns the commit.
+// Requires the blob SHA of the file to be deleted.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/contents/#delete-a-file
+func (s *RepositoriesService) DeleteFile(ctx context.Context, owner, repo, path string, opt *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path)
+	req, err := s.client.NewRequest("DELETE", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+	deleteResponse := new(RepositoryContentResponse)
+	resp, err := s.client.Do(ctx, req, deleteResponse)
+	if err != nil {
+		return nil, resp, err
+	}
+	return deleteResponse, resp, nil
+}
+
+// archiveFormat is used to define the archive type when calling GetArchiveLink.
+type archiveFormat string
+
+const (
+	// Tarball specifies an archive in gzipped tar format.
+	Tarball archiveFormat = "tarball"
+
+	// Zipball specifies an archive in zip format.
+	Zipball archiveFormat = "zipball"
+)
+
+// GetArchiveLink returns an URL to download a tarball or zipball archive for a
+// repository. The archiveFormat can be specified by either the github.Tarball
+// or github.Zipball constant.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/contents/#get-archive-link
+func (s *RepositoriesService) GetArchiveLink(ctx context.Context, owner, repo string, archiveformat archiveFormat, opt *RepositoryContentGetOptions) (*url.URL, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/%s", owner, repo, archiveformat)
+	if opt != nil && opt.Ref != "" {
+		u += fmt.Sprintf("/%s", opt.Ref)
+	}
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+	var resp *http.Response
+	// Use http.DefaultTransport if no custom Transport is configured
+	req = withContext(ctx, req)
+	if s.client.client.Transport == nil {
+		resp, err = http.DefaultTransport.RoundTrip(req)
+	} else {
+		resp, err = s.client.client.Transport.RoundTrip(req)
+	}
+	if err != nil {
+		return nil, nil, err
+	}
+	resp.Body.Close()
+	if resp.StatusCode != http.StatusFound {
+		return nil, newResponse(resp), fmt.Errorf("unexpected status code: %s", resp.Status)
+	}
+	parsedURL, err := url.Parse(resp.Header.Get("Location"))
+	return parsedURL, newResponse(resp), err
+}

+ 237 - 0
vendor/github.com/google/go-github/github/repos_deployments.go

@@ -0,0 +1,237 @@
+// Copyright 2014 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"strings"
+)
+
+// Deployment represents a deployment in a repo
+type Deployment struct {
+	URL           *string         `json:"url,omitempty"`
+	ID            *int64          `json:"id,omitempty"`
+	SHA           *string         `json:"sha,omitempty"`
+	Ref           *string         `json:"ref,omitempty"`
+	Task          *string         `json:"task,omitempty"`
+	Payload       json.RawMessage `json:"payload,omitempty"`
+	Environment   *string         `json:"environment,omitempty"`
+	Description   *string         `json:"description,omitempty"`
+	Creator       *User           `json:"creator,omitempty"`
+	CreatedAt     *Timestamp      `json:"created_at,omitempty"`
+	UpdatedAt     *Timestamp      `json:"updated_at,omitempty"`
+	StatusesURL   *string         `json:"statuses_url,omitempty"`
+	RepositoryURL *string         `json:"repository_url,omitempty"`
+	NodeID        *string         `json:"node_id,omitempty"`
+}
+
+// DeploymentRequest represents a deployment request
+type DeploymentRequest struct {
+	Ref                   *string   `json:"ref,omitempty"`
+	Task                  *string   `json:"task,omitempty"`
+	AutoMerge             *bool     `json:"auto_merge,omitempty"`
+	RequiredContexts      *[]string `json:"required_contexts,omitempty"`
+	Payload               *string   `json:"payload,omitempty"`
+	Environment           *string   `json:"environment,omitempty"`
+	Description           *string   `json:"description,omitempty"`
+	TransientEnvironment  *bool     `json:"transient_environment,omitempty"`
+	ProductionEnvironment *bool     `json:"production_environment,omitempty"`
+}
+
+// DeploymentsListOptions specifies the optional parameters to the
+// RepositoriesService.ListDeployments method.
+type DeploymentsListOptions struct {
+	// SHA of the Deployment.
+	SHA string `url:"sha,omitempty"`
+
+	// List deployments for a given ref.
+	Ref string `url:"ref,omitempty"`
+
+	// List deployments for a given task.
+	Task string `url:"task,omitempty"`
+
+	// List deployments for a given environment.
+	Environment string `url:"environment,omitempty"`
+
+	ListOptions
+}
+
+// ListDeployments lists the deployments of a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/deployments/#list-deployments
+func (s *RepositoriesService) ListDeployments(ctx context.Context, owner, repo string, opt *DeploymentsListOptions) ([]*Deployment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/deployments", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	var deployments []*Deployment
+	resp, err := s.client.Do(ctx, req, &deployments)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return deployments, resp, nil
+}
+
+// GetDeployment returns a single deployment of a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/deployments/#get-a-single-deployment
+func (s *RepositoriesService) GetDeployment(ctx context.Context, owner, repo string, deploymentID int64) (*Deployment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/deployments/%v", owner, repo, deploymentID)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	deployment := new(Deployment)
+	resp, err := s.client.Do(ctx, req, deployment)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return deployment, resp, nil
+}
+
+// CreateDeployment creates a new deployment for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/deployments/#create-a-deployment
+func (s *RepositoriesService) CreateDeployment(ctx context.Context, owner, repo string, request *DeploymentRequest) (*Deployment, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/deployments", owner, repo)
+
+	req, err := s.client.NewRequest("POST", u, request)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeDeploymentStatusPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	d := new(Deployment)
+	resp, err := s.client.Do(ctx, req, d)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return d, resp, nil
+}
+
+// DeploymentStatus represents the status of a
+// particular deployment.
+type DeploymentStatus struct {
+	ID *int64 `json:"id,omitempty"`
+	// State is the deployment state.
+	// Possible values are: "pending", "success", "failure", "error", "inactive".
+	State         *string    `json:"state,omitempty"`
+	Creator       *User      `json:"creator,omitempty"`
+	Description   *string    `json:"description,omitempty"`
+	TargetURL     *string    `json:"target_url,omitempty"`
+	CreatedAt     *Timestamp `json:"created_at,omitempty"`
+	UpdatedAt     *Timestamp `json:"updated_at,omitempty"`
+	DeploymentURL *string    `json:"deployment_url,omitempty"`
+	RepositoryURL *string    `json:"repository_url,omitempty"`
+	NodeID        *string    `json:"node_id,omitempty"`
+}
+
+// DeploymentStatusRequest represents a deployment request
+type DeploymentStatusRequest struct {
+	State          *string `json:"state,omitempty"`
+	LogURL         *string `json:"log_url,omitempty"`
+	Description    *string `json:"description,omitempty"`
+	EnvironmentURL *string `json:"environment_url,omitempty"`
+	AutoInactive   *bool   `json:"auto_inactive,omitempty"`
+}
+
+// ListDeploymentStatuses lists the statuses of a given deployment of a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/deployments/#list-deployment-statuses
+func (s *RepositoriesService) ListDeploymentStatuses(ctx context.Context, owner, repo string, deployment int64, opt *ListOptions) ([]*DeploymentStatus, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/deployments/%v/statuses", owner, repo, deployment)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
+	var statuses []*DeploymentStatus
+	resp, err := s.client.Do(ctx, req, &statuses)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return statuses, resp, nil
+}
+
+// GetDeploymentStatus returns a single deployment status of a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/deployments/#get-a-single-deployment-status
+func (s *RepositoriesService) GetDeploymentStatus(ctx context.Context, owner, repo string, deploymentID, deploymentStatusID int64) (*DeploymentStatus, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/deployments/%v/statuses/%v", owner, repo, deploymentID, deploymentStatusID)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeDeploymentStatusPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	d := new(DeploymentStatus)
+	resp, err := s.client.Do(ctx, req, d)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return d, resp, nil
+}
+
+// CreateDeploymentStatus creates a new status for a deployment.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/deployments/#create-a-deployment-status
+func (s *RepositoriesService) CreateDeploymentStatus(ctx context.Context, owner, repo string, deployment int64, request *DeploymentStatusRequest) (*DeploymentStatus, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/deployments/%v/statuses", owner, repo, deployment)
+
+	req, err := s.client.NewRequest("POST", u, request)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeDeploymentStatusPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	d := new(DeploymentStatus)
+	resp, err := s.client.Do(ctx, req, d)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return d, resp, nil
+}

+ 85 - 0
vendor/github.com/google/go-github/github/repos_forks.go

@@ -0,0 +1,85 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// RepositoryListForksOptions specifies the optional parameters to the
+// RepositoriesService.ListForks method.
+type RepositoryListForksOptions struct {
+	// How to sort the forks list. Possible values are: newest, oldest,
+	// watchers. Default is "newest".
+	Sort string `url:"sort,omitempty"`
+
+	ListOptions
+}
+
+// ListForks lists the forks of the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/forks/#list-forks
+func (s *RepositoriesService) ListForks(ctx context.Context, owner, repo string, opt *RepositoryListForksOptions) ([]*Repository, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/forks", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when topics API fully launches.
+	req.Header.Set("Accept", mediaTypeTopicsPreview)
+
+	var repos []*Repository
+	resp, err := s.client.Do(ctx, req, &repos)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repos, resp, nil
+}
+
+// RepositoryCreateForkOptions specifies the optional parameters to the
+// RepositoriesService.CreateFork method.
+type RepositoryCreateForkOptions struct {
+	// The organization to fork the repository into.
+	Organization string `url:"organization,omitempty"`
+}
+
+// CreateFork creates a fork of the specified repository.
+//
+// This method might return an *AcceptedError and a status code of
+// 202. This is because this is the status that GitHub returns to signify that
+// it is now computing creating the fork in a background task.
+// A follow up request, after a delay of a second or so, should result
+// in a successful request.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/forks/#create-a-fork
+func (s *RepositoriesService) CreateFork(ctx context.Context, owner, repo string, opt *RepositoryCreateForkOptions) (*Repository, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/forks", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("POST", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	fork := new(Repository)
+	resp, err := s.client.Do(ctx, req, fork)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return fork, resp, nil
+}

+ 192 - 0
vendor/github.com/google/go-github/github/repos_hooks.go

@@ -0,0 +1,192 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// WebHookPayload represents the data that is received from GitHub when a push
+// event hook is triggered. The format of these payloads pre-date most of the
+// GitHub v3 API, so there are lots of minor incompatibilities with the types
+// defined in the rest of the API. Therefore, several types are duplicated
+// here to account for these differences.
+//
+// GitHub API docs: https://help.github.com/articles/post-receive-hooks
+type WebHookPayload struct {
+	After      *string         `json:"after,omitempty"`
+	Before     *string         `json:"before,omitempty"`
+	Commits    []WebHookCommit `json:"commits,omitempty"`
+	Compare    *string         `json:"compare,omitempty"`
+	Created    *bool           `json:"created,omitempty"`
+	Deleted    *bool           `json:"deleted,omitempty"`
+	Forced     *bool           `json:"forced,omitempty"`
+	HeadCommit *WebHookCommit  `json:"head_commit,omitempty"`
+	Pusher     *User           `json:"pusher,omitempty"`
+	Ref        *string         `json:"ref,omitempty"`
+	Repo       *Repository     `json:"repository,omitempty"`
+	Sender     *User           `json:"sender,omitempty"`
+}
+
+func (w WebHookPayload) String() string {
+	return Stringify(w)
+}
+
+// WebHookCommit represents the commit variant we receive from GitHub in a
+// WebHookPayload.
+type WebHookCommit struct {
+	Added     []string       `json:"added,omitempty"`
+	Author    *WebHookAuthor `json:"author,omitempty"`
+	Committer *WebHookAuthor `json:"committer,omitempty"`
+	Distinct  *bool          `json:"distinct,omitempty"`
+	ID        *string        `json:"id,omitempty"`
+	Message   *string        `json:"message,omitempty"`
+	Modified  []string       `json:"modified,omitempty"`
+	Removed   []string       `json:"removed,omitempty"`
+	Timestamp *time.Time     `json:"timestamp,omitempty"`
+}
+
+func (w WebHookCommit) String() string {
+	return Stringify(w)
+}
+
+// WebHookAuthor represents the author or committer of a commit, as specified
+// in a WebHookCommit. The commit author may not correspond to a GitHub User.
+type WebHookAuthor struct {
+	Email    *string `json:"email,omitempty"`
+	Name     *string `json:"name,omitempty"`
+	Username *string `json:"username,omitempty"`
+}
+
+func (w WebHookAuthor) String() string {
+	return Stringify(w)
+}
+
+// Hook represents a GitHub (web and service) hook for a repository.
+type Hook struct {
+	CreatedAt *time.Time             `json:"created_at,omitempty"`
+	UpdatedAt *time.Time             `json:"updated_at,omitempty"`
+	Name      *string                `json:"name,omitempty"`
+	URL       *string                `json:"url,omitempty"`
+	Events    []string               `json:"events,omitempty"`
+	Active    *bool                  `json:"active,omitempty"`
+	Config    map[string]interface{} `json:"config,omitempty"`
+	ID        *int64                 `json:"id,omitempty"`
+}
+
+func (h Hook) String() string {
+	return Stringify(h)
+}
+
+// CreateHook creates a Hook for the specified repository.
+// Name and Config are required fields.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/hooks/#create-a-hook
+func (s *RepositoriesService) CreateHook(ctx context.Context, owner, repo string, hook *Hook) (*Hook, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/hooks", owner, repo)
+	req, err := s.client.NewRequest("POST", u, hook)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	h := new(Hook)
+	resp, err := s.client.Do(ctx, req, h)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return h, resp, nil
+}
+
+// ListHooks lists all Hooks for the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/hooks/#list
+func (s *RepositoriesService) ListHooks(ctx context.Context, owner, repo string, opt *ListOptions) ([]*Hook, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/hooks", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var hooks []*Hook
+	resp, err := s.client.Do(ctx, req, &hooks)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return hooks, resp, nil
+}
+
+// GetHook returns a single specified Hook.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/hooks/#get-single-hook
+func (s *RepositoriesService) GetHook(ctx context.Context, owner, repo string, id int64) (*Hook, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+	hook := new(Hook)
+	resp, err := s.client.Do(ctx, req, hook)
+	return hook, resp, err
+}
+
+// EditHook updates a specified Hook.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/hooks/#edit-a-hook
+func (s *RepositoriesService) EditHook(ctx context.Context, owner, repo string, id int64, hook *Hook) (*Hook, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, id)
+	req, err := s.client.NewRequest("PATCH", u, hook)
+	if err != nil {
+		return nil, nil, err
+	}
+	h := new(Hook)
+	resp, err := s.client.Do(ctx, req, h)
+	return h, resp, err
+}
+
+// DeleteHook deletes a specified Hook.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/hooks/#delete-a-hook
+func (s *RepositoriesService) DeleteHook(ctx context.Context, owner, repo string, id int64) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, id)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
+
+// PingHook triggers a 'ping' event to be sent to the Hook.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/hooks/#ping-a-hook
+func (s *RepositoriesService) PingHook(ctx context.Context, owner, repo string, id int64) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/hooks/%d/pings", owner, repo, id)
+	req, err := s.client.NewRequest("POST", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
+
+// TestHook triggers a test Hook by github.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/hooks/#test-a-push-hook
+func (s *RepositoriesService) TestHook(ctx context.Context, owner, repo string, id int64) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/hooks/%d/tests", owner, repo, id)
+	req, err := s.client.NewRequest("POST", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}

+ 98 - 0
vendor/github.com/google/go-github/github/repos_invitations.go

@@ -0,0 +1,98 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// RepositoryInvitation represents an invitation to collaborate on a repo.
+type RepositoryInvitation struct {
+	ID      *int64      `json:"id,omitempty"`
+	Repo    *Repository `json:"repository,omitempty"`
+	Invitee *User       `json:"invitee,omitempty"`
+	Inviter *User       `json:"inviter,omitempty"`
+
+	// Permissions represents the permissions that the associated user will have
+	// on the repository. Possible values are: "read", "write", "admin".
+	Permissions *string    `json:"permissions,omitempty"`
+	CreatedAt   *Timestamp `json:"created_at,omitempty"`
+	URL         *string    `json:"url,omitempty"`
+	HTMLURL     *string    `json:"html_url,omitempty"`
+}
+
+// ListInvitations lists all currently-open repository invitations.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/invitations/#list-invitations-for-a-repository
+func (s *RepositoriesService) ListInvitations(ctx context.Context, owner, repo string, opt *ListOptions) ([]*RepositoryInvitation, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/invitations", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeRepositoryInvitationsPreview)
+
+	invites := []*RepositoryInvitation{}
+	resp, err := s.client.Do(ctx, req, &invites)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return invites, resp, nil
+}
+
+// DeleteInvitation deletes a repository invitation.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/invitations/#delete-a-repository-invitation
+func (s *RepositoriesService) DeleteInvitation(ctx context.Context, owner, repo string, invitationID int64) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/invitations/%v", owner, repo, invitationID)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeRepositoryInvitationsPreview)
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// UpdateInvitation updates the permissions associated with a repository
+// invitation.
+//
+// permissions represents the permissions that the associated user will have
+// on the repository. Possible values are: "read", "write", "admin".
+//
+// GitHub API docs: https://developer.github.com/v3/repos/invitations/#update-a-repository-invitation
+func (s *RepositoriesService) UpdateInvitation(ctx context.Context, owner, repo string, invitationID int64, permissions string) (*RepositoryInvitation, *Response, error) {
+	opts := &struct {
+		Permissions string `json:"permissions"`
+	}{Permissions: permissions}
+	u := fmt.Sprintf("repos/%v/%v/invitations/%v", owner, repo, invitationID)
+	req, err := s.client.NewRequest("PATCH", u, opts)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeRepositoryInvitationsPreview)
+
+	invite := &RepositoryInvitation{}
+	resp, err := s.client.Do(ctx, req, invite)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return invite, resp, nil
+}

+ 111 - 0
vendor/github.com/google/go-github/github/repos_keys.go

@@ -0,0 +1,111 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// The Key type is defined in users_keys.go
+
+// ListKeys lists the deploy keys for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/keys/#list
+func (s *RepositoriesService) ListKeys(ctx context.Context, owner string, repo string, opt *ListOptions) ([]*Key, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/keys", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var keys []*Key
+	resp, err := s.client.Do(ctx, req, &keys)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return keys, resp, nil
+}
+
+// GetKey fetches a single deploy key.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/keys/#get
+func (s *RepositoriesService) GetKey(ctx context.Context, owner string, repo string, id int64) (*Key, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/keys/%v", owner, repo, id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	key := new(Key)
+	resp, err := s.client.Do(ctx, req, key)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return key, resp, nil
+}
+
+// CreateKey adds a deploy key for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/keys/#create
+func (s *RepositoriesService) CreateKey(ctx context.Context, owner string, repo string, key *Key) (*Key, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/keys", owner, repo)
+
+	req, err := s.client.NewRequest("POST", u, key)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	k := new(Key)
+	resp, err := s.client.Do(ctx, req, k)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return k, resp, nil
+}
+
+// EditKey edits a deploy key.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/keys/#edit
+func (s *RepositoriesService) EditKey(ctx context.Context, owner string, repo string, id int, key *Key) (*Key, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/keys/%v", owner, repo, id)
+
+	req, err := s.client.NewRequest("PATCH", u, key)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	k := new(Key)
+	resp, err := s.client.Do(ctx, req, k)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return k, resp, nil
+}
+
+// DeleteKey deletes a deploy key.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/keys/#delete
+func (s *RepositoriesService) DeleteKey(ctx context.Context, owner string, repo string, id int) (*Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/keys/%v", owner, repo, id)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}

+ 38 - 0
vendor/github.com/google/go-github/github/repos_merging.go

@@ -0,0 +1,38 @@
+// Copyright 2014 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// RepositoryMergeRequest represents a request to merge a branch in a
+// repository.
+type RepositoryMergeRequest struct {
+	Base          *string `json:"base,omitempty"`
+	Head          *string `json:"head,omitempty"`
+	CommitMessage *string `json:"commit_message,omitempty"`
+}
+
+// Merge a branch in the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/merging/#perform-a-merge
+func (s *RepositoriesService) Merge(ctx context.Context, owner, repo string, request *RepositoryMergeRequest) (*RepositoryCommit, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/merges", owner, repo)
+	req, err := s.client.NewRequest("POST", u, request)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	commit := new(RepositoryCommit)
+	resp, err := s.client.Do(ctx, req, commit)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return commit, resp, nil
+}

+ 143 - 0
vendor/github.com/google/go-github/github/repos_pages.go

@@ -0,0 +1,143 @@
+// Copyright 2014 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// Pages represents a GitHub Pages site configuration.
+type Pages struct {
+	URL       *string `json:"url,omitempty"`
+	Status    *string `json:"status,omitempty"`
+	CNAME     *string `json:"cname,omitempty"`
+	Custom404 *bool   `json:"custom_404,omitempty"`
+	HTMLURL   *string `json:"html_url,omitempty"`
+}
+
+// PagesError represents a build error for a GitHub Pages site.
+type PagesError struct {
+	Message *string `json:"message,omitempty"`
+}
+
+// PagesBuild represents the build information for a GitHub Pages site.
+type PagesBuild struct {
+	URL       *string     `json:"url,omitempty"`
+	Status    *string     `json:"status,omitempty"`
+	Error     *PagesError `json:"error,omitempty"`
+	Pusher    *User       `json:"pusher,omitempty"`
+	Commit    *string     `json:"commit,omitempty"`
+	Duration  *int        `json:"duration,omitempty"`
+	CreatedAt *Timestamp  `json:"created_at,omitempty"`
+	UpdatedAt *Timestamp  `json:"updated_at,omitempty"`
+}
+
+// GetPagesInfo fetches information about a GitHub Pages site.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/pages/#get-information-about-a-pages-site
+func (s *RepositoriesService) GetPagesInfo(ctx context.Context, owner, repo string) (*Pages, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pages", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypePagesPreview)
+
+	site := new(Pages)
+	resp, err := s.client.Do(ctx, req, site)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return site, resp, nil
+}
+
+// ListPagesBuilds lists the builds for a GitHub Pages site.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/pages/#list-pages-builds
+func (s *RepositoriesService) ListPagesBuilds(ctx context.Context, owner, repo string, opt *ListOptions) ([]*PagesBuild, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pages/builds", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var pages []*PagesBuild
+	resp, err := s.client.Do(ctx, req, &pages)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return pages, resp, nil
+}
+
+// GetLatestPagesBuild fetches the latest build information for a GitHub pages site.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/pages/#list-latest-pages-build
+func (s *RepositoriesService) GetLatestPagesBuild(ctx context.Context, owner, repo string) (*PagesBuild, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pages/builds/latest", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	build := new(PagesBuild)
+	resp, err := s.client.Do(ctx, req, build)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return build, resp, nil
+}
+
+// GetPageBuild fetches the specific build information for a GitHub pages site.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/pages/#list-a-specific-pages-build
+func (s *RepositoriesService) GetPageBuild(ctx context.Context, owner, repo string, id int64) (*PagesBuild, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pages/builds/%v", owner, repo, id)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	build := new(PagesBuild)
+	resp, err := s.client.Do(ctx, req, build)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return build, resp, nil
+}
+
+// RequestPageBuild requests a build of a GitHub Pages site without needing to push new commit.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/pages/#request-a-page-build
+func (s *RepositoriesService) RequestPageBuild(ctx context.Context, owner, repo string) (*PagesBuild, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/pages/builds", owner, repo)
+	req, err := s.client.NewRequest("POST", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypePagesPreview)
+
+	build := new(PagesBuild)
+	resp, err := s.client.Do(ctx, req, build)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return build, resp, nil
+}

+ 69 - 0
vendor/github.com/google/go-github/github/repos_projects.go

@@ -0,0 +1,69 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// ProjectListOptions specifies the optional parameters to the
+// OrganizationsService.ListProjects and RepositoriesService.ListProjects methods.
+type ProjectListOptions struct {
+	// Indicates the state of the projects to return. Can be either open, closed, or all. Default: open
+	State string `url:"state,omitempty"`
+
+	ListOptions
+}
+
+// ListProjects lists the projects for a repo.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/#list-repository-projects
+func (s *RepositoriesService) ListProjects(ctx context.Context, owner, repo string, opt *ProjectListOptions) ([]*Project, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/projects", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	var projects []*Project
+	resp, err := s.client.Do(ctx, req, &projects)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return projects, resp, nil
+}
+
+// CreateProject creates a GitHub Project for the specified repository.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/#create-a-repository-project
+func (s *RepositoriesService) CreateProject(ctx context.Context, owner, repo string, opt *ProjectOptions) (*Project, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/projects", owner, repo)
+	req, err := s.client.NewRequest("POST", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeProjectsPreview)
+
+	project := &Project{}
+	resp, err := s.client.Do(ctx, req, project)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return project, resp, nil
+}

+ 327 - 0
vendor/github.com/google/go-github/github/repos_releases.go

@@ -0,0 +1,327 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"io"
+	"mime"
+	"net/http"
+	"os"
+	"path/filepath"
+	"strings"
+)
+
+// RepositoryRelease represents a GitHub release in a repository.
+type RepositoryRelease struct {
+	ID              *int64         `json:"id,omitempty"`
+	TagName         *string        `json:"tag_name,omitempty"`
+	TargetCommitish *string        `json:"target_commitish,omitempty"`
+	Name            *string        `json:"name,omitempty"`
+	Body            *string        `json:"body,omitempty"`
+	Draft           *bool          `json:"draft,omitempty"`
+	Prerelease      *bool          `json:"prerelease,omitempty"`
+	CreatedAt       *Timestamp     `json:"created_at,omitempty"`
+	PublishedAt     *Timestamp     `json:"published_at,omitempty"`
+	URL             *string        `json:"url,omitempty"`
+	HTMLURL         *string        `json:"html_url,omitempty"`
+	AssetsURL       *string        `json:"assets_url,omitempty"`
+	Assets          []ReleaseAsset `json:"assets,omitempty"`
+	UploadURL       *string        `json:"upload_url,omitempty"`
+	ZipballURL      *string        `json:"zipball_url,omitempty"`
+	TarballURL      *string        `json:"tarball_url,omitempty"`
+	Author          *User          `json:"author,omitempty"`
+}
+
+func (r RepositoryRelease) String() string {
+	return Stringify(r)
+}
+
+// ReleaseAsset represents a GitHub release asset in a repository.
+type ReleaseAsset struct {
+	ID                 *int64     `json:"id,omitempty"`
+	URL                *string    `json:"url,omitempty"`
+	Name               *string    `json:"name,omitempty"`
+	Label              *string    `json:"label,omitempty"`
+	State              *string    `json:"state,omitempty"`
+	ContentType        *string    `json:"content_type,omitempty"`
+	Size               *int       `json:"size,omitempty"`
+	DownloadCount      *int       `json:"download_count,omitempty"`
+	CreatedAt          *Timestamp `json:"created_at,omitempty"`
+	UpdatedAt          *Timestamp `json:"updated_at,omitempty"`
+	BrowserDownloadURL *string    `json:"browser_download_url,omitempty"`
+	Uploader           *User      `json:"uploader,omitempty"`
+}
+
+func (r ReleaseAsset) String() string {
+	return Stringify(r)
+}
+
+// ListReleases lists the releases for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#list-releases-for-a-repository
+func (s *RepositoriesService) ListReleases(ctx context.Context, owner, repo string, opt *ListOptions) ([]*RepositoryRelease, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var releases []*RepositoryRelease
+	resp, err := s.client.Do(ctx, req, &releases)
+	if err != nil {
+		return nil, resp, err
+	}
+	return releases, resp, nil
+}
+
+// GetRelease fetches a single release.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-single-release
+func (s *RepositoriesService) GetRelease(ctx context.Context, owner, repo string, id int64) (*RepositoryRelease, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id)
+	return s.getSingleRelease(ctx, u)
+}
+
+// GetLatestRelease fetches the latest published release for the repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-the-latest-release
+func (s *RepositoriesService) GetLatestRelease(ctx context.Context, owner, repo string) (*RepositoryRelease, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/latest", owner, repo)
+	return s.getSingleRelease(ctx, u)
+}
+
+// GetReleaseByTag fetches a release with the specified tag.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-release-by-tag-name
+func (s *RepositoriesService) GetReleaseByTag(ctx context.Context, owner, repo, tag string) (*RepositoryRelease, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/tags/%s", owner, repo, tag)
+	return s.getSingleRelease(ctx, u)
+}
+
+func (s *RepositoriesService) getSingleRelease(ctx context.Context, url string) (*RepositoryRelease, *Response, error) {
+	req, err := s.client.NewRequest("GET", url, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	release := new(RepositoryRelease)
+	resp, err := s.client.Do(ctx, req, release)
+	if err != nil {
+		return nil, resp, err
+	}
+	return release, resp, nil
+}
+
+// CreateRelease adds a new release for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#create-a-release
+func (s *RepositoriesService) CreateRelease(ctx context.Context, owner, repo string, release *RepositoryRelease) (*RepositoryRelease, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases", owner, repo)
+
+	req, err := s.client.NewRequest("POST", u, release)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r := new(RepositoryRelease)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+	return r, resp, nil
+}
+
+// EditRelease edits a repository release.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#edit-a-release
+func (s *RepositoriesService) EditRelease(ctx context.Context, owner, repo string, id int64, release *RepositoryRelease) (*RepositoryRelease, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id)
+
+	req, err := s.client.NewRequest("PATCH", u, release)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r := new(RepositoryRelease)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+	return r, resp, nil
+}
+
+// DeleteRelease delete a single release from a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#delete-a-release
+func (s *RepositoriesService) DeleteRelease(ctx context.Context, owner, repo string, id int64) (*Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
+
+// ListReleaseAssets lists the release's assets.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#list-assets-for-a-release
+func (s *RepositoriesService) ListReleaseAssets(ctx context.Context, owner, repo string, id int64, opt *ListOptions) ([]*ReleaseAsset, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/%d/assets", owner, repo, id)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var assets []*ReleaseAsset
+	resp, err := s.client.Do(ctx, req, &assets)
+	if err != nil {
+		return nil, resp, err
+	}
+	return assets, resp, nil
+}
+
+// GetReleaseAsset fetches a single release asset.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-single-release-asset
+func (s *RepositoriesService) GetReleaseAsset(ctx context.Context, owner, repo string, id int64) (*ReleaseAsset, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	asset := new(ReleaseAsset)
+	resp, err := s.client.Do(ctx, req, asset)
+	if err != nil {
+		return nil, resp, err
+	}
+	return asset, resp, nil
+}
+
+// DownloadReleaseAsset downloads a release asset or returns a redirect URL.
+//
+// DownloadReleaseAsset returns an io.ReadCloser that reads the contents of the
+// specified release asset. It is the caller's responsibility to close the ReadCloser.
+// If a redirect is returned, the redirect URL will be returned as a string instead
+// of the io.ReadCloser. Exactly one of rc and redirectURL will be zero.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-single-release-asset
+func (s *RepositoriesService) DownloadReleaseAsset(ctx context.Context, owner, repo string, id int64) (rc io.ReadCloser, redirectURL string, err error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, "", err
+	}
+	req.Header.Set("Accept", defaultMediaType)
+
+	s.client.clientMu.Lock()
+	defer s.client.clientMu.Unlock()
+
+	var loc string
+	saveRedirect := s.client.client.CheckRedirect
+	s.client.client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
+		loc = req.URL.String()
+		return errors.New("disable redirect")
+	}
+	defer func() { s.client.client.CheckRedirect = saveRedirect }()
+
+	req = withContext(ctx, req)
+	resp, err := s.client.client.Do(req)
+	if err != nil {
+		if !strings.Contains(err.Error(), "disable redirect") {
+			return nil, "", err
+		}
+		return nil, loc, nil // Intentionally return no error with valid redirect URL.
+	}
+
+	if err := CheckResponse(resp); err != nil {
+		resp.Body.Close()
+		return nil, "", err
+	}
+
+	return resp.Body, "", nil
+}
+
+// EditReleaseAsset edits a repository release asset.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#edit-a-release-asset
+func (s *RepositoriesService) EditReleaseAsset(ctx context.Context, owner, repo string, id int64, release *ReleaseAsset) (*ReleaseAsset, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id)
+
+	req, err := s.client.NewRequest("PATCH", u, release)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	asset := new(ReleaseAsset)
+	resp, err := s.client.Do(ctx, req, asset)
+	if err != nil {
+		return nil, resp, err
+	}
+	return asset, resp, nil
+}
+
+// DeleteReleaseAsset delete a single release asset from a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#delete-a-release-asset
+func (s *RepositoriesService) DeleteReleaseAsset(ctx context.Context, owner, repo string, id int64) (*Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(ctx, req, nil)
+}
+
+// UploadReleaseAsset creates an asset by uploading a file into a release repository.
+// To upload assets that cannot be represented by an os.File, call NewUploadRequest directly.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/releases/#upload-a-release-asset
+func (s *RepositoriesService) UploadReleaseAsset(ctx context.Context, owner, repo string, id int64, opt *UploadOptions, file *os.File) (*ReleaseAsset, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/%d/assets", owner, repo, id)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	stat, err := file.Stat()
+	if err != nil {
+		return nil, nil, err
+	}
+	if stat.IsDir() {
+		return nil, nil, errors.New("the asset to upload can't be a directory")
+	}
+
+	mediaType := mime.TypeByExtension(filepath.Ext(file.Name()))
+	req, err := s.client.NewUploadRequest(u, file, stat.Size(), mediaType)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	asset := new(ReleaseAsset)
+	resp, err := s.client.Do(ctx, req, asset)
+	if err != nil {
+		return nil, resp, err
+	}
+	return asset, resp, nil
+}

+ 226 - 0
vendor/github.com/google/go-github/github/repos_stats.go

@@ -0,0 +1,226 @@
+// Copyright 2014 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// ContributorStats represents a contributor to a repository and their
+// weekly contributions to a given repo.
+type ContributorStats struct {
+	Author *Contributor  `json:"author,omitempty"`
+	Total  *int          `json:"total,omitempty"`
+	Weeks  []WeeklyStats `json:"weeks,omitempty"`
+}
+
+func (c ContributorStats) String() string {
+	return Stringify(c)
+}
+
+// WeeklyStats represents the number of additions, deletions and commits
+// a Contributor made in a given week.
+type WeeklyStats struct {
+	Week      *Timestamp `json:"w,omitempty"`
+	Additions *int       `json:"a,omitempty"`
+	Deletions *int       `json:"d,omitempty"`
+	Commits   *int       `json:"c,omitempty"`
+}
+
+func (w WeeklyStats) String() string {
+	return Stringify(w)
+}
+
+// ListContributorsStats gets a repo's contributor list with additions,
+// deletions and commit counts.
+//
+// If this is the first time these statistics are requested for the given
+// repository, this method will return an *AcceptedError and a status code of
+// 202. This is because this is the status that GitHub returns to signify that
+// it is now computing the requested statistics. A follow up request, after a
+// delay of a second or so, should result in a successful request.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/statistics/#contributors
+func (s *RepositoriesService) ListContributorsStats(ctx context.Context, owner, repo string) ([]*ContributorStats, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/stats/contributors", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var contributorStats []*ContributorStats
+	resp, err := s.client.Do(ctx, req, &contributorStats)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return contributorStats, resp, nil
+}
+
+// WeeklyCommitActivity represents the weekly commit activity for a repository.
+// The days array is a group of commits per day, starting on Sunday.
+type WeeklyCommitActivity struct {
+	Days  []int      `json:"days,omitempty"`
+	Total *int       `json:"total,omitempty"`
+	Week  *Timestamp `json:"week,omitempty"`
+}
+
+func (w WeeklyCommitActivity) String() string {
+	return Stringify(w)
+}
+
+// ListCommitActivity returns the last year of commit activity
+// grouped by week. The days array is a group of commits per day,
+// starting on Sunday.
+//
+// If this is the first time these statistics are requested for the given
+// repository, this method will return an *AcceptedError and a status code of
+// 202. This is because this is the status that GitHub returns to signify that
+// it is now computing the requested statistics. A follow up request, after a
+// delay of a second or so, should result in a successful request.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/statistics/#commit-activity
+func (s *RepositoriesService) ListCommitActivity(ctx context.Context, owner, repo string) ([]*WeeklyCommitActivity, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/stats/commit_activity", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var weeklyCommitActivity []*WeeklyCommitActivity
+	resp, err := s.client.Do(ctx, req, &weeklyCommitActivity)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return weeklyCommitActivity, resp, nil
+}
+
+// ListCodeFrequency returns a weekly aggregate of the number of additions and
+// deletions pushed to a repository. Returned WeeklyStats will contain
+// additions and deletions, but not total commits.
+//
+// If this is the first time these statistics are requested for the given
+// repository, this method will return an *AcceptedError and a status code of
+// 202. This is because this is the status that GitHub returns to signify that
+// it is now computing the requested statistics. A follow up request, after a
+// delay of a second or so, should result in a successful request.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/statistics/#code-frequency
+func (s *RepositoriesService) ListCodeFrequency(ctx context.Context, owner, repo string) ([]*WeeklyStats, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/stats/code_frequency", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var weeks [][]int
+	resp, err := s.client.Do(ctx, req, &weeks)
+
+	// convert int slices into WeeklyStats
+	var stats []*WeeklyStats
+	for _, week := range weeks {
+		if len(week) != 3 {
+			continue
+		}
+		stat := &WeeklyStats{
+			Week:      &Timestamp{time.Unix(int64(week[0]), 0)},
+			Additions: Int(week[1]),
+			Deletions: Int(week[2]),
+		}
+		stats = append(stats, stat)
+	}
+
+	return stats, resp, err
+}
+
+// RepositoryParticipation is the number of commits by everyone
+// who has contributed to the repository (including the owner)
+// as well as the number of commits by the owner themself.
+type RepositoryParticipation struct {
+	All   []int `json:"all,omitempty"`
+	Owner []int `json:"owner,omitempty"`
+}
+
+func (r RepositoryParticipation) String() string {
+	return Stringify(r)
+}
+
+// ListParticipation returns the total commit counts for the 'owner'
+// and total commit counts in 'all'. 'all' is everyone combined,
+// including the 'owner' in the last 52 weeks. If you’d like to get
+// the commit counts for non-owners, you can subtract 'all' from 'owner'.
+//
+// The array order is oldest week (index 0) to most recent week.
+//
+// If this is the first time these statistics are requested for the given
+// repository, this method will return an *AcceptedError and a status code of
+// 202. This is because this is the status that GitHub returns to signify that
+// it is now computing the requested statistics. A follow up request, after a
+// delay of a second or so, should result in a successful request.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/statistics/#participation
+func (s *RepositoriesService) ListParticipation(ctx context.Context, owner, repo string) (*RepositoryParticipation, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/stats/participation", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	participation := new(RepositoryParticipation)
+	resp, err := s.client.Do(ctx, req, participation)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return participation, resp, nil
+}
+
+// PunchCard represents the number of commits made during a given hour of a
+// day of the week.
+type PunchCard struct {
+	Day     *int // Day of the week (0-6: =Sunday - Saturday).
+	Hour    *int // Hour of day (0-23).
+	Commits *int // Number of commits.
+}
+
+// ListPunchCard returns the number of commits per hour in each day.
+//
+// If this is the first time these statistics are requested for the given
+// repository, this method will return an *AcceptedError and a status code of
+// 202. This is because this is the status that GitHub returns to signify that
+// it is now computing the requested statistics. A follow up request, after a
+// delay of a second or so, should result in a successful request.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/statistics/#punch-card
+func (s *RepositoriesService) ListPunchCard(ctx context.Context, owner, repo string) ([]*PunchCard, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/stats/punch_card", owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var results [][]int
+	resp, err := s.client.Do(ctx, req, &results)
+
+	// convert int slices into Punchcards
+	var cards []*PunchCard
+	for _, result := range results {
+		if len(result) != 3 {
+			continue
+		}
+		card := &PunchCard{
+			Day:     Int(result[0]),
+			Hour:    Int(result[1]),
+			Commits: Int(result[2]),
+		}
+		cards = append(cards, card)
+	}
+
+	return cards, resp, err
+}

+ 129 - 0
vendor/github.com/google/go-github/github/repos_statuses.go

@@ -0,0 +1,129 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+	"time"
+)
+
+// RepoStatus represents the status of a repository at a particular reference.
+type RepoStatus struct {
+	ID  *int64  `json:"id,omitempty"`
+	URL *string `json:"url,omitempty"`
+
+	// State is the current state of the repository. Possible values are:
+	// pending, success, error, or failure.
+	State *string `json:"state,omitempty"`
+
+	// TargetURL is the URL of the page representing this status. It will be
+	// linked from the GitHub UI to allow users to see the source of the status.
+	TargetURL *string `json:"target_url,omitempty"`
+
+	// Description is a short high level summary of the status.
+	Description *string `json:"description,omitempty"`
+
+	// A string label to differentiate this status from the statuses of other systems.
+	Context *string `json:"context,omitempty"`
+
+	Creator   *User      `json:"creator,omitempty"`
+	CreatedAt *time.Time `json:"created_at,omitempty"`
+	UpdatedAt *time.Time `json:"updated_at,omitempty"`
+}
+
+func (r RepoStatus) String() string {
+	return Stringify(r)
+}
+
+// ListStatuses lists the statuses of a repository at the specified
+// reference. ref can be a SHA, a branch name, or a tag name.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/statuses/#list-statuses-for-a-specific-ref
+func (s *RepositoriesService) ListStatuses(ctx context.Context, owner, repo, ref string, opt *ListOptions) ([]*RepoStatus, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/commits/%v/statuses", owner, repo, ref)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var statuses []*RepoStatus
+	resp, err := s.client.Do(ctx, req, &statuses)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return statuses, resp, nil
+}
+
+// CreateStatus creates a new status for a repository at the specified
+// reference. Ref can be a SHA, a branch name, or a tag name.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/statuses/#create-a-status
+func (s *RepositoriesService) CreateStatus(ctx context.Context, owner, repo, ref string, status *RepoStatus) (*RepoStatus, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/statuses/%v", owner, repo, ref)
+	req, err := s.client.NewRequest("POST", u, status)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	repoStatus := new(RepoStatus)
+	resp, err := s.client.Do(ctx, req, repoStatus)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repoStatus, resp, nil
+}
+
+// CombinedStatus represents the combined status of a repository at a particular reference.
+type CombinedStatus struct {
+	// State is the combined state of the repository. Possible values are:
+	// failure, pending, or success.
+	State *string `json:"state,omitempty"`
+
+	Name       *string      `json:"name,omitempty"`
+	SHA        *string      `json:"sha,omitempty"`
+	TotalCount *int         `json:"total_count,omitempty"`
+	Statuses   []RepoStatus `json:"statuses,omitempty"`
+
+	CommitURL     *string `json:"commit_url,omitempty"`
+	RepositoryURL *string `json:"repository_url,omitempty"`
+}
+
+func (s CombinedStatus) String() string {
+	return Stringify(s)
+}
+
+// GetCombinedStatus returns the combined status of a repository at the specified
+// reference. ref can be a SHA, a branch name, or a tag name.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref
+func (s *RepositoriesService) GetCombinedStatus(ctx context.Context, owner, repo, ref string, opt *ListOptions) (*CombinedStatus, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/commits/%v/status", owner, repo, ref)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	status := new(CombinedStatus)
+	resp, err := s.client.Do(ctx, req, status)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return status, resp, nil
+}

+ 141 - 0
vendor/github.com/google/go-github/github/repos_traffic.go

@@ -0,0 +1,141 @@
+// Copyright 2016 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+)
+
+// TrafficReferrer represent information about traffic from a referrer .
+type TrafficReferrer struct {
+	Referrer *string `json:"referrer,omitempty"`
+	Count    *int    `json:"count,omitempty"`
+	Uniques  *int    `json:"uniques,omitempty"`
+}
+
+// TrafficPath represent information about the traffic on a path of the repo.
+type TrafficPath struct {
+	Path    *string `json:"path,omitempty"`
+	Title   *string `json:"title,omitempty"`
+	Count   *int    `json:"count,omitempty"`
+	Uniques *int    `json:"uniques,omitempty"`
+}
+
+// TrafficData represent information about a specific timestamp in views or clones list.
+type TrafficData struct {
+	Timestamp *Timestamp `json:"timestamp,omitempty"`
+	Count     *int       `json:"count,omitempty"`
+	Uniques   *int       `json:"uniques,omitempty"`
+}
+
+// TrafficViews represent information about the number of views in the last 14 days.
+type TrafficViews struct {
+	Views   []*TrafficData `json:"views,omitempty"`
+	Count   *int           `json:"count,omitempty"`
+	Uniques *int           `json:"uniques,omitempty"`
+}
+
+// TrafficClones represent information about the number of clones in the last 14 days.
+type TrafficClones struct {
+	Clones  []*TrafficData `json:"clones,omitempty"`
+	Count   *int           `json:"count,omitempty"`
+	Uniques *int           `json:"uniques,omitempty"`
+}
+
+// TrafficBreakdownOptions specifies the parameters to methods that support breakdown per day or week.
+// Can be one of: day, week. Default: day.
+type TrafficBreakdownOptions struct {
+	Per string `url:"per,omitempty"`
+}
+
+// ListTrafficReferrers list the top 10 referrers over the last 14 days.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/traffic/#list-referrers
+func (s *RepositoriesService) ListTrafficReferrers(ctx context.Context, owner, repo string) ([]*TrafficReferrer, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/traffic/popular/referrers", owner, repo)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var trafficReferrers []*TrafficReferrer
+	resp, err := s.client.Do(ctx, req, &trafficReferrers)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return trafficReferrers, resp, nil
+}
+
+// ListTrafficPaths list the top 10 popular content over the last 14 days.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/traffic/#list-paths
+func (s *RepositoriesService) ListTrafficPaths(ctx context.Context, owner, repo string) ([]*TrafficPath, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/traffic/popular/paths", owner, repo)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var paths []*TrafficPath
+	resp, err := s.client.Do(ctx, req, &paths)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return paths, resp, nil
+}
+
+// ListTrafficViews get total number of views for the last 14 days and breaks it down either per day or week.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/traffic/#views
+func (s *RepositoriesService) ListTrafficViews(ctx context.Context, owner, repo string, opt *TrafficBreakdownOptions) (*TrafficViews, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/traffic/views", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	trafficViews := new(TrafficViews)
+	resp, err := s.client.Do(ctx, req, &trafficViews)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return trafficViews, resp, nil
+}
+
+// ListTrafficClones get total number of clones for the last 14 days and breaks it down either per day or week for the last 14 days.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/traffic/#views
+func (s *RepositoriesService) ListTrafficClones(ctx context.Context, owner, repo string, opt *TrafficBreakdownOptions) (*TrafficClones, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/traffic/clones", owner, repo)
+	u, err := addOptions(u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	trafficClones := new(TrafficClones)
+	resp, err := s.client.Do(ctx, req, &trafficClones)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return trafficClones, resp, nil
+}

+ 210 - 0
vendor/github.com/google/go-github/github/search.go

@@ -0,0 +1,210 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"context"
+	"fmt"
+
+	qs "github.com/google/go-querystring/query"
+)
+
+// SearchService provides access to the search related functions
+// in the GitHub API.
+//
+// Each method takes a query string defining the search keywords and any search qualifiers.
+// For example, when searching issues, the query "gopher is:issue language:go" will search
+// for issues containing the word "gopher" in Go repositories. The method call
+//   opts :=  &github.SearchOptions{Sort: "created", Order: "asc"}
+//   cl.Search.Issues(ctx, "gopher is:issue language:go", opts)
+// will search for such issues, sorting by creation date in ascending order
+// (i.e., oldest first).
+//
+// GitHub API docs: https://developer.github.com/v3/search/
+type SearchService service
+
+// SearchOptions specifies optional parameters to the SearchService methods.
+type SearchOptions struct {
+	// How to sort the search results. Possible values are:
+	//   - for repositories: stars, fork, updated
+	//   - for commits: author-date, committer-date
+	//   - for code: indexed
+	//   - for issues: comments, created, updated
+	//   - for users: followers, repositories, joined
+	//
+	// Default is to sort by best match.
+	Sort string `url:"sort,omitempty"`
+
+	// Sort order if sort parameter is provided. Possible values are: asc,
+	// desc. Default is desc.
+	Order string `url:"order,omitempty"`
+
+	// Whether to retrieve text match metadata with a query
+	TextMatch bool `url:"-"`
+
+	ListOptions
+}
+
+// RepositoriesSearchResult represents the result of a repositories search.
+type RepositoriesSearchResult struct {
+	Total             *int         `json:"total_count,omitempty"`
+	IncompleteResults *bool        `json:"incomplete_results,omitempty"`
+	Repositories      []Repository `json:"items,omitempty"`
+}
+
+// Repositories searches repositories via various criteria.
+//
+// GitHub API docs: https://developer.github.com/v3/search/#search-repositories
+func (s *SearchService) Repositories(ctx context.Context, query string, opt *SearchOptions) (*RepositoriesSearchResult, *Response, error) {
+	result := new(RepositoriesSearchResult)
+	resp, err := s.search(ctx, "repositories", query, opt, result)
+	return result, resp, err
+}
+
+// CommitsSearchResult represents the result of a commits search.
+type CommitsSearchResult struct {
+	Total             *int            `json:"total_count,omitempty"`
+	IncompleteResults *bool           `json:"incomplete_results,omitempty"`
+	Commits           []*CommitResult `json:"items,omitempty"`
+}
+
+// CommitResult represents a commit object as returned in commit search endpoint response.
+type CommitResult struct {
+	SHA         *string   `json:"sha,omitempty"`
+	Commit      *Commit   `json:"commit,omitempty"`
+	Author      *User     `json:"author,omitempty"`
+	Committer   *User     `json:"committer,omitempty"`
+	Parents     []*Commit `json:"parents,omitempty"`
+	HTMLURL     *string   `json:"html_url,omitempty"`
+	URL         *string   `json:"url,omitempty"`
+	CommentsURL *string   `json:"comments_url,omitempty"`
+
+	Repository *Repository `json:"repository,omitempty"`
+	Score      *float64    `json:"score,omitempty"`
+}
+
+// Commits searches commits via various criteria.
+//
+// GitHub API docs: https://developer.github.com/v3/search/#search-commits
+func (s *SearchService) Commits(ctx context.Context, query string, opt *SearchOptions) (*CommitsSearchResult, *Response, error) {
+	result := new(CommitsSearchResult)
+	resp, err := s.search(ctx, "commits", query, opt, result)
+	return result, resp, err
+}
+
+// IssuesSearchResult represents the result of an issues search.
+type IssuesSearchResult struct {
+	Total             *int    `json:"total_count,omitempty"`
+	IncompleteResults *bool   `json:"incomplete_results,omitempty"`
+	Issues            []Issue `json:"items,omitempty"`
+}
+
+// Issues searches issues via various criteria.
+//
+// GitHub API docs: https://developer.github.com/v3/search/#search-issues
+func (s *SearchService) Issues(ctx context.Context, query string, opt *SearchOptions) (*IssuesSearchResult, *Response, error) {
+	result := new(IssuesSearchResult)
+	resp, err := s.search(ctx, "issues", query, opt, result)
+	return result, resp, err
+}
+
+// UsersSearchResult represents the result of a users search.
+type UsersSearchResult struct {
+	Total             *int   `json:"total_count,omitempty"`
+	IncompleteResults *bool  `json:"incomplete_results,omitempty"`
+	Users             []User `json:"items,omitempty"`
+}
+
+// Users searches users via various criteria.
+//
+// GitHub API docs: https://developer.github.com/v3/search/#search-users
+func (s *SearchService) Users(ctx context.Context, query string, opt *SearchOptions) (*UsersSearchResult, *Response, error) {
+	result := new(UsersSearchResult)
+	resp, err := s.search(ctx, "users", query, opt, result)
+	return result, resp, err
+}
+
+// Match represents a single text match.
+type Match struct {
+	Text    *string `json:"text,omitempty"`
+	Indices []int   `json:"indices,omitempty"`
+}
+
+// TextMatch represents a text match for a SearchResult
+type TextMatch struct {
+	ObjectURL  *string `json:"object_url,omitempty"`
+	ObjectType *string `json:"object_type,omitempty"`
+	Property   *string `json:"property,omitempty"`
+	Fragment   *string `json:"fragment,omitempty"`
+	Matches    []Match `json:"matches,omitempty"`
+}
+
+func (tm TextMatch) String() string {
+	return Stringify(tm)
+}
+
+// CodeSearchResult represents the result of a code search.
+type CodeSearchResult struct {
+	Total             *int         `json:"total_count,omitempty"`
+	IncompleteResults *bool        `json:"incomplete_results,omitempty"`
+	CodeResults       []CodeResult `json:"items,omitempty"`
+}
+
+// CodeResult represents a single search result.
+type CodeResult struct {
+	Name        *string     `json:"name,omitempty"`
+	Path        *string     `json:"path,omitempty"`
+	SHA         *string     `json:"sha,omitempty"`
+	HTMLURL     *string     `json:"html_url,omitempty"`
+	Repository  *Repository `json:"repository,omitempty"`
+	TextMatches []TextMatch `json:"text_matches,omitempty"`
+}
+
+func (c CodeResult) String() string {
+	return Stringify(c)
+}
+
+// Code searches code via various criteria.
+//
+// GitHub API docs: https://developer.github.com/v3/search/#search-code
+func (s *SearchService) Code(ctx context.Context, query string, opt *SearchOptions) (*CodeSearchResult, *Response, error) {
+	result := new(CodeSearchResult)
+	resp, err := s.search(ctx, "code", query, opt, result)
+	return result, resp, err
+}
+
+// Helper function that executes search queries against different
+// GitHub search types (repositories, commits, code, issues, users)
+func (s *SearchService) search(ctx context.Context, searchType string, query string, opt *SearchOptions, result interface{}) (*Response, error) {
+	params, err := qs.Values(opt)
+	if err != nil {
+		return nil, err
+	}
+	params.Set("q", query)
+	u := fmt.Sprintf("search/%s?%s", searchType, params.Encode())
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	switch {
+	case searchType == "commits":
+		// Accept header for search commits preview endpoint
+		// TODO: remove custom Accept header when this API fully launches.
+		req.Header.Set("Accept", mediaTypeCommitSearchPreview)
+	case searchType == "repositories":
+		// Accept header for search repositories based on topics preview endpoint
+		// TODO: remove custom Accept header when this API fully launches.
+		req.Header.Set("Accept", mediaTypeTopicsPreview)
+	case opt != nil && opt.TextMatch:
+		// Accept header defaults to "application/vnd.github.v3+json"
+		// We change it here to fetch back text-match metadata
+		req.Header.Set("Accept", "application/vnd.github.v3.text-match+json")
+	}
+
+	return s.client.Do(ctx, req, result)
+}

+ 93 - 0
vendor/github.com/google/go-github/github/strings.go

@@ -0,0 +1,93 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+
+	"reflect"
+)
+
+var timestampType = reflect.TypeOf(Timestamp{})
+
+// Stringify attempts to create a reasonable string representation of types in
+// the GitHub library. It does things like resolve pointers to their values
+// and omits struct fields with nil values.
+func Stringify(message interface{}) string {
+	var buf bytes.Buffer
+	v := reflect.ValueOf(message)
+	stringifyValue(&buf, v)
+	return buf.String()
+}
+
+// stringifyValue was heavily inspired by the goprotobuf library.
+
+func stringifyValue(w io.Writer, val reflect.Value) {
+	if val.Kind() == reflect.Ptr && val.IsNil() {
+		w.Write([]byte("<nil>"))
+		return
+	}
+
+	v := reflect.Indirect(val)
+
+	switch v.Kind() {
+	case reflect.String:
+		fmt.Fprintf(w, `"%s"`, v)
+	case reflect.Slice:
+		w.Write([]byte{'['})
+		for i := 0; i < v.Len(); i++ {
+			if i > 0 {
+				w.Write([]byte{' '})
+			}
+
+			stringifyValue(w, v.Index(i))
+		}
+
+		w.Write([]byte{']'})
+		return
+	case reflect.Struct:
+		if v.Type().Name() != "" {
+			w.Write([]byte(v.Type().String()))
+		}
+
+		// special handling of Timestamp values
+		if v.Type() == timestampType {
+			fmt.Fprintf(w, "{%s}", v.Interface())
+			return
+		}
+
+		w.Write([]byte{'{'})
+
+		var sep bool
+		for i := 0; i < v.NumField(); i++ {
+			fv := v.Field(i)
+			if fv.Kind() == reflect.Ptr && fv.IsNil() {
+				continue
+			}
+			if fv.Kind() == reflect.Slice && fv.IsNil() {
+				continue
+			}
+
+			if sep {
+				w.Write([]byte(", "))
+			} else {
+				sep = true
+			}
+
+			w.Write([]byte(v.Type().Field(i).Name))
+			w.Write([]byte{':'})
+			stringifyValue(w, fv)
+		}
+
+		w.Write([]byte{'}'})
+	default:
+		if v.CanInterface() {
+			fmt.Fprint(w, v.Interface())
+		}
+	}
+}

+ 41 - 0
vendor/github.com/google/go-github/github/timestamp.go

@@ -0,0 +1,41 @@
+// Copyright 2013 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+	"strconv"
+	"time"
+)
+
+// Timestamp represents a time that can be unmarshalled from a JSON string
+// formatted as either an RFC3339 or Unix timestamp. This is necessary for some
+// fields since the GitHub API is inconsistent in how it represents times. All
+// exported methods of time.Time can be called on Timestamp.
+type Timestamp struct {
+	time.Time
+}
+
+func (t Timestamp) String() string {
+	return t.Time.String()
+}
+
+// UnmarshalJSON implements the json.Unmarshaler interface.
+// Time is expected in RFC3339 or Unix format.
+func (t *Timestamp) UnmarshalJSON(data []byte) (err error) {
+	str := string(data)
+	i, err := strconv.ParseInt(str, 10, 64)
+	if err == nil {
+		(*t).Time = time.Unix(i, 0)
+	} else {
+		(*t).Time, err = time.Parse(`"`+time.RFC3339+`"`, str)
+	}
+	return
+}
+
+// Equal reports whether t and u are equal based on time.Equal
+func (t Timestamp) Equal(u Timestamp) bool {
+	return t.Time.Equal(u.Time)
+}

Неке датотеке нису приказане због велике количине промена