func ReuseTokenSource(t *Token, src TokenSource) TokenSource {
	if rt, ok := src.(*reuseTokenSource); ok {
		if t == nil {
			return rt
		}
		src = rt.new
	}
	return &reuseTokenSource{
		t:   t,
		new: src,
	}
}
ReuseTokenSource returns a TokenSource which repeatedly returns the
same token as long as it's valid, starting with t.
When its cached token is invalid, a new token is obtained from src.

ReuseTokenSource is typically used to reuse tokens from a cache
(such as a file on disk) between runs of a program, rather than
obtaining new tokens unnecessarily.

The initial token t may be nil, in which case the TokenSource is
wrapped in a caching version if it isn't one already. This also
means it's always safe to wrap ReuseTokenSource around any other
TokenSource without adverse effects.
package oauth2
import (
	"bytes"
	"errors"
	"net/http"
	"net/url"
	"strings"
	"sync"
	"golang.org/x/net/context"
	"golang.org/x/oauth2/internal"
)
var NoContext = context.TODO()
func RegisterBrokenAuthHeaderProvider(tokenURL string) {
	internal.RegisterBrokenAuthHeaderProvider(tokenURL)
}
type Config struct {
	ClientID string
	ClientSecret string
	Endpoint Endpoint
	RedirectURL string
	Scopes []string
}
type TokenSource interface {
	Token() (*Token, error)
}
type Endpoint struct {
	AuthURL  string
	TokenURL string
}
var (
	AccessTypeOnline  AuthCodeOption = SetAuthURLParam("access_type", "online")
	AccessTypeOffline AuthCodeOption = SetAuthURLParam("access_type", "offline")
	ApprovalForce AuthCodeOption = SetAuthURLParam("approval_prompt", "force")
)
type AuthCodeOption interface {
	setValue(url.Values)
}
type setParam struct{ k, v string }
func (p setParam) setValue(m url.Values) { m.Set(p.k, p.v) }
func SetAuthURLParam(key, value string) AuthCodeOption {
	return setParam{key, value}
}
func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string {
	var buf bytes.Buffer
	buf.WriteString(c.Endpoint.AuthURL)
	v := url.Values{
		"response_type": {"code"},
		"client_id":     {c.ClientID},
		"redirect_uri":  internal.CondVal(c.RedirectURL),
		"scope":         internal.CondVal(strings.Join(c.Scopes, " ")),
		"state":         internal.CondVal(state),
	}
	for _, opt := range opts {
		opt.setValue(v)
	}
	if strings.Contains(c.Endpoint.AuthURL, "?") {
		buf.WriteByte('&')
	} else {
		buf.WriteByte('?')
	}
	buf.WriteString(v.Encode())
	return buf.String()
}
func (c *Config) PasswordCredentialsToken(ctx context.Context, username, password string) (*Token, error) {
	return retrieveToken(ctx, c, url.Values{
		"grant_type": {"password"},
		"username":   {username},
		"password":   {password},
		"scope":      internal.CondVal(strings.Join(c.Scopes, " ")),
	})
}
func (c *Config) Exchange(ctx context.Context, code string) (*Token, error) {
	return retrieveToken(ctx, c, url.Values{
		"grant_type":   {"authorization_code"},
		"code":         {code},
		"redirect_uri": internal.CondVal(c.RedirectURL),
		"scope":        internal.CondVal(strings.Join(c.Scopes, " ")),
	})
}
func (c *Config) Client(ctx context.Context, t *Token) *http.Client {
	return NewClient(ctx, c.TokenSource(ctx, t))
}
func (c *Config) TokenSource(ctx context.Context, t *Token) TokenSource {
	tkr := &tokenRefresher{
		ctx:  ctx,
		conf: c,
	}
	if t != nil {
		tkr.refreshToken = t.RefreshToken
	}
	return &reuseTokenSource{
		t:   t,
		new: tkr,
	}
}
type tokenRefresher struct {
	ctx          context.Context  
	conf         *Config
	refreshToken string
}
func (tf *tokenRefresher) Token() (*Token, error) {
	if tf.refreshToken == "" {
		return nil, errors.New("oauth2: token expired and refresh token is not set")
	}
	tk, err := retrieveToken(tf.ctx, tf.conf, url.Values{
		"grant_type":    {"refresh_token"},
		"refresh_token": {tf.refreshToken},
	})
	if err != nil {
		return nil, err
	}
	if tf.refreshToken != tk.RefreshToken {
		tf.refreshToken = tk.RefreshToken
	}
	return tk, err
}
type reuseTokenSource struct {
	new TokenSource  
	mu sync.Mutex  
	t  *Token
}
func (s *reuseTokenSource) Token() (*Token, error) {
	s.mu.Lock()
	defer s.mu.Unlock()
	if s.t.Valid() {
		return s.t, nil
	}
	t, err := s.new.Token()
	if err != nil {
		return nil, err
	}
	s.t = t
	return t, nil
}
func StaticTokenSource(t *Token) TokenSource {
	return staticTokenSource{t}
}
type staticTokenSource struct {
	t *Token
}
func (s staticTokenSource) Token() (*Token, error) {
	return s.t, nil
}
var HTTPClient internal.ContextKey
func NewClient(ctx context.Context, src TokenSource) *http.Client {
	if src == nil {
		c, err := internal.ContextClient(ctx)
		if err != nil {
			return &http.Client{Transport: internal.ErrorTransport{Err: err}}
		}
		return c
	}
	return &http.Client{
		Transport: &Transport{
			Base:   internal.ContextTransport(ctx),
			Source: ReuseTokenSource(nil, src),
		},
	}
}