Repository: google/go-github
Pull request #1344 (2019-12-04 13:41:32)

Bump major version to v29
Note to @willnorris - the only way I could figure out to get this to work (now with the inclusion of the scrape package) was to remove the `go.mod` and `go.sum` from the `scrape` directory.  (Because v29 of `go-github` does not exist until the PR is committed and the repo is tagged.)

I'm thinking this makes the most sense anyway since the top-level `go.mod` covers the whole repo.

If you find a better mechanism, though, I'm totally happy to close this PR and go with the better solution.

gmlewis: Note to self: If this gets merged, then a release of this repo should be tagged with `v29.0.0` before other PRs get merged.
willnorris: having a separate go.mod for the scrape package was very intentional (see https://github.com/google/go-github/issues/1308#issuecomment-542230233).  I likely won't be able to fully review this today, but do please wait to submit, as I'd like very much to keep the modules separate if at all possible.

/cc @dmitshur for comment and review as well
willnorris: what if you just leave the scrape package as relying on v28, and don't update that one in this change?  Then, after this PR has landed and the new tag created, update the scrape package to use v29 in a separate change.  Would that work?
gmlewis: Ah! OK. Sorry about that. I will fix it tonight and let you know when it is ready for review.
Thank you, Will!
gmlewis: Hi @willnorris - I believe this preserves the scrape versioning.

(I was a bit surprised that the dependencies of scrape are now being brought up into the top-level `go.mod`... and that they weren't before when scrape was first brought in. All I did to update `go.mod` was to run `go test ./...` and then all the scrape dependencies showed up... but I believe this is correct.)

PTAL.
dmitshur: I agree with Will’s comments, we must not remove the scrape/go.mod file, and it’s a good idea to keep this PR focused on just one module; updating the scrape module can be more safely done in later PRs.

Trying to make changes to more than one module (especially ones that are interconnected) in one PR is tricky and not worth doing until feeling very confident about the process.

Glenn, have you done `go mod tidy` in the latest version of this PR?
gmlewis: Thank you, @dmitshur!

Now I've run 'go mod tidy'. :smile:

PTAL.

Patch:
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e2a2b282..bd7db848 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -64,6 +64,9 @@ are more sensitive, emailed to <opensource@google.com>.
      messages are able to be formatted properly by various git tools.
 
   1. Finally, push the commits to your fork and submit a [pull request][].
+     **NOTE:** Please do not use force-push on PRs in this repo, as it makes
+     it more difficult for reviewers to see what has changed since the last
+     code review.
 
 [forking]: https://help.github.com/articles/fork-a-repo
 [golint]: https://github.com/golang/lint
diff --git a/README.md b/README.md
index c6f57924..8a496fb0 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ If you're interested in using the [GraphQL API v4][], the recommended library is
 ## Usage ##
 
 ```go
-import "github.com/google/go-github/v28/github"	// with go modules enabled (GO111MODULE=on or outside GOPATH)
+import "github.com/google/go-github/v29/github"	// with go modules enabled (GO111MODULE=on or outside GOPATH)
 import "github.com/google/go-github/github" // with go modules disabled
 ```
 
diff --git a/example/appengine/app.go b/example/appengine/app.go
index 8f567496..ba281842 100644
--- a/example/appengine/app.go
+++ b/example/appengine/app.go
@@ -12,7 +12,7 @@ import (
 	"net/http"
 	"os"
 
-	"github.com/google/go-github/v28/github"
+	"github.com/google/go-github/v29/github"
 	"golang.org/x/oauth2"
 	"google.golang.org/appengine"
 	"google.golang.org/appengine/log"
diff --git a/example/basicauth/main.go b/example/basicauth/main.go
index 33b118ba..4c31a30c 100644
--- a/example/basicauth/main.go
+++ b/example/basicauth/main.go
@@ -16,7 +16,7 @@ import (
 	"strings"
 	"syscall"
 
-	"github.com/google/go-github/v28/github"
+	"github.com/google/go-github/v29/github"
 	"golang.org/x/crypto/ssh/terminal"
 )
 
diff --git a/example/commitpr/main.go b/example/commitpr/main.go
index 53061841..188424dc 100644
--- a/example/commitpr/main.go
+++ b/example/commitpr/main.go
@@ -31,7 +31,7 @@ import (
 	"strings"
 	"time"
 
-	"github.com/google/go-github/v28/github"
+	"github.com/google/go-github/v29/github"
 	"golang.org/x/oauth2"
 )
 
diff --git a/example/migrations/main.go b/example/migrations/main.go
index e0d30530..d73380a7 100644
--- a/example/migrations/main.go
+++ b/example/migrations/main.go
@@ -12,7 +12,7 @@ import (
 	"context"
 	"fmt"
 
-	"github.com/google/go-github/v28/github"
+	"github.com/google/go-github/v29/github"
 	"golang.org/x/oauth2"
 )
 
diff --git a/example/newrepo/main.go b/example/newrepo/main.go
index 82eccf5e..4b03a440 100644
--- a/example/newrepo/main.go
+++ b/example/newrepo/main.go
@@ -16,7 +16,7 @@ import (
 	"log"
 	"os"
 
-	"github.com/google/go-github/v28/github"
+	"github.com/google/go-github/v29/github"
 	"golang.org/x/oauth2"
 )
 
diff --git a/example/simple/main.go b/example/simple/main.go
index 8bab9603..33af5e5e 100644
--- a/example/simple/main.go
+++ b/example/simple/main.go
@@ -12,7 +12,7 @@ import (
 	"context"
 	"fmt"
 
-	"github.com/google/go-github/v28/github"
+	"github.com/google/go-github/v29/github"
 )
 
 // Fetch all the public organizations' membership of a user.
diff --git a/example/topics/main.go b/example/topics/main.go
new file mode 100644
index 00000000..96098efe
--- /dev/null
+++ b/example/topics/main.go
@@ -0,0 +1,40 @@
+// Copyright 2019 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.
+
+// The simple command demonstrates a simple functionality which
+// prompts the user for a GitHub topic and lists all the public
+// organization memberships of the specified topic.
+package main
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/google/go-github/v28/github"
+)
+
+// Fetch all the public organizations' membership of a user.
+//
+func FetchTopics(topic string) (*github.TopicsSearchResult, error) {
+	client := github.NewClient(nil)
+	topics, _, err := client.Search.Topics(context.Background(), topic, nil)
+	return topics, err
+}
+
+func main() {
+	var topic string
+	fmt.Print("Enter GitHub topic: ")
+	fmt.Scanf("%s", &topic)
+
+	topics, err := FetchTopics(topic)
+	if err != nil {
+		fmt.Printf("Error: %v\n", err)
+		return
+	}
+
+	for _, topic := range topics.Topics {
+		fmt.Println(*topic.Name)
+	}
+}
diff --git a/github/admin.go b/github/admin.go
index 2d96733a..31cd1fa2 100644
--- a/github/admin.go
+++ b/github/admin.go
@@ -62,6 +62,24 @@ func (m UserLDAPMapping) String() string {
 	return Stringify(m)
 }
 
+// Enterprise represents the GitHub enterprise profile.
+type Enterprise struct {
+	ID          *int       `json:"id,omitempty"`
+	Slug        *string    `json:"slug,omitempty"`
+	Name        *string    `json:"name,omitempty"`
+	NodeID      *string    `json:"node_id,omitempty"`
+	AvatarURL   *string    `json:"avatar_url,omitempty"`
+	Description *string    `json:"description,omitempty"`
+	WebsiteURL  *string    `json:"website_url,omitempty"`
+	HTMLURL     *string    `json:"html_url,omitempty"`
+	CreatedAt   *Timestamp `json:"created_at,omitempty"`
+	UpdatedAt   *Timestamp `json:"updated_at,omitempty"`
+}
+
+func (m Enterprise) 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
diff --git a/github/admin_users.go b/github/admin_users.go
index ea7a47d3..74285550 100644
--- a/github/admin_users.go
+++ b/github/admin_users.go
@@ -7,6 +7,7 @@ package github
 
 import (
 	"context"
+	"fmt"
 )
 
 // createUserRequest is a subset of User and is used internally
@@ -59,3 +60,74 @@ func (s *AdminService) DeleteUser(ctx context.Context, username string) (*Respon
 
 	return resp, nil
 }
+
+// ImpersonateUserOptions represents the scoping for the OAuth token.
+type ImpersonateUserOptions struct {
+	Scopes []string `json:"scopes,omitempty"`
+}
+
+// OAuthAPP represents the GitHub Site Administrator OAuth app.
+type OAuthAPP struct {
+	URL      *string `json:"url,omitempty"`
+	Name     *string `json:"name,omitempty"`
+	ClientID *string `json:"client_id,omitempty"`
+}
+
+func (s OAuthAPP) String() string {
+	return Stringify(s)
+}
+
+// UserAuthorization represents the impersonation response.
+type UserAuthorization struct {
+	ID             *int64     `json:"id,omitempty"`
+	URL            *string    `json:"url,omitempty"`
+	Scopes         []string   `json:"scopes,omitempty"`
+	Token          *string    `json:"token,omitempty"`
+	TokenLastEight *string    `json:"token_last_eight,omitempty"`
+	HashedToken    *string    `json:"hashed_token,omitempty"`
+	App            *OAuthAPP  `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"`
+}
+
+// CreateUserImpersonation creates an impersonation OAuth token.
+//
+// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#create-an-impersonation-oauth-token
+func (s *AdminService) CreateUserImpersonation(ctx context.Context, username string, opt *ImpersonateUserOptions) (*UserAuthorization, *Response, error) {
+	u := fmt.Sprintf("admin/users/%s/authorizations", username)
+
+	req, err := s.client.NewRequest("POST", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	a := new(UserAuthorization)
+	resp, err := s.client.Do(ctx, req, a)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return a, resp, nil
+}
+
+// DeleteUserImpersonation deletes an impersonation OAuth token.
+//
+// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#delete-an-impersonation-oauth-token
+func (s *AdminService) DeleteUserImpersonation(ctx context.Context, username string) (*Response, error) {
+	u := fmt.Sprintf("admin/users/%s/authorizations", username)
+
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	resp, err := s.client.Do(ctx, req, nil)
+	if err != nil {
+		return resp, err
+	}
+
+	return resp, nil
+}
diff --git a/github/apps.go b/github/apps.go
index 913464f6..251ac631 100644
--- a/github/apps.go
+++ b/github/apps.go
@@ -19,15 +19,18 @@ type AppsService service
 
 // App represents a GitHub App.
 type App struct {
-	ID          *int64     `json:"id,omitempty"`
-	NodeID      *string    `json:"node_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   *Timestamp `json:"created_at,omitempty"`
-	UpdatedAt   *Timestamp `json:"updated_at,omitempty"`
+	ID          *int64                   `json:"id,omitempty"`
+	Slug        *string                  `json:"slug,omitempty"`
+	NodeID      *string                  `json:"node_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   *Timestamp               `json:"created_at,omitempty"`
+	UpdatedAt   *Timestamp               `json:"updated_at,omitempty"`
+	Permissions *InstallationPermissions `json:"permissions,omitempty"`
+	Events      []*Event                 `json:"events,omitempty"`
 }
 
 // InstallationToken represents an installation token.
@@ -56,10 +59,13 @@ type InstallationTokenOptions struct {
 //   https://developer.github.com/enterprise/v3/apps/permissions/
 type InstallationPermissions struct {
 	Administration              *string `json:"administration,omitempty"`
+	Blocking                    *string `json:"blocking,omitempty"`
 	Checks                      *string `json:"checks,omitempty"`
 	Contents                    *string `json:"contents,omitempty"`
 	ContentReferences           *string `json:"content_references,omitempty"`
 	Deployments                 *string `json:"deployments,omitempty"`
+	Emails                      *string `json:"emails,omitempty"`
+	Followers                   *string `json:"followers,omitempty"`
 	Issues                      *string `json:"issues,omitempty"`
 	Metadata                    *string `json:"metadata,omitempty"`
 	Members                     *string `json:"members,omitempty"`
diff --git a/github/checks.go b/github/checks.go
index 84f84034..1acc26e9 100644
--- a/github/checks.go
+++ b/github/checks.go
@@ -140,7 +140,6 @@ func (s *ChecksService) GetCheckSuite(ctx context.Context, owner, repo string, c
 // CreateCheckRunOptions sets up parameters needed to create a CheckRun.
 type CreateCheckRunOptions struct {
 	Name        string            `json:"name"`                   // The name of the check (e.g., "code-coverage"). (Required.)
-	HeadBranch  string            `json:"head_branch"`            // The name of the branch to perform a check against. (Required.)
 	HeadSHA     string            `json:"head_sha"`               // The SHA of the commit. (Required.)
 	DetailsURL  *string           `json:"details_url,omitempty"`  // The URL of the integrator's site that has the full details of the check. (Optional.)
 	ExternalID  *string           `json:"external_id,omitempty"`  // A reference for the run on the integrator's system. (Optional.)
@@ -183,7 +182,6 @@ func (s *ChecksService) CreateCheckRun(ctx context.Context, owner, repo string,
 // UpdateCheckRunOptions sets up parameters needed to update a CheckRun.
 type UpdateCheckRunOptions struct {
 	Name        string            `json:"name"`                   // The name of the check (e.g., "code-coverage"). (Required.)
-	HeadBranch  *string           `json:"head_branch,omitempty"`  // The name of the branch to perform a check against. (Optional.)
 	HeadSHA     *string           `json:"head_sha,omitempty"`     // The SHA of the commit. (Optional.)
 	DetailsURL  *string           `json:"details_url,omitempty"`  // The URL of the integrator's site that has the full details of the check. (Optional.)
 	ExternalID  *string           `json:"external_id,omitempty"`  // A reference for the run on the integrator's system. (Optional.)
diff --git a/github/doc.go b/github/doc.go
index 8adfdc1d..403a6ecc 100644
--- a/github/doc.go
+++ b/github/doc.go
@@ -8,7 +8,7 @@ Package github provides a client for using the GitHub API.
 
 Usage:
 
-	import "github.com/google/go-github/v28/github"	// with go modules enabled (GO111MODULE=on or outside GOPATH)
+	import "github.com/google/go-github/v29/github"	// with go modules enabled (GO111MODULE=on or outside GOPATH)
 	import "github.com/google/go-github/github"     // with go modules disabled
 
 Construct a new GitHub client, then use the various services on the client to
diff --git a/github/event.go b/github/event.go
index 0ba8f46a..848fa6da 100644
--- a/github/event.go
+++ b/github/event.go
@@ -100,6 +100,8 @@ func (e *Event) ParsePayload() (payload interface{}, err error) {
 		payload = &ReleaseEvent{}
 	case "RepositoryEvent":
 		payload = &RepositoryEvent{}
+	case "RepositoryDispatchEvent":
+		payload = &RepositoryDispatchEvent{}
 	case "RepositoryVulnerabilityAlertEvent":
 		payload = &RepositoryVulnerabilityAlertEvent{}
 	case "StarEvent":
@@ -110,6 +112,8 @@ func (e *Event) ParsePayload() (payload interface{}, err error) {
 		payload = &TeamEvent{}
 	case "TeamAddEvent":
 		payload = &TeamAddEvent{}
+	case "UserEvent":
+		payload = &UserEvent{}
 	case "WatchEvent":
 		payload = &WatchEvent{}
 	}
diff --git a/github/event_types.go b/github/event_types.go
index 049751aa..df12821c 100644
--- a/github/event_types.go
+++ b/github/event_types.go
@@ -7,6 +7,8 @@
 
 package github
 
+import "encoding/json"
+
 // RequestedAction is included in a CheckRunEvent when a user has invoked an action,
 // i.e. when the CheckRunEvent's Action field is "requested_action".
 type RequestedAction struct {
@@ -776,6 +778,22 @@ type RepositoryEvent struct {
 	Installation *Installation `json:"installation,omitempty"`
 }
 
+// RepositoryDispatchEvent is triggered when a client sends a POST request to the repository dispatch event endpoint.
+//
+// GitHub API docs: https://developer.github.com/v3/activity/events/types/#repositorydispatchevent
+type RepositoryDispatchEvent struct {
+	// Action is the event_type that submitted with the repository dispatch payload. Value can be any string.
+	Action        *string         `json:"action,omitempty"`
+	Branch        *string         `json:"branch,omitempty"`
+	ClientPayload json.RawMessage `json:"client_payload,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"`
+}
+
 // RepositoryVulnerabilityAlertEvent is triggered when a security alert is created, dismissed, or resolved.
 //
 // GitHub API docs: https://developer.github.com/v3/activity/events/types/#repositoryvulnerabilityalertevent
@@ -872,6 +890,20 @@ type TeamAddEvent struct {
 	Installation *Installation `json:"installation,omitempty"`
 }
 
+// UserEvent is triggered when a user is created or deleted.
+// The Webhook event name is "user".
+//
+// Only global webhooks can subscribe to this event type.
+//
+// GitHub API docs: https://developer.github.com/enterprise/v3/activity/events/types/#userevent-enterprise
+type UserEvent struct {
+	User *User `json:"user,omitempty"`
+	// The action performed. Possible values are: "created" or "deleted".
+	Action     *string     `json:"action,omitempty"`
+	Enterprise *Enterprise `json:"enterprise,omitempty"`
+	Sender     *User       `json:"sender,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/
 //
diff --git a/github/git_trees.go b/github/git_trees.go
index 4bc29135..df843f4d 100644
--- a/github/git_trees.go
+++ b/github/git_trees.go
@@ -7,6 +7,7 @@ package github
 
 import (
 	"context"
+	"encoding/json"
 	"fmt"
 )
 
@@ -43,6 +44,39 @@ func (t TreeEntry) String() string {
 	return Stringify(t)
 }
 
+func (t *TreeEntry) MarshalJSON() ([]byte, error) {
+	if t.SHA == nil && t.Content == nil {
+		return json.Marshal(struct {
+			SHA  *string `json:"sha"`
+			Path *string `json:"path,omitempty"`
+			Mode *string `json:"mode,omitempty"`
+			Type *string `json:"type,omitempty"`
+		}{
+			nil,
+			t.Path,
+			t.Mode,
+			t.Type,
+		})
+	}
+	return json.Marshal(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"`
+	}{
+		SHA:     t.SHA,
+		Path:    t.Path,
+		Mode:    t.Mode,
+		Type:    t.Type,
+		Size:    t.Size,
+		Content: t.Content,
+		URL:     t.URL,
+	})
+}
+
 // 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
diff --git a/github/github-accessors.go b/github/github-accessors.go
index 8aaeb247..4ff4a3f5 100644
--- a/github/github-accessors.go
+++ b/github/github-accessors.go
@@ -180,6 +180,22 @@ func (a *App) GetOwner() *User {
 	return a.Owner
 }
 
+// GetPermissions returns the Permissions field.
+func (a *App) GetPermissions() *InstallationPermissions {
+	if a == nil {
+		return nil
+	}
+	return a.Permissions
+}
+
+// GetSlug returns the Slug field if it's non-nil, zero value otherwise.
+func (a *App) GetSlug() string {
+	if a == nil || a.Slug == nil {
+		return ""
+	}
+	return *a.Slug
+}
+
 // GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
 func (a *App) GetUpdatedAt() Timestamp {
 	if a == nil || a.UpdatedAt == nil {
@@ -1180,6 +1196,70 @@ func (c *CodeSearchResult) GetTotal() int {
 	return *c.Total
 }
 
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (c *CollaboratorInvitation) GetCreatedAt() Timestamp {
+	if c == nil || c.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *c.CreatedAt
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (c *CollaboratorInvitation) 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 *CollaboratorInvitation) GetID() int64 {
+	if c == nil || c.ID == nil {
+		return 0
+	}
+	return *c.ID
+}
+
+// GetInvitee returns the Invitee field.
+func (c *CollaboratorInvitation) GetInvitee() *User {
+	if c == nil {
+		return nil
+	}
+	return c.Invitee
+}
+
+// GetInviter returns the Inviter field.
+func (c *CollaboratorInvitation) GetInviter() *User {
+	if c == nil {
+		return nil
+	}
+	return c.Inviter
+}
+
+// GetPermissions returns the Permissions field if it's non-nil, zero value otherwise.
+func (c *CollaboratorInvitation) GetPermissions() string {
+	if c == nil || c.Permissions == nil {
+		return ""
+	}
+	return *c.Permissions
+}
+
+// GetRepo returns the Repo field.
+func (c *CollaboratorInvitation) GetRepo() *Repository {
+	if c == nil {
+		return nil
+	}
+	return c.Repo
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (c *CollaboratorInvitation) GetURL() string {
+	if c == nil || c.URL == nil {
+		return ""
+	}
+	return *c.URL
+}
+
 // GetCommitURL returns the CommitURL field if it's non-nil, zero value otherwise.
 func (c *CombinedStatus) GetCommitURL() string {
 	if c == nil || c.CommitURL == nil {
@@ -2092,6 +2172,14 @@ func (c *CreateOrgInvitationOptions) GetRole() string {
 	return *c.Role
 }
 
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (c *CreateUserProjectOptions) GetBody() string {
+	if c == nil || c.Body == nil {
+		return ""
+	}
+	return *c.Body
+}
+
 // GetInstallation returns the Installation field.
 func (d *DeleteEvent) GetInstallation() *Installation {
 	if d == nil {
@@ -2316,14 +2404,6 @@ func (d *DeploymentRequest) GetEnvironment() string {
 	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 {
@@ -2684,6 +2764,14 @@ func (d *DismissedReview) GetState() string {
 	return *d.State
 }
 
+// GetClientPayload returns the ClientPayload field if it's non-nil, zero value otherwise.
+func (d *DispatchRequestOptions) GetClientPayload() json.RawMessage {
+	if d == nil || d.ClientPayload == nil {
+		return json.RawMessage{}
+	}
+	return *d.ClientPayload
+}
+
 // GetBody returns the Body field if it's non-nil, zero value otherwise.
 func (d *DraftReviewComment) GetBody() string {
 	if d == nil || d.Body == nil {
@@ -2708,6 +2796,86 @@ func (d *DraftReviewComment) GetPosition() int {
 	return *d.Position
 }
 
+// GetAvatarURL returns the AvatarURL field if it's non-nil, zero value otherwise.
+func (e *Enterprise) GetAvatarURL() string {
+	if e == nil || e.AvatarURL == nil {
+		return ""
+	}
+	return *e.AvatarURL
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (e *Enterprise) GetCreatedAt() Timestamp {
+	if e == nil || e.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *e.CreatedAt
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (e *Enterprise) GetDescription() string {
+	if e == nil || e.Description == nil {
+		return ""
+	}
+	return *e.Description
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (e *Enterprise) GetHTMLURL() string {
+	if e == nil || e.HTMLURL == nil {
+		return ""
+	}
+	return *e.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (e *Enterprise) GetID() int {
+	if e == nil || e.ID == nil {
+		return 0
+	}
+	return *e.ID
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (e *Enterprise) GetName() string {
+	if e == nil || e.Name == nil {
+		return ""
+	}
+	return *e.Name
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (e *Enterprise) GetNodeID() string {
+	if e == nil || e.NodeID == nil {
+		return ""
+	}
+	return *e.NodeID
+}
+
+// GetSlug returns the Slug field if it's non-nil, zero value otherwise.
+func (e *Enterprise) GetSlug() string {
+	if e == nil || e.Slug == nil {
+		return ""
+	}
+	return *e.Slug
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (e *Enterprise) GetUpdatedAt() Timestamp {
+	if e == nil || e.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *e.UpdatedAt
+}
+
+// GetWebsiteURL returns the WebsiteURL field if it's non-nil, zero value otherwise.
+func (e *Enterprise) GetWebsiteURL() string {
+	if e == nil || e.WebsiteURL == nil {
+		return ""
+	}
+	return *e.WebsiteURL
+}
+
 // GetActor returns the Actor field.
 func (e *Event) GetActor() *User {
 	if e == nil {
@@ -3780,6 +3948,14 @@ func (i *InstallationPermissions) GetAdministration() string {
 	return *i.Administration
 }
 
+// GetBlocking returns the Blocking field if it's non-nil, zero value otherwise.
+func (i *InstallationPermissions) GetBlocking() string {
+	if i == nil || i.Blocking == nil {
+		return ""
+	}
+	return *i.Blocking
+}
+
 // GetChecks returns the Checks field if it's non-nil, zero value otherwise.
 func (i *InstallationPermissions) GetChecks() string {
 	if i == nil || i.Checks == nil {
@@ -3812,6 +3988,22 @@ func (i *InstallationPermissions) GetDeployments() string {
 	return *i.Deployments
 }
 
+// GetEmails returns the Emails field if it's non-nil, zero value otherwise.
+func (i *InstallationPermissions) GetEmails() string {
+	if i == nil || i.Emails == nil {
+		return ""
+	}
+	return *i.Emails
+}
+
+// GetFollowers returns the Followers field if it's non-nil, zero value otherwise.
+func (i *InstallationPermissions) GetFollowers() string {
+	if i == nil || i.Followers == nil {
+		return ""
+	}
+	return *i.Followers
+}
+
 // GetIssues returns the Issues field if it's non-nil, zero value otherwise.
 func (i *InstallationPermissions) GetIssues() string {
 	if i == nil || i.Issues == nil {
@@ -4588,6 +4780,30 @@ func (i *IssueEvent) GetURL() string {
 	return *i.URL
 }
 
+// GetDirection returns the Direction field if it's non-nil, zero value otherwise.
+func (i *IssueListCommentsOptions) GetDirection() string {
+	if i == nil || i.Direction == nil {
+		return ""
+	}
+	return *i.Direction
+}
+
+// GetSince returns the Since field if it's non-nil, zero value otherwise.
+func (i *IssueListCommentsOptions) GetSince() time.Time {
+	if i == nil || i.Since == nil {
+		return time.Time{}
+	}
+	return *i.Since
+}
+
+// GetSort returns the Sort field if it's non-nil, zero value otherwise.
+func (i *IssueListCommentsOptions) GetSort() string {
+	if i == nil || i.Sort == nil {
+		return ""
+	}
+	return *i.Sort
+}
+
 // GetAssignee returns the Assignee field if it's non-nil, zero value otherwise.
 func (i *IssueRequest) GetAssignee() string {
 	if i == nil || i.Assignee == nil {
@@ -6140,6 +6356,30 @@ func (n *NotificationSubject) GetURL() string {
 	return *n.URL
 }
 
+// GetClientID returns the ClientID field if it's non-nil, zero value otherwise.
+func (o *OAuthAPP) GetClientID() string {
+	if o == nil || o.ClientID == nil {
+		return ""
+	}
+	return *o.ClientID
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (o *OAuthAPP) GetName() string {
+	if o == nil || o.Name == nil {
+		return ""
+	}
+	return *o.Name
+}
+
+// GetURL returns the URL field if it's non-nil, zero value otherwise.
+func (o *OAuthAPP) GetURL() string {
+	if o == nil || o.URL == nil {
+		return ""
+	}
+	return *o.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 {
@@ -6308,6 +6548,30 @@ func (o *Organization) GetMembersAllowedRepositoryCreationType() string {
 	return *o.MembersAllowedRepositoryCreationType
 }
 
+// GetMembersCanCreateInternalRepos returns the MembersCanCreateInternalRepos field if it's non-nil, zero value otherwise.
+func (o *Organization) GetMembersCanCreateInternalRepos() bool {
+	if o == nil || o.MembersCanCreateInternalRepos == nil {
+		return false
+	}
+	return *o.MembersCanCreateInternalRepos
+}
+
+// GetMembersCanCreatePrivateRepos returns the MembersCanCreatePrivateRepos field if it's non-nil, zero value otherwise.
+func (o *Organization) GetMembersCanCreatePrivateRepos() bool {
+	if o == nil || o.MembersCanCreatePrivateRepos == nil {
+		return false
+	}
+	return *o.MembersCanCreatePrivateRepos
+}
+
+// GetMembersCanCreatePublicRepos returns the MembersCanCreatePublicRepos field if it's non-nil, zero value otherwise.
+func (o *Organization) GetMembersCanCreatePublicRepos() bool {
+	if o == nil || o.MembersCanCreatePublicRepos == nil {
+		return false
+	}
+	return *o.MembersCanCreatePublicRepos
+}
+
 // GetMembersCanCreateRepos returns the MembersCanCreateRepos field if it's non-nil, zero value otherwise.
 func (o *Organization) GetMembersCanCreateRepos() bool {
 	if o == nil || o.MembersCanCreateRepos == nil {
@@ -8084,6 +8348,14 @@ func (p *PullRequestComment) GetInReplyTo() int64 {
 	return *p.InReplyTo
 }
 
+// GetLine returns the Line field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetLine() int {
+	if p == nil || p.Line == nil {
+		return 0
+	}
+	return *p.Line
+}
+
 // GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
 func (p *PullRequestComment) GetNodeID() string {
 	if p == nil || p.NodeID == nil {
@@ -8100,6 +8372,14 @@ func (p *PullRequestComment) GetOriginalCommitID() string {
 	return *p.OriginalCommitID
 }
 
+// GetOriginalLine returns the OriginalLine field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetOriginalLine() int {
+	if p == nil || p.OriginalLine == nil {
+		return 0
+	}
+	return *p.OriginalLine
+}
+
 // GetOriginalPosition returns the OriginalPosition field if it's non-nil, zero value otherwise.
 func (p *PullRequestComment) GetOriginalPosition() int {
 	if p == nil || p.OriginalPosition == nil {
@@ -8108,6 +8388,14 @@ func (p *PullRequestComment) GetOriginalPosition() int {
 	return *p.OriginalPosition
 }
 
+// GetOriginalStartLine returns the OriginalStartLine field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetOriginalStartLine() int {
+	if p == nil || p.OriginalStartLine == nil {
+		return 0
+	}
+	return *p.OriginalStartLine
+}
+
 // GetPath returns the Path field if it's non-nil, zero value otherwise.
 func (p *PullRequestComment) GetPath() string {
 	if p == nil || p.Path == nil {
@@ -8148,6 +8436,30 @@ func (p *PullRequestComment) GetReactions() *Reactions {
 	return p.Reactions
 }
 
+// GetSide returns the Side field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetSide() string {
+	if p == nil || p.Side == nil {
+		return ""
+	}
+	return *p.Side
+}
+
+// GetStartLine returns the StartLine field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetStartLine() int {
+	if p == nil || p.StartLine == nil {
+		return 0
+	}
+	return *p.StartLine
+}
+
+// GetStartSide returns the StartSide field if it's non-nil, zero value otherwise.
+func (p *PullRequestComment) GetStartSide() string {
+	if p == nil || p.StartSide == nil {
+		return ""
+	}
+	return *p.StartSide
+}
+
 // 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 {
@@ -8548,6 +8860,14 @@ func (p *PullRequestReviewRequest) GetNodeID() string {
 	return *p.NodeID
 }
 
+// GetDismissalRestrictions returns the DismissalRestrictions field.
+func (p *PullRequestReviewsEnforcement) GetDismissalRestrictions() *DismissalRestrictions {
+	if p == nil {
+		return nil
+	}
+	return p.DismissalRestrictions
+}
+
 // GetDismissalRestrictionsRequest returns the DismissalRestrictionsRequest field.
 func (p *PullRequestReviewsEnforcementRequest) GetDismissalRestrictionsRequest() *DismissalRestrictionsRequest {
 	if p == nil {
@@ -10444,6 +10764,54 @@ func (r *RepositoryContentResponse) GetContent() *RepositoryContent {
 	return r.Content
 }
 
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (r *RepositoryDispatchEvent) GetAction() string {
+	if r == nil || r.Action == nil {
+		return ""
+	}
+	return *r.Action
+}
+
+// GetBranch returns the Branch field if it's non-nil, zero value otherwise.
+func (r *RepositoryDispatchEvent) GetBranch() string {
+	if r == nil || r.Branch == nil {
+		return ""
+	}
+	return *r.Branch
+}
+
+// GetInstallation returns the Installation field.
+func (r *RepositoryDispatchEvent) GetInstallation() *Installation {
+	if r == nil {
+		return nil
+	}
+	return r.Installation
+}
+
+// GetOrg returns the Org field.
+func (r *RepositoryDispatchEvent) GetOrg() *Organization {
+	if r == nil {
+		return nil
+	}
+	return r.Org
+}
+
+// GetRepo returns the Repo field.
+func (r *RepositoryDispatchEvent) GetRepo() *Repository {
+	if r == nil {
+		return nil
+	}
+	return r.Repo
+}
+
+// GetSender returns the Sender field.
+func (r *RepositoryDispatchEvent) GetSender() *User {
+	if r == nil {
+		return nil
+	}
+	return r.Sender
+}
+
 // GetAction returns the Action field if it's non-nil, zero value otherwise.
 func (r *RepositoryEvent) GetAction() string {
 	if r == nil || r.Action == nil {
@@ -12044,6 +12412,102 @@ func (t *Timeline) GetURL() string {
 	return *t.URL
 }
 
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (t *TopicResult) GetCreatedAt() Timestamp {
+	if t == nil || t.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *t.CreatedAt
+}
+
+// GetCreatedBy returns the CreatedBy field if it's non-nil, zero value otherwise.
+func (t *TopicResult) GetCreatedBy() string {
+	if t == nil || t.CreatedBy == nil {
+		return ""
+	}
+	return *t.CreatedBy
+}
+
+// GetCurated returns the Curated field if it's non-nil, zero value otherwise.
+func (t *TopicResult) GetCurated() bool {
+	if t == nil || t.Curated == nil {
+		return false
+	}
+	return *t.Curated
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (t *TopicResult) GetDescription() string {
+	if t == nil || t.Description == nil {
+		return ""
+	}
+	return *t.Description
+}
+
+// GetDisplayName returns the DisplayName field if it's non-nil, zero value otherwise.
+func (t *TopicResult) GetDisplayName() string {
+	if t == nil || t.DisplayName == nil {
+		return ""
+	}
+	return *t.DisplayName
+}
+
+// GetFeatured returns the Featured field if it's non-nil, zero value otherwise.
+func (t *TopicResult) GetFeatured() bool {
+	if t == nil || t.Featured == nil {
+		return false
+	}
+	return *t.Featured
+}
+
+// GetName returns the Name field if it's non-nil, zero value otherwise.
+func (t *TopicResult) GetName() string {
+	if t == nil || t.Name == nil {
+		return ""
+	}
+	return *t.Name
+}
+
+// GetScore returns the Score field.
+func (t *TopicResult) GetScore() *float64 {
+	if t == nil {
+		return nil
+	}
+	return t.Score
+}
+
+// GetShortDescription returns the ShortDescription field if it's non-nil, zero value otherwise.
+func (t *TopicResult) GetShortDescription() string {
+	if t == nil || t.ShortDescription == nil {
+		return ""
+	}
+	return *t.ShortDescription
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (t *TopicResult) GetUpdatedAt() string {
+	if t == nil || t.UpdatedAt == nil {
+		return ""
+	}
+	return *t.UpdatedAt
+}
+
+// GetIncompleteResults returns the IncompleteResults field if it's non-nil, zero value otherwise.
+func (t *TopicsSearchResult) GetIncompleteResults() bool {
+	if t == nil || t.IncompleteResults == nil {
+		return false
+	}
+	return *t.IncompleteResults
+}
+
+// GetTotal returns the Total field if it's non-nil, zero value otherwise.
+func (t *TopicsSearchResult) GetTotal() int {
+	if t == nil || t.Total == nil {
+		return 0
+	}
+	return *t.Total
+}
+
 // GetCount returns the Count field if it's non-nil, zero value otherwise.
 func (t *TrafficClones) GetCount() int {
 	if t == nil || t.Count == nil {
@@ -12260,14 +12724,6 @@ func (u *UpdateCheckRunOptions) GetExternalID() string {
 	return *u.ExternalID
 }
 
-// GetHeadBranch returns the HeadBranch field if it's non-nil, zero value otherwise.
-func (u *UpdateCheckRunOptions) GetHeadBranch() string {
-	if u == nil || u.HeadBranch == nil {
-		return ""
-	}
-	return *u.HeadBranch
-}
-
 // GetHeadSHA returns the HeadSHA field if it's non-nil, zero value otherwise.
 func (u *UpdateCheckRunOptions) GetHeadSHA() string {
 	if u == nil || u.HeadSHA == nil {
@@ -12620,6 +13076,94 @@ func (u *User) GetURL() string {
 	return *u.URL
 }
 
+// GetApp returns the App field.
+func (u *UserAuthorization) GetApp() *OAuthAPP {
+	if u == nil {
+		return nil
+	}
+	return u.App
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (u *UserAuthorization) GetCreatedAt() Timestamp {
+	if u == nil || u.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *u.CreatedAt
+}
+
+// GetFingerprint returns the Fingerprint field if it's non-nil, zero value otherwise.
+func (u *UserAuthorization) GetFingerprint() string {
+	if u == nil || u.Fingerprint == nil {
+		return ""
+	}
+	return *u.Fingerprint
+}
+
+// GetHashedToken returns the HashedToken field if it's non-nil, zero value otherwise.
+func (u *UserAuthorization) GetHashedToken() string {
+	if u == nil || u.HashedToken == nil {
+		return ""
+	}
+	return *u.HashedToken
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (u *UserAuthorization) GetID() int64 {
+	if u == nil || u.ID == nil {
+		return 0
+	}
+	return *u.ID
+}
+
+// GetNote returns the Note field if it's non-nil, zero value otherwise.
+func (u *UserAuthorization) GetNote() string {
+	if u == nil || u.Note == nil {
+		return ""
+	}
+	return *u.Note
+}
+
+// GetNoteURL returns the NoteURL field if it's non-nil, zero value otherwise.
+func (u *UserAuthorization) GetNoteURL() string {
+	if u == nil || u.NoteURL == nil {
+		return ""
+	}
+	return *u.NoteURL
+}
+
+// GetToken returns the Token field if it's non-nil, zero value otherwise.
+func (u *UserAuthorization) GetToken() string {
+	if u == nil || u.Token == nil {
+		return ""
+	}
+	return *u.Token
+}
+
+// GetTokenLastEight returns the TokenLastEight field if it's non-nil, zero value otherwise.
+func (u *UserAuthorization) GetTokenLastEight() string {
+	if u == nil || u.TokenLastEight == nil {
+		return ""
+	}
+	return *u.TokenLastEight
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (u *UserAuthorization) 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 *UserAuthorization) GetURL() string {
+	if u == nil || u.URL == nil {
+		return ""
+	}
+	return *u.URL
+}
+
 // GetMessage returns the Message field if it's non-nil, zero value otherwise.
 func (u *UserContext) GetMessage() string {
 	if u == nil || u.Message == nil {
@@ -12668,6 +13212,38 @@ func (u *UserEmail) GetVisibility() string {
 	return *u.Visibility
 }
 
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (u *UserEvent) GetAction() string {
+	if u == nil || u.Action == nil {
+		return ""
+	}
+	return *u.Action
+}
+
+// GetEnterprise returns the Enterprise field.
+func (u *UserEvent) GetEnterprise() *Enterprise {
+	if u == nil {
+		return nil
+	}
+	return u.Enterprise
+}
+
+// GetSender returns the Sender field.
+func (u *UserEvent) GetSender() *User {
+	if u == nil {
+		return nil
+	}
+	return u.Sender
+}
+
+// GetUser returns the User field.
+func (u *UserEvent) GetUser() *User {
+	if u == nil {
+		return nil
+	}
+	return u.User
+}
+
 // GetAvatarURL returns the AvatarURL field if it's non-nil, zero value otherwise.
 func (u *UserLDAPMapping) GetAvatarURL() string {
 	if u == nil || u.AvatarURL == nil {
diff --git a/github/github.go b/github/github.go
index 0580271c..3ea1f6ad 100644
--- a/github/github.go
+++ b/github/github.go
@@ -67,9 +67,6 @@ const (
 	// https://developer.github.com/changes/2016-05-23-timeline-preview-api/
 	mediaTypeTimelinePreview = "application/vnd.github.mockingbird-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"
 
@@ -91,27 +88,9 @@ const (
 	// 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-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/2018-01-25-organization-invitation-api-preview/
-	mediaTypeOrganizationInvitationPreview = "application/vnd.github.dazzler-preview+json"
-
 	// https://developer.github.com/changes/2018-03-16-protected-branches-required-approving-reviews/
 	mediaTypeRequiredApprovingReviewsPreview = "application/vnd.github.luke-cage-preview+json"
 
-	// https://developer.github.com/changes/2018-02-22-label-description-search-preview/
-	mediaTypeLabelDescriptionSearchPreview = "application/vnd.github.symmetra-preview+json"
-
-	// https://developer.github.com/changes/2018-02-07-team-discussions-api/
-	mediaTypeTeamDiscussionsPreview = "application/vnd.github.echo-preview+json"
-
-	// https://developer.github.com/changes/2018-03-21-hovercard-api-preview/
-	mediaTypeHovercardPreview = "application/vnd.github.hagar-preview+json"
-
 	// https://developer.github.com/changes/2018-01-10-lock-reason-api-preview/
 	mediaTypeLockReasonPreview = "application/vnd.github.sailor-v-preview+json"
 
@@ -148,14 +127,17 @@ const (
 	// https://developer.github.com/changes/2019-04-11-pulls-branches-for-commit/
 	mediaTypeListPullsOrBranchesForCommitPreview = "application/vnd.github.groot-preview+json"
 
-	// https://developer.github.com/changes/2019-06-12-team-sync/
-	mediaTypeTeamSyncPreview = "application/vnd.github.team-sync-preview+json"
-
 	// https://developer.github.com/v3/previews/#repository-creation-permissions
 	mediaTypeMemberAllowedRepoCreationTypePreview = "application/vnd.github.surtur-preview+json"
 
 	// https://developer.github.com/v3/previews/#create-and-use-repository-templates
 	mediaTypeRepositoryTemplatePreview = "application/vnd.github.baptiste-preview+json"
+
+	// https://developer.github.com/changes/2019-10-03-multi-line-comments/
+	mediaTypeMultiLineCommentsPreview = "application/vnd.github.comfort-fade-preview+json"
+
+	// https://developer.github.com/v3/repos/#create-a-repository-dispatch-event
+	mediaTypeRepositoryDispatchPreview = "application/vnd.github.everest-preview+json"
 )
 
 // A Client manages communication with the GitHub API.
@@ -504,9 +486,12 @@ func parseRate(r *http.Response) Rate {
 // 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,
+// The provided ctx must be non-nil, if it is nil an error is returned. 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) {
+	if ctx == nil {
+		return nil, errors.New("context must be non-nil")
+	}
 	req = withContext(ctx, req)
 
 	rateLimitCategory := category(req.URL.Path)
@@ -648,7 +633,7 @@ 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 ".
+// remaining value of 0.
 type RateLimitError struct {
 	Rate     Rate           // Rate specifies last known rate limit for the client
 	Response *http.Response // HTTP response that caused this error
@@ -724,6 +709,10 @@ These are the possible validation error codes:
         some resources return this (e.g. github.User.CreateKey()), additional
         information is set in the Message field of the Error
 
+GitHub error responses structure are often undocumented and inconsistent.
+Sometimes error is just a simple string (Issue #540).
+In such cases, Message represents an error message as a workaround.
+
 GitHub API docs: https://developer.github.com/v3/#client-errors
 */
 type Error struct {
@@ -738,12 +727,19 @@ func (e *Error) Error() string {
 		e.Code, e.Field, e.Resource)
 }
 
+func (e *Error) UnmarshalJSON(data []byte) error {
+	type aliasError Error // avoid infinite recursion by using type alias.
+	if err := json.Unmarshal(data, (*aliasError)(e)); err != nil {
+		return json.Unmarshal(data, &e.Message) // data can be json string.
+	}
+	return nil
+}
+
 // 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.
+// API error responses are expected to have response
+// body, and a JSON response body that maps to ErrorResponse.
 //
 // The error type will be *RateLimitError for rate limit exceeded errors,
 // *AcceptedError for 202 Accepted status codes,
@@ -760,10 +756,14 @@ func CheckResponse(r *http.Response) error {
 	if err == nil && data != nil {
 		json.Unmarshal(data, errorResponse)
 	}
+	// Re-populate error response body because GitHub error responses are often
+	// undocumented and inconsistent.
+	// Issue #1136, #540.
+	r.Body = ioutil.NopCloser(bytes.NewBuffer(data))
 	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 "):
+	case r.StatusCode == http.StatusForbidden && r.Header.Get(headerRateRemaining) == "0":
 		return &RateLimitError{
 			Rate:     parseRate(r),
 			Response: errorResponse.Response,
diff --git a/github/issues.go b/github/issues.go
index 1e0991ce..b08934c3 100644
--- a/github/issues.go
+++ b/github/issues.go
@@ -160,7 +160,7 @@ func (s *IssuesService) listIssues(ctx context.Context, u string, opt *IssueList
 	}
 
 	// TODO: remove custom Accept headers when APIs fully launch.
-	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLockReasonPreview}
 	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	var issues []*Issue
@@ -228,7 +228,7 @@ func (s *IssuesService) ListByRepo(ctx context.Context, owner string, repo strin
 	}
 
 	// TODO: remove custom Accept headers when APIs fully launch.
-	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeIntegrationPreview}
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeIntegrationPreview}
 	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	var issues []*Issue
@@ -251,7 +251,7 @@ func (s *IssuesService) Get(ctx context.Context, owner string, repo string, numb
 	}
 
 	// TODO: remove custom Accept headers when APIs fully launch.
-	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLockReasonPreview}
 	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	issue := new(Issue)
@@ -273,9 +273,6 @@ func (s *IssuesService) Create(ctx context.Context, owner string, repo string, i
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
-
 	i := new(Issue)
 	resp, err := s.client.Do(ctx, req, i)
 	if err != nil {
@@ -295,9 +292,6 @@ func (s *IssuesService) Edit(ctx context.Context, owner string, repo string, num
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
-
 	i := new(Issue)
 	resp, err := s.client.Do(ctx, req, i)
 	if err != nil {
diff --git a/github/issues_comments.go b/github/issues_comments.go
index ab68afe2..42d6bc78 100644
--- a/github/issues_comments.go
+++ b/github/issues_comments.go
@@ -36,13 +36,13 @@ func (i IssueComment) String() string {
 // IssuesService.ListComments method.
 type IssueListCommentsOptions struct {
 	// Sort specifies how to sort comments. Possible values are: created, updated.
-	Sort string `url:"sort,omitempty"`
+	Sort *string `url:"sort,omitempty"`
 
 	// Direction in which to sort comments. Possible values are: asc, desc.
-	Direction string `url:"direction,omitempty"`
+	Direction *string `url:"direction,omitempty"`
 
 	// Since filters comments by time.
-	Since time.Time `url:"since,omitempty"`
+	Since *time.Time `url:"since,omitempty"`
 
 	ListOptions
 }
diff --git a/github/issues_labels.go b/github/issues_labels.go
index adcbe068..0771a28c 100644
--- a/github/issues_labels.go
+++ b/github/issues_labels.go
@@ -40,9 +40,6 @@ func (s *IssuesService) ListLabels(ctx context.Context, owner string, repo strin
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
-
 	var labels []*Label
 	resp, err := s.client.Do(ctx, req, &labels)
 	if err != nil {
@@ -62,9 +59,6 @@ func (s *IssuesService) GetLabel(ctx context.Context, owner string, repo string,
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
-
 	label := new(Label)
 	resp, err := s.client.Do(ctx, req, label)
 	if err != nil {
@@ -84,9 +78,6 @@ func (s *IssuesService) CreateLabel(ctx context.Context, owner string, repo stri
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
-
 	l := new(Label)
 	resp, err := s.client.Do(ctx, req, l)
 	if err != nil {
@@ -106,9 +97,6 @@ func (s *IssuesService) EditLabel(ctx context.Context, owner string, repo string
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
-
 	l := new(Label)
 	resp, err := s.client.Do(ctx, req, l)
 	if err != nil {
@@ -145,9 +133,6 @@ func (s *IssuesService) ListLabelsByIssue(ctx context.Context, owner string, rep
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
-
 	var labels []*Label
 	resp, err := s.client.Do(ctx, req, &labels)
 	if err != nil {
@@ -167,9 +152,6 @@ func (s *IssuesService) AddLabelsToIssue(ctx context.Context, owner string, repo
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
-
 	var l []*Label
 	resp, err := s.client.Do(ctx, req, &l)
 	if err != nil {
@@ -189,9 +171,6 @@ func (s *IssuesService) RemoveLabelForIssue(ctx context.Context, owner string, r
 		return nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
-
 	return s.client.Do(ctx, req, nil)
 }
 
@@ -205,9 +184,6 @@ func (s *IssuesService) ReplaceLabelsForIssue(ctx context.Context, owner string,
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
-
 	var l []*Label
 	resp, err := s.client.Do(ctx, req, &l)
 	if err != nil {
@@ -227,9 +203,6 @@ func (s *IssuesService) RemoveLabelsForIssue(ctx context.Context, owner string,
 		return nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
-
 	return s.client.Do(ctx, req, nil)
 }
 
@@ -248,9 +221,6 @@ func (s *IssuesService) ListLabelsForMilestone(ctx context.Context, owner string
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
-
 	var labels []*Label
 	resp, err := s.client.Do(ctx, req, &labels)
 	if err != nil {
diff --git a/github/messages.go b/github/messages.go
index ac7c17f3..759f9e81 100644
--- a/github/messages.go
+++ b/github/messages.go
@@ -74,12 +74,14 @@ var (
 		"pull_request":                   "PullRequestEvent",
 		"push":                           "PushEvent",
 		"repository":                     "RepositoryEvent",
+		"repository_dispatch":            "RepositoryDispatchEvent",
 		"repository_vulnerability_alert": "RepositoryVulnerabilityAlertEvent",
 		"release":                        "ReleaseEvent",
 		"star":                           "StarEvent",
 		"status":                         "StatusEvent",
 		"team":                           "TeamEvent",
 		"team_add":                       "TeamAddEvent",
+		"user":                           "UserEvent",
 		"watch":                          "WatchEvent",
 	}
 )
diff --git a/github/orgs.go b/github/orgs.go
index 5012c6c9..bae67dad 100644
--- a/github/orgs.go
+++ b/github/orgs.go
@@ -56,8 +56,17 @@ type Organization struct {
 	// MembersCanCreateRepos default value is true and is only used in Organizations.Edit.
 	MembersCanCreateRepos *bool `json:"members_can_create_repositories,omitempty"`
 
+	// https://developer.github.com/changes/2019-12-03-internal-visibility-changes/#rest-v3-api
+	MembersCanCreatePublicRepos   *bool `json:"members_can_create_public_repositories,omitempty"`
+	MembersCanCreatePrivateRepos  *bool `json:"members_can_create_private_repositories,omitempty"`
+	MembersCanCreateInternalRepos *bool `json:"members_can_create_internal_repositories,omitempty"`
+
 	// MembersAllowedRepositoryCreationType denotes if organization members can create repositories
 	// and the type of repositories they can create. Possible values are: "all", "private", or "none".
+	//
+	// Deprecated: Use MembersCanCreatePublicRepos, MembersCanCreatePrivateRepos, MembersCanCreateInternalRepos
+	// instead. The new fields overrides the existing MembersAllowedRepositoryCreationType during 'edit'
+	// operation and does not consider 'internal' repositories during 'get' operation
 	MembersAllowedRepositoryCreationType *string `json:"members_allowed_repository_creation_type,omitempty"`
 
 	// API URLs
@@ -213,6 +222,9 @@ func (s *OrganizationsService) Edit(ctx context.Context, name string, org *Organ
 		return nil, nil, err
 	}
 
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeMemberAllowedRepoCreationTypePreview)
+
 	o := new(Organization)
 	resp, err := s.client.Do(ctx, req, o)
 	if err != nil {
diff --git a/github/orgs_members.go b/github/orgs_members.go
index d1843599..a2fc9265 100644
--- a/github/orgs_members.go
+++ b/github/orgs_members.go
@@ -331,9 +331,6 @@ func (s *OrganizationsService) CreateOrgInvitation(ctx context.Context, org stri
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeOrganizationInvitationPreview)
-
 	var invitation *Invitation
 	resp, err := s.client.Do(ctx, req, &invitation)
 	if err != nil {
@@ -358,9 +355,6 @@ func (s *OrganizationsService) ListOrgInvitationTeams(ctx context.Context, org,
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeOrganizationInvitationPreview)
-
 	var orgInvitationTeams []*Team
 	resp, err := s.client.Do(ctx, req, &orgInvitationTeams)
 	if err != nil {
diff --git a/github/pulls.go b/github/pulls.go
index 83ca9e55..867455ae 100644
--- a/github/pulls.go
+++ b/github/pulls.go
@@ -149,7 +149,7 @@ func (s *PullRequestsService) List(ctx context.Context, owner string, repo strin
 	}
 
 	// TODO: remove custom Accept header when this API fully launches.
-	acceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview, mediaTypeDraftPreview}
+	acceptHeaders := []string{mediaTypeLockReasonPreview, mediaTypeDraftPreview}
 	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	var pulls []*PullRequest
@@ -179,7 +179,7 @@ func (s *PullRequestsService) ListPullRequestsWithCommit(ctx context.Context, ow
 	}
 
 	// TODO: remove custom Accept header when this API fully launches.
-	acceptHeaders := []string{mediaTypeListPullsOrBranchesForCommitPreview, mediaTypeDraftPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
+	acceptHeaders := []string{mediaTypeListPullsOrBranchesForCommitPreview, mediaTypeDraftPreview, mediaTypeLockReasonPreview}
 	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 	var pulls []*PullRequest
 	resp, err := s.client.Do(ctx, req, &pulls)
@@ -201,7 +201,7 @@ func (s *PullRequestsService) Get(ctx context.Context, owner string, repo string
 	}
 
 	// TODO: remove custom Accept header when this API fully launches.
-	acceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview, mediaTypeDraftPreview}
+	acceptHeaders := []string{mediaTypeLockReasonPreview, mediaTypeDraftPreview}
 	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	pull := new(PullRequest)
@@ -261,7 +261,7 @@ func (s *PullRequestsService) Create(ctx context.Context, owner string, repo str
 	}
 
 	// TODO: remove custom Accept header when this API fully launches.
-	acceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeDraftPreview}
+	acceptHeaders := []string{mediaTypeDraftPreview}
 	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	p := new(PullRequest)
@@ -357,7 +357,7 @@ func (s *PullRequestsService) Edit(ctx context.Context, owner string, repo strin
 	}
 
 	// TODO: remove custom Accept header when this API fully launches.
-	acceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
+	acceptHeaders := []string{mediaTypeLockReasonPreview}
 	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	p := new(PullRequest)
diff --git a/github/pulls_comments.go b/github/pulls_comments.go
index 8886c9d1..3372e338 100644
--- a/github/pulls_comments.go
+++ b/github/pulls_comments.go
@@ -8,6 +8,7 @@ package github
 import (
 	"context"
 	"fmt"
+	"strings"
 	"time"
 )
 
@@ -22,6 +23,12 @@ type PullRequestComment struct {
 	PullRequestReviewID *int64     `json:"pull_request_review_id,omitempty"`
 	Position            *int       `json:"position,omitempty"`
 	OriginalPosition    *int       `json:"original_position,omitempty"`
+	StartLine           *int       `json:"start_line,omitempty"`
+	Line                *int       `json:"line,omitempty"`
+	OriginalLine        *int       `json:"original_line,omitempty"`
+	OriginalStartLine   *int       `json:"original_start_line,omitempty"`
+	Side                *string    `json:"side,omitempty"`
+	StartSide           *string    `json:"start_side,omitempty"`
 	CommitID            *string    `json:"commit_id,omitempty"`
 	OriginalCommitID    *string    `json:"original_commit_id,omitempty"`
 	User                *User      `json:"user,omitempty"`
@@ -78,7 +85,8 @@ func (s *PullRequestsService) ListComments(ctx context.Context, owner string, re
 	}
 
 	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeReactionsPreview)
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeMultiLineCommentsPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	var comments []*PullRequestComment
 	resp, err := s.client.Do(ctx, req, &comments)
@@ -100,7 +108,8 @@ func (s *PullRequestsService) GetComment(ctx context.Context, owner string, repo
 	}
 
 	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeReactionsPreview)
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeMultiLineCommentsPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	comment := new(PullRequestComment)
 	resp, err := s.client.Do(ctx, req, comment)
@@ -120,6 +129,9 @@ func (s *PullRequestsService) CreateComment(ctx context.Context, owner string, r
 	if err != nil {
 		return nil, nil, err
 	}
+	// TODO: remove custom Accept headers when their respective API fully launches.
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeMultiLineCommentsPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	c := new(PullRequestComment)
 	resp, err := s.client.Do(ctx, req, c)
diff --git a/github/reactions.go b/github/reactions.go
index 0865f8cd..1935ce11 100644
--- a/github/reactions.go
+++ b/github/reactions.go
@@ -44,10 +44,21 @@ func (r Reaction) String() string {
 	return Stringify(r)
 }
 
+// ListCommentReactionOptions specifies the optional parameters to the
+// ReactionsService.ListCommentReactions method.
+type ListCommentReactionOptions struct {
+	// Content restricts the returned comment reactions to only those with the given type.
+	// Omit this parameter to list all reactions to a commit comment.
+	// Possible values are: "+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", or "eyes".
+	Content string `url:"content,omitempty"`
+
+	ListOptions
+}
+
 // 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) {
+func (s *ReactionsService) ListCommentReactions(ctx context.Context, owner, repo string, id int64, opt *ListCommentReactionOptions) ([]*Reaction, *Response, error) {
 	u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions", owner, repo, id)
 	u, err := addOptions(u, opt)
 	if err != nil {
diff --git a/github/repos.go b/github/repos.go
index 37a09d5b..c695d8c0 100644
--- a/github/repos.go
+++ b/github/repos.go
@@ -7,6 +7,7 @@ package github
 
 import (
 	"context"
+	"encoding/json"
 	"fmt"
 	"strings"
 )
@@ -519,6 +520,26 @@ type ListContributorsOptions struct {
 	ListOptions
 }
 
+// GetVulnerabilityAlerts checks if vulnerability alerts are enabled for a repository.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#check-if-vulnerability-alerts-are-enabled-for-a-repository
+func (s *RepositoriesService) GetVulnerabilityAlerts(ctx context.Context, owner, repository string) (bool, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/vulnerability-alerts", owner, repository)
+
+	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", mediaTypeRequiredVulnerabilityAlertsPreview)
+
+	resp, err := s.client.Do(ctx, req, nil)
+	vulnerabilityAlertsEnabled, err := parseBoolResponse(err)
+
+	return vulnerabilityAlertsEnabled, resp, err
+}
+
 // EnableVulnerabilityAlerts enables vulnerability alerts and the dependency graph for a repository.
 //
 // GitHub API docs: https://developer.github.com/v3/repos/#enable-vulnerability-alerts
@@ -652,8 +673,6 @@ func (s *RepositoriesService) ListTeams(ctx context.Context, owner string, repo
 		return nil, nil, err
 	}
 
-	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
-
 	var teams []*Team
 	resp, err := s.client.Do(ctx, req, &teams)
 	if err != nil {
@@ -736,7 +755,7 @@ type RequiredStatusChecksRequest struct {
 // 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"`
+	DismissalRestrictions *DismissalRestrictions `json:"dismissal_restrictions,omitempty"`
 	// 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.
@@ -791,6 +810,8 @@ type BranchRestrictions struct {
 	Users []*User `json:"users"`
 	// The list of team slugs with push access.
 	Teams []*Team `json:"teams"`
+	// The list of app slugs with push access.
+	Apps []*App `json:"apps"`
 }
 
 // BranchRestrictionsRequest represents the request to create/edit the
@@ -802,6 +823,8 @@ type BranchRestrictionsRequest struct {
 	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"`
+	// The list of app slugs with push access.
+	Apps []string `json:"apps,omitempty"`
 }
 
 // DismissalRestrictions specifies which users and teams can dismiss pull request reviews.
@@ -1134,9 +1157,9 @@ func (s *RepositoriesService) UpdatePullRequestReviewEnforcement(ctx context.Con
 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{}{}}
+	data := new(struct {
+		DismissalRestrictionsRequest `json:"dismissal_restrictions"`
+	})
 
 	req, err := s.client.NewRequest("PATCH", u, data)
 	if err != nil {
@@ -1287,6 +1310,93 @@ func (s *RepositoriesService) ReplaceAllTopics(ctx context.Context, owner, repo
 	return t.Names, resp, nil
 }
 
+// ListApps lists the Github apps that have push access to a given protected branch.
+// It requires the Github apps to have `write` access to the `content` permission.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#list-apps-with-access-to-protected-branch
+func (s *RepositoriesService) ListApps(ctx context.Context, owner, repo, branch string) ([]*App, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var apps []*App
+	resp, err := s.client.Do(ctx, req, &apps)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return apps, resp, nil
+}
+
+// ReplaceAppRestrictions replaces the apps that have push access to a given protected branch.
+// It removes all apps that previously had push access and grants push access to the new list of apps.
+// It requires the Github apps to have `write` access to the `content` permission.
+//
+// Note: The list of users, apps, and teams in total is limited to 100 items.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#replace-app-restrictions-of-protected-branch
+func (s *RepositoriesService) ReplaceAppRestrictions(ctx context.Context, owner, repo, branch string, slug []string) ([]*App, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch)
+	req, err := s.client.NewRequest("PUT", u, slug)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var apps []*App
+	resp, err := s.client.Do(ctx, req, &apps)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	return apps, resp, nil
+}
+
+// AddAppRestrictions grants the specified apps push access to a given protected branch.
+// It requires the Github apps to have `write` access to the `content` permission.
+//
+// Note: The list of users, apps, and teams in total is limited to 100 items.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#add-app-restrictions-of-protected-branch
+func (s *RepositoriesService) AddAppRestrictions(ctx context.Context, owner, repo, branch string, slug []string) ([]*App, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch)
+	req, err := s.client.NewRequest("POST", u, slug)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var apps []*App
+	resp, err := s.client.Do(ctx, req, &apps)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	return apps, resp, nil
+}
+
+// RemoveAppRestrictions removes the ability of an app to push to this branch.
+// It requires the Github apps to have `write` access to the `content` permission.
+//
+// Note: The list of users, apps, and teams in total is limited to 100 items.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/branches/#remove-app-restrictions-of-protected-branch
+func (s *RepositoriesService) RemoveAppRestrictions(ctx context.Context, owner, repo, branch string, slug []string) ([]*App, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch)
+	req, err := s.client.NewRequest("DELETE", u, slug)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var apps []*App
+	resp, err := s.client.Do(ctx, req, &apps)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	return apps, resp, nil
+}
+
 // TransferRequest represents a request to transfer a repository.
 type TransferRequest struct {
 	NewOwner string  `json:"new_owner"`
@@ -1310,8 +1420,37 @@ func (s *RepositoriesService) Transfer(ctx context.Context, owner, repo string,
 		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
+}
+
+// DispatchRequestOptions represents a request to trigger a repository_dispatch event.
+type DispatchRequestOptions struct {
+	// EventType is a custom webhook event name. (Required.)
+	EventType string `json:"event_type"`
+	// ClientPayload is a custom JSON payload with extra information about the webhook event.
+	// Defaults to an empty JSON object.
+	ClientPayload *json.RawMessage `json:"client_payload,omitempty"`
+}
+
+// Dispatch triggers a repository_dispatch event in a GitHub Actions workflow.
+//
+// GitHub API docs: https://developer.github.com/v3/repos/#create-a-repository-dispatch-event
+func (s *RepositoriesService) Dispatch(ctx context.Context, owner, repo string, opts DispatchRequestOptions) (*Repository, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/dispatches", owner, repo)
+
+	req, err := s.client.NewRequest("POST", u, &opts)
+	if err != nil {
+		return nil, nil, err
+	}
+
 	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeRepositoryTransferPreview)
+	req.Header.Set("Accept", mediaTypeRepositoryDispatchPreview)
 
 	r := new(Repository)
 	resp, err := s.client.Do(ctx, req, r)
diff --git a/github/repos_collaborators.go b/github/repos_collaborators.go
index 757e9f39..8254ac06 100644
--- a/github/repos_collaborators.go
+++ b/github/repos_collaborators.go
@@ -26,6 +26,19 @@ type ListCollaboratorsOptions struct {
 	ListOptions
 }
 
+// CollaboratorInvitation represents an invitation created when adding a collaborator.
+// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#response-when-a-new-invitation-is-created
+type CollaboratorInvitation struct {
+	ID          *int64      `json:"id,omitempty"`
+	Repo        *Repository `json:"repository,omitempty"`
+	Invitee     *User       `json:"invitee,omitempty"`
+	Inviter     *User       `json:"inviter,omitempty"`
+	Permissions *string     `json:"permissions,omitempty"`
+	CreatedAt   *Timestamp  `json:"created_at,omitempty"`
+	URL         *string     `json:"url,omitempty"`
+	HTMLURL     *string     `json:"html_url,omitempty"`
+}
+
 // ListCollaborators lists the GitHub users that have access to the repository.
 //
 // GitHub API docs: https://developer.github.com/v3/repos/collaborators/#list-collaborators
@@ -41,8 +54,6 @@ func (s *RepositoriesService) ListCollaborators(ctx context.Context, owner, repo
 		return nil, nil, err
 	}
 
-	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
-
 	var users []*User
 	resp, err := s.client.Do(ctx, req, &users)
 	if err != nil {
@@ -113,14 +124,18 @@ type RepositoryAddCollaboratorOptions struct {
 // 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) {
+func (s *RepositoriesService) AddCollaborator(ctx context.Context, owner, repo, user string, opt *RepositoryAddCollaboratorOptions) (*CollaboratorInvitation, *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
+		return nil, nil, err
 	}
-
-	return s.client.Do(ctx, req, nil)
+	acr := new(CollaboratorInvitation)
+	resp, err := s.client.Do(ctx, req, acr)
+	if err != nil {
+		return nil, resp, err
+	}
+	return acr, resp, nil
 }
 
 // RemoveCollaborator removes the specified GitHub user as collaborator from the given repo.
diff --git a/github/repos_contents.go b/github/repos_contents.go
index bf6cabc5..eed0420a 100644
--- a/github/repos_contents.go
+++ b/github/repos_contents.go
@@ -240,15 +240,28 @@ const (
 // 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) {
+func (s *RepositoriesService) GetArchiveLink(ctx context.Context, owner, repo string, archiveformat archiveFormat, opt *RepositoryContentGetOptions, followRedirects bool) (*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)
+	resp, err := s.getArchiveLinkFromURL(ctx, u, followRedirects)
 	if err != nil {
 		return nil, nil, err
 	}
+	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
+}
+
+func (s *RepositoriesService) getArchiveLinkFromURL(ctx context.Context, u string, followRedirects bool) (*http.Response, error) {
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
 	var resp *http.Response
 	// Use http.DefaultTransport if no custom Transport is configured
 	req = withContext(ctx, req)
@@ -258,12 +271,14 @@ func (s *RepositoriesService) GetArchiveLink(ctx context.Context, owner, repo st
 		resp, err = s.client.client.Transport.RoundTrip(req)
 	}
 	if err != nil {
-		return nil, nil, err
+		return nil, err
 	}
 	resp.Body.Close()
-	if resp.StatusCode != http.StatusFound {
-		return nil, newResponse(resp), fmt.Errorf("unexpected status code: %s", resp.Status)
+
+	// If redirect response is returned, follow it
+	if followRedirects && resp.StatusCode == http.StatusMovedPermanently {
+		u = resp.Header.Get("Location")
+		resp, err = s.getArchiveLinkFromURL(ctx, u, false)
 	}
-	parsedURL, err := url.Parse(resp.Header.Get("Location"))
-	return parsedURL, newResponse(resp), err
+	return resp, err
 }
diff --git a/github/repos_deployments.go b/github/repos_deployments.go
index 604632e9..6453345e 100644
--- a/github/repos_deployments.go
+++ b/github/repos_deployments.go
@@ -32,15 +32,15 @@ type Deployment struct {
 
 // 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"`
+	Ref                   *string     `json:"ref,omitempty"`
+	Task                  *string     `json:"task,omitempty"`
+	AutoMerge             *bool       `json:"auto_merge,omitempty"`
+	RequiredContexts      *[]string   `json:"required_contexts,omitempty"`
+	Payload               interface{} `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
diff --git a/github/repos_pages.go b/github/repos_pages.go
index 28674130..7eb32a9d 100644
--- a/github/repos_pages.go
+++ b/github/repos_pages.go
@@ -8,7 +8,6 @@ package github
 import (
 	"context"
 	"fmt"
-	"strings"
 )
 
 // Pages represents a GitHub Pages site configuration.
@@ -54,9 +53,7 @@ func (s *RepositoriesService) EnablePages(ctx context.Context, owner, repo strin
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	acceptHeaders := []string{mediaTypeEnablePagesAPIPreview, mediaTypePagesPreview}
-	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+	req.Header.Set("Accept", mediaTypeEnablePagesAPIPreview)
 
 	enable := new(Pages)
 	resp, err := s.client.Do(ctx, req, enable)
@@ -93,9 +90,6 @@ func (s *RepositoriesService) GetPagesInfo(ctx context.Context, owner, repo stri
 		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 {
@@ -177,9 +171,6 @@ func (s *RepositoriesService) RequestPageBuild(ctx context.Context, owner, repo
 		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 {
diff --git a/github/search.go b/github/search.go
index 13cc4c84..d294a4f0 100644
--- a/github/search.go
+++ b/github/search.go
@@ -76,6 +76,37 @@ func (s *SearchService) Repositories(ctx context.Context, query string, opt *Sea
 	return result, resp, err
 }
 
+// TopicsSearchResult represents the result of a topics search.
+type TopicsSearchResult struct {
+	Total             *int           `json:"total_count,omitempty"`
+	IncompleteResults *bool          `json:"incomplete_results,omitempty"`
+	Topics            []*TopicResult `json:"items,omitempty"`
+}
+
+type TopicResult struct {
+	Name             *string    `json:"name,omitempty"`
+	DisplayName      *string    `json:"display_name,omitempty"`
+	ShortDescription *string    `json:"short_description,omitempty"`
+	Description      *string    `json:"description,omitempty"`
+	CreatedBy        *string    `json:"created_by,omitempty"`
+	CreatedAt        *Timestamp `json:"created_at,omitempty"`
+	UpdatedAt        *string    `json:"updated_at,omitempty"`
+	Featured         *bool      `json:"featured,omitempty"`
+	Curated          *bool      `json:"curated,omitempty"`
+	Score            *float64   `json:"score,omitempty"`
+}
+
+// Topics finds topics via various criteria. Results are sorted by best match.
+// Please see https://help.github.com/en/articles/searching-topics for more
+// information about search qualifiers.
+//
+// GitHub API docs: https://developer.github.com/v3/search/#search-topics
+func (s *SearchService) Topics(ctx context.Context, query string, opt *SearchOptions) (*TopicsSearchResult, *Response, error) {
+	result := new(TopicsSearchResult)
+	resp, err := s.search(ctx, "topics", &searchParameters{Query: query}, opt, result)
+	return result, resp, err
+}
+
 // CommitsSearchResult represents the result of a commits search.
 type CommitsSearchResult struct {
 	Total             *int            `json:"total_count,omitempty"`
@@ -245,14 +276,14 @@ func (s *SearchService) search(ctx context.Context, searchType string, parameter
 		// 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":
+	case searchType == "topics":
 		// 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 searchType == "labels":
-		// Accept header for search labels based on label description preview endpoint.
+	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", mediaTypeLabelDescriptionSearchPreview)
+		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
diff --git a/github/teams.go b/github/teams.go
index b4953e63..2f7c6cb7 100644
--- a/github/teams.go
+++ b/github/teams.go
@@ -8,6 +8,7 @@ package github
 import (
 	"context"
 	"fmt"
+	"net/http"
 	"strings"
 	"time"
 )
@@ -87,9 +88,6 @@ func (s *TeamsService) ListTeams(ctx context.Context, org string, opt *ListOptio
 		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 {
@@ -109,9 +107,6 @@ func (s *TeamsService) GetTeam(ctx context.Context, team int64) (*Team, *Respons
 		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 {
@@ -181,9 +176,6 @@ func (s *TeamsService) CreateTeam(ctx context.Context, org string, team NewTeam)
 		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 {
@@ -193,19 +185,51 @@ func (s *TeamsService) CreateTeam(ctx context.Context, org string, team NewTeam)
 	return t, resp, nil
 }
 
+// newTeamNoParent is the same as NewTeam but ensures that the
+// "parent_team_id" field will be null. It is for internal use
+// only and should not be exported.
+type newTeamNoParent struct {
+	Name         string   `json:"name"`
+	Description  *string  `json:"description,omitempty"`
+	Maintainers  []string `json:"maintainers,omitempty"`
+	RepoNames    []string `json:"repo_names,omitempty"`
+	ParentTeamID *int64   `json:"parent_team_id"` // This will be "null"
+	Privacy      *string  `json:"privacy,omitempty"`
+	LDAPDN       *string  `json:"ldap_dn,omitempty"`
+}
+
+// copyNewTeamWithoutParent is used to set the "parent_team_id"
+// field to "null" after copying the other fields from a NewTeam.
+// It is for internal use only and should not be exported.
+func copyNewTeamWithoutParent(team *NewTeam) *newTeamNoParent {
+	return &newTeamNoParent{
+		Name:        team.Name,
+		Description: team.Description,
+		Maintainers: team.Maintainers,
+		RepoNames:   team.RepoNames,
+		Privacy:     team.Privacy,
+		LDAPDN:      team.LDAPDN,
+	}
+}
+
 // EditTeam edits a team.
 //
 // GitHub API docs: https://developer.github.com/v3/teams/#edit-team
-func (s *TeamsService) EditTeam(ctx context.Context, id int64, team NewTeam) (*Team, *Response, error) {
+func (s *TeamsService) EditTeam(ctx context.Context, id int64, team NewTeam, removeParent bool) (*Team, *Response, error) {
 	u := fmt.Sprintf("teams/%v", id)
-	req, err := s.client.NewRequest("PATCH", u, team)
+
+	var req *http.Request
+	var err error
+	if removeParent {
+		teamRemoveParent := copyNewTeamWithoutParent(&team)
+		req, err = s.client.NewRequest("PATCH", u, teamRemoveParent)
+	} else {
+		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 {
@@ -225,8 +249,6 @@ func (s *TeamsService) DeleteTeam(ctx context.Context, team int64) (*Response, e
 		return nil, err
 	}
 
-	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
-
 	return s.client.Do(ctx, req, nil)
 }
 
@@ -245,8 +267,6 @@ func (s *TeamsService) ListChildTeams(ctx context.Context, teamID int64, opt *Li
 		return nil, nil, err
 	}
 
-	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
-
 	var teams []*Team
 	resp, err := s.client.Do(ctx, req, &teams)
 	if err != nil {
@@ -272,7 +292,7 @@ func (s *TeamsService) ListTeamRepos(ctx context.Context, team int64, opt *ListO
 	}
 
 	// TODO: remove custom Accept header when topics API fully launches.
-	headers := []string{mediaTypeTopicsPreview, mediaTypeNestedTeamsPreview}
+	headers := []string{mediaTypeTopicsPreview}
 	req.Header.Set("Accept", strings.Join(headers, ", "))
 
 	var repos []*Repository
@@ -296,7 +316,7 @@ func (s *TeamsService) IsTeamRepo(ctx context.Context, team int64, owner string,
 		return nil, nil, err
 	}
 
-	headers := []string{mediaTypeOrgPermissionRepo, mediaTypeNestedTeamsPreview}
+	headers := []string{mediaTypeOrgPermissionRepo}
 	req.Header.Set("Accept", strings.Join(headers, ", "))
 
 	repository := new(Repository)
@@ -365,9 +385,6 @@ func (s *TeamsService) ListUserTeams(ctx context.Context, opt *ListOptions) ([]*
 		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 {
@@ -389,7 +406,7 @@ func (s *TeamsService) ListTeamProjects(ctx context.Context, teamID int64) ([]*P
 	}
 
 	// TODO: remove custom Accept header when this API fully launches.
-	acceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview}
+	acceptHeaders := []string{mediaTypeProjectsPreview}
 	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	var projects []*Project
@@ -413,7 +430,7 @@ func (s *TeamsService) ReviewTeamProjects(ctx context.Context, teamID, projectID
 	}
 
 	// TODO: remove custom Accept header when this API fully launches.
-	acceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview}
+	acceptHeaders := []string{mediaTypeProjectsPreview}
 	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	projects := &Project{}
@@ -450,7 +467,7 @@ func (s *TeamsService) AddTeamProject(ctx context.Context, teamID, projectID int
 	}
 
 	// TODO: remove custom Accept header when this API fully launches.
-	acceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview}
+	acceptHeaders := []string{mediaTypeProjectsPreview}
 	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	return s.client.Do(ctx, req, nil)
@@ -471,7 +488,7 @@ func (s *TeamsService) RemoveTeamProject(ctx context.Context, teamID int64, proj
 	}
 
 	// TODO: remove custom Accept header when this API fully launches.
-	acceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview}
+	acceptHeaders := []string{mediaTypeProjectsPreview}
 	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	return s.client.Do(ctx, req, nil)
@@ -504,9 +521,6 @@ func (s *TeamsService) ListIDPGroupsInOrganization(ctx context.Context, org stri
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeTeamSyncPreview)
-
 	groups := new(IDPGroupList)
 	resp, err := s.client.Do(ctx, req, groups)
 	if err != nil {
@@ -526,9 +540,6 @@ func (s *TeamsService) ListIDPGroupsForTeam(ctx context.Context, teamID string)
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeTeamSyncPreview)
-
 	groups := new(IDPGroupList)
 	resp, err := s.client.Do(ctx, req, groups)
 	if err != nil {
@@ -549,9 +560,6 @@ func (s *TeamsService) CreateOrUpdateIDPGroupConnections(ctx context.Context, te
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeTeamSyncPreview)
-
 	groups := new(IDPGroupList)
 	resp, err := s.client.Do(ctx, req, groups)
 	if err != nil {
diff --git a/github/teams_discussion_comments.go b/github/teams_discussion_comments.go
index a0206b9c..ff871f22 100644
--- a/github/teams_discussion_comments.go
+++ b/github/teams_discussion_comments.go
@@ -55,9 +55,6 @@ func (s *TeamsService) ListComments(ctx context.Context, teamID int64, discussio
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview)
-
 	var comments []*DiscussionComment
 	resp, err := s.client.Do(ctx, req, &comments)
 	if err != nil {
@@ -78,9 +75,6 @@ func (s *TeamsService) GetComment(ctx context.Context, teamID int64, discussionN
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview)
-
 	discussionComment := &DiscussionComment{}
 	resp, err := s.client.Do(ctx, req, discussionComment)
 	if err != nil {
@@ -101,9 +95,6 @@ func (s *TeamsService) CreateComment(ctx context.Context, teamID int64, discsusi
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview)
-
 	discussionComment := &DiscussionComment{}
 	resp, err := s.client.Do(ctx, req, discussionComment)
 	if err != nil {
@@ -125,9 +116,6 @@ func (s *TeamsService) EditComment(ctx context.Context, teamID int64, discussion
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview)
-
 	discussionComment := &DiscussionComment{}
 	resp, err := s.client.Do(ctx, req, discussionComment)
 	if err != nil {
@@ -148,8 +136,5 @@ func (s *TeamsService) DeleteComment(ctx context.Context, teamID int64, discussi
 		return nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview)
-
 	return s.client.Do(ctx, req, nil)
 }
diff --git a/github/teams_discussions.go b/github/teams_discussions.go
index f491c9d1..433d0159 100644
--- a/github/teams_discussions.go
+++ b/github/teams_discussions.go
@@ -60,9 +60,6 @@ func (s *TeamsService) ListDiscussions(ctx context.Context, teamID int64, option
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview)
-
 	var teamDiscussions []*TeamDiscussion
 	resp, err := s.client.Do(ctx, req, &teamDiscussions)
 	if err != nil {
@@ -83,9 +80,6 @@ func (s *TeamsService) GetDiscussion(ctx context.Context, teamID int64, discussi
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview)
-
 	teamDiscussion := &TeamDiscussion{}
 	resp, err := s.client.Do(ctx, req, teamDiscussion)
 	if err != nil {
@@ -106,9 +100,6 @@ func (s *TeamsService) CreateDiscussion(ctx context.Context, teamID int64, discu
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview)
-
 	teamDiscussion := &TeamDiscussion{}
 	resp, err := s.client.Do(ctx, req, teamDiscussion)
 	if err != nil {
@@ -130,9 +121,6 @@ func (s *TeamsService) EditDiscussion(ctx context.Context, teamID int64, discuss
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview)
-
 	teamDiscussion := &TeamDiscussion{}
 	resp, err := s.client.Do(ctx, req, teamDiscussion)
 	if err != nil {
@@ -153,8 +141,5 @@ func (s *TeamsService) DeleteDiscussion(ctx context.Context, teamID int64, discu
 		return nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview)
-
 	return s.client.Do(ctx, req, nil)
 }
diff --git a/github/teams_members.go b/github/teams_members.go
index d5cfa0dc..2a211fe9 100644
--- a/github/teams_members.go
+++ b/github/teams_members.go
@@ -36,8 +36,6 @@ func (s *TeamsService) ListTeamMembers(ctx context.Context, team int64, opt *Tea
 		return nil, nil, err
 	}
 
-	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
-
 	var members []*User
 	resp, err := s.client.Do(ctx, req, &members)
 	if err != nil {
@@ -75,8 +73,6 @@ func (s *TeamsService) GetTeamMembership(ctx context.Context, team int64, user s
 		return nil, nil, err
 	}
 
-	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)
-
 	t := new(Membership)
 	resp, err := s.client.Do(ctx, req, t)
 	if err != nil {
diff --git a/github/users.go b/github/users.go
index 2592aea0..88a15bdb 100644
--- a/github/users.go
+++ b/github/users.go
@@ -176,9 +176,6 @@ func (s *UsersService) GetHovercard(ctx context.Context, user string, opt *Hover
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeHovercardPreview)
-
 	hc := new(Hovercard)
 	resp, err := s.client.Do(ctx, req, hc)
 	if err != nil {
diff --git a/github/users_projects.go b/github/users_projects.go
new file mode 100644
index 00000000..bd2ca75e
--- /dev/null
+++ b/github/users_projects.go
@@ -0,0 +1,68 @@
+// Copyright 2019 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 the specified user.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/#list-user-projects
+func (s *UsersService) ListProjects(ctx context.Context, user string, opt *ProjectListOptions) ([]*Project, *Response, error) {
+	u := fmt.Sprintf("users/%v/projects", 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
+	}
+
+	// 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
+}
+
+// CreateUserProjectOptions specifies the parameters to the UsersService.CreateProject method.
+type CreateUserProjectOptions struct {
+	// The name of the project. (Required.)
+	Name string `json:"name"`
+	// The description of the project. (Optional.)
+	Body *string `json:"body,omitempty"`
+}
+
+// CreateProject creates a GitHub Project for the current user.
+//
+// GitHub API docs: https://developer.github.com/v3/projects/#create-a-user-project
+func (s *UsersService) CreateProject(ctx context.Context, opt *CreateUserProjectOptions) (*Project, *Response, error) {
+	u := "users/projects"
+	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
+}
diff --git a/go.mod b/go.mod
index 23ce41ca..bb82bb43 100644
--- a/go.mod
+++ b/go.mod
@@ -1,4 +1,4 @@
-module github.com/google/go-github/v28
+module github.com/google/go-github/v29
 
 require (
 	github.com/golang/protobuf v1.3.2 // indirect


Test patch:
diff --git a/github/admin_users_test.go b/github/admin_users_test.go
index ad5379e2..2c3b6d7a 100644
--- a/github/admin_users_test.go
+++ b/github/admin_users_test.go
@@ -12,6 +12,7 @@ import (
 	"net/http"
 	"reflect"
 	"testing"
+	"time"
 )
 
 func TestAdminUsers_Create(t *testing.T) {
@@ -55,3 +56,74 @@ func TestAdminUsers_Delete(t *testing.T) {
 		t.Errorf("Admin.DeleteUser returned error: %v", err)
 	}
 }
+
+func TestUserImpersonation_Create(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/admin/users/github/authorizations", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "POST")
+		testBody(t, r, `{"scopes":["repo"]}`+"\n")
+		fmt.Fprint(w, `{"id": 1234,
+		"url": "https://git.company.com/api/v3/authorizations/1234",
+		"app": {
+		  "name": "GitHub Site Administrator",
+		  "url": "https://developer.github.com/v3/enterprise/users/",
+		  "client_id": "1234"
+		},
+		"token": "1234",
+		"hashed_token": "1234",
+		"token_last_eight": "1234",
+		"note": null,
+		"note_url": null,
+		"created_at": "2018-01-01T00:00:00Z",
+		"updated_at": "2018-01-01T00:00:00Z",
+		"scopes": [
+		  "repo"
+		],
+		"fingerprint": null}`)
+	})
+
+	opt := &ImpersonateUserOptions{Scopes: []string{"repo"}}
+	auth, _, err := client.Admin.CreateUserImpersonation(context.Background(), "github", opt)
+	if err != nil {
+		t.Errorf("Admin.CreateUserImpersonation returned error: %v", err)
+	}
+
+	date := Timestamp{Time: time.Date(2018, time.January, 1, 0, 0, 0, 0, time.UTC)}
+	want := &UserAuthorization{
+		ID:  Int64(1234),
+		URL: String("https://git.company.com/api/v3/authorizations/1234"),
+		App: &OAuthAPP{
+			Name:     String("GitHub Site Administrator"),
+			URL:      String("https://developer.github.com/v3/enterprise/users/"),
+			ClientID: String("1234"),
+		},
+		Token:          String("1234"),
+		HashedToken:    String("1234"),
+		TokenLastEight: String("1234"),
+		Note:           nil,
+		NoteURL:        nil,
+		CreatedAt:      &date,
+		UpdatedAt:      &date,
+		Scopes:         []string{"repo"},
+		Fingerprint:    nil,
+	}
+	if !reflect.DeepEqual(auth, want) {
+		t.Errorf("Admin.CreateUserImpersonation returned %+v, want %+v", auth, want)
+	}
+}
+
+func TestUserImpersonation_Delete(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/admin/users/github/authorizations", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "DELETE")
+	})
+
+	_, err := client.Admin.DeleteUserImpersonation(context.Background(), "github")
+	if err != nil {
+		t.Errorf("Admin.DeleteUserImpersonation returned error: %v", err)
+	}
+}
diff --git a/github/checks_test.go b/github/checks_test.go
index 848c7e7d..e510e32f 100644
--- a/github/checks_test.go
+++ b/github/checks_test.go
@@ -102,11 +102,10 @@ func TestChecksService_CreateCheckRun(t *testing.T) {
 	})
 	startedAt, _ := time.Parse(time.RFC3339, "2018-05-04T01:14:52Z")
 	checkRunOpt := CreateCheckRunOptions{
-		HeadBranch: "master",
-		Name:       "testCreateCheckRun",
-		HeadSHA:    "deadbeef",
-		Status:     String("in_progress"),
-		StartedAt:  &Timestamp{startedAt},
+		Name:      "testCreateCheckRun",
+		HeadSHA:   "deadbeef",
+		Status:    String("in_progress"),
+		StartedAt: &Timestamp{startedAt},
 		Output: &CheckRunOutput{
 			Title:   String("Mighty test report"),
 			Summary: String(""),
@@ -200,7 +199,6 @@ func TestChecksService_UpdateCheckRun(t *testing.T) {
 	})
 	startedAt, _ := time.Parse(time.RFC3339, "2018-05-04T01:14:52Z")
 	updateCheckRunOpt := UpdateCheckRunOptions{
-		HeadBranch:  String("master"),
 		Name:        "testUpdateCheckRun",
 		HeadSHA:     String("deadbeef"),
 		Status:      String("completed"),
diff --git a/github/examples_test.go b/github/examples_test.go
index a47f927e..3035f0cc 100644
--- a/github/examples_test.go
+++ b/github/examples_test.go
@@ -12,7 +12,7 @@ import (
 	"fmt"
 	"log"
 
-	"github.com/google/go-github/v28/github"
+	"github.com/google/go-github/v29/github"
 )
 
 func ExampleClient_Markdown() {
diff --git a/github/git_trees_test.go b/github/git_trees_test.go
index 1f7024fc..1d1b789c 100644
--- a/github/git_trees_test.go
+++ b/github/git_trees_test.go
@@ -186,6 +186,72 @@ func TestGitService_CreateTree_Content(t *testing.T) {
 	}
 }
 
+func TestGitService_CreateTree_Delete(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	input := []TreeEntry{
+		{
+			Path: String("content.md"),
+			Mode: String("100644"),
+		},
+	}
+
+	mux.HandleFunc("/repos/o/r/git/trees", func(w http.ResponseWriter, r *http.Request) {
+		v := new(createTree)
+		json.NewDecoder(r.Body).Decode(v)
+
+		testMethod(t, r, "POST")
+
+		want := &createTree{
+			BaseTree: "b",
+			Entries:  input,
+		}
+		if !reflect.DeepEqual(v, want) {
+			t.Errorf("Git.CreateTree request body: %+v, want %+v", v, want)
+		}
+
+		fmt.Fprint(w, `{
+		  "sha": "5c6780ad2c68743383b740fd1dab6f6a33202b11",
+		  "url": "https://api.github.com/repos/o/r/git/trees/5c6780ad2c68743383b740fd1dab6f6a33202b11",
+		  "tree": [
+		    {
+			  "mode": "100644",
+			  "type": "blob",
+			  "sha":  null,
+			  "path": "content.md",
+			  "size": 12,
+			  "url": "https://api.github.com/repos/o/r/git/blobs/aad8feacf6f8063150476a7b2bd9770f2794c08b"
+		    }
+		  ]
+		}`)
+	})
+
+	tree, _, err := client.Git.CreateTree(context.Background(), "o", "r", "b", input)
+	if err != nil {
+		t.Errorf("Git.CreateTree returned error: %v", err)
+	}
+
+	want := Tree{
+		String("5c6780ad2c68743383b740fd1dab6f6a33202b11"),
+		[]TreeEntry{
+			{
+				Path: String("content.md"),
+				Mode: String("100644"),
+				Type: String("blob"),
+				Size: Int(12),
+				SHA:  nil,
+				URL:  String("https://api.github.com/repos/o/r/git/blobs/aad8feacf6f8063150476a7b2bd9770f2794c08b"),
+			},
+		},
+		nil,
+	}
+
+	if !reflect.DeepEqual(*tree, want) {
+		t.Errorf("Git.CreateTree returned %+v, want %+v", *tree, want)
+	}
+}
+
 func TestGitService_CreateTree_invalidOwner(t *testing.T) {
 	client, _, _, teardown := setup()
 	defer teardown()
diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go
index f7e6d2b4..97a13ee2 100644
--- a/github/github-stringify_test.go
+++ b/github/github-stringify_test.go
@@ -307,6 +307,25 @@ func TestDraftReviewComment_String(t *testing.T) {
 	}
 }
 
+func TestEnterprise_String(t *testing.T) {
+	v := Enterprise{
+		ID:          Int(0),
+		Slug:        String(""),
+		Name:        String(""),
+		NodeID:      String(""),
+		AvatarURL:   String(""),
+		Description: String(""),
+		WebsiteURL:  String(""),
+		HTMLURL:     String(""),
+		CreatedAt:   &Timestamp{},
+		UpdatedAt:   &Timestamp{},
+	}
+	want := `github.Enterprise{ID:0, Slug:"", Name:"", NodeID:"", AvatarURL:"", Description:"", WebsiteURL:"", HTMLURL:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}`
+	if got := v.String(); got != want {
+		t.Errorf("Enterprise.String = %v, want %v", got, want)
+	}
+}
+
 func TestEvent_String(t *testing.T) {
 	v := Event{
 		Type:   String(""),
@@ -779,6 +798,18 @@ func TestNewTeam_String(t *testing.T) {
 	}
 }
 
+func TestOAuthAPP_String(t *testing.T) {
+	v := OAuthAPP{
+		URL:      String(""),
+		Name:     String(""),
+		ClientID: String(""),
+	}
+	want := `github.OAuthAPP{URL:"", Name:"", ClientID:""}`
+	if got := v.String(); got != want {
+		t.Errorf("OAuthAPP.String = %v, want %v", got, want)
+	}
+}
+
 func TestOrgStats_String(t *testing.T) {
 	v := OrgStats{
 		TotalOrgs:        Int(0),
@@ -821,6 +852,9 @@ func TestOrganization_String(t *testing.T) {
 		DefaultRepoPermission:                String(""),
 		DefaultRepoSettings:                  String(""),
 		MembersCanCreateRepos:                Bool(false),
+		MembersCanCreatePublicRepos:          Bool(false),
+		MembersCanCreatePrivateRepos:         Bool(false),
+		MembersCanCreateInternalRepos:        Bool(false),
 		MembersAllowedRepositoryCreationType: String(""),
 		URL:                                  String(""),
 		EventsURL:                            String(""),
@@ -830,7 +864,7 @@ func TestOrganization_String(t *testing.T) {
 		PublicMembersURL:                     String(""),
 		ReposURL:                             String(""),
 	}
-	want := `github.Organization{Login:"", ID:0, NodeID:"", AvatarURL:"", HTMLURL:"", Name:"", Company:"", Blog:"", Location:"", Email:"", Description:"", PublicRepos:0, PublicGists:0, Followers:0, Following:0, TotalPrivateRepos:0, OwnedPrivateRepos:0, PrivateGists:0, DiskUsage:0, Collaborators:0, BillingEmail:"", Type:"", Plan:github.Plan{}, TwoFactorRequirementEnabled:false, DefaultRepoPermission:"", DefaultRepoSettings:"", MembersCanCreateRepos:false, MembersAllowedRepositoryCreationType:"", URL:"", EventsURL:"", HooksURL:"", IssuesURL:"", MembersURL:"", PublicMembersURL:"", ReposURL:""}`
+	want := `github.Organization{Login:"", ID:0, NodeID:"", AvatarURL:"", HTMLURL:"", Name:"", Company:"", Blog:"", Location:"", Email:"", Description:"", PublicRepos:0, PublicGists:0, Followers:0, Following:0, TotalPrivateRepos:0, OwnedPrivateRepos:0, PrivateGists:0, DiskUsage:0, Collaborators:0, BillingEmail:"", Type:"", Plan:github.Plan{}, TwoFactorRequirementEnabled:false, DefaultRepoPermission:"", DefaultRepoSettings:"", MembersCanCreateRepos:false, MembersCanCreatePublicRepos:false, MembersCanCreatePrivateRepos:false, MembersCanCreateInternalRepos:false, MembersAllowedRepositoryCreationType:"", URL:"", EventsURL:"", HooksURL:"", IssuesURL:"", MembersURL:"", PublicMembersURL:"", ReposURL:""}`
 	if got := v.String(); got != want {
 		t.Errorf("Organization.String = %v, want %v", got, want)
 	}
@@ -955,6 +989,12 @@ func TestPullRequestComment_String(t *testing.T) {
 		PullRequestReviewID: Int64(0),
 		Position:            Int(0),
 		OriginalPosition:    Int(0),
+		StartLine:           Int(0),
+		Line:                Int(0),
+		OriginalLine:        Int(0),
+		OriginalStartLine:   Int(0),
+		Side:                String(""),
+		StartSide:           String(""),
 		CommitID:            String(""),
 		OriginalCommitID:    String(""),
 		User:                &User{},
@@ -964,7 +1004,7 @@ func TestPullRequestComment_String(t *testing.T) {
 		HTMLURL:             String(""),
 		PullRequestURL:      String(""),
 	}
-	want := `github.PullRequestComment{ID:0, NodeID:"", InReplyTo:0, Body:"", Path:"", DiffHunk:"", PullRequestReviewID:0, Position:0, OriginalPosition:0, CommitID:"", OriginalCommitID:"", User:github.User{}, Reactions:github.Reactions{}, AuthorAssociation:"", URL:"", HTMLURL:"", PullRequestURL:""}`
+	want := `github.PullRequestComment{ID:0, NodeID:"", InReplyTo:0, Body:"", Path:"", DiffHunk:"", PullRequestReviewID:0, Position:0, OriginalPosition:0, StartLine:0, Line:0, OriginalLine:0, OriginalStartLine:0, Side:"", StartSide:"", CommitID:"", OriginalCommitID:"", User:github.User{}, Reactions:github.Reactions{}, AuthorAssociation:"", URL:"", HTMLURL:"", PullRequestURL:""}`
 	if got := v.String(); got != want {
 		t.Errorf("PullRequestComment.String = %v, want %v", got, want)
 	}
diff --git a/github/github_test.go b/github/github_test.go
index 9dfac059..0780d14d 100644
--- a/github/github_test.go
+++ b/github/github_test.go
@@ -6,9 +6,9 @@
 package github
 
 import (
-	"bytes"
 	"context"
 	"encoding/json"
+	"errors"
 	"fmt"
 	"io/ioutil"
 	"net/http"
@@ -135,32 +135,29 @@ func testBody(t *testing.T, r *http.Request, want string) {
 	}
 }
 
-// Helper function to test that a value is marshalled to JSON as expected.
+// Test whether the marshaling of v produces JSON that corresponds
+// to the want string.
 func testJSONMarshal(t *testing.T, v interface{}, want string) {
-	j, err := json.Marshal(v)
+	// Unmarshal the wanted JSON, to verify its correctness, and marshal it back
+	// to sort the keys.
+	u := reflect.New(reflect.TypeOf(v)).Interface()
+	if err := json.Unmarshal([]byte(want), &u); err != nil {
+		t.Errorf("Unable to unmarshal JSON for %v: %v", want, err)
+	}
+	w, err := json.Marshal(u)
 	if err != nil {
-		t.Errorf("Unable to marshal JSON for %v", v)
+		t.Errorf("Unable to marshal JSON for %#v", u)
 	}
 
-	w := new(bytes.Buffer)
-	err = json.Compact(w, []byte(want))
+	// Marshal the target value.
+	j, err := json.Marshal(v)
 	if err != nil {
-		t.Errorf("String is not valid json: %s", want)
+		t.Errorf("Unable to marshal JSON for %#v", v)
 	}
 
-	if w.String() != string(j) {
+	if string(w) != string(j) {
 		t.Errorf("json.Marshal(%q) returned %s, want %s", v, j, w)
 	}
-
-	// now go the other direction and make sure things unmarshal as expected
-	u := reflect.ValueOf(v).Interface()
-	if err := json.Unmarshal([]byte(want), u); err != nil {
-		t.Errorf("Unable to unmarshal JSON for %v: %v", want, err)
-	}
-
-	if !reflect.DeepEqual(v, u) {
-		t.Errorf("json.Unmarshal(%q) returned %s, want %s", want, u, v)
-	}
 }
 
 func TestNewClient(t *testing.T) {
@@ -481,6 +478,18 @@ func TestDo(t *testing.T) {
 	}
 }
 
+func TestDo_nilContext(t *testing.T) {
+	client, _, _, teardown := setup()
+	defer teardown()
+
+	req, _ := client.NewRequest("GET", ".", nil)
+	_, err := client.Do(nil, req, nil)
+
+	if !reflect.DeepEqual(err, errors.New("context must be non-nil")) {
+		t.Errorf("Expected context must be non-nil error")
+	}
+}
+
 func TestDo_httpError(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
@@ -862,6 +871,56 @@ func TestCheckResponse(t *testing.T) {
 	}
 }
 
+func TestCheckResponse_RateLimit(t *testing.T) {
+	res := &http.Response{
+		Request:    &http.Request{},
+		StatusCode: http.StatusForbidden,
+		Header:     http.Header{},
+		Body: ioutil.NopCloser(strings.NewReader(`{"message":"m",
+			"documentation_url": "url"}`)),
+	}
+	res.Header.Set(headerRateLimit, "60")
+	res.Header.Set(headerRateRemaining, "0")
+	res.Header.Set(headerRateReset, "243424")
+
+	err := CheckResponse(res).(*RateLimitError)
+
+	if err == nil {
+		t.Errorf("Expected error response.")
+	}
+
+	want := &RateLimitError{
+		Rate:     parseRate(res),
+		Response: res,
+		Message:  "m",
+	}
+	if !reflect.DeepEqual(err, want) {
+		t.Errorf("Error = %#v, want %#v", err, want)
+	}
+}
+
+func TestCheckResponse_AbuseRateLimit(t *testing.T) {
+	res := &http.Response{
+		Request:    &http.Request{},
+		StatusCode: http.StatusForbidden,
+		Body: ioutil.NopCloser(strings.NewReader(`{"message":"m",
+			"documentation_url": "developer.github.com/v3/#abuse-rate-limits"}`)),
+	}
+	err := CheckResponse(res).(*AbuseRateLimitError)
+
+	if err == nil {
+		t.Errorf("Expected error response.")
+	}
+
+	want := &AbuseRateLimitError{
+		Response: res,
+		Message:  "m",
+	}
+	if !reflect.DeepEqual(err, want) {
+		t.Errorf("Error = %#v, want %#v", err, want)
+	}
+}
+
 // ensure that we properly handle API errors that do not contain a response body
 func TestCheckResponse_noBody(t *testing.T) {
 	res := &http.Response{
@@ -883,6 +942,36 @@ func TestCheckResponse_noBody(t *testing.T) {
 	}
 }
 
+func TestCheckResponse_unexpectedErrorStructure(t *testing.T) {
+	httpBody := `{"message":"m", "errors": ["error 1"]}`
+	res := &http.Response{
+		Request:    &http.Request{},
+		StatusCode: http.StatusBadRequest,
+		Body:       ioutil.NopCloser(strings.NewReader(httpBody)),
+	}
+	err := CheckResponse(res).(*ErrorResponse)
+
+	if err == nil {
+		t.Errorf("Expected error response.")
+	}
+
+	want := &ErrorResponse{
+		Response: res,
+		Message:  "m",
+		Errors:   []Error{{Message: "error 1"}},
+	}
+	if !reflect.DeepEqual(err, want) {
+		t.Errorf("Error = %#v, want %#v", err, want)
+	}
+	data, err2 := ioutil.ReadAll(err.Response.Body)
+	if err2 != nil {
+		t.Fatalf("failed to read response body: %v", err)
+	}
+	if got := string(data); got != httpBody {
+		t.Errorf("ErrorResponse.Response.Body = %q, want %q", got, httpBody)
+	}
+}
+
 func TestParseBooleanResponse_true(t *testing.T) {
 	result, err := parseBoolResponse(nil)
 	if err != nil {
diff --git a/github/issues_comments_test.go b/github/issues_comments_test.go
index 6911a798..69acb242 100644
--- a/github/issues_comments_test.go
+++ b/github/issues_comments_test.go
@@ -31,10 +31,11 @@ func TestIssuesService_ListComments_allIssues(t *testing.T) {
 		fmt.Fprint(w, `[{"id":1}]`)
 	})
 
+	since := time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC)
 	opt := &IssueListCommentsOptions{
-		Sort:        "updated",
-		Direction:   "desc",
-		Since:       time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC),
+		Sort:        String("updated"),
+		Direction:   String("desc"),
+		Since:       &since,
 		ListOptions: ListOptions{Page: 2},
 	}
 	comments, _, err := client.Issues.ListComments(context.Background(), "o", "r", 0, opt)
diff --git a/github/issues_labels_test.go b/github/issues_labels_test.go
index 6437d880..e97b23b0 100644
--- a/github/issues_labels_test.go
+++ b/github/issues_labels_test.go
@@ -20,7 +20,6 @@ func TestIssuesService_ListLabels(t *testing.T) {
 
 	mux.HandleFunc("/repos/o/r/labels", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview)
 		testFormValues(t, r, values{"page": "2"})
 		fmt.Fprint(w, `[{"name": "a"},{"name": "b"}]`)
 	})
@@ -51,7 +50,6 @@ func TestIssuesService_GetLabel(t *testing.T) {
 
 	mux.HandleFunc("/repos/o/r/labels/n", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview)
 		fmt.Fprint(w, `{"url":"u", "name": "n", "color": "c", "description": "d"}`)
 	})
 
@@ -85,7 +83,6 @@ func TestIssuesService_CreateLabel(t *testing.T) {
 		json.NewDecoder(r.Body).Decode(v)
 
 		testMethod(t, r, "POST")
-		testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview)
 		if !reflect.DeepEqual(v, input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
 		}
@@ -123,7 +120,6 @@ func TestIssuesService_EditLabel(t *testing.T) {
 		json.NewDecoder(r.Body).Decode(v)
 
 		testMethod(t, r, "PATCH")
-		testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview)
 		if !reflect.DeepEqual(v, input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
 		}
@@ -178,7 +174,6 @@ func TestIssuesService_ListLabelsByIssue(t *testing.T) {
 
 	mux.HandleFunc("/repos/o/r/issues/1/labels", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview)
 		testFormValues(t, r, values{"page": "2"})
 		fmt.Fprint(w, `[{"name":"a","id":1},{"name":"b","id":2}]`)
 	})
@@ -217,7 +212,6 @@ func TestIssuesService_AddLabelsToIssue(t *testing.T) {
 		json.NewDecoder(r.Body).Decode(&v)
 
 		testMethod(t, r, "POST")
-		testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview)
 		if !reflect.DeepEqual(v, input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
 		}
@@ -249,7 +243,6 @@ func TestIssuesService_RemoveLabelForIssue(t *testing.T) {
 	defer teardown()
 
 	mux.HandleFunc("/repos/o/r/issues/1/labels/l", func(w http.ResponseWriter, r *http.Request) {
-		testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview)
 		testMethod(t, r, "DELETE")
 	})
 
@@ -278,7 +271,6 @@ func TestIssuesService_ReplaceLabelsForIssue(t *testing.T) {
 		json.NewDecoder(r.Body).Decode(&v)
 
 		testMethod(t, r, "PUT")
-		testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview)
 		if !reflect.DeepEqual(v, input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
 		}
@@ -311,7 +303,6 @@ func TestIssuesService_RemoveLabelsForIssue(t *testing.T) {
 
 	mux.HandleFunc("/repos/o/r/issues/1/labels", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "DELETE")
-		testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview)
 	})
 
 	_, err := client.Issues.RemoveLabelsForIssue(context.Background(), "o", "r", 1)
@@ -334,7 +325,6 @@ func TestIssuesService_ListLabelsForMilestone(t *testing.T) {
 
 	mux.HandleFunc("/repos/o/r/milestones/1/labels", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview)
 		testFormValues(t, r, values{"page": "2"})
 		fmt.Fprint(w, `[{"name": "a"},{"name": "b"}]`)
 	})
diff --git a/github/issues_test.go b/github/issues_test.go
index 7edcf09b..e26d7f5d 100644
--- a/github/issues_test.go
+++ b/github/issues_test.go
@@ -20,7 +20,7 @@ func TestIssuesService_List_all(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
+	wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLockReasonPreview}
 	mux.HandleFunc("/issues", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
@@ -57,7 +57,7 @@ func TestIssuesService_List_owned(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
+	wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLockReasonPreview}
 	mux.HandleFunc("/user/issues", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
@@ -79,7 +79,7 @@ func TestIssuesService_ListByOrg(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
+	wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLockReasonPreview}
 	mux.HandleFunc("/orgs/o/issues", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
@@ -109,7 +109,7 @@ func TestIssuesService_ListByRepo(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeIntegrationPreview}
+	wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeIntegrationPreview}
 	mux.HandleFunc("/repos/o/r/issues", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
@@ -155,7 +155,7 @@ func TestIssuesService_Get(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
+	wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeLockReasonPreview}
 	mux.HandleFunc("/repos/o/r/issues/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
@@ -204,7 +204,6 @@ func TestIssuesService_Create(t *testing.T) {
 		json.NewDecoder(r.Body).Decode(v)
 
 		testMethod(t, r, "POST")
-		testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview)
 		if !reflect.DeepEqual(v, input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
 		}
@@ -242,7 +241,6 @@ func TestIssuesService_Edit(t *testing.T) {
 		json.NewDecoder(r.Body).Decode(v)
 
 		testMethod(t, r, "PATCH")
-		testHeader(t, r, "Accept", mediaTypeLabelDescriptionSearchPreview)
 		if !reflect.DeepEqual(v, input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
 		}
diff --git a/github/messages_test.go b/github/messages_test.go
index 105904c6..2dad2473 100644
--- a/github/messages_test.go
+++ b/github/messages_test.go
@@ -339,10 +339,18 @@ func TestParseWebHook(t *testing.T) {
 			payload:     &TeamAddEvent{},
 			messageType: "team_add",
 		},
+		{
+			payload:     &UserEvent{},
+			messageType: "user",
+		},
 		{
 			payload:     &WatchEvent{},
 			messageType: "watch",
 		},
+		{
+			payload:     &RepositoryDispatchEvent{},
+			messageType: "repository_dispatch",
+		},
 	}
 
 	for _, test := range tests {
diff --git a/github/orgs_members_test.go b/github/orgs_members_test.go
index e524d03f..50da85d2 100644
--- a/github/orgs_members_test.go
+++ b/github/orgs_members_test.go
@@ -402,7 +402,7 @@ func TestOrganizationsService_ListPendingOrgInvitations(t *testing.T) {
       						"site_admin": false
 						},
 						"team_count": 2,
-						"invitation_team_url": "https://api.github.com/organizations/2/invitations/1/teams"	  	
+						"invitation_team_url": "https://api.github.com/organizations/2/invitations/1/teams"
   				}
 			]`)
 	})
@@ -466,7 +466,6 @@ func TestOrganizationsService_CreateOrgInvitation(t *testing.T) {
 		json.NewDecoder(r.Body).Decode(v)
 
 		testMethod(t, r, "POST")
-		testHeader(t, r, "Accept", mediaTypeOrganizationInvitationPreview)
 		if !reflect.DeepEqual(v, input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
 		}
@@ -493,7 +492,6 @@ func TestOrganizationsService_ListOrgInvitationTeams(t *testing.T) {
 	mux.HandleFunc("/orgs/o/invitations/22/teams", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testFormValues(t, r, values{"page": "1"})
-		testHeader(t, r, "Accept", mediaTypeOrganizationInvitationPreview)
 		fmt.Fprint(w, `[
 			{
 				"id": 1,
diff --git a/github/orgs_test.go b/github/orgs_test.go
index 9383bf11..cf69453c 100644
--- a/github/orgs_test.go
+++ b/github/orgs_test.go
@@ -14,6 +14,44 @@ import (
 	"testing"
 )
 
+func TestOrganization_marshal(t *testing.T) {
+	testJSONMarshal(t, &Organization{}, "{}")
+
+	o := &Organization{
+		BillingEmail:                         String("support@github.com"),
+		Blog:                                 String("https://github.com/blog"),
+		Company:                              String("GitHub"),
+		Email:                                String("support@github.com"),
+		Location:                             String("San Francisco"),
+		Name:                                 String("github"),
+		Description:                          String("GitHub, the company."),
+		DefaultRepoPermission:                String("read"),
+		MembersCanCreateRepos:                Bool(true),
+		MembersCanCreateInternalRepos:        Bool(true),
+		MembersCanCreatePrivateRepos:         Bool(true),
+		MembersCanCreatePublicRepos:          Bool(false),
+		MembersAllowedRepositoryCreationType: String("all"),
+	}
+	want := `
+		{
+			"billing_email": "support@github.com",
+			"blog": "https://github.com/blog",
+			"company": "GitHub",
+			"email": "support@github.com",
+			"location": "San Francisco",
+			"name": "github",
+			"description": "GitHub, the company.",
+			"default_repository_permission": "read",
+			"members_can_create_repositories": true,
+			"members_can_create_public_repositories": false,
+			"members_can_create_private_repositories": true,
+			"members_can_create_internal_repositories": true,
+			"members_allowed_repository_creation_type": "all"
+		}
+	`
+	testJSONMarshal(t, o, want)
+}
+
 func TestOrganizationsService_ListAll(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
@@ -146,6 +184,7 @@ func TestOrganizationsService_Edit(t *testing.T) {
 		v := new(Organization)
 		json.NewDecoder(r.Body).Decode(v)
 
+		testHeader(t, r, "Accept", mediaTypeMemberAllowedRepoCreationTypePreview)
 		testMethod(t, r, "PATCH")
 		if !reflect.DeepEqual(v, input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
diff --git a/github/pulls_comments_test.go b/github/pulls_comments_test.go
index b07b2cd9..ace57003 100644
--- a/github/pulls_comments_test.go
+++ b/github/pulls_comments_test.go
@@ -11,6 +11,7 @@ import (
 	"fmt"
 	"net/http"
 	"reflect"
+	"strings"
 	"testing"
 	"time"
 )
@@ -40,6 +41,12 @@ func TestPullComments_marshall(t *testing.T) {
 		PullRequestReviewID: Int64(42),
 		Position:            Int(1),
 		OriginalPosition:    Int(4),
+		StartLine:           Int(2),
+		Line:                Int(3),
+		OriginalLine:        Int(2),
+		OriginalStartLine:   Int(2),
+		Side:                String("RIGHT"),
+		StartSide:           String("LEFT"),
 		CommitID:            String("ab"),
 		OriginalCommitID:    String("9c"),
 		User: &User{
@@ -76,6 +83,12 @@ func TestPullComments_marshall(t *testing.T) {
 		"pull_request_review_id": 42,
 		"position": 1,
 		"original_position": 4,
+		"start_line": 2,
+		"line": 3,
+		"original_line": 2,
+		"original_start_line": 2,
+		"side": "RIGHT",
+		"start_side": "LEFT",
 		"commit_id": "ab",
 		"original_commit_id": "9c",
 		"user": {
@@ -119,9 +132,10 @@ func TestPullRequestsService_ListComments_allPulls(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
+	wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeMultiLineCommentsPreview}
 	mux.HandleFunc("/repos/o/r/pulls/comments", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeReactionsPreview)
+		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
 		testFormValues(t, r, values{
 			"sort":      "updated",
 			"direction": "desc",
@@ -152,9 +166,10 @@ func TestPullRequestsService_ListComments_specificPull(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
+	wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeMultiLineCommentsPreview}
 	mux.HandleFunc("/repos/o/r/pulls/1/comments", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeReactionsPreview)
+		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
 		fmt.Fprint(w, `[{"id":1, "pull_request_review_id":42}]`)
 	})
 
@@ -181,9 +196,10 @@ func TestPullRequestsService_GetComment(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
+	wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeMultiLineCommentsPreview}
 	mux.HandleFunc("/repos/o/r/pulls/comments/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeReactionsPreview)
+		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
 		fmt.Fprint(w, `{"id":1}`)
 	})
 
@@ -212,10 +228,13 @@ func TestPullRequestsService_CreateComment(t *testing.T) {
 
 	input := &PullRequestComment{Body: String("b")}
 
+	wantAcceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeMultiLineCommentsPreview}
 	mux.HandleFunc("/repos/o/r/pulls/1/comments", func(w http.ResponseWriter, r *http.Request) {
 		v := new(PullRequestComment)
 		json.NewDecoder(r.Body).Decode(v)
 
+		// TODO: remove custom Accept header assertion when the API fully launches.
+		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
 		testMethod(t, r, "POST")
 		if !reflect.DeepEqual(v, input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
diff --git a/github/pulls_test.go b/github/pulls_test.go
index 65647d65..b19921f5 100644
--- a/github/pulls_test.go
+++ b/github/pulls_test.go
@@ -20,7 +20,7 @@ func TestPullRequestsService_List(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	wantAcceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview, mediaTypeDraftPreview}
+	wantAcceptHeaders := []string{mediaTypeLockReasonPreview, mediaTypeDraftPreview}
 	mux.HandleFunc("/repos/o/r/pulls", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
@@ -51,7 +51,7 @@ func TestPullRequestsService_ListPullRequestsWithCommit(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	wantAcceptHeaders := []string{mediaTypeListPullsOrBranchesForCommitPreview, mediaTypeDraftPreview, mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
+	wantAcceptHeaders := []string{mediaTypeListPullsOrBranchesForCommitPreview, mediaTypeDraftPreview, mediaTypeLockReasonPreview}
 	mux.HandleFunc("/repos/o/r/commits/sha/pulls", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
@@ -90,7 +90,7 @@ func TestPullRequestsService_Get(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	wantAcceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview, mediaTypeDraftPreview}
+	wantAcceptHeaders := []string{mediaTypeLockReasonPreview, mediaTypeDraftPreview}
 	mux.HandleFunc("/repos/o/r/pulls/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
@@ -306,7 +306,7 @@ func TestPullRequestsService_Create(t *testing.T) {
 		json.NewDecoder(r.Body).Decode(v)
 
 		testMethod(t, r, "POST")
-		wantAcceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeDraftPreview}
+		wantAcceptHeaders := []string{mediaTypeDraftPreview}
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
 		if !reflect.DeepEqual(v, input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
@@ -398,7 +398,7 @@ func TestPullRequestsService_Edit(t *testing.T) {
 
 	for i, tt := range tests {
 		madeRequest := false
-		wantAcceptHeaders := []string{mediaTypeLabelDescriptionSearchPreview, mediaTypeLockReasonPreview}
+		wantAcceptHeaders := []string{mediaTypeLockReasonPreview}
 		mux.HandleFunc(fmt.Sprintf("/repos/o/r/pulls/%v", i), func(w http.ResponseWriter, r *http.Request) {
 			testMethod(t, r, "PATCH")
 			testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
diff --git a/github/reactions_test.go b/github/reactions_test.go
index ef1660d9..c32274de 100644
--- a/github/reactions_test.go
+++ b/github/reactions_test.go
@@ -7,6 +7,7 @@ package github
 
 import (
 	"context"
+	"fmt"
 	"net/http"
 	"reflect"
 	"testing"
@@ -67,17 +68,18 @@ func TestReactionsService_ListCommentReactions(t *testing.T) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", mediaTypeReactionsPreview)
 
-		w.WriteHeader(http.StatusOK)
-		w.Write([]byte(`[{"id":1,"user":{"login":"l","id":2},"content":"+1"}]`))
+		testFormValues(t, r, values{"content": "+1"})
+		fmt.Fprint(w, `[{"id":1,"user":{"login":"l","id":2},"content":"+1"}]`)
 	})
 
-	got, _, err := client.Reactions.ListCommentReactions(context.Background(), "o", "r", 1, nil)
+	opt := &ListCommentReactionOptions{Content: "+1"}
+	reactions, _, err := client.Reactions.ListCommentReactions(context.Background(), "o", "r", 1, opt)
 	if err != nil {
 		t.Errorf("ListCommentReactions returned error: %v", err)
 	}
 	want := []*Reaction{{ID: Int64(1), User: &User{Login: String("l"), ID: Int64(2)}, Content: String("+1")}}
-	if !reflect.DeepEqual(got, want) {
-		t.Errorf("ListCommentReactions = %+v, want %+v", got, want)
+	if !reflect.DeepEqual(reactions, want) {
+		t.Errorf("ListCommentReactions = %+v, want %+v", reactions, want)
 	}
 }
 
diff --git a/github/repos_collaborators_test.go b/github/repos_collaborators_test.go
index a4d3210c..e14dc8bd 100644
--- a/github/repos_collaborators_test.go
+++ b/github/repos_collaborators_test.go
@@ -20,7 +20,6 @@ func TestRepositoriesService_ListCollaborators(t *testing.T) {
 
 	mux.HandleFunc("/repos/o/r/collaborators", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview)
 		testFormValues(t, r, values{"page": "2"})
 		fmt.Fprintf(w, `[{"id":1}, {"id":2}]`)
 	})
@@ -149,30 +148,48 @@ func TestRepositoriesService_AddCollaborator(t *testing.T) {
 	defer teardown()
 
 	opt := &RepositoryAddCollaboratorOptions{Permission: "admin"}
-
 	mux.HandleFunc("/repos/o/r/collaborators/u", func(w http.ResponseWriter, r *http.Request) {
 		v := new(RepositoryAddCollaboratorOptions)
 		json.NewDecoder(r.Body).Decode(v)
-
 		testMethod(t, r, "PUT")
 		if !reflect.DeepEqual(v, opt) {
 			t.Errorf("Request body = %+v, want %+v", v, opt)
 		}
-
-		w.WriteHeader(http.StatusNoContent)
+		w.WriteHeader(http.StatusOK)
+		w.Write([]byte(`{"permissions": "write","url": "https://api.github.com/user/repository_invitations/1296269","html_url": "https://github.com/octocat/Hello-World/invitations","id":1,"permissions":"write","repository":{"url":"s","name":"r","id":1},"invitee":{"login":"u"},"inviter":{"login":"o"}}`))
 	})
-
-	_, err := client.Repositories.AddCollaborator(context.Background(), "o", "r", "u", opt)
+	collaboratorInvitation, _, err := client.Repositories.AddCollaborator(context.Background(), "o", "r", "u", opt)
 	if err != nil {
 		t.Errorf("Repositories.AddCollaborator returned error: %v", err)
 	}
+	want := &CollaboratorInvitation{
+		ID: Int64(1),
+		Repo: &Repository{
+			ID:   Int64(1),
+			URL:  String("s"),
+			Name: String("r"),
+		},
+		Invitee: &User{
+			Login: String("u"),
+		},
+		Inviter: &User{
+			Login: String("o"),
+		},
+		Permissions: String("write"),
+		URL:         String("https://api.github.com/user/repository_invitations/1296269"),
+		HTMLURL:     String("https://github.com/octocat/Hello-World/invitations"),
+	}
+
+	if !reflect.DeepEqual(collaboratorInvitation, want) {
+		t.Errorf("AddCollaborator returned %+v, want %+v", collaboratorInvitation, want)
+	}
 }
 
 func TestRepositoriesService_AddCollaborator_invalidUser(t *testing.T) {
 	client, _, _, teardown := setup()
 	defer teardown()
 
-	_, err := client.Repositories.AddCollaborator(context.Background(), "%", "%", "%", nil)
+	_, _, err := client.Repositories.AddCollaborator(context.Background(), "%", "%", "%", nil)
 	testURLParseError(t, err)
 }
 
diff --git a/github/repos_contents_test.go b/github/repos_contents_test.go
index 29bab8d2..f1225258 100644
--- a/github/repos_contents_test.go
+++ b/github/repos_contents_test.go
@@ -10,6 +10,7 @@ import (
 	"fmt"
 	"io/ioutil"
 	"net/http"
+	"net/url"
 	"reflect"
 	"testing"
 )
@@ -375,7 +376,46 @@ func TestRepositoriesService_GetArchiveLink(t *testing.T) {
 		testMethod(t, r, "GET")
 		http.Redirect(w, r, "http://github.com/a", http.StatusFound)
 	})
-	url, resp, err := client.Repositories.GetArchiveLink(context.Background(), "o", "r", Tarball, &RepositoryContentGetOptions{})
+	url, resp, err := client.Repositories.GetArchiveLink(context.Background(), "o", "r", Tarball, &RepositoryContentGetOptions{}, true)
+	if err != nil {
+		t.Errorf("Repositories.GetArchiveLink returned error: %v", err)
+	}
+	if resp.StatusCode != http.StatusFound {
+		t.Errorf("Repositories.GetArchiveLink returned status: %d, want %d", resp.StatusCode, http.StatusFound)
+	}
+	want := "http://github.com/a"
+	if url.String() != want {
+		t.Errorf("Repositories.GetArchiveLink returned %+v, want %+v", url.String(), want)
+	}
+}
+
+func TestRepositoriesService_GetArchiveLink_StatusMovedPermanently_dontFollowRedirects(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+	mux.HandleFunc("/repos/o/r/tarball", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		http.Redirect(w, r, "http://github.com/a", http.StatusMovedPermanently)
+	})
+	_, resp, _ := client.Repositories.GetArchiveLink(context.Background(), "o", "r", Tarball, &RepositoryContentGetOptions{}, false)
+	if resp.StatusCode != http.StatusMovedPermanently {
+		t.Errorf("Repositories.GetArchiveLink returned status: %d, want %d", resp.StatusCode, http.StatusMovedPermanently)
+	}
+}
+
+func TestRepositoriesService_GetArchiveLink_StatusMovedPermanently_followRedirects(t *testing.T) {
+	client, mux, serverURL, teardown := setup()
+	defer teardown()
+	// Mock a redirect link, which leads to an archive link
+	mux.HandleFunc("/repos/o/r/tarball", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		redirectURL, _ := url.Parse(serverURL + baseURLPath + "/redirect")
+		http.Redirect(w, r, redirectURL.String(), http.StatusMovedPermanently)
+	})
+	mux.HandleFunc("/redirect", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		http.Redirect(w, r, "http://github.com/a", http.StatusFound)
+	})
+	url, resp, err := client.Repositories.GetArchiveLink(context.Background(), "o", "r", Tarball, &RepositoryContentGetOptions{}, true)
 	if err != nil {
 		t.Errorf("Repositories.GetArchiveLink returned error: %v", err)
 	}
diff --git a/github/repos_pages_test.go b/github/repos_pages_test.go
index 62d42470..ec77f717 100644
--- a/github/repos_pages_test.go
+++ b/github/repos_pages_test.go
@@ -10,7 +10,6 @@ import (
 	"fmt"
 	"net/http"
 	"reflect"
-	"strings"
 	"testing"
 )
 
@@ -20,8 +19,7 @@ func TestRepositoriesService_EnablePages(t *testing.T) {
 
 	mux.HandleFunc("/repos/o/r/pages", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "POST")
-		wantAcceptHeaders := []string{mediaTypeEnablePagesAPIPreview, mediaTypePagesPreview}
-		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
+		testHeader(t, r, "Accept", mediaTypeEnablePagesAPIPreview)
 		fmt.Fprint(w, `{"url":"u","status":"s","cname":"c","custom_404":false,"html_url":"h", "source": {"branch":"master", "path":"/"}}`)
 	})
 
@@ -58,7 +56,6 @@ func TestRepositoriesService_GetPagesInfo(t *testing.T) {
 
 	mux.HandleFunc("/repos/o/r/pages", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypePagesPreview)
 		fmt.Fprint(w, `{"url":"u","status":"s","cname":"c","custom_404":false,"html_url":"h"}`)
 	})
 
@@ -157,7 +154,6 @@ func TestRepositoriesService_RequestPageBuild(t *testing.T) {
 
 	mux.HandleFunc("/repos/o/r/pages/builds", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "POST")
-		testHeader(t, r, "Accept", mediaTypePagesPreview)
 		fmt.Fprint(w, `{"url":"u","status":"s"}`)
 	})
 
diff --git a/github/repos_test.go b/github/repos_test.go
index 5ed6682c..1e48b7e2 100644
--- a/github/repos_test.go
+++ b/github/repos_test.go
@@ -630,6 +630,27 @@ func TestRepositoriesService_Edit_invalidOwner(t *testing.T) {
 	testURLParseError(t, err)
 }
 
+func TestRepositoriesService_GetVulnerabilityAlerts(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/repos/o/r/vulnerability-alerts", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		testHeader(t, r, "Accept", mediaTypeRequiredVulnerabilityAlertsPreview)
+
+		w.WriteHeader(http.StatusNoContent)
+	})
+
+	vulnerabilityAlertsEnabled, _, err := client.Repositories.GetVulnerabilityAlerts(context.Background(), "o", "r")
+	if err != nil {
+		t.Errorf("Repositories.GetVulnerabilityAlerts returned error: %v", err)
+	}
+
+	if want := true; vulnerabilityAlertsEnabled != want {
+		t.Errorf("Repositories.GetVulnerabilityAlerts returned %+v, want %+v", vulnerabilityAlertsEnabled, want)
+	}
+}
+
 func TestRepositoriesService_EnableVulnerabilityAlerts(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
@@ -745,7 +766,6 @@ func TestRepositoriesService_ListTeams(t *testing.T) {
 
 	mux.HandleFunc("/repos/o/r/teams", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview)
 		testFormValues(t, r, values{"page": "2"})
 		fmt.Fprint(w, `[{"id":1}]`)
 	})
@@ -907,7 +927,7 @@ func TestRepositoriesService_GetBranchProtection(t *testing.T) {
 		},
 		RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
 			DismissStaleReviews: true,
-			DismissalRestrictions: DismissalRestrictions{
+			DismissalRestrictions: &DismissalRestrictions{
 				Users: []*User{
 					{Login: String("u"), ID: Int64(3)},
 				},
@@ -936,6 +956,70 @@ func TestRepositoriesService_GetBranchProtection(t *testing.T) {
 	}
 }
 
+func TestRepositoriesService_GetBranchProtection_noDismissalRestrictions(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) {
+
+		testMethod(t, r, "GET")
+		// TODO: remove custom Accept header when this API fully launches
+		testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
+		fmt.Fprintf(w, `{
+				"required_status_checks":{
+					"strict":true,
+					"contexts":["continuous-integration"]
+				},
+				"required_pull_request_reviews":{
+					"dismiss_stale_reviews":true,
+					"require_code_owner_reviews":true,
+					"required_approving_review_count":1
+					},
+					"enforce_admins":{
+						"url":"/repos/o/r/branches/b/protection/enforce_admins",
+						"enabled":true
+					},
+					"restrictions":{
+						"users":[{"id":1,"login":"u"}],
+						"teams":[{"id":2,"slug":"t"}]
+					}
+				}`)
+	})
+
+	protection, _, err := client.Repositories.GetBranchProtection(context.Background(), "o", "r", "b")
+	if err != nil {
+		t.Errorf("Repositories.GetBranchProtection returned error: %v", err)
+	}
+
+	want := &Protection{
+		RequiredStatusChecks: &RequiredStatusChecks{
+			Strict:   true,
+			Contexts: []string{"continuous-integration"},
+		},
+		RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
+			DismissStaleReviews:          true,
+			DismissalRestrictions:        nil,
+			RequireCodeOwnerReviews:      true,
+			RequiredApprovingReviewCount: 1,
+		},
+		EnforceAdmins: &AdminEnforcement{
+			URL:     String("/repos/o/r/branches/b/protection/enforce_admins"),
+			Enabled: true,
+		},
+		Restrictions: &BranchRestrictions{
+			Users: []*User{
+				{Login: String("u"), ID: Int64(1)},
+			},
+			Teams: []*Team{
+				{Slug: String("t"), ID: Int64(2)},
+			},
+		},
+	}
+	if !reflect.DeepEqual(protection, want) {
+		t.Errorf("Repositories.GetBranchProtection returned %+v, want %+v", protection, want)
+	}
+}
+
 func TestRepositoriesService_UpdateBranchProtection(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
@@ -955,6 +1039,7 @@ func TestRepositoriesService_UpdateBranchProtection(t *testing.T) {
 		Restrictions: &BranchRestrictionsRequest{
 			Users: []string{"u"},
 			Teams: []string{"t"},
+			Apps:  []string{"a"},
 		},
 	}
 
@@ -990,7 +1075,8 @@ func TestRepositoriesService_UpdateBranchProtection(t *testing.T) {
 			},
 			"restrictions":{
 				"users":[{"id":1,"login":"u"}],
-				"teams":[{"id":2,"slug":"t"}]
+				"teams":[{"id":2,"slug":"t"}],
+				"apps":[{"id":3,"slug":"a"}]
 			}
 		}`)
 	})
@@ -1007,7 +1093,7 @@ func TestRepositoriesService_UpdateBranchProtection(t *testing.T) {
 		},
 		RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
 			DismissStaleReviews: true,
-			DismissalRestrictions: DismissalRestrictions{
+			DismissalRestrictions: &DismissalRestrictions{
 				Users: []*User{
 					{Login: String("uu"), ID: Int64(3)},
 				},
@@ -1024,6 +1110,9 @@ func TestRepositoriesService_UpdateBranchProtection(t *testing.T) {
 			Teams: []*Team{
 				{Slug: String("t"), ID: Int64(2)},
 			},
+			Apps: []*App{
+				{Slug: String("a"), ID: Int64(3)},
+			},
 		},
 	}
 	if !reflect.DeepEqual(protection, want) {
@@ -1201,7 +1290,7 @@ func TestRepositoriesService_GetPullRequestReviewEnforcement(t *testing.T) {
 
 	want := &PullRequestReviewsEnforcement{
 		DismissStaleReviews: true,
-		DismissalRestrictions: DismissalRestrictions{
+		DismissalRestrictions: &DismissalRestrictions{
 			Users: []*User{
 				{Login: String("u"), ID: Int64(1)},
 			},
@@ -1257,7 +1346,7 @@ func TestRepositoriesService_UpdatePullRequestReviewEnforcement(t *testing.T) {
 
 	want := &PullRequestReviewsEnforcement{
 		DismissStaleReviews: true,
-		DismissalRestrictions: DismissalRestrictions{
+		DismissalRestrictions: &DismissalRestrictions{
 			Users: []*User{
 				{Login: String("u"), ID: Int64(1)},
 			},
@@ -1281,8 +1370,8 @@ func TestRepositoriesService_DisableDismissalRestrictions(t *testing.T) {
 		testMethod(t, r, "PATCH")
 		// TODO: remove custom Accept header when this API fully launches
 		testHeader(t, r, "Accept", mediaTypeRequiredApprovingReviewsPreview)
-		testBody(t, r, `{"dismissal_restrictions":[]}`+"\n")
-		fmt.Fprintf(w, `{"dismissal_restrictions":{"users":[],"teams":[]},"dismiss_stale_reviews":true,"require_code_owner_reviews":true,"required_approving_review_count":1}`)
+		testBody(t, r, `{"dismissal_restrictions":{}}`+"\n")
+		fmt.Fprintf(w, `{"dismiss_stale_reviews":true,"require_code_owner_reviews":true,"required_approving_review_count":1}`)
 	})
 
 	enforcement, _, err := client.Repositories.DisableDismissalRestrictions(context.Background(), "o", "r", "b")
@@ -1291,11 +1380,8 @@ func TestRepositoriesService_DisableDismissalRestrictions(t *testing.T) {
 	}
 
 	want := &PullRequestReviewsEnforcement{
-		DismissStaleReviews: true,
-		DismissalRestrictions: DismissalRestrictions{
-			Users: []*User{},
-			Teams: []*Team{},
-		},
+		DismissStaleReviews:          true,
+		DismissalRestrictions:        nil,
 		RequireCodeOwnerReviews:      true,
 		RequiredApprovingReviewCount: 1,
 	}
@@ -1603,6 +1689,85 @@ func TestRepositoriesService_ReplaceAllTopics_emptySlice(t *testing.T) {
 	}
 }
 
+func TestRepositoriesService_ListApps(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+	})
+
+	_, _, err := client.Repositories.ListApps(context.Background(), "o", "r", "b")
+	if err != nil {
+		t.Errorf("Repositories.ListApps returned error: %v", err)
+	}
+}
+
+func TestRepositoriesService_ReplaceAppRestrictions(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "PUT")
+		fmt.Fprint(w, `[{
+				"name": "octocat"
+			}]`)
+	})
+	input := []string{"octocat"}
+	got, _, err := client.Repositories.ReplaceAppRestrictions(context.Background(), "o", "r", "b", input)
+	if err != nil {
+		t.Errorf("Repositories.ReplaceAppRestrictions returned error: %v", err)
+	}
+	want := []*App{
+		{Name: String("octocat")},
+	}
+	if !reflect.DeepEqual(got, want) {
+		t.Errorf("Repositories.ReplaceAppRestrictions returned %+v, want %+v", got, want)
+	}
+}
+
+func TestRepositoriesService_AddAppRestrictions(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "POST")
+		fmt.Fprint(w, `[{
+				"name": "octocat"
+			}]`)
+	})
+	input := []string{"octocat"}
+	got, _, err := client.Repositories.AddAppRestrictions(context.Background(), "o", "r", "b", input)
+	if err != nil {
+		t.Errorf("Repositories.AddAppRestrictions returned error: %v", err)
+	}
+	want := []*App{
+		{Name: String("octocat")},
+	}
+	if !reflect.DeepEqual(got, want) {
+		t.Errorf("Repositories.AddAppRestrictions returned %+v, want %+v", got, want)
+	}
+}
+
+func TestRepositoriesService_RemoveAppRestrictions(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/repos/o/r/branches/b/protection/restrictions/apps", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "DELETE")
+		fmt.Fprint(w, `[]`)
+	})
+	input := []string{"octocat"}
+	got, _, err := client.Repositories.RemoveAppRestrictions(context.Background(), "o", "r", "b", input)
+	if err != nil {
+		t.Errorf("Repositories.RemoveAppRestrictions returned error: %v", err)
+	}
+	want := []*App{}
+	if !reflect.DeepEqual(got, want) {
+		t.Errorf("Repositories.RemoveAppRestrictions returned %+v, want %+v", got, want)
+	}
+}
+
 func TestRepositoriesService_Transfer(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
@@ -1614,7 +1779,6 @@ func TestRepositoriesService_Transfer(t *testing.T) {
 		json.NewDecoder(r.Body).Decode(&v)
 
 		testMethod(t, r, "POST")
-		testHeader(t, r, "Accept", mediaTypeRepositoryTransferPreview)
 		if !reflect.DeepEqual(v, input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
 		}
@@ -1632,3 +1796,95 @@ func TestRepositoriesService_Transfer(t *testing.T) {
 		t.Errorf("Repositories.Transfer returned %+v, want %+v", got, want)
 	}
 }
+
+func TestRepositoriesService_Dispatch(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	var input DispatchRequestOptions
+
+	mux.HandleFunc("/repos/o/r/dispatches", func(w http.ResponseWriter, r *http.Request) {
+		var v DispatchRequestOptions
+		json.NewDecoder(r.Body).Decode(&v)
+
+		testMethod(t, r, "POST")
+		testHeader(t, r, "Accept", mediaTypeRepositoryDispatchPreview)
+		if !reflect.DeepEqual(v, input) {
+			t.Errorf("Request body = %+v, want %+v", v, input)
+		}
+
+		fmt.Fprint(w, `{"owner":{"login":"a"}}`)
+	})
+
+	ctx := context.Background()
+
+	testCases := []interface{}{
+		nil,
+		struct {
+			Foo string
+		}{
+			Foo: "test",
+		},
+		struct {
+			Bar int
+		}{
+			Bar: 42,
+		},
+		struct {
+			Foo string
+			Bar int
+			Baz bool
+		}{
+			Foo: "test",
+			Bar: 42,
+			Baz: false,
+		},
+	}
+	for _, tc := range testCases {
+
+		if tc == nil {
+			input = DispatchRequestOptions{EventType: "go"}
+		} else {
+			bytes, _ := json.Marshal(tc)
+			payload := json.RawMessage(bytes)
+			input = DispatchRequestOptions{EventType: "go", ClientPayload: &payload}
+		}
+
+		got, _, err := client.Repositories.Dispatch(ctx, "o", "r", input)
+		if err != nil {
+			t.Errorf("Repositories.Dispatch returned error: %v", err)
+		}
+
+		want := &Repository{Owner: &User{Login: String("a")}}
+		if !reflect.DeepEqual(got, want) {
+			t.Errorf("Repositories.Dispatch returned %+v, want %+v", got, want)
+		}
+	}
+
+	// Test s.client.NewRequest failure
+	client.BaseURL.Path = ""
+	got, resp, err := client.Repositories.Dispatch(ctx, "o", "r", input)
+	if got != nil {
+		t.Errorf("client.BaseURL.Path='' Dispatch = %#v, want nil", got)
+	}
+	if resp != nil {
+		t.Errorf("client.BaseURL.Path='' Dispatch resp = %#v, want nil", resp)
+	}
+	if err == nil {
+		t.Error("client.BaseURL.Path='' Dispatch err = nil, want error")
+	}
+
+	// Test s.client.Do failure
+	client.BaseURL.Path = "/api-v3/"
+	client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute)
+	got, resp, err = client.Repositories.Dispatch(ctx, "o", "r", input)
+	if got != nil {
+		t.Errorf("rate.Reset.Time > now Dispatch = %#v, want nil", got)
+	}
+	if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want {
+		t.Errorf("rate.Reset.Time > now Dispatch resp = %#v, want StatusCode=%v", resp.Response, want)
+	}
+	if err == nil {
+		t.Error("rate.Reset.Time > now Dispatch err = nil, want error")
+	}
+}
diff --git a/github/search_test.go b/github/search_test.go
index 4b686884..7b607569 100644
--- a/github/search_test.go
+++ b/github/search_test.go
@@ -47,6 +47,37 @@ func TestSearchService_Repositories(t *testing.T) {
 	}
 }
 
+func TestSearchService_Topics(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/search/topics", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		testFormValues(t, r, values{
+			"q":        "blah",
+			"page":     "2",
+			"per_page": "2",
+		})
+
+		fmt.Fprint(w, `{"total_count": 4, "incomplete_results": false, "items": [{"name":"blah"},{"name":"blahblah"}]}`)
+	})
+
+	opts := &SearchOptions{ListOptions: ListOptions{Page: 2, PerPage: 2}}
+	result, _, err := client.Search.Topics(context.Background(), "blah", opts)
+	if err != nil {
+		t.Errorf("Search.Topics returned error: %v", err)
+	}
+
+	want := &TopicsSearchResult{
+		Total:             Int(4),
+		IncompleteResults: Bool(false),
+		Topics:            []*TopicResult{{Name: String("blah")}, {Name: String("blahblah")}},
+	}
+	if !reflect.DeepEqual(result, want) {
+		t.Errorf("Search.Topics returned %+v, want %+v", result, want)
+	}
+}
+
 func TestSearchService_Commits(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
diff --git a/github/teams_discussion_comments_test.go b/github/teams_discussion_comments_test.go
index f4c9f96f..96ed1464 100644
--- a/github/teams_discussion_comments_test.go
+++ b/github/teams_discussion_comments_test.go
@@ -21,7 +21,6 @@ func TestTeamsService_ListComments(t *testing.T) {
 
 	mux.HandleFunc("/teams/2/discussions/3/comments", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeTeamDiscussionsPreview)
 		testFormValues(t, r, values{
 			"direction": "desc",
 		})
@@ -112,7 +111,6 @@ func TestTeamsService_GetComment(t *testing.T) {
 
 	mux.HandleFunc("/teams/2/discussions/3/comments/4", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeTeamDiscussionsPreview)
 		fmt.Fprint(w, `{"number":4}`)
 	})
 
@@ -138,7 +136,6 @@ func TestTeamsService_CreateComment(t *testing.T) {
 		json.NewDecoder(r.Body).Decode(v)
 
 		testMethod(t, r, "POST")
-		testHeader(t, r, "Accept", mediaTypeTeamDiscussionsPreview)
 		if !reflect.DeepEqual(v, &input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
 		}
@@ -168,7 +165,6 @@ func TestTeamsService_EditComment(t *testing.T) {
 		json.NewDecoder(r.Body).Decode(v)
 
 		testMethod(t, r, "PATCH")
-		testHeader(t, r, "Accept", mediaTypeTeamDiscussionsPreview)
 		if !reflect.DeepEqual(v, &input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
 		}
@@ -193,7 +189,6 @@ func TestTeamsService_DeleteComment(t *testing.T) {
 
 	mux.HandleFunc("/teams/2/discussions/3/comments/4", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "DELETE")
-		testHeader(t, r, "Accept", mediaTypeTeamDiscussionsPreview)
 	})
 
 	_, err := client.Teams.DeleteComment(context.Background(), 2, 3, 4)
diff --git a/github/teams_discussions_test.go b/github/teams_discussions_test.go
index c588c228..65be1ce6 100644
--- a/github/teams_discussions_test.go
+++ b/github/teams_discussions_test.go
@@ -21,7 +21,6 @@ func TestTeamsService_ListDiscussions(t *testing.T) {
 
 	mux.HandleFunc("/teams/2/discussions", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeTeamDiscussionsPreview)
 		testFormValues(t, r, values{
 			"direction": "desc",
 		})
@@ -121,7 +120,6 @@ func TestTeamsService_GetDiscussion(t *testing.T) {
 
 	mux.HandleFunc("/teams/2/discussions/3", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeTeamDiscussionsPreview)
 		fmt.Fprint(w, `{"number":3}`)
 	})
 
@@ -147,7 +145,6 @@ func TestTeamsService_CreateDiscussion(t *testing.T) {
 		json.NewDecoder(r.Body).Decode(v)
 
 		testMethod(t, r, "POST")
-		testHeader(t, r, "Accept", mediaTypeTeamDiscussionsPreview)
 		if !reflect.DeepEqual(v, &input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
 		}
@@ -177,7 +174,6 @@ func TestTeamsService_EditDiscussion(t *testing.T) {
 		json.NewDecoder(r.Body).Decode(v)
 
 		testMethod(t, r, "PATCH")
-		testHeader(t, r, "Accept", mediaTypeTeamDiscussionsPreview)
 		if !reflect.DeepEqual(v, &input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
 		}
@@ -202,7 +198,6 @@ func TestTeamsService_DeleteDiscussion(t *testing.T) {
 
 	mux.HandleFunc("/teams/2/discussions/3", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "DELETE")
-		testHeader(t, r, "Accept", mediaTypeTeamDiscussionsPreview)
 	})
 
 	_, err := client.Teams.DeleteDiscussion(context.Background(), 2, 3)
diff --git a/github/teams_members_test.go b/github/teams_members_test.go
index 2489da0e..616a747b 100644
--- a/github/teams_members_test.go
+++ b/github/teams_members_test.go
@@ -20,7 +20,6 @@ func TestTeamsService__ListTeamMembers(t *testing.T) {
 
 	mux.HandleFunc("/teams/1/members", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview)
 		testFormValues(t, r, values{"role": "member", "page": "2"})
 		fmt.Fprint(w, `[{"id":1}]`)
 	})
@@ -107,7 +106,6 @@ func TestTeamsService__GetTeamMembership(t *testing.T) {
 
 	mux.HandleFunc("/teams/1/memberships/u", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview)
 		fmt.Fprint(w, `{"url":"u", "state":"active"}`)
 	})
 
diff --git a/github/teams_test.go b/github/teams_test.go
index 6210bb59..d65b7ffa 100644
--- a/github/teams_test.go
+++ b/github/teams_test.go
@@ -6,9 +6,11 @@
 package github
 
 import (
+	"bytes"
 	"context"
 	"encoding/json"
 	"fmt"
+	"io/ioutil"
 	"net/http"
 	"reflect"
 	"strings"
@@ -22,7 +24,6 @@ func TestTeamsService_ListTeams(t *testing.T) {
 
 	mux.HandleFunc("/orgs/o/teams", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview)
 		testFormValues(t, r, values{"page": "2"})
 		fmt.Fprint(w, `[{"id":1}]`)
 	})
@@ -53,7 +54,6 @@ func TestTeamsService_GetTeam(t *testing.T) {
 
 	mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview)
 		fmt.Fprint(w, `{"id":1, "name":"n", "description": "d", "url":"u", "slug": "s", "permission":"p", "ldap_dn":"cn=n,ou=groups,dc=example,dc=com", "parent":null}`)
 	})
 
@@ -74,7 +74,6 @@ func TestTeamsService_GetTeam_nestedTeams(t *testing.T) {
 
 	mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview)
 		fmt.Fprint(w, `{"id":1, "name":"n", "description": "d", "url":"u", "slug": "s", "permission":"p",
 		"parent": {"id":2, "name":"n", "description": "d", "parent": null}}`)
 	})
@@ -152,7 +151,6 @@ func TestTeamsService_CreateTeam(t *testing.T) {
 		json.NewDecoder(r.Body).Decode(v)
 
 		testMethod(t, r, "POST")
-		testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview)
 		if !reflect.DeepEqual(v, &input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
 		}
@@ -189,7 +187,6 @@ func TestTeamsService_EditTeam(t *testing.T) {
 		v := new(NewTeam)
 		json.NewDecoder(r.Body).Decode(v)
 
-		testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview)
 		testMethod(t, r, "PATCH")
 		if !reflect.DeepEqual(v, &input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
@@ -198,7 +195,7 @@ func TestTeamsService_EditTeam(t *testing.T) {
 		fmt.Fprint(w, `{"id":1}`)
 	})
 
-	team, _, err := client.Teams.EditTeam(context.Background(), 1, input)
+	team, _, err := client.Teams.EditTeam(context.Background(), 1, input, false)
 	if err != nil {
 		t.Errorf("Teams.EditTeam returned error: %v", err)
 	}
@@ -209,13 +206,51 @@ func TestTeamsService_EditTeam(t *testing.T) {
 	}
 }
 
+func TestTeamsService_EditTeam_RemoveParent(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	input := NewTeam{Name: "n", Privacy: String("closed")}
+	var body string
+
+	mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) {
+		v := new(NewTeam)
+		buf, err := ioutil.ReadAll(r.Body)
+		if err != nil {
+			t.Errorf("Unable to read body: %v", err)
+		}
+		body = string(buf)
+		json.NewDecoder(bytes.NewBuffer(buf)).Decode(v)
+
+		testMethod(t, r, "PATCH")
+		if !reflect.DeepEqual(v, &input) {
+			t.Errorf("Request body = %+v, want %+v", v, input)
+		}
+
+		fmt.Fprint(w, `{"id":1}`)
+	})
+
+	team, _, err := client.Teams.EditTeam(context.Background(), 1, input, true)
+	if err != nil {
+		t.Errorf("Teams.EditTeam returned error: %v", err)
+	}
+
+	want := &Team{ID: Int64(1)}
+	if !reflect.DeepEqual(team, want) {
+		t.Errorf("Teams.EditTeam returned %+v, want %+v", team, want)
+	}
+
+	if want := `{"name":"n","parent_team_id":null,"privacy":"closed"}` + "\n"; body != want {
+		t.Errorf("Teams.EditTeam body = %+v, want %+v", body, want)
+	}
+}
+
 func TestTeamsService_DeleteTeam(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
 	mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "DELETE")
-		testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview)
 	})
 
 	_, err := client.Teams.DeleteTeam(context.Background(), 1)
@@ -230,7 +265,6 @@ func TestTeamsService_ListChildTeams(t *testing.T) {
 
 	mux.HandleFunc("/teams/1/teams", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview)
 		testFormValues(t, r, values{"page": "2"})
 		fmt.Fprint(w, `[{"id":2}]`)
 	})
@@ -253,7 +287,7 @@ func TestTeamsService_ListTeamRepos(t *testing.T) {
 
 	mux.HandleFunc("/teams/1/repos", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		wantAcceptHeaders := []string{mediaTypeTopicsPreview, mediaTypeNestedTeamsPreview}
+		wantAcceptHeaders := []string{mediaTypeTopicsPreview}
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
 		testFormValues(t, r, values{"page": "2"})
 		fmt.Fprint(w, `[{"id":1}]`)
@@ -277,7 +311,7 @@ func TestTeamsService_IsTeamRepo_true(t *testing.T) {
 
 	mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		wantAcceptHeaders := []string{mediaTypeOrgPermissionRepo, mediaTypeNestedTeamsPreview}
+		wantAcceptHeaders := []string{mediaTypeOrgPermissionRepo}
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
 		fmt.Fprint(w, `{"id":1}`)
 	})
@@ -419,7 +453,6 @@ func TestTeamsService_ListUserTeams(t *testing.T) {
 
 	mux.HandleFunc("/user/teams", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeNestedTeamsPreview)
 		testFormValues(t, r, values{"page": "1"})
 		fmt.Fprint(w, `[{"id":1}]`)
 	})
@@ -517,7 +550,7 @@ func TestTeamsService_ListProjects(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	wantAcceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview}
+	wantAcceptHeaders := []string{mediaTypeProjectsPreview}
 	mux.HandleFunc("/teams/1/projects", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
@@ -539,7 +572,7 @@ func TestTeamsService_ReviewProjects(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	wantAcceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview}
+	wantAcceptHeaders := []string{mediaTypeProjectsPreview}
 	mux.HandleFunc("/teams/1/projects/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
@@ -565,7 +598,7 @@ func TestTeamsService_AddTeamProject(t *testing.T) {
 		Permission: String("admin"),
 	}
 
-	wantAcceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview}
+	wantAcceptHeaders := []string{mediaTypeProjectsPreview}
 	mux.HandleFunc("/teams/1/projects/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "PUT")
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
@@ -589,7 +622,7 @@ func TestTeamsService_RemoveTeamProject(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	wantAcceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview}
+	wantAcceptHeaders := []string{mediaTypeProjectsPreview}
 	mux.HandleFunc("/teams/1/projects/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "DELETE")
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
@@ -608,7 +641,6 @@ func TestTeamsService_ListIDPGroupsInOrganization(t *testing.T) {
 
 	mux.HandleFunc("/orgs/o/team-sync/groups", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeTeamSyncPreview)
 		testFormValues(t, r, values{
 			"page": "2",
 		})
@@ -641,7 +673,6 @@ func TestTeamsService_ListIDPGroupsForTeam(t *testing.T) {
 
 	mux.HandleFunc("/teams/1/team-sync/group-mappings", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeTeamSyncPreview)
 		fmt.Fprint(w, `{"groups": [{"group_id": "1",  "group_name": "n", "group_description": "d"}]}`)
 	})
 
@@ -670,7 +701,6 @@ func TestTeamsService_CreateOrUpdateIDPGroupConnections(t *testing.T) {
 
 	mux.HandleFunc("/teams/1/team-sync/group-mappings", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "PATCH")
-		testHeader(t, r, "Accept", mediaTypeTeamSyncPreview)
 		fmt.Fprint(w, `{"groups": [{"group_id": "1",  "group_name": "n", "group_description": "d"}]}`)
 	})
 
diff --git a/github/users_projects_test.go b/github/users_projects_test.go
new file mode 100644
index 00000000..b186fbf0
--- /dev/null
+++ b/github/users_projects_test.go
@@ -0,0 +1,68 @@
+// Copyright 2019 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"
+	"net/http"
+	"reflect"
+	"testing"
+)
+
+func TestUsersService_ListProjects(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/users/u/projects", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
+		testFormValues(t, r, values{"state": "open", "page": "2"})
+		fmt.Fprint(w, `[{"id":1}]`)
+	})
+
+	opt := &ProjectListOptions{State: "open", ListOptions: ListOptions{Page: 2}}
+	projects, _, err := client.Users.ListProjects(context.Background(), "u", opt)
+	if err != nil {
+		t.Errorf("Users.ListProjects returned error: %v", err)
+	}
+
+	want := []*Project{{ID: Int64(1)}}
+	if !reflect.DeepEqual(projects, want) {
+		t.Errorf("Users.ListProjects returned %+v, want %+v", projects, want)
+	}
+}
+
+func TestUsersService_CreateProject(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	input := &CreateUserProjectOptions{Name: "Project Name", Body: String("Project body.")}
+
+	mux.HandleFunc("/users/projects", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "POST")
+		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
+
+		v := &CreateUserProjectOptions{}
+		json.NewDecoder(r.Body).Decode(v)
+		if !reflect.DeepEqual(v, input) {
+			t.Errorf("Request body = %+v, want %+v", v, input)
+		}
+
+		fmt.Fprint(w, `{"id":1}`)
+	})
+
+	project, _, err := client.Users.CreateProject(context.Background(), input)
+	if err != nil {
+		t.Errorf("Users.CreateProject returned error: %v", err)
+	}
+
+	want := &Project{ID: Int64(1)}
+	if !reflect.DeepEqual(project, want) {
+		t.Errorf("Users.CreateProject returned %+v, want %+v", project, want)
+	}
+}
diff --git a/github/users_test.go b/github/users_test.go
index 8fa95a22..d1ce7e39 100644
--- a/github/users_test.go
+++ b/github/users_test.go
@@ -159,7 +159,6 @@ func TestUsersService_GetHovercard(t *testing.T) {
 
 	mux.HandleFunc("/users/u/hovercard", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeHovercardPreview)
 		testFormValues(t, r, values{"subject_type": "repository", "subject_id": "20180408"})
 		fmt.Fprint(w, `{"contexts": [{"message":"Owns this repository", "octicon": "repo"}]}`)
 	})
diff --git a/test/fields/fields.go b/test/fields/fields.go
index 6c7eac6b..59a2c647 100644
--- a/test/fields/fields.go
+++ b/test/fields/fields.go
@@ -25,7 +25,7 @@ import (
 	"reflect"
 	"strings"
 
-	"github.com/google/go-github/v28/github"
+	"github.com/google/go-github/v29/github"
 	"golang.org/x/oauth2"
 )
 
diff --git a/test/integration/activity_test.go b/test/integration/activity_test.go
index 0ec78056..15daf5d0 100644
--- a/test/integration/activity_test.go
+++ b/test/integration/activity_test.go
@@ -11,7 +11,7 @@ import (
 	"context"
 	"testing"
 
-	"github.com/google/go-github/v28/github"
+	"github.com/google/go-github/v29/github"
 )
 
 const (
diff --git a/test/integration/authorizations_test.go b/test/integration/authorizations_test.go
index f6f065d3..7eaeca39 100644
--- a/test/integration/authorizations_test.go
+++ b/test/integration/authorizations_test.go
@@ -16,7 +16,7 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/go-github/v28/github"
+	"github.com/google/go-github/v29/github"
 )
 
 const msgEnvMissing = "Skipping test because the required environment variable (%v) is not present."
diff --git a/test/integration/github_test.go b/test/integration/github_test.go
index e68a56c4..a9aace3f 100644
--- a/test/integration/github_test.go
+++ b/test/integration/github_test.go
@@ -14,7 +14,7 @@ import (
 	"net/http"
 	"os"
 
-	"github.com/google/go-github/v28/github"
+	"github.com/google/go-github/v29/github"
 	"golang.org/x/oauth2"
 )
 
diff --git a/test/integration/repos_test.go b/test/integration/repos_test.go
index c722fabd..e4a09bfb 100644
--- a/test/integration/repos_test.go
+++ b/test/integration/repos_test.go
@@ -13,7 +13,7 @@ import (
 	"reflect"
 	"testing"
 
-	"github.com/google/go-github/v28/github"
+	"github.com/google/go-github/v29/github"
 )
 
 func TestRepositories_CRUD(t *testing.T) {
diff --git a/test/integration/users_test.go b/test/integration/users_test.go
index 3d587b69..bb8c5e23 100644
--- a/test/integration/users_test.go
+++ b/test/integration/users_test.go
@@ -13,7 +13,7 @@ import (
 	"math/rand"
 	"testing"
 
-	"github.com/google/go-github/v28/github"
+	"github.com/google/go-github/v29/github"
 )
 
 func TestUsers_Get(t *testing.T) {