diff --git a/.circleci/config.yml b/.circleci/config.yml index c5f520b70..ddfd88844 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,26 +1,74 @@ -# Golang CircleCI 2.0 configuration file -# -# Check https://circleci.com/docs/2.0/language-go/ for more details version: 2 jobs: build: docker: - # specify the version - - image: circleci/golang:1.9 + - image: circleci/golang:1.11 - # Specify service dependencies here if necessary - # CircleCI maintains a library of pre-built images - # documented at https://circleci.com/docs/2.0/circleci-images/ - # - image: circleci/postgres:9.4 - - #### TEMPLATE_NOTE: go expects specific checkout path representing url - #### expecting it in the form of - #### /go/src/github.com/circleci/go-tool - #### /go/src/bitbucket.org/circleci/go-tool working_directory: /go/src/github.com/jesseduffield/lazygit steps: - checkout + - run: + name: Ensure go.mod file is up to date + command: | + export GO111MODULE=on + rm go.sum + mv go.mod /tmp/ + go mod init + export GO111MODULE=auto - # specify any bash command here prefixed with `run: ` - - run: go test -v ./... - - run: bash <(curl -s https://codecov.io/bash) + if [ $(diff /tmp/go.mod go.mod|wc -l) -gt 0 ]; then + diff /tmp/go.mod go.mod + exit 1; + fi + - run: + name: Run gofmt -s + command: | + if [ $(find . ! -path "./vendor/*" -name "*.go" -exec gofmt -s -d {} \;|wc -l) -gt 0 ]; then + find . ! -path "./vendor/*" -name "*.go" -exec gofmt -s -d {} \; + exit 1; + fi + - restore_cache: + keys: + - pkg-cache-{{ checksum "Gopkg.lock" }}-v2 + - run: + name: Run tests + command: | + ./test.sh + - run: + name: Compile project on every platform + command: | + go get github.com/mitchellh/gox + gox -parallel 10 -os "linux freebsd netbsd windows" -osarch "darwin/i386 darwin/amd64" + - run: + name: Push on codecov result + command: | + bash <(curl -s https://codecov.io/bash) + - save_cache: + key: pkg-cache-{{ checksum "Gopkg.lock" }}-v2 + paths: + - ~/.cache/go-build + + release: + docker: + - image: circleci/golang:1.10 + working_directory: /go/src/github.com/jesseduffield/lazygit + steps: + - checkout + - run: + name: Run gorelease + command: | + curl -sL https://git.io/goreleaser | bash + +workflows: + version: 2 + build: + jobs: + - build + release: + jobs: + - release: + filters: + tags: + only: /v[0-9]+(\.[0-9]+)*/ + branches: + ignore: /.*/ diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 1a96635a3..b10cb5f37 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -23,6 +23,7 @@ If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - OS: [e.g. Windows] - Lazygit Version [e.g. v0.1.45] + - The last commit id if you built project from sources (run : ```git-rev parse HEAD```) **Additional context** Add any other context about the problem here. diff --git a/.gitignore b/.gitignore index 3d59e16c5..e87f09a89 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,26 @@ -development.log -commands.log -extra/lgit.rb -notes/go.notes -TODO.notes -TODO.md +# Please do not add personal files + +# Logs +*.log + +# Hidden +.* + +# TODO +TODO.* + +# Notes +*.notes + +# Tests test/repos/repo +coverage.txt + +# Binaries +lazygit + +# Exceptions +!.gitignore +!.goreleaser.yml +!.circleci/ +!.github/ \ No newline at end of file diff --git a/.goreleaser.yml b/.goreleaser.yml index 6ae81e27d..c02fb0c67 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -13,8 +13,9 @@ builds: - arm - arm64 - 386 + # Default is `-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}`. ldflags: - - -s -w -X main.version={{.Version}} -X main.tag={{.Tag}} -X main.date={{.Date}} -X main.commit={{.Commit}} -X main.goos={{.Os}} -X main.arch={{.Arch}} -X main.arm={{.Arm}} + - -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.buildSource=binaryRelease archive: replacements: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 540eebb79..e59a42044 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,9 +15,10 @@ welcome your pull requests: 1. Fork the repo and create your branch from `master`. 2. If you've added code that should be tested, add tests. 3. If you've added code that need documentation, update the documentation. -4. Be sure to test your modifications. -5. Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). -6. Issue that pull request! +4. Make sure your code follows the [effective go](https://golang.org/doc/effective_go.html) guidelines as much as possible. +5. Be sure to test your modifications. +6. Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). +7. Issue that pull request! ## Code of conduct Please note by participating in this project, you agree to abide by the [code of conduct]. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..092e82a46 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +# run with: +# docker build -t lazygit . +# docker run -it lazygit:latest + +FROM golang:alpine + +RUN apk add -U git xdg-utils + +ADD . /go/src/github.com/jesseduffield/lazygit + +RUN go install github.com/jesseduffield/lazygit + +WORKDIR /go/src/github.com/jesseduffield/lazygit \ No newline at end of file diff --git a/Gopkg.lock b/Gopkg.lock index 662a9c28d..2bbaa2118 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -2,12 +2,52 @@ [[projects]] - digest = "1:b2339e83ce9b5c4f79405f949429a7f68a9a904fed903c672aac1e7ceb7f5f02" - name = "github.com/Sirupsen/logrus" - packages = ["."] + digest = "1:e24ea5dbc89fbab51635ee32e5be4f61a9267cae20788efcae4c07efb4abec99" + name = "github.com/aws/aws-sdk-go" + packages = [ + "aws", + "aws/awserr", + "aws/awsutil", + "aws/client", + "aws/client/metadata", + "aws/corehandlers", + "aws/credentials", + "aws/credentials/ec2rolecreds", + "aws/credentials/endpointcreds", + "aws/credentials/stscreds", + "aws/csm", + "aws/defaults", + "aws/ec2metadata", + "aws/endpoints", + "aws/request", + "aws/session", + "aws/signer/v4", + "internal/sdkio", + "internal/sdkrand", + "internal/sdkuri", + "internal/shareddefaults", + "private/protocol", + "private/protocol/eventstream", + "private/protocol/eventstream/eventstreamapi", + "private/protocol/query", + "private/protocol/query/queryutil", + "private/protocol/rest", + "private/protocol/restxml", + "private/protocol/xml/xmlutil", + "service/s3", + "service/sts", + ] pruneopts = "NUT" - revision = "3e01752db0189b9157070a0e1668a620f9a85da2" - version = "v1.0.6" + revision = "4324bc9d8865bdb3e6aa86ec7772ca1272d2750e" + version = "v1.15.21" + +[[projects]] + branch = "master" + digest = "1:37011b20a70e205b93ebea5287e1afa5618db54bf3998c36ff5a8e4b146a170a" + name = "github.com/bgentry/go-netrc" + packages = ["netrc"] + pruneopts = "NUT" + revision = "9fd32a8b3d3d3f9d43c341bfe098430e07609480" [[projects]] branch = "master" @@ -56,6 +96,14 @@ revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9" version = "v1.4.7" +[[projects]] + digest = "1:74d9b0a7b4107b41e0ade759fac64502876f82d29fb23d77b3dd24b194ee3dd5" + name = "github.com/go-ini/ini" + packages = ["."] + pruneopts = "NUT" + revision = "5cf292cae48347c2490ac1a58fe36735fb78df7e" + version = "v1.38.2" + [[projects]] branch = "master" digest = "1:4a8ed9b8cf22bd03bee5d74179fa06a282e4a73b6de949f7a865ff56cd2537e0" @@ -64,6 +112,38 @@ pruneopts = "NUT" revision = "604e922904d35e97f98a774db7881f049cd8d970" +[[projects]] + branch = "master" + digest = "1:a5d940c38bf56f121721bfa747c66356df387cb9d5318c570c6d4170aab62862" + name = "github.com/hashicorp/go-cleanhttp" + packages = ["."] + pruneopts = "NUT" + revision = "d5fe4b57a186c716b0e00b8c301cbd9b4182694d" + +[[projects]] + branch = "master" + digest = "1:b634d733abf079dc191d359e5a8d31479f1795d00e656f8a018a459571046266" + name = "github.com/hashicorp/go-getter" + packages = ["helper/url"] + pruneopts = "NUT" + revision = "4bda8fa99001c61db3cad96b421d4c12a81f256d" + +[[projects]] + branch = "master" + digest = "1:fbab03227343a0285fc74a68dd2ff46cda7edecbbe5a3e98d2cecd00cc67b217" + name = "github.com/hashicorp/go-safetemp" + packages = ["."] + pruneopts = "NUT" + revision = "b1a1dbde6fdc11e3ae79efd9039009e22d4ae240" + +[[projects]] + digest = "1:0b06ffe0c0764e413a6738e3f045d6bb14117359aef80a09f8c60fbff2ecad6b" + name = "github.com/hashicorp/go-version" + packages = ["."] + pruneopts = "NUT" + revision = "b5a281d3160aa11950a6182bd9a9dc2cb1e02d50" + version = "v1.0.0" + [[projects]] branch = "master" digest = "1:11c6c696067d3127ecf332b10f89394d386d9083f82baf71f40f2da31841a009" @@ -83,6 +163,14 @@ pruneopts = "NUT" revision = "ef8a98b0bbce4a65b5aa4c368430a80ddc533168" +[[projects]] + branch = "master" + digest = "1:d457d39e88f678ed14ac29517c3d74927a48dbc6a9f073fa241cf364a68cbe5c" + name = "github.com/heroku/rollrus" + packages = ["."] + pruneopts = "NUT" + revision = "fc0cef2ff331aebb24cd4e9ded7e20650f3d7006" + [[projects]] branch = "master" digest = "1:62fe3a7ea2050ecbd753a71889026f83d73329337ada66325cbafd5dea5f713d" @@ -93,11 +181,34 @@ [[projects]] branch = "master" - digest = "1:c9a848b0484a72da2dae28957b4f67501fe27fa38bc73f4713e454353c0a4a60" + digest = "1:490643e333b848f3d6ab772c21082d706663dcf4a3c0fbe9a4b4ef7b205ce6c7" + name = "github.com/jesseduffield/go-getter" + packages = ["."] + pruneopts = "NUT" + revision = "906e15686e6309ff310c1c10463ab53287c3a678" + +[[projects]] + branch = "master" + digest = "1:71e6c15797951d3fabaa944d70253e36a6cee96bf54ca0bc43ca3de3b4814bbb" name = "github.com/jesseduffield/gocui" packages = ["."] pruneopts = "NUT" - revision = "432b7f6215f81ef1aaa1b2d9b69887822923cf79" + revision = "2cb6e95bbbf850bb32cc1799e07d08ff0f144746" + +[[projects]] + digest = "1:ac6d01547ec4f7f673311b4663909269bfb8249952de3279799289467837c3cc" + name = "github.com/jmespath/go-jmespath" + packages = ["."] + pruneopts = "NUT" + revision = "0b12d6b5" + +[[projects]] + branch = "master" + digest = "1:263f9b0a0bcbfff9d5e7d9f2aa11f53995d98214fe0fb97e429e7a5f4534a0f9" + name = "github.com/kardianos/osext" + packages = ["."] + pruneopts = "NUT" + revision = "ae77be60afb1dcacde03767a8c37337fad28ac14" [[projects]] digest = "1:8021af4dcbd531ae89433c8c3a6520e51064114aaf8eb1724c3cf911c497c9ba" @@ -155,6 +266,14 @@ pruneopts = "NUT" revision = "58046073cbffe2f25d425fe1331102f55cf719de" +[[projects]] + branch = "master" + digest = "1:18b773b92ac82a451c1276bd2776c1e55ce057ee202691ab33c8d6690efcc048" + name = "github.com/mitchellh/go-testing-interface" + packages = ["."] + pruneopts = "NUT" + revision = "a61a99592b77c9ba629d254a693acffaeb4b7e28" + [[projects]] branch = "master" digest = "1:5fe20cfe4ef484c237cec9f947b2a6fa90bad4b8610fd014f0e4211e13d82d5d" @@ -199,6 +318,22 @@ revision = "c01d1270ff3e442a8a57cddc1c92dc1138598194" version = "v1.2.0" +[[projects]] + digest = "1:5cf3f025cbee5951a4ee961de067c8a89fc95a5adabead774f82822efabab121" + name = "github.com/pkg/errors" + packages = ["."] + pruneopts = "NUT" + revision = "645ef00459ed84a119197bfb8d8205042c6df63d" + version = "v0.8.0" + +[[projects]] + digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe" + name = "github.com/pmezard/go-difflib" + packages = ["difflib"] + pruneopts = "NUT" + revision = "792786c7400a136282c1664665ae0a8db921c6c2" + version = "v1.0.0" + [[projects]] digest = "1:d917313f309bda80d27274d53985bc65651f81a5b66b820749ac7f8ef061fd04" name = "github.com/sergi/go-diff" @@ -208,13 +343,20 @@ version = "v1.0.0" [[projects]] - branch = "master" digest = "1:41618aee8828e62dfe62d44f579c06892d0e98907d1c6d5bcd83bfe8536ec5a3" name = "github.com/shibukawa/configdir" packages = ["."] pruneopts = "NUT" revision = "e180dbdc8da04c4fa04272e875ce64949f38bd3e" +[[projects]] + digest = "1:b2339e83ce9b5c4f79405f949429a7f68a9a904fed903c672aac1e7ceb7f5f02" + name = "github.com/sirupsen/logrus" + packages = ["."] + pruneopts = "NUT" + revision = "3e01752db0189b9157070a0e1668a620f9a85da2" + version = "v1.0.6" + [[projects]] digest = "1:330e9062b308ac597e28485699c02223bd052437a6eed32a173c9227dcb9d95a" name = "github.com/spf13/afero" @@ -258,6 +400,14 @@ revision = "907c19d40d9a6c9bb55f040ff4ae45271a4754b9" version = "v1.1.0" +[[projects]] + branch = "master" + digest = "1:0e9a5ac14bcc11f205031a671b28c7e05cb88b2ebbe06f383c1ab0b2c12c7cb5" + name = "github.com/spkg/bom" + packages = ["."] + pruneopts = "NUT" + revision = "59b7046e48ad6bac800c5e1dd5142282cbfcf154" + [[projects]] digest = "1:ccca1dcd18bc54e23b517a3c5babeff2e3924a7d8fc1932162225876cfe4bfb0" name = "github.com/src-d/gcfg" @@ -271,6 +421,22 @@ revision = "f187355171c936ac84a82793659ebb4936bc1c23" version = "v1.3.0" +[[projects]] + digest = "1:bacb8b590716ab7c33f2277240972c9582d389593ee8d66fc10074e0508b8126" + name = "github.com/stretchr/testify" + packages = ["assert"] + pruneopts = "NUT" + revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686" + version = "v1.2.2" + +[[projects]] + branch = "master" + digest = "1:e42372d3f4921ec35df07f9b23239631e9d28580f7c1edcca212bc6daddc68fe" + name = "github.com/stvp/roll" + packages = ["."] + pruneopts = "NUT" + revision = "3627a5cbeaeaa68023abd02bb8687925265f2f63" + [[projects]] digest = "1:cd5ffc5bda4e0296ab3e4de90dbb415259c78e45e7fab13694b14cde8ab74541" name = "github.com/tcnksm/go-gitconfig" @@ -279,6 +445,19 @@ revision = "d154598bacbf4501c095a309753c5d4af66caa81" version = "v0.1.2" +[[projects]] + digest = "1:07e8742c479bab0066149ad02a710024154e76874fd0a2dba002d87702725825" + name = "github.com/ulikunitz/xz" + packages = [ + ".", + "internal/hash", + "internal/xlog", + "lzma", + ] + pruneopts = "NUT" + revision = "0c6b41e72360850ca4f98dc341fd999726ea007f" + version = "v0.5.4" + [[projects]] digest = "1:3148cb3478c26a92b4c1a18abb9428234b281e278af6267840721a24b6cbc6a3" name = "github.com/xanzy/ssh-agent" @@ -431,20 +610,25 @@ analyzer-name = "dep" analyzer-version = 1 input-imports = [ - "github.com/Sirupsen/logrus", "github.com/cloudfoundry/jibber_jabber", - "github.com/davecgh/go-spew/spew", "github.com/fatih/color", "github.com/golang-collections/collections/stack", + "github.com/heroku/rollrus", + "github.com/jesseduffield/go-getter", "github.com/jesseduffield/gocui", + "github.com/kardianos/osext", "github.com/mgutz/str", "github.com/nicksnyder/go-i18n/v2/i18n", "github.com/shibukawa/configdir", + "github.com/sirupsen/logrus", "github.com/spf13/viper", + "github.com/spkg/bom", + "github.com/stretchr/testify/assert", "github.com/tcnksm/go-gitconfig", "golang.org/x/text/language", "gopkg.in/src-d/go-git.v4", "gopkg.in/src-d/go-git.v4/plumbing", + "gopkg.in/yaml.v2", ] solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index a47fe5e93..1f0b03cee 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -40,3 +40,7 @@ [[constraint]] name = "gopkg.in/src-d/go-git.v4" revision = "43d17e14b714665ab5bc2ecc220b6740779d733f" + +[[constraint]] + branch = "master" + name = "github.com/spkg/bom" diff --git a/README.md b/README.md index 721dc0862..4f40e8f8e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# lazygit [![Go Report Card](https://goreportcard.com/badge/github.com/jesseduffield/lazygit)](https://goreportcard.com/report/github.com/jesseduffield/lazygit) +# lazygit [![CircleCI](https://circleci.com/gh/jesseduffield/lazygit.svg?style=svg)](https://circleci.com/gh/jesseduffield/lazygit) [![codecov](https://codecov.io/gh/jesseduffield/lazygit/branch/master/graph/badge.svg)](https://codecov.io/gh/jesseduffield/lazygit) [![Go Report Card](https://goreportcard.com/badge/github.com/jesseduffield/lazygit)](https://goreportcard.com/report/github.com/jesseduffield/lazygit) [![GolangCI](https://golangci.com/badges/github.com/jesseduffield/lazygit.svg)](https://golangci.com) [![GoDoc](https://godoc.org/github.com/jesseduffield/lazygit?status.svg)](http://godoc.org/github.com/jesseduffield/lazygit) [![GitHub tag](https://img.shields.io/github/tag/jesseduffield/lazygit.svg)]() A simple terminal UI for git commands, written in Go with the [gocui](https://github.com/jroimartin/gocui "gocui") library. @@ -7,7 +7,7 @@ too stubborn to use Sourcetree because you'll never forgive Atlassian for making Jira? This is the app for you! -![Gif](https://image.ibb.co/mmeXho/optimisedgif.gif) +![Gif](/docs/resources/lazygit-example.gif) * [Installation](https://github.com/jesseduffield/lazygit#installation) * [Usage](https://github.com/jesseduffield/lazygit#usage), @@ -90,7 +90,7 @@ whichever rc file you're using). * Basic video tutorial [here](https://www.youtube.com/watch?v=VDXvbHZYeKY). * List of keybindings -[here](https://github.com/jesseduffield/lazygit/blob/master/docs/Keybindings.md). +[here](/docs/Keybindings.md). ## Cool features * Adding files easily @@ -101,10 +101,10 @@ whichever rc file you're using). * Squash down and rename commits ### Resolving merge conflicts -![Gif](https://image.ibb.co/iyxUTT/shortermerging.gif) +![Gif](/docs/resources/resolving-merge-conflicts.gif) ### Viewing commit diffs -![Viewing Commit Diffs](https://image.ibb.co/gPD02o/capture.png) +![Viewing Commit Diffs](/docs/resources/viewing-commit-diffs.png) ## Milestones - [x] Easy Installation (homebrew, release binaries) @@ -119,7 +119,7 @@ whichever rc file you're using). We love your input! Please check out the [contributing guide](CONTRIBUTING.md). For contributor discussion about things not better discussed here in the repo, join the slack channel -[![Slack](/files/slack_rgb.png)](https://join.slack.com/t/lazygit/shared_invite/enQtNDE3MjIwNTYyMDA0LTM3Yjk3NzdiYzhhNTA1YjM4Y2M4MWNmNDBkOTI0YTE4YjQ1ZmI2YWRhZTgwNjg2YzhhYjg3NDBlMmQyMTI5N2M) +[![Slack](/docs/resources/slack_rgb.png)](https://join.slack.com/t/lazygit/shared_invite/enQtNDE3MjIwNTYyMDA0LTM3Yjk3NzdiYzhhNTA1YjM4Y2M4MWNmNDBkOTI0YTE4YjQ1ZmI2YWRhZTgwNjg2YzhhYjg3NDBlMmQyMTI5N2M) ## Work in progress This is still a work in progress so there's still bugs to iron out and as this @@ -131,3 +131,7 @@ feel free to [raise an issue](https://github.com/jesseduffield/lazygit/issues)/[ If you want to see what I (Jesse) am up to in terms of development, follow me on [twitter](https://twitter.com/DuffieldJesse) or watch me program on [twitch](https://www.twitch.tv/jesseduffield). + +## Alternatives +If you find that lazygit doesn't quite satisfy your requirements, these may be a better fit: +- [tig](https://github.com/jonas/tig) diff --git a/VERSION b/VERSION deleted file mode 100644 index 71b47abc8..000000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -v0.1.70 \ No newline at end of file diff --git a/docs/Config.md b/docs/Config.md index e6e2c3974..7f342df7f 100644 --- a/docs/Config.md +++ b/docs/Config.md @@ -14,10 +14,45 @@ - white optionsTextColor: - blue - git: - # stuff relating to git + commitLength: + show: true + update: + method: prompt # can be: prompt | background | never + days: 14 # how often an update is checked for + reporting: 'undetermined' # one of: 'on' | 'off' | 'undetermined' + confirmOnQuit: false +``` + +## Platform Defaults: + +### Windows: + +``` os: - # stuff relating to the OS + openCommand: 'cmd /c "start "" {{filename}}"' +``` + +### Linux: + +``` + os: + openCommand: 'sh -c "xdg-open {{filename}} >/dev/null"' +``` + +### OSX: + +``` + os: + openCommand: 'open {{filename}}' +``` + +### Recommended Config Values: + +for users of VSCode + +``` + os: + openCommand: 'code -r {{filename}}' ``` ## Color Attributes: @@ -37,3 +72,7 @@ The available attributes are: - bold - reverse # useful for high-contrast - underline + +## Example Coloring: + +![border example](/docs/resources/colored-border-example.png) diff --git a/docs/Keybindings.md b/docs/Keybindings.md index 2a1b1817f..2f10a297c 100644 --- a/docs/Keybindings.md +++ b/docs/Keybindings.md @@ -22,6 +22,7 @@
   space:    toggle staged
+  a:        stage/unstage all
   c:        commit changes
   shift+C: commit using git editor
   shift+S: stash files
@@ -33,6 +34,7 @@
   i:        add to .gitignore
   d:        delete if untracked checkout if tracked (aka go away)
   shift+R: refresh files
+  shift+A: abort merge
 
## Branches Panel: @@ -44,6 +46,7 @@ c: checkout by name n: new branch d: delete branch + D: force delete branch ## Commits Panel: @@ -51,6 +54,7 @@
   s:       squash down (only available for topmost commit)
   r:       rename commit
+  shift+R: rename commit using git editor
   g:       reset to this commit
 
diff --git a/docs/resources/colored-border-example.png b/docs/resources/colored-border-example.png new file mode 100644 index 000000000..06bb7bf8b Binary files /dev/null and b/docs/resources/colored-border-example.png differ diff --git a/docs/resources/lazygit-example.gif b/docs/resources/lazygit-example.gif new file mode 100644 index 000000000..c169f8470 Binary files /dev/null and b/docs/resources/lazygit-example.gif differ diff --git a/docs/resources/resolving-merge-conflicts.gif b/docs/resources/resolving-merge-conflicts.gif new file mode 100644 index 000000000..0b943fd49 Binary files /dev/null and b/docs/resources/resolving-merge-conflicts.gif differ diff --git a/files/slack_rgb.png b/docs/resources/slack_rgb.png similarity index 100% rename from files/slack_rgb.png rename to docs/resources/slack_rgb.png diff --git a/docs/resources/viewing-commit-diffs.png b/docs/resources/viewing-commit-diffs.png new file mode 100644 index 000000000..6bb5c42ed Binary files /dev/null and b/docs/resources/viewing-commit-diffs.png differ diff --git a/go.mod b/go.mod new file mode 100644 index 000000000..02db8a03e --- /dev/null +++ b/go.mod @@ -0,0 +1,62 @@ +module github.com/jesseduffield/lazygit + +require ( + github.com/aws/aws-sdk-go v1.15.21 + github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d + github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 + github.com/davecgh/go-spew v1.1.0 + github.com/emirpasic/gods v1.9.0 + github.com/fatih/color v1.7.0 + github.com/fsnotify/fsnotify v1.4.7 + github.com/go-ini/ini v1.38.2 + github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 + github.com/hashicorp/go-cleanhttp v0.0.0-20171218145408-d5fe4b57a186 + github.com/hashicorp/go-getter v0.0.0-20180809191950-4bda8fa99001 + github.com/hashicorp/go-safetemp v0.0.0-20180326211150-b1a1dbde6fdc + github.com/hashicorp/go-version v1.0.0 + github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce + github.com/heroku/rollrus v0.0.0-20180515183152-fc0cef2ff331 + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 + github.com/jesseduffield/go-getter v0.0.0-20180822080847-906e15686e63 + github.com/jesseduffield/gocui v0.0.0-20180905104005-2cb6e95bbbf8 + github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 + github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 + github.com/kevinburke/ssh_config v0.0.0-20180317175531-9fc7bb800b55 + github.com/magiconair/properties v1.8.0 + github.com/mattn/go-colorable v0.0.9 + github.com/mattn/go-isatty v0.0.3 + github.com/mattn/go-runewidth v0.0.2 + github.com/mgutz/str v1.2.0 + github.com/mitchellh/go-homedir v0.0.0-20180801233206-58046073cbff + github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 + github.com/mitchellh/mapstructure v0.0.0-20180715050151-f15292f7a699 + github.com/nicksnyder/go-i18n v0.0.0-20180803040939-a16b91a3ba80 + github.com/nsf/termbox-go v0.0.0-20180613055208-5c94acc5e6eb + github.com/pelletier/go-buffruneio v0.2.0 + github.com/pelletier/go-toml v1.2.0 + github.com/pkg/errors v0.8.0 + github.com/pmezard/go-difflib v1.0.0 + github.com/sergi/go-diff v1.0.0 + github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 + github.com/sirupsen/logrus v1.0.6 + github.com/spf13/afero v1.1.1 + github.com/spf13/cast v1.2.0 + github.com/spf13/jwalterweatherman v0.0.0-20180814060501-14d3d4c51834 + github.com/spf13/pflag v1.0.2 + github.com/spf13/viper v1.1.0 + github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad + github.com/src-d/gcfg v1.3.0 + github.com/stretchr/testify v1.2.2 + github.com/stvp/roll v0.0.0-20170522205222-3627a5cbeaea + github.com/tcnksm/go-gitconfig v0.1.2 + github.com/ulikunitz/xz v0.5.4 + github.com/xanzy/ssh-agent v0.2.0 + golang.org/x/crypto v0.0.0-20180808211826-de0752318171 + golang.org/x/net v0.0.0-20180811021610-c39426892332 + golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0 + golang.org/x/text v0.3.0 + gopkg.in/src-d/go-billy.v4 v4.2.0 + gopkg.in/src-d/go-git.v4 v4.0.0-20180807092216-43d17e14b714 + gopkg.in/warnings.v0 v0.1.2 + gopkg.in/yaml.v2 v2.2.1 +) diff --git a/go.sum b/go.sum new file mode 100644 index 000000000..e1d3249fa --- /dev/null +++ b/go.sum @@ -0,0 +1,163 @@ +github.com/BurntSushi/toml v0.3.0 h1:e1/Ivsx3Z0FVTV0NSOv/aVgbUWyQuzj7DDnFblkRvsY= +github.com/BurntSushi/toml v0.3.0/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= +github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/aws/aws-sdk-go v1.15.21 h1:STLvc6RrpycslC1NRtTvt/YSgDkIGCTrB9K9vE5R2oQ= +github.com/aws/aws-sdk-go v1.15.21/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= +github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 h1:tuijfIjZyjZaHq9xDUh0tNitwXshJpbLkqMOJv4H3do= +github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21/go.mod h1:po7NpZ/QiTKzBKyrsEAxwnTamCoh8uDk/egRpQ7siIc= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emirpasic/gods v1.9.0 h1:rUF4PuzEjMChMiNsVjdI+SyLu7rEqpQ5reNFnhC7oFo= +github.com/emirpasic/gods v1.9.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gliderlabs/ssh v0.1.1 h1:j3L6gSLQalDETeEg/Jg0mGY0/y/N6zI2xX1978P0Uqw= +github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-ini/ini v1.38.2 h1:6Hl/z3p3iFkA0dlDfzYxuFuUGD+kaweypF6btsR2/Q4= +github.com/go-ini/ini v1.38.2/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 h1:zN2lZNZRflqFyxVaTIU61KNKQ9C0055u9CAfpmqUvo4= +github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3/go.mod h1:nPpo7qLxd6XL3hWJG/O60sR8ZKfMCiIoNap5GvD12KU= +github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c h1:16eHWuMGvCjSfgRJKqIzapE78onvvTbdi1rMkU00lZw= +github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/hashicorp/go-cleanhttp v0.0.0-20171218145408-d5fe4b57a186 h1:URgjUo+bs1KwatoNbwG0uCO4dHN4r1jsp4a5AGgHRjo= +github.com/hashicorp/go-cleanhttp v0.0.0-20171218145408-d5fe4b57a186/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-getter v0.0.0-20180809191950-4bda8fa99001 h1:MFPzqpPED05pFyGjNPJEC2sXM6EHTzFyvX+0s0JoZ48= +github.com/hashicorp/go-getter v0.0.0-20180809191950-4bda8fa99001/go.mod h1:6rdJFnhkXnzGOJbvkrdv4t9nLwKcVA+tmbQeUlkIzrU= +github.com/hashicorp/go-safetemp v0.0.0-20180326211150-b1a1dbde6fdc h1:wAa9fGALVHfjYxZuXRnmuJG2CnwRpJYOTvY6YdErAh0= +github.com/hashicorp/go-safetemp v0.0.0-20180326211150-b1a1dbde6fdc/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= +github.com/hashicorp/go-version v1.0.0 h1:21MVWPKDphxa7ineQQTrCU5brh7OuVVAzGOCnnCPtE8= +github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce h1:xdsDDbiBDQTKASoGEZ+pEmF1OnWuu8AQ9I8iNbHNeno= +github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= +github.com/heroku/rollrus v0.0.0-20180515183152-fc0cef2ff331 h1:qio0y/sQdhbHRA3cmgczo04MaSV2zw+n46G1owvgWIk= +github.com/heroku/rollrus v0.0.0-20180515183152-fc0cef2ff331/go.mod h1:BT+PgT529opmb6mcUY+Fg0IwVRRmwqFyavEMU17GnBg= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jesseduffield/go-getter v0.0.0-20180822080847-906e15686e63 h1:Nrr/yUxNjXWYK0B3IqcFlYh1ICnesJDB4ogcfOVc5Ns= +github.com/jesseduffield/go-getter v0.0.0-20180822080847-906e15686e63/go.mod h1:fNqjRf+4XnTo2PrGN1JRb79b/BeoHwP4lU00f39SQY0= +github.com/jesseduffield/gocui v0.0.0-20180905104005-2cb6e95bbbf8 h1:YMYnpIu5HUJfx/yfIwnZhFrgWTg51FQWtvZi+PMzQm8= +github.com/jesseduffield/gocui v0.0.0-20180905104005-2cb6e95bbbf8/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Aowv3l/EQUlocDHW2Cp4G9WJVH7uyH8QFJE= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= +github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 h1:PJPDf8OUfOK1bb/NeTKd4f1QXZItOX389VN3B6qC8ro= +github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= +github.com/kevinburke/ssh_config v0.0.0-20180317175531-9fc7bb800b55 h1:S38dC4mEwxdw/U41+97VWdbun8mTcTjwg5Ujfg8QPME= +github.com/kevinburke/ssh_config v0.0.0-20180317175531-9fc7bb800b55/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-runewidth v0.0.2 h1:UnlwIPBGaTZfPQ6T1IGzPI0EkYAQmT9fAEJ/poFC63o= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mgutz/str v1.2.0 h1:4IzWSdIz9qPQWLfKZ0rJcV0jcUDpxvP4JVZ4GXQyvSw= +github.com/mgutz/str v1.2.0/go.mod h1:w1v0ofgLaJdoD0HpQ3fycxKD1WtxpjSo151pK/31q6w= +github.com/mitchellh/go-homedir v0.0.0-20180801233206-58046073cbff h1:jM4Eo4qMmmcqePS3u6X2lcEELtVuXWkWJIS/pRI3oSk= +github.com/mitchellh/go-homedir v0.0.0-20180801233206-58046073cbff/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 h1:7GoSOOW2jpsfkntVKaS2rAr1TJqfcxotyaUcuxoZSzg= +github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/mapstructure v0.0.0-20180715050151-f15292f7a699 h1:KXZJFdun9knAVAR8tg/aHJEr5DgtcbqyvzacK+CDCaI= +github.com/mitchellh/mapstructure v0.0.0-20180715050151-f15292f7a699/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/nicksnyder/go-i18n v0.0.0-20180803040939-a16b91a3ba80/go.mod h1:e4Di5xjP9oTVrC6y3C7C0HoSYXjSbhh/dU0eUV32nB4= +github.com/nicksnyder/go-i18n/v2 v2.0.0-beta.5 h1:/TjjTS4kg7vC+05gD0LE4+97f/+PRFICnK/7wJPk7kE= +github.com/nicksnyder/go-i18n/v2 v2.0.0-beta.5/go.mod h1:4Opqa6/HIv0lhG3WRAkqzO0afezkRhxXI0P8EJkqeRU= +github.com/nsf/termbox-go v0.0.0-20180613055208-5c94acc5e6eb h1:YahEjAGkJtCrkqgVHhX6n8ZX+CZ3hDRL9fjLYugLfSs= +github.com/nsf/termbox-go v0.0.0-20180613055208-5c94acc5e6eb/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ= +github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.1 h1:PZSj/UFNaVp3KxrzHOcS7oyuWA7LoOY/77yCTEFu21U= +github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWooScCR7aA= +github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 h1:Xuk8ma/ibJ1fOy4Ee11vHhUFHQNpHhrBneOCNHVXS5w= +github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0/go.mod h1:7AwjWCpdPhkSmNAgUv5C7EJ4AbmjEB3r047r3DXWu3Y= +github.com/sirupsen/logrus v1.0.6 h1:hcP1GmhGigz/O7h1WVUM5KklBp1JoNS9FggWKdj/j3s= +github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/smartystreets/assertions v0.0.0-20180820201707-7c9eb446e3cf h1:6V1qxN6Usn4jy8unvggSJz/NC790tefw8Zdy6OZS5co= +github.com/smartystreets/assertions v0.0.0-20180820201707-7c9eb446e3cf/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a h1:JSvGDIbmil4Ui/dDdFBExb7/cmkNjyX5F97oglmvCDo= +github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= +github.com/spf13/afero v1.1.1 h1:Lt3ihYMlE+lreX1GS4Qw4ZsNpYQLxIXKBTEOXm3nt6I= +github.com/spf13/afero v1.1.1/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.2.0 h1:HHl1DSRbEQN2i8tJmtS6ViPyHx35+p51amrdsiTCrkg= +github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= +github.com/spf13/jwalterweatherman v0.0.0-20180814060501-14d3d4c51834 h1:kJI9pPzfsULT/72wy7mxkRQZPtKWgFdCA2RTGZ4v8/E= +github.com/spf13/jwalterweatherman v0.0.0-20180814060501-14d3d4c51834/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.2 h1:Fy0orTDgHdbnzHcsOgfCN4LtHf0ec3wwtiwJqwvf3Gc= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.1.0 h1:V7OZpY8i3C1x/pDmU0zNNlfVoDz112fSYvtWMjjS3f4= +github.com/spf13/viper v1.1.0/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= +github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad h1:fiWzISvDn0Csy5H0iwgAuJGQTUpVfEMJJd4nRFXogbc= +github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= +github.com/src-d/gcfg v1.3.0 h1:2BEDr8r0I0b8h/fOqwtxCEiq2HJu8n2JGZJQFGXWLjg= +github.com/src-d/gcfg v1.3.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= +github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stvp/roll v0.0.0-20170522205222-3627a5cbeaea h1:jysxIKov/4GJ33wI2aRvuIK7yBwB28E5almlgDLPRpM= +github.com/stvp/roll v0.0.0-20170522205222-3627a5cbeaea/go.mod h1:Ffmqrj3nXIMIjeA4uW3Qjj0Ud9eDoTG0fu4JxyAr/tE= +github.com/tcnksm/go-gitconfig v0.1.2 h1:iiDhRitByXAEyjgBqsKi9QU4o2TNtv9kPP3RgPgXBPw= +github.com/tcnksm/go-gitconfig v0.1.2/go.mod h1:/8EhP4H7oJZdIPyT+/UIsG87kTzrzM4UsLGSItWYCpE= +github.com/ulikunitz/xz v0.5.4 h1:zATC2OoZ8H1TZll3FpbX+ikwmadbO699PE06cIkm9oU= +github.com/ulikunitz/xz v0.5.4/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= +github.com/xanzy/ssh-agent v0.2.0 h1:Adglfbi5p9Z0BmK2oKU9nTG+zKfniSfnaMYB+ULd+Ro= +github.com/xanzy/ssh-agent v0.2.0/go.mod h1:0NyE30eGUDliuLEHJgYte/zncp2zdTStcOnWhgSqHD8= +golang.org/x/crypto v0.0.0-20180808211826-de0752318171 h1:vYogbvSFj2YXcjQxFHu/rASSOt9sLytpCaSkiwQ135I= +golang.org/x/crypto v0.0.0-20180808211826-de0752318171/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180811021610-c39426892332 h1:efGso+ep0DjyCBJPjvoz0HI6UldX4Md2F1rZFe1ir0E= +golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0 h1:8H8QZJ30plJyIVj60H3lr8TZGIq2Fh3Cyrs/ZNg1foU= +golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.0.0-20171214130843-f21a4dfb5e38/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo= +gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 h1:OAj3g0cR6Dx/R07QgQe8wkA9RNjB2u4i700xBkIT4e0= +gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= +gopkg.in/ini.v1 v1.38.2 h1:dGcbywv4RufeGeiMycPT/plKB5FtmLKLnWKwBiLhUA4= +gopkg.in/ini.v1 v1.38.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/src-d/go-billy.v4 v4.2.0 h1:VGbrP1EsYxtvVPEiHui+4//imr4E5MGEFLx66bQtusg= +gopkg.in/src-d/go-billy.v4 v4.2.0/go.mod h1:ZHSF0JP+7oD97194otDUCD7Ofbk63+xFcfWP5bT6h+Q= +gopkg.in/src-d/go-git-fixtures.v3 v3.1.1 h1:XWW/s5W18RaJpmo1l0IYGqXKuJITWRFuA45iOf1dKJs= +gopkg.in/src-d/go-git-fixtures.v3 v3.1.1/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= +gopkg.in/src-d/go-git.v4 v4.0.0-20180807092216-43d17e14b714 h1:+wM2BGgQ1znCKBexOB4OrGVSDw8mtKNUSq3wqxZhi/k= +gopkg.in/src-d/go-git.v4 v4.0.0-20180807092216-43d17e14b714/go.mod h1:CzbUWqMn4pvmvndg3gnh5iZFmSsbhyhUWdI0IQ60AQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/main.go b/main.go index b8b9af931..890b69a7f 100644 --- a/main.go +++ b/main.go @@ -3,7 +3,6 @@ package main import ( "flag" "fmt" - "io/ioutil" "os" "path/filepath" "runtime" @@ -13,10 +12,12 @@ import ( ) var ( - commit string - version = "unversioned" - date string + commit string + version = "unversioned" + date string + buildSource = "unknown" + configFlag = flag.Bool("config", false, "Print the current default config") debuggingFlag = flag.Bool("debug", false, "a boolean") versionFlag = flag.Bool("v", false, "Print the current version") ) @@ -26,40 +27,27 @@ func projectPath(path string) string { return filepath.FromSlash(gopath + "/src/github.com/jesseduffield/lazygit/" + path) } -// when building the binary, `version` is set as a compile-time variable, along -// with `date` and `commit`. If this program has been opened directly via go, -// we will populate the `version` with VERSION in the lazygit root directory -func fallbackVersion() string { - path := projectPath("VERSION") - byteVersion, err := ioutil.ReadFile(path) - if err != nil { - return "unversioned" - } - return string(byteVersion) -} - func main() { flag.Parse() - if version == "unversioned" { - version = fallbackVersion() - } if *versionFlag { - fmt.Printf("commit=%s, build date=%s, version=%s, os=%s, arch=%s\n", commit, date, version, runtime.GOOS, runtime.GOARCH) + fmt.Printf("commit=%s, build date=%s, build source=%s, version=%s, os=%s, arch=%s\n", commit, date, buildSource, version, runtime.GOOS, runtime.GOARCH) os.Exit(0) } - appConfig, err := config.NewAppConfig("lazygit", version, commit, date, debuggingFlag) + + if *configFlag { + fmt.Printf("%s\n", config.GetDefaultConfig()) + os.Exit(0) + } + appConfig, err := config.NewAppConfig("lazygit", version, commit, date, buildSource, debuggingFlag) if err != nil { panic(err) } - app, err := app.NewApp(appConfig) + app, err := app.Setup(appConfig) if err != nil { - // TODO: remove this call to panic after anonymous error reporting - // is setup (right now the call to panic logs nothing to the screen which - // would make debugging difficult + app.Log.Error(err.Error()) panic(err) - // app.Log.Panic(err.Error()) } - app.GitCommand.SetupGit() + app.Gui.RunWithSubprocesses() } diff --git a/pkg/app/app.go b/pkg/app/app.go index aaa925e53..b03ec5b42 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -5,11 +5,13 @@ import ( "io/ioutil" "os" - "github.com/Sirupsen/logrus" + "github.com/heroku/rollrus" "github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/gui" "github.com/jesseduffield/lazygit/pkg/i18n" + "github.com/jesseduffield/lazygit/pkg/updates" + "github.com/sirupsen/logrus" ) // App struct @@ -17,19 +19,22 @@ type App struct { closers []io.Closer Config config.AppConfigurer - Log *logrus.Logger + Log *logrus.Entry OSCommand *commands.OSCommand GitCommand *commands.GitCommand Gui *gui.Gui Tr *i18n.Localizer + Updater *updates.Updater // may only need this on the Gui } -func newLogger(config config.AppConfigurer) *logrus.Logger { +func newProductionLogger(config config.AppConfigurer) *logrus.Logger { + log := logrus.New() + log.Out = ioutil.Discard + return log +} + +func newDevelopmentLogger() *logrus.Logger { log := logrus.New() - if !config.GetDebug() { - log.Out = ioutil.Discard - return log - } file, err := os.OpenFile("development.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if err != nil { panic("unable to log to file") // TODO: don't panic (also, remove this call to the `panic` function) @@ -38,29 +43,49 @@ func newLogger(config config.AppConfigurer) *logrus.Logger { return log } -// NewApp retruns a new applications -func NewApp(config config.AppConfigurer) (*App, error) { +func newLogger(config config.AppConfigurer) *logrus.Entry { + var log *logrus.Logger + environment := "production" + if config.GetDebug() { + environment = "development" + log = newDevelopmentLogger() + } else { + log = newProductionLogger(config) + } + if config.GetUserConfig().GetString("reporting") == "on" { + // this isn't really a secret token: it only has permission to push new rollbar items + hook := rollrus.NewHook("23432119147a4367abf7c0de2aa99a2d", environment) + log.Hooks.Add(hook) + } + return log.WithFields(logrus.Fields{ + "debug": config.GetDebug(), + "version": config.GetVersion(), + "commit": config.GetCommit(), + "buildDate": config.GetBuildDate(), + }) +} + +// Setup bootstrap a new application +func Setup(config config.AppConfigurer) (*App, error) { app := &App{ closers: []io.Closer{}, Config: config, } var err error app.Log = newLogger(config) - app.OSCommand, err = commands.NewOSCommand(app.Log) - if err != nil { - return app, err - } + app.OSCommand = commands.NewOSCommand(app.Log, config) - app.Tr, err = i18n.NewLocalizer(app.Log) - if err != nil { - return app, err - } + app.Tr = i18n.NewLocalizer(app.Log) - app.GitCommand, err = commands.NewGitCommand(app.Log, app.OSCommand) + app.GitCommand, err = commands.NewGitCommand(app.Log, app.OSCommand, app.Tr) if err != nil { return app, err } - app.Gui, err = gui.NewGui(app.Log, app.GitCommand, app.OSCommand, app.Tr, config) + app.Updater, err = updates.NewUpdater(app.Log, config, app.OSCommand, app.Tr) + if err != nil { + return app, err + } + app.Gui, err = gui.NewGui(app.Log, app.GitCommand, app.OSCommand, app.Tr, config, app.Updater) if err != nil { return app, err } diff --git a/pkg/commands/git.go b/pkg/commands/git.go index 94c3c3e1c..f7a80dc63 100644 --- a/pkg/commands/git.go +++ b/pkg/commands/git.go @@ -7,41 +7,103 @@ import ( "os/exec" "strings" - "github.com/Sirupsen/logrus" "github.com/jesseduffield/gocui" + "github.com/jesseduffield/lazygit/pkg/i18n" "github.com/jesseduffield/lazygit/pkg/utils" + "github.com/sirupsen/logrus" gitconfig "github.com/tcnksm/go-gitconfig" gogit "gopkg.in/src-d/go-git.v4" ) +func verifyInGitRepo(runCmd func(string) error) error { + return runCmd("git status") +} + +func navigateToRepoRootDirectory(stat func(string) (os.FileInfo, error), chdir func(string) error) error { + for { + f, err := stat(".git") + + if err == nil && f.IsDir() { + return nil + } + + if !os.IsNotExist(err) { + return err + } + + if err = chdir(".."); err != nil { + return err + } + } +} + +func setupRepositoryAndWorktree(openGitRepository func(string) (*gogit.Repository, error), sLocalize func(string) string) (repository *gogit.Repository, worktree *gogit.Worktree, err error) { + repository, err = openGitRepository(".") + + if err != nil { + if strings.Contains(err.Error(), `unquoted '\' must be followed by new line`) { + return nil, nil, errors.New(sLocalize("GitconfigParseErr")) + } + + return + } + + worktree, err = repository.Worktree() + + if err != nil { + return + } + + return +} + // GitCommand is our main git interface type GitCommand struct { - Log *logrus.Logger + Log *logrus.Entry OSCommand *OSCommand Worktree *gogit.Worktree Repo *gogit.Repository + Tr *i18n.Localizer } // NewGitCommand it runs git commands -func NewGitCommand(log *logrus.Logger, osCommand *OSCommand) (*GitCommand, error) { - gitCommand := &GitCommand{ +func NewGitCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Localizer) (*GitCommand, error) { + var worktree *gogit.Worktree + var repo *gogit.Repository + + fs := []func() error{ + func() error { + return verifyInGitRepo(osCommand.RunCommand) + }, + func() error { + return navigateToRepoRootDirectory(os.Stat, os.Chdir) + }, + func() error { + var err error + repo, worktree, err = setupRepositoryAndWorktree(gogit.PlainOpen, tr.SLocalize) + return err + }, + } + + for _, f := range fs { + if err := f(); err != nil { + return nil, err + } + } + + return &GitCommand{ Log: log, OSCommand: osCommand, - } - return gitCommand, nil -} - -// SetupGit sets git repo up -func (c *GitCommand) SetupGit() { - c.verifyInGitRepo() - c.navigateToRepoRootDirectory() - c.setupWorktree() + Tr: tr, + Worktree: worktree, + Repo: repo, + }, nil } // GetStashEntries stash entryies func (c *GitCommand) GetStashEntries() []StashEntry { - stashEntries := make([]StashEntry, 0) rawString, _ := c.OSCommand.RunCommandWithOutput("git stash list --pretty='%gs'") + stashEntries := []StashEntry{} for i, line := range utils.SplitLines(rawString) { stashEntries = append(stashEntries, stashEntryFromLine(line, i)) } @@ -61,35 +123,29 @@ func (c *GitCommand) GetStashEntryDiff(index int) (string, error) { return c.OSCommand.RunCommandWithOutput("git stash show -p --color stash@{" + fmt.Sprint(index) + "}") } -func includes(array []string, str string) bool { - for _, arrayStr := range array { - if arrayStr == str { - return true - } - } - return false -} - // GetStatusFiles git status files func (c *GitCommand) GetStatusFiles() []File { statusOutput, _ := c.GitStatus() statusStrings := utils.SplitLines(statusOutput) - files := make([]File, 0) + files := []File{} for _, statusString := range statusStrings { change := statusString[0:2] stagedChange := change[0:1] unstagedChange := statusString[1:2] - filename := statusString[3:] - tracked := !includes([]string{"??", "A ", "AM"}, change) + filename := c.OSCommand.Unquote(statusString[3:]) + _, untracked := map[string]bool{"??": true, "A ": true, "AM": true}[change] + _, hasNoStagedChanges := map[string]bool{" ": true, "U": true, "?": true}[stagedChange] + file := File{ Name: filename, DisplayString: statusString, - HasStagedChanges: !includes([]string{" ", "U", "?"}, stagedChange), + HasStagedChanges: !hasNoStagedChanges, HasUnstagedChanges: unstagedChange != " ", - Tracked: tracked, + Tracked: !untracked, Deleted: unstagedChange == "D" || stagedChange == "D", HasMergeConflicts: change == "UU", + Type: c.OSCommand.FileType(filename), } files = append(files, file) } @@ -99,13 +155,13 @@ func (c *GitCommand) GetStatusFiles() []File { // StashDo modify stash func (c *GitCommand) StashDo(index int, method string) error { - return c.OSCommand.RunCommand("git stash " + method + " stash@{" + fmt.Sprint(index) + "}") + return c.OSCommand.RunCommand(fmt.Sprintf("git stash %s stash@{%d}", method, index)) } // StashSave save stash // TODO: before calling this, check if there is anything to save func (c *GitCommand) StashSave(message string) error { - return c.OSCommand.RunCommand("git stash save " + c.OSCommand.Quote(message)) + return c.OSCommand.RunCommand(fmt.Sprintf("git stash save %s", c.OSCommand.Quote(message))) } // MergeStatusFiles merge status files @@ -114,35 +170,28 @@ func (c *GitCommand) MergeStatusFiles(oldFiles, newFiles []File) []File { return newFiles } - appendedIndexes := make([]int, 0) + headResults := []File{} + tailResults := []File{} - // retain position of files we already could see - result := make([]File, 0) - for _, oldFile := range oldFiles { - for newIndex, newFile := range newFiles { + for _, newFile := range newFiles { + var isHeadResult bool + + for _, oldFile := range oldFiles { if oldFile.Name == newFile.Name { - result = append(result, newFile) - appendedIndexes = append(appendedIndexes, newIndex) + isHeadResult = true break } } - } - // append any new files to the end - for index, newFile := range newFiles { - if !includesInt(appendedIndexes, index) { - result = append(result, newFile) + if isHeadResult { + headResults = append(headResults, newFile) + continue } + + tailResults = append(tailResults, newFile) } - return result -} - -func (c *GitCommand) verifyInGitRepo() { - if output, err := c.OSCommand.RunCommandWithOutput("git status"); err != nil { - fmt.Println(output) - os.Exit(1) - } + return append(headResults, tailResults...) } // GetBranchName branch name @@ -150,29 +199,6 @@ func (c *GitCommand) GetBranchName() (string, error) { return c.OSCommand.RunCommandWithOutput("git symbolic-ref --short HEAD") } -func (c *GitCommand) navigateToRepoRootDirectory() { - _, err := os.Stat(".git") - for os.IsNotExist(err) { - c.Log.Debug("going up a directory to find the root") - os.Chdir("..") - _, err = os.Stat(".git") - } -} - -func (c *GitCommand) setupWorktree() { - r, err := gogit.PlainOpen(".") - if err != nil { - panic(err) - } - c.Repo = r - - w, err := r.Worktree() - if err != nil { - panic(err) - } - c.Worktree = w -} - // ResetHard does the equivalent of `git reset --hard HEAD` func (c *GitCommand) ResetHard() error { return c.Worktree.Reset(&gogit.ResetOptions{Mode: gogit.HardReset}) @@ -197,14 +223,14 @@ func (c *GitCommand) UpstreamDifferenceCount() (string, string) { func (c *GitCommand) GetCommitsToPush() []string { pushables, err := c.OSCommand.RunCommandWithOutput("git rev-list @{u}..head --abbrev-commit") if err != nil { - return make([]string, 0) + return []string{} } return utils.SplitLines(pushables) } // RenameCommit renames the topmost commit with the given name func (c *GitCommand) RenameCommit(name string) error { - return c.OSCommand.RunCommand("git commit --allow-empty --amend -m " + c.OSCommand.Quote(name)) + return c.OSCommand.RunCommand(fmt.Sprintf("git commit --allow-empty --amend -m %s", c.OSCommand.Quote(name))) } // Fetch fetch git repo @@ -214,17 +240,23 @@ func (c *GitCommand) Fetch() error { // ResetToCommit reset to commit func (c *GitCommand) ResetToCommit(sha string) error { - return c.OSCommand.RunCommand("git reset " + sha) + return c.OSCommand.RunCommand(fmt.Sprintf("git reset %s", sha)) } // NewBranch create new branch func (c *GitCommand) NewBranch(name string) error { - return c.OSCommand.RunCommand("git checkout -b " + name) + return c.OSCommand.RunCommand(fmt.Sprintf("git checkout -b %s", name)) } // DeleteBranch delete branch -func (c *GitCommand) DeleteBranch(branch string) error { - return c.OSCommand.RunCommand("git branch -d " + branch) +func (c *GitCommand) DeleteBranch(branch string, force bool) error { + command := "git branch -d" + + if force { + command = "git branch -D" + } + + return c.OSCommand.RunCommand(fmt.Sprintf("%s %s", command, branch)) } // ListStash list stash @@ -234,7 +266,7 @@ func (c *GitCommand) ListStash() (string, error) { // Merge merge func (c *GitCommand) Merge(branchName string) error { - return c.OSCommand.RunCommand("git merge --no-edit " + branchName) + return c.OSCommand.RunCommand(fmt.Sprintf("git merge --no-edit %s", branchName)) } // AbortMerge abort merge @@ -259,7 +291,7 @@ func (c *GitCommand) UsingGpg() bool { func (c *GitCommand) Commit(g *gocui.Gui, message string) (*exec.Cmd, error) { command := "git commit -m " + c.OSCommand.Quote(message) if c.UsingGpg() { - return c.OSCommand.PrepareSubProcess(c.OSCommand.Platform.shell, c.OSCommand.Platform.shellArg, command) + return c.OSCommand.PrepareSubProcess(c.OSCommand.Platform.shell, c.OSCommand.Platform.shellArg, command), nil } return nil, c.OSCommand.RunCommand(command) } @@ -270,8 +302,12 @@ func (c *GitCommand) Pull() error { } // Push push to a branch -func (c *GitCommand) Push(branchName string) error { - return c.OSCommand.RunCommand("git push -u origin " + branchName) +func (c *GitCommand) Push(branchName string, force bool) error { + forceFlag := "" + if force { + forceFlag = "--force-with-lease " + } + return c.OSCommand.RunCommand("git push " + forceFlag + "-u origin " + branchName) } // SquashPreviousTwoCommits squashes a commit down to the one below it @@ -321,24 +357,34 @@ func (c *GitCommand) SquashFixupCommit(branchName string, shaValue string) error } // CatFile obtain the contents of a file -func (c *GitCommand) CatFile(file string) (string, error) { - return c.OSCommand.RunCommandWithOutput("cat " + file) +func (c *GitCommand) CatFile(fileName string) (string, error) { + return c.OSCommand.RunCommandWithOutput("cat " + c.OSCommand.Quote(fileName)) } // StageFile stages a file -func (c *GitCommand) StageFile(file string) error { - return c.OSCommand.RunCommand("git add " + c.OSCommand.Quote(file)) +func (c *GitCommand) StageFile(fileName string) error { + return c.OSCommand.RunCommand("git add " + c.OSCommand.Quote(fileName)) +} + +// StageAll stages all files +func (c *GitCommand) StageAll() error { + return c.OSCommand.RunCommand("git add -A") +} + +// UnstageAll stages all files +func (c *GitCommand) UnstageAll() error { + return c.OSCommand.RunCommand("git reset") } // UnStageFile unstages a file -func (c *GitCommand) UnStageFile(file string, tracked bool) error { +func (c *GitCommand) UnStageFile(fileName string, tracked bool) error { var command string if tracked { command = "git reset HEAD " } else { command = "git rm --cached " } - return c.OSCommand.RunCommand(command + file) + return c.OSCommand.RunCommand(command + c.OSCommand.Quote(fileName)) } // GitStatus returns the plaintext short status of the repo @@ -364,7 +410,7 @@ func (c *GitCommand) RemoveFile(file File) error { } } if !file.Tracked { - return os.RemoveAll(c.OSCommand.Unquote(file.Name)) + return os.RemoveAll(file.Name) } // if the file is tracked, we assume you want to just check it out return c.OSCommand.RunCommand("git checkout -- " + file.Name) @@ -381,15 +427,20 @@ func (c *GitCommand) Checkout(branch string, force bool) error { // AddPatch prepares a subprocess for adding a patch by patch // this will eventually be swapped out for a better solution inside the Gui -func (c *GitCommand) AddPatch(filename string) (*exec.Cmd, error) { +func (c *GitCommand) AddPatch(filename string) *exec.Cmd { return c.OSCommand.PrepareSubProcess("git", "add", "--patch", filename) } // PrepareCommitSubProcess prepares a subprocess for `git commit` -func (c *GitCommand) PrepareCommitSubProcess() (*exec.Cmd, error) { +func (c *GitCommand) PrepareCommitSubProcess() *exec.Cmd { return c.OSCommand.PrepareSubProcess("git", "commit") } +// PrepareCommitAmendSubProcess prepares a subprocess for `git commit --amend --allow-empty` +func (c *GitCommand) PrepareCommitAmendSubProcess() *exec.Cmd { + return c.OSCommand.PrepareSubProcess("git", "commit", "--amend", "--allow-empty") +} + // GetBranchGraph gets the color-formatted graph of the log for the given branch // Currently it limits the result to 100 commits, but when we get async stuff // working we can do lazy loading @@ -397,15 +448,6 @@ func (c *GitCommand) GetBranchGraph(branchName string) (string, error) { return c.OSCommand.RunCommandWithOutput("git log --graph --color --abbrev-commit --decorate --date=relative --pretty=medium -100 " + branchName) } -// Map (from https://gobyexample.com/collection-functions) -func Map(vs []string, f func(string) string) []string { - vsm := make([]string, len(vs)) - for i, v := range vs { - vsm[i] = f(v) - } - return vsm -} - func includesString(list []string, a string) bool { for _, b := range list { if b == a { @@ -415,22 +457,11 @@ func includesString(list []string, a string) bool { return false } -// not sure how to genericise this because []interface{} doesn't accept e.g. -// []int arguments -func includesInt(list []int, a int) bool { - for _, b := range list { - if b == a { - return true - } - } - return false -} - // GetCommits obtains the commits of the current branch func (c *GitCommand) GetCommits() []Commit { pushables := c.GetCommitsToPush() log := c.GetLog() - commits := make([]Commit, 0) + commits := []Commit{} // now we can split it up and turn it into commits lines := utils.SplitLines(log) for _, line := range lines { @@ -461,10 +492,8 @@ func (c *GitCommand) GetLog() string { } // Ignore adds a file to the gitignore for the repo -func (c *GitCommand) Ignore(filename string) { - if _, err := c.OSCommand.RunDirectCommand("echo '" + filename + "' >> .gitignore"); err != nil { - panic(err) - } +func (c *GitCommand) Ignore(filename string) error { + return c.OSCommand.AppendLineToFile(".gitignore", filename) } // Show shows the diff of a commit @@ -479,22 +508,15 @@ func (c *GitCommand) Show(sha string) string { // Diff returns the diff of a file func (c *GitCommand) Diff(file File) string { cachedArg := "" - fileName := file.Name + fileName := c.OSCommand.Quote(file.Name) if file.HasStagedChanges && !file.HasUnstagedChanges { cachedArg = "--cached" - } else { - // if the file is staged and has spaces in it, it comes pre-quoted - fileName = c.OSCommand.Quote(fileName) } - deletedArg := "" - if file.Deleted { - deletedArg = "--" - } - trackedArg := "" + trackedArg := "--" if !file.Tracked && !file.HasStagedChanges { trackedArg = "--no-index /dev/null" } - command := fmt.Sprintf("%s %s %s %s %s", "git diff --color ", cachedArg, deletedArg, trackedArg, fileName) + command := fmt.Sprintf("%s %s %s %s", "git diff --color ", cachedArg, trackedArg, fileName) // for now we assume an error means the file was deleted s, _ := c.OSCommand.RunCommandWithOutput(command) diff --git a/pkg/commands/git_structs.go b/pkg/commands/git_structs.go index 6b10b18bb..2b3b3f2db 100644 --- a/pkg/commands/git_structs.go +++ b/pkg/commands/git_structs.go @@ -1,7 +1,6 @@ package commands // File : A staged/unstaged file -// TODO: decide whether to give all of these the Git prefix type File struct { Name string HasStagedChanges bool @@ -10,6 +9,7 @@ type File struct { Deleted bool HasMergeConflicts bool DisplayString string + Type string // one of 'file', 'directory', and 'other' } // Commit : A git commit diff --git a/pkg/commands/git_test.go b/pkg/commands/git_test.go new file mode 100644 index 000000000..7bc7a8910 --- /dev/null +++ b/pkg/commands/git_test.go @@ -0,0 +1,826 @@ +package commands + +import ( + "fmt" + "io/ioutil" + "os" + "os/exec" + "testing" + "time" + + "github.com/jesseduffield/lazygit/pkg/i18n" + "github.com/jesseduffield/lazygit/pkg/test" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + gogit "gopkg.in/src-d/go-git.v4" +) + +type fileInfoMock struct { + name string + size int64 + fileMode os.FileMode + fileModTime time.Time + isDir bool + sys interface{} +} + +func (f fileInfoMock) Name() string { + return f.name +} + +func (f fileInfoMock) Size() int64 { + return f.size +} + +func (f fileInfoMock) Mode() os.FileMode { + return f.fileMode +} + +func (f fileInfoMock) ModTime() time.Time { + return f.fileModTime +} + +func (f fileInfoMock) IsDir() bool { + return f.isDir +} + +func (f fileInfoMock) Sys() interface{} { + return f.sys +} + +func newDummyLog() *logrus.Entry { + log := logrus.New() + log.Out = ioutil.Discard + return log.WithField("test", "test") +} + +func newDummyGitCommand() *GitCommand { + return &GitCommand{ + Log: newDummyLog(), + OSCommand: newDummyOSCommand(), + Tr: i18n.NewLocalizer(newDummyLog()), + } +} + +func TestVerifyInGitRepo(t *testing.T) { + type scenario struct { + testName string + runCmd func(string) error + test func(error) + } + + scenarios := []scenario{ + { + "Valid git repository", + func(string) error { + return nil + }, + func(err error) { + assert.NoError(t, err) + }, + }, + { + "Not a valid git repository", + func(string) error { + return fmt.Errorf("fatal: Not a git repository (or any of the parent directories): .git") + }, + func(err error) { + assert.Error(t, err) + assert.Regexp(t, "fatal: .ot a git repository \\(or any of the parent directories\\): \\.git", err.Error()) + }, + }, + } + + for _, s := range scenarios { + t.Run(s.testName, func(t *testing.T) { + s.test(verifyInGitRepo(s.runCmd)) + }) + } +} + +func TestNavigateToRepoRootDirectory(t *testing.T) { + type scenario struct { + testName string + stat func(string) (os.FileInfo, error) + chdir func(string) error + test func(error) + } + + scenarios := []scenario{ + { + "Navigate to git repository", + func(string) (os.FileInfo, error) { + return fileInfoMock{isDir: true}, nil + }, + func(string) error { + return nil + }, + func(err error) { + assert.NoError(t, err) + }, + }, + { + "An error occurred when getting path informations", + func(string) (os.FileInfo, error) { + return nil, fmt.Errorf("An error occurred") + }, + func(string) error { + return nil + }, + func(err error) { + assert.Error(t, err) + assert.EqualError(t, err, "An error occurred") + }, + }, + { + "An error occurred when trying to move one path backward", + func(string) (os.FileInfo, error) { + return nil, os.ErrNotExist + }, + func(string) error { + return fmt.Errorf("An error occurred") + }, + func(err error) { + assert.Error(t, err) + assert.EqualError(t, err, "An error occurred") + }, + }, + } + + for _, s := range scenarios { + t.Run(s.testName, func(t *testing.T) { + s.test(navigateToRepoRootDirectory(s.stat, s.chdir)) + }) + } +} + +func TestSetupRepositoryAndWorktree(t *testing.T) { + type scenario struct { + testName string + openGitRepository func(string) (*gogit.Repository, error) + sLocalize func(string) string + test func(*gogit.Repository, *gogit.Worktree, error) + } + + scenarios := []scenario{ + { + "A gitconfig parsing error occurred", + func(string) (*gogit.Repository, error) { + return nil, fmt.Errorf(`unquoted '\' must be followed by new line`) + }, + func(string) string { + return "error translated" + }, + func(r *gogit.Repository, w *gogit.Worktree, err error) { + assert.Error(t, err) + assert.EqualError(t, err, "error translated") + }, + }, + { + "A gogit error occurred", + func(string) (*gogit.Repository, error) { + return nil, fmt.Errorf("Error from inside gogit") + }, + func(string) string { return "" }, + func(r *gogit.Repository, w *gogit.Worktree, err error) { + assert.Error(t, err) + assert.EqualError(t, err, "Error from inside gogit") + }, + }, + { + "An error occurred cause git repository is a bare repository", + func(string) (*gogit.Repository, error) { + return &gogit.Repository{}, nil + }, + func(string) string { return "" }, + func(r *gogit.Repository, w *gogit.Worktree, err error) { + assert.Error(t, err) + assert.Equal(t, gogit.ErrIsBareRepository, err) + }, + }, + { + "Setup done properly", + func(string) (*gogit.Repository, error) { + assert.NoError(t, os.RemoveAll("/tmp/lazygit-test")) + r, err := gogit.PlainInit("/tmp/lazygit-test", false) + assert.NoError(t, err) + return r, nil + }, + func(string) string { return "" }, + func(r *gogit.Repository, w *gogit.Worktree, err error) { + assert.NoError(t, err) + assert.NotNil(t, w) + assert.NotNil(t, r) + }, + }, + } + + for _, s := range scenarios { + t.Run(s.testName, func(t *testing.T) { + s.test(setupRepositoryAndWorktree(s.openGitRepository, s.sLocalize)) + }) + } +} + +func TestNewGitCommand(t *testing.T) { + actual, err := os.Getwd() + assert.NoError(t, err) + + defer func() { + assert.NoError(t, os.Chdir(actual)) + }() + + type scenario struct { + testName string + setup func() + test func(*GitCommand, error) + } + + scenarios := []scenario{ + { + "An error occurred, folder doesn't contains a git repository", + func() { + assert.NoError(t, os.Chdir("/tmp")) + }, + func(gitCmd *GitCommand, err error) { + assert.Error(t, err) + assert.Regexp(t, "fatal: .ot a git repository \\(or any of the parent directories\\): \\.git", err.Error()) + }, + }, + { + "New GitCommand object created", + func() { + assert.NoError(t, os.RemoveAll("/tmp/lazygit-test")) + _, err := gogit.PlainInit("/tmp/lazygit-test", false) + assert.NoError(t, err) + assert.NoError(t, os.Chdir("/tmp/lazygit-test")) + }, + func(gitCmd *GitCommand, err error) { + assert.NoError(t, err) + }, + }, + } + + for _, s := range scenarios { + t.Run(s.testName, func(t *testing.T) { + s.setup() + s.test(NewGitCommand(newDummyLog(), newDummyOSCommand(), i18n.NewLocalizer(newDummyLog()))) + }) + } +} + +func TestGitCommandGetStashEntries(t *testing.T) { + type scenario struct { + testName string + command func(string, ...string) *exec.Cmd + test func([]StashEntry) + } + + scenarios := []scenario{ + { + "No stash entries found", + func(string, ...string) *exec.Cmd { + return exec.Command("echo") + }, + func(entries []StashEntry) { + assert.Len(t, entries, 0) + }, + }, + { + "Several stash entries found", + func(string, ...string) *exec.Cmd { + return exec.Command("echo", "WIP on add-pkg-commands-test: 55c6af2 increase parallel build\nWIP on master: bb86a3f update github template") + }, + func(entries []StashEntry) { + expected := []StashEntry{ + { + 0, + "WIP on add-pkg-commands-test: 55c6af2 increase parallel build", + "WIP on add-pkg-commands-test: 55c6af2 increase parallel build", + }, + { + 1, + "WIP on master: bb86a3f update github template", + "WIP on master: bb86a3f update github template", + }, + } + + assert.Len(t, entries, 2) + assert.EqualValues(t, expected, entries) + }, + }, + } + + for _, s := range scenarios { + t.Run(s.testName, func(t *testing.T) { + gitCmd := newDummyGitCommand() + gitCmd.OSCommand.command = s.command + + s.test(gitCmd.GetStashEntries()) + }) + } +} + +func TestGitCommandGetStashEntryDiff(t *testing.T) { + gitCmd := newDummyGitCommand() + gitCmd.OSCommand.command = func(cmd string, args ...string) *exec.Cmd { + assert.EqualValues(t, "git", cmd) + assert.EqualValues(t, []string{"stash", "show", "-p", "--color", "stash@{1}"}, args) + + return exec.Command("echo") + } + + _, err := gitCmd.GetStashEntryDiff(1) + + assert.NoError(t, err) +} + +func TestGitCommandGetStatusFiles(t *testing.T) { + type scenario struct { + testName string + command func(string, ...string) *exec.Cmd + test func([]File) + } + + scenarios := []scenario{ + { + "No files found", + func(cmd string, args ...string) *exec.Cmd { + return exec.Command("echo") + }, + func(files []File) { + assert.Len(t, files, 0) + }, + }, + { + "Several files found", + func(cmd string, args ...string) *exec.Cmd { + return exec.Command( + "echo", + "MM file1.txt\nA file3.txt\nAM file2.txt\n?? file4.txt", + ) + }, + func(files []File) { + assert.Len(t, files, 4) + + expected := []File{ + { + Name: "file1.txt", + HasStagedChanges: true, + HasUnstagedChanges: true, + Tracked: true, + Deleted: false, + HasMergeConflicts: false, + DisplayString: "MM file1.txt", + Type: "other", + }, + { + Name: "file3.txt", + HasStagedChanges: true, + HasUnstagedChanges: false, + Tracked: false, + Deleted: false, + HasMergeConflicts: false, + DisplayString: "A file3.txt", + Type: "other", + }, + { + Name: "file2.txt", + HasStagedChanges: true, + HasUnstagedChanges: true, + Tracked: false, + Deleted: false, + HasMergeConflicts: false, + DisplayString: "AM file2.txt", + Type: "other", + }, + { + Name: "file4.txt", + HasStagedChanges: false, + HasUnstagedChanges: true, + Tracked: false, + Deleted: false, + HasMergeConflicts: false, + DisplayString: "?? file4.txt", + Type: "other", + }, + } + + assert.EqualValues(t, expected, files) + }, + }, + } + + for _, s := range scenarios { + t.Run(s.testName, func(t *testing.T) { + gitCmd := newDummyGitCommand() + gitCmd.OSCommand.command = s.command + + s.test(gitCmd.GetStatusFiles()) + }) + } +} + +func TestGitCommandStashDo(t *testing.T) { + gitCmd := newDummyGitCommand() + gitCmd.OSCommand.command = func(cmd string, args ...string) *exec.Cmd { + assert.EqualValues(t, "git", cmd) + assert.EqualValues(t, []string{"stash", "drop", "stash@{1}"}, args) + + return exec.Command("echo") + } + + assert.NoError(t, gitCmd.StashDo(1, "drop")) +} + +func TestGitCommandStashSave(t *testing.T) { + gitCmd := newDummyGitCommand() + gitCmd.OSCommand.command = func(cmd string, args ...string) *exec.Cmd { + assert.EqualValues(t, "git", cmd) + assert.EqualValues(t, []string{"stash", "save", "A stash message"}, args) + + return exec.Command("echo") + } + + assert.NoError(t, gitCmd.StashSave("A stash message")) +} + +func TestGitCommandCommitAmend(t *testing.T) { + gitCmd := newDummyGitCommand() + gitCmd.OSCommand.command = func(cmd string, args ...string) *exec.Cmd { + assert.EqualValues(t, "git", cmd) + assert.EqualValues(t, []string{"commit", "--amend", "--allow-empty"}, args) + + return exec.Command("echo") + } + + _, err := gitCmd.PrepareCommitAmendSubProcess().CombinedOutput() + assert.NoError(t, err) +} + +func TestGitCommandMergeStatusFiles(t *testing.T) { + type scenario struct { + testName string + oldFiles []File + newFiles []File + test func([]File) + } + + scenarios := []scenario{ + { + "Old file and new file are the same", + []File{}, + []File{ + { + Name: "new_file.txt", + }, + }, + func(files []File) { + expected := []File{ + { + Name: "new_file.txt", + }, + } + + assert.Len(t, files, 1) + assert.EqualValues(t, expected, files) + }, + }, + { + "Several files to merge, with some identical", + []File{ + { + Name: "new_file1.txt", + }, + { + Name: "new_file2.txt", + }, + { + Name: "new_file3.txt", + }, + }, + []File{ + { + Name: "new_file4.txt", + }, + { + Name: "new_file5.txt", + }, + { + Name: "new_file1.txt", + }, + }, + func(files []File) { + expected := []File{ + { + Name: "new_file1.txt", + }, + { + Name: "new_file4.txt", + }, + { + Name: "new_file5.txt", + }, + } + + assert.Len(t, files, 3) + assert.EqualValues(t, expected, files) + }, + }, + } + + for _, s := range scenarios { + t.Run(s.testName, func(t *testing.T) { + gitCmd := newDummyGitCommand() + + s.test(gitCmd.MergeStatusFiles(s.oldFiles, s.newFiles)) + }) + } +} + +func TestGitCommandUpstreamDifferentCount(t *testing.T) { + type scenario struct { + testName string + command func(string, ...string) *exec.Cmd + test func(string, string) + } + + scenarios := []scenario{ + { + "Can't retrieve pushable count", + func(string, ...string) *exec.Cmd { + return exec.Command("exit", "1") + }, + func(pushableCount string, pullableCount string) { + assert.EqualValues(t, "?", pushableCount) + assert.EqualValues(t, "?", pullableCount) + }, + }, + { + "Can't retrieve pullable count", + func(cmd string, args ...string) *exec.Cmd { + if args[1] == "head..@{u}" { + return exec.Command("exit", "1") + } + + return exec.Command("echo") + }, + func(pushableCount string, pullableCount string) { + assert.EqualValues(t, "?", pushableCount) + assert.EqualValues(t, "?", pullableCount) + }, + }, + { + "Retrieve pullable and pushable count", + func(cmd string, args ...string) *exec.Cmd { + if args[1] == "head..@{u}" { + return exec.Command("echo", "10") + } + + return exec.Command("echo", "11") + }, + func(pushableCount string, pullableCount string) { + assert.EqualValues(t, "11", pushableCount) + assert.EqualValues(t, "10", pullableCount) + }, + }, + } + + for _, s := range scenarios { + t.Run(s.testName, func(t *testing.T) { + gitCmd := newDummyGitCommand() + gitCmd.OSCommand.command = s.command + s.test(gitCmd.UpstreamDifferenceCount()) + }) + } +} + +func TestGitCommandGetCommitsToPush(t *testing.T) { + type scenario struct { + testName string + command func(string, ...string) *exec.Cmd + test func([]string) + } + + scenarios := []scenario{ + { + "Can't retrieve pushable commits", + func(string, ...string) *exec.Cmd { + return exec.Command("exit", "1") + }, + func(pushables []string) { + assert.EqualValues(t, []string{}, pushables) + }, + }, + { + "Retrieve pushable commits", + func(cmd string, args ...string) *exec.Cmd { + return exec.Command("echo", "8a2bb0e\n78976bc") + }, + func(pushables []string) { + assert.Len(t, pushables, 2) + assert.EqualValues(t, []string{"8a2bb0e", "78976bc"}, pushables) + }, + }, + } + + for _, s := range scenarios { + t.Run(s.testName, func(t *testing.T) { + gitCmd := newDummyGitCommand() + gitCmd.OSCommand.command = s.command + s.test(gitCmd.GetCommitsToPush()) + }) + } +} + +func TestGitCommandRenameCommit(t *testing.T) { + gitCmd := newDummyGitCommand() + gitCmd.OSCommand.command = func(cmd string, args ...string) *exec.Cmd { + assert.EqualValues(t, "git", cmd) + assert.EqualValues(t, []string{"commit", "--allow-empty", "--amend", "-m", "test"}, args) + + return exec.Command("echo") + } + + assert.NoError(t, gitCmd.RenameCommit("test")) +} + +func TestGitCommandResetToCommit(t *testing.T) { + gitCmd := newDummyGitCommand() + gitCmd.OSCommand.command = func(cmd string, args ...string) *exec.Cmd { + assert.EqualValues(t, "git", cmd) + assert.EqualValues(t, []string{"reset", "78976bc"}, args) + + return exec.Command("echo") + } + + assert.NoError(t, gitCmd.ResetToCommit("78976bc")) +} + +func TestGitCommandNewBranch(t *testing.T) { + gitCmd := newDummyGitCommand() + gitCmd.OSCommand.command = func(cmd string, args ...string) *exec.Cmd { + assert.EqualValues(t, "git", cmd) + assert.EqualValues(t, []string{"checkout", "-b", "test"}, args) + + return exec.Command("echo") + } + + assert.NoError(t, gitCmd.NewBranch("test")) +} + +func TestGitCommandDeleteBranch(t *testing.T) { + type scenario struct { + testName string + branch string + force bool + command func(string, ...string) *exec.Cmd + test func(error) + } + + scenarios := []scenario{ + { + "Delete a branch", + "test", + false, + func(cmd string, args ...string) *exec.Cmd { + assert.EqualValues(t, "git", cmd) + assert.EqualValues(t, []string{"branch", "-d", "test"}, args) + + return exec.Command("echo") + }, + func(err error) { + assert.NoError(t, err) + }, + }, + { + "Force delete a branch", + "test", + true, + func(cmd string, args ...string) *exec.Cmd { + assert.EqualValues(t, "git", cmd) + assert.EqualValues(t, []string{"branch", "-D", "test"}, args) + + return exec.Command("echo") + }, + func(err error) { + assert.NoError(t, err) + }, + }, + } + + for _, s := range scenarios { + t.Run(s.testName, func(t *testing.T) { + gitCmd := newDummyGitCommand() + gitCmd.OSCommand.command = s.command + s.test(gitCmd.DeleteBranch(s.branch, s.force)) + }) + } +} + +func TestGitCommandMerge(t *testing.T) { + gitCmd := newDummyGitCommand() + gitCmd.OSCommand.command = func(cmd string, args ...string) *exec.Cmd { + assert.EqualValues(t, "git", cmd) + assert.EqualValues(t, []string{"merge", "--no-edit", "test"}, args) + + return exec.Command("echo") + } + + assert.NoError(t, gitCmd.Merge("test")) +} + +func TestGitCommandDiff(t *testing.T) { + gitCommand := newDummyGitCommand() + assert.NoError(t, test.GenerateRepo("lots_of_diffs.sh")) + + files := []File{ + { + Name: "deleted_staged", + HasStagedChanges: false, + HasUnstagedChanges: true, + Tracked: true, + Deleted: true, + HasMergeConflicts: false, + DisplayString: " D deleted_staged", + }, + { + Name: "file with space staged", + HasStagedChanges: true, + HasUnstagedChanges: false, + Tracked: false, + Deleted: false, + HasMergeConflicts: false, + DisplayString: "A \"file with space staged\"", + }, + { + Name: "file with space unstaged", + HasStagedChanges: false, + HasUnstagedChanges: true, + Tracked: false, + Deleted: false, + HasMergeConflicts: false, + DisplayString: "?? file with space unstaged", + }, + { + Name: "modified_unstaged", + HasStagedChanges: true, + HasUnstagedChanges: false, + Tracked: true, + Deleted: false, + HasMergeConflicts: false, + DisplayString: "M modified_unstaged", + }, + { + Name: "modified_staged", + HasStagedChanges: false, + HasUnstagedChanges: true, + Tracked: true, + Deleted: false, + HasMergeConflicts: false, + DisplayString: " M modified_staged", + }, + { + Name: "renamed_before -> renamed_after", + HasStagedChanges: true, + HasUnstagedChanges: false, + Tracked: true, + Deleted: false, + HasMergeConflicts: false, + DisplayString: "R renamed_before -> renamed_after", + }, + { + Name: "untracked_unstaged", + HasStagedChanges: false, + HasUnstagedChanges: true, + Tracked: false, + Deleted: false, + HasMergeConflicts: false, + DisplayString: "?? untracked_unstaged", + }, + { + Name: "untracked_staged", + HasStagedChanges: true, + HasUnstagedChanges: false, + Tracked: false, + Deleted: false, + HasMergeConflicts: false, + DisplayString: "A untracked_staged", + }, + { + Name: "master", + HasStagedChanges: false, + HasUnstagedChanges: true, + Tracked: false, + Deleted: false, + HasMergeConflicts: false, + DisplayString: "?? master", + }, + } + + for _, file := range files { + t.Run(file.Name, func(t *testing.T) { + assert.NotContains(t, gitCommand.Diff(file), "error") + }) + } +} diff --git a/pkg/commands/os.go b/pkg/commands/os.go index b72585e44..834c45376 100644 --- a/pkg/commands/os.go +++ b/pkg/commands/os.go @@ -4,14 +4,14 @@ import ( "errors" "os" "os/exec" - "runtime" "strings" - "github.com/davecgh/go-spew/spew" + "github.com/jesseduffield/lazygit/pkg/config" + "github.com/jesseduffield/lazygit/pkg/utils" "github.com/mgutz/str" - "github.com/Sirupsen/logrus" + "github.com/sirupsen/logrus" gitconfig "github.com/tcnksm/go-gitconfig" ) @@ -21,21 +21,29 @@ type Platform struct { shell string shellArg string escapedQuote string + openCommand string } // OSCommand holds all the os commands type OSCommand struct { - Log *logrus.Logger - Platform *Platform + Log *logrus.Entry + Platform *Platform + Config config.AppConfigurer + command func(string, ...string) *exec.Cmd + getGlobalGitConfig func(string) (string, error) + getenv func(string) string } // NewOSCommand os command runner -func NewOSCommand(log *logrus.Logger) (*OSCommand, error) { - osCommand := &OSCommand{ - Log: log, - Platform: getPlatform(), +func NewOSCommand(log *logrus.Entry, config config.AppConfigurer) *OSCommand { + return &OSCommand{ + Log: log, + Platform: getPlatform(), + Config: config, + command: exec.Command, + getGlobalGitConfig: gitconfig.Global, + getenv: os.Getenv, } - return osCommand, nil } // RunCommandWithOutput wrapper around commands returning their output and error @@ -43,8 +51,9 @@ func (c *OSCommand) RunCommandWithOutput(command string) (string, error) { c.Log.WithField("command", command).Info("RunCommand") splitCmd := str.ToArgv(command) c.Log.Info(splitCmd) - cmdOut, err := exec.Command(splitCmd[0], splitCmd[1:]...).CombinedOutput() - return sanitisedCommandOutput(cmdOut, err) + return sanitisedCommandOutput( + c.command(splitCmd[0], splitCmd[1:]...).CombinedOutput(), + ) } // RunCommand runs a command and just returns the error @@ -53,16 +62,26 @@ func (c *OSCommand) RunCommand(command string) error { return err } +// FileType tells us if the file is a file, directory or other +func (c *OSCommand) FileType(path string) string { + fileInfo, err := os.Stat(path) + if err != nil { + return "other" + } + if fileInfo.IsDir() { + return "directory" + } + return "file" +} + // RunDirectCommand wrapper around direct commands func (c *OSCommand) RunDirectCommand(command string) (string, error) { c.Log.WithField("command", command).Info("RunDirectCommand") - args := str.ToArgv(c.Platform.shellArg + " " + command) - c.Log.Info(spew.Sdump(args)) - cmdOut, err := exec. - Command(c.Platform.shell, args...). - CombinedOutput() - return sanitisedCommandOutput(cmdOut, err) + return sanitisedCommandOutput( + c.command(c.Platform.shell, c.Platform.shellArg, command). + CombinedOutput(), + ) } func sanitisedCommandOutput(output []byte, err error) (string, error) { @@ -70,80 +89,36 @@ func sanitisedCommandOutput(output []byte, err error) (string, error) { if err != nil { // errors like 'exit status 1' are not very useful so we'll create an error // from the combined output + if outputString == "" { + return "", err + } return outputString, errors.New(outputString) } return outputString, nil } -func getPlatform() *Platform { - switch runtime.GOOS { - case "windows": - return &Platform{ - os: "windows", - shell: "cmd", - shellArg: "/c", - escapedQuote: "\\\"", - } - default: - return &Platform{ - os: runtime.GOOS, - shell: "bash", - shellArg: "-c", - escapedQuote: "\"", - } - } -} - -// GetOpenCommand get open command -func (c *OSCommand) GetOpenCommand() (string, string, error) { - //NextStep open equivalents: xdg-open (linux), cygstart (cygwin), open (OSX) - trailMap := map[string]string{ - "xdg-open": " &>/dev/null &", - "cygstart": "", - "open": "", - } - for name, trail := range trailMap { - if err := c.RunCommand("which " + name); err == nil { - return name, trail, nil - } - } - return "", "", errors.New("Unsure what command to use to open this file") -} - -// VsCodeOpenFile opens the file in code, with the -r flag to open in the -// current window -// each of these open files needs to have the same function signature because -// they're being passed as arguments into another function, -// but only editFile actually returns a *exec.Cmd -func (c *OSCommand) VsCodeOpenFile(filename string) (*exec.Cmd, error) { - return nil, c.RunCommand("code -r " + filename) -} - -// SublimeOpenFile opens the filein sublime -// may be deprecated in the future -func (c *OSCommand) SublimeOpenFile(filename string) (*exec.Cmd, error) { - return nil, c.RunCommand("subl " + filename) -} - // OpenFile opens a file with the given -func (c *OSCommand) OpenFile(filename string) (*exec.Cmd, error) { - cmdName, cmdTrail, err := c.GetOpenCommand() - if err != nil { - return nil, err +func (c *OSCommand) OpenFile(filename string) error { + commandTemplate := c.Config.GetUserConfig().GetString("os.openCommand") + templateValues := map[string]string{ + "filename": c.Quote(filename), } - err = c.RunCommand(cmdName + " " + c.Quote(filename) + cmdTrail) // TODO: test on linux - return nil, err + + command := utils.ResolvePlaceholderString(commandTemplate, templateValues) + err := c.RunCommand(command) + return err } // EditFile opens a file in a subprocess using whatever editor is available, // falling back to core.editor, VISUAL, EDITOR, then vi func (c *OSCommand) EditFile(filename string) (*exec.Cmd, error) { - editor, _ := gitconfig.Global("core.editor") + editor, _ := c.getGlobalGitConfig("core.editor") + if editor == "" { - editor = os.Getenv("VISUAL") + editor = c.getenv("VISUAL") } if editor == "" { - editor = os.Getenv("EDITOR") + editor = c.getenv("EDITOR") } if editor == "" { if err := c.RunCommand("which vi"); err == nil { @@ -153,13 +128,13 @@ func (c *OSCommand) EditFile(filename string) (*exec.Cmd, error) { if editor == "" { return nil, errors.New("No editor defined in $VISUAL, $EDITOR, or git config") } - return c.PrepareSubProcess(editor, filename) + + return c.PrepareSubProcess(editor, filename), nil } // PrepareSubProcess iniPrepareSubProcessrocess then tells the Gui to switch to it -func (c *OSCommand) PrepareSubProcess(cmdName string, commandArgs ...string) (*exec.Cmd, error) { - subprocess := exec.Command(cmdName, commandArgs...) - return subprocess, nil +func (c *OSCommand) PrepareSubProcess(cmdName string, commandArgs ...string) *exec.Cmd { + return c.command(cmdName, commandArgs...) } // Quote wraps a message in platform-specific quotation marks @@ -171,6 +146,17 @@ func (c *OSCommand) Quote(message string) string { // Unquote removes wrapping quotations marks if they are present // this is needed for removing quotes from staged filenames with spaces func (c *OSCommand) Unquote(message string) string { - message = strings.Replace(message, `"`, "", -1) - return message + return strings.Replace(message, `"`, "", -1) +} + +// AppendLineToFile adds a new line in file +func (c *OSCommand) AppendLineToFile(filename, line string) error { + f, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) + if err != nil { + return err + } + defer f.Close() + + _, err = f.WriteString("\n" + line) + return err } diff --git a/pkg/commands/os_default_platform.go b/pkg/commands/os_default_platform.go new file mode 100644 index 000000000..f106bbd62 --- /dev/null +++ b/pkg/commands/os_default_platform.go @@ -0,0 +1,17 @@ +// +build !windows + +package commands + +import ( + "runtime" +) + +func getPlatform() *Platform { + return &Platform{ + os: runtime.GOOS, + shell: "bash", + shellArg: "-c", + escapedQuote: "\"", + openCommand: "open {{filename}}", + } +} diff --git a/pkg/commands/os_test.go b/pkg/commands/os_test.go index 29540aff6..01173fb15 100644 --- a/pkg/commands/os_test.go +++ b/pkg/commands/os_test.go @@ -1,16 +1,333 @@ package commands -import "testing" +import ( + "os" + "os/exec" + "testing" -func TestQuote(t *testing.T) { - osCommand := &OSCommand{ - Log: nil, - Platform: getPlatform(), + "github.com/jesseduffield/lazygit/pkg/config" + "github.com/spf13/viper" + "github.com/stretchr/testify/assert" + yaml "gopkg.in/yaml.v2" +) + +func newDummyOSCommand() *OSCommand { + return NewOSCommand(newDummyLog(), newDummyAppConfig()) +} + +func newDummyAppConfig() *config.AppConfig { + appConfig := &config.AppConfig{ + Name: "lazygit", + Version: "unversioned", + Commit: "", + BuildDate: "", + Debug: false, + BuildSource: "", + UserConfig: viper.New(), } - test := "hello `test`" - expected := osCommand.Platform.escapedQuote + "hello \\`test\\`" + osCommand.Platform.escapedQuote - test = osCommand.Quote(test) - if test != expected { - t.Error("Expected " + expected + ", got " + test) + _ = yaml.Unmarshal([]byte{}, appConfig.AppState) + return appConfig +} + +func TestOSCommandRunCommandWithOutput(t *testing.T) { + type scenario struct { + command string + test func(string, error) + } + + scenarios := []scenario{ + { + "echo -n '123'", + func(output string, err error) { + assert.NoError(t, err) + assert.EqualValues(t, "123", output) + }, + }, + { + "rmdir unexisting-folder", + func(output string, err error) { + assert.Regexp(t, "rmdir.*unexisting-folder.*", err.Error()) + }, + }, + } + + for _, s := range scenarios { + s.test(newDummyOSCommand().RunCommandWithOutput(s.command)) + } +} + +func TestOSCommandRunCommand(t *testing.T) { + type scenario struct { + command string + test func(error) + } + + scenarios := []scenario{ + { + "rmdir unexisting-folder", + func(err error) { + assert.Regexp(t, "rmdir.*unexisting-folder.*", err.Error()) + }, + }, + } + + for _, s := range scenarios { + s.test(newDummyOSCommand().RunCommand(s.command)) + } +} + +func TestOSCommandOpenFile(t *testing.T) { + type scenario struct { + filename string + command func(string, ...string) *exec.Cmd + test func(error) + } + + scenarios := []scenario{ + { + "test", + func(name string, arg ...string) *exec.Cmd { + return exec.Command("exit", "1") + }, + func(err error) { + assert.Error(t, err) + }, + }, + { + "test", + func(name string, arg ...string) *exec.Cmd { + assert.Equal(t, "open", name) + assert.Equal(t, []string{"test"}, arg) + return exec.Command("echo") + }, + func(err error) { + assert.NoError(t, err) + }, + }, + { + "filename with spaces", + func(name string, arg ...string) *exec.Cmd { + assert.Equal(t, "open", name) + assert.Equal(t, []string{"filename with spaces"}, arg) + return exec.Command("echo") + }, + func(err error) { + assert.NoError(t, err) + }, + }, + } + + for _, s := range scenarios { + OSCmd := newDummyOSCommand() + OSCmd.command = s.command + OSCmd.Config.GetUserConfig().Set("os.openCommand", "open {{filename}}") + + s.test(OSCmd.OpenFile(s.filename)) + } +} + +func TestOSCommandEditFile(t *testing.T) { + type scenario struct { + filename string + command func(string, ...string) *exec.Cmd + getenv func(string) string + getGlobalGitConfig func(string) (string, error) + test func(*exec.Cmd, error) + } + + scenarios := []scenario{ + { + "test", + func(name string, arg ...string) *exec.Cmd { + return exec.Command("exit", "1") + }, + func(env string) string { + return "" + }, + func(cf string) (string, error) { + return "", nil + }, + func(cmd *exec.Cmd, err error) { + assert.EqualError(t, err, "No editor defined in $VISUAL, $EDITOR, or git config") + }, + }, + { + "test", + func(name string, arg ...string) *exec.Cmd { + if name == "which" { + return exec.Command("exit", "1") + } + + assert.EqualValues(t, "nano", name) + + return nil + }, + func(env string) string { + return "" + }, + func(cf string) (string, error) { + return "nano", nil + }, + func(cmd *exec.Cmd, err error) { + assert.NoError(t, err) + }, + }, + { + "test", + func(name string, arg ...string) *exec.Cmd { + if name == "which" { + return exec.Command("exit", "1") + } + + assert.EqualValues(t, "nano", name) + + return nil + }, + func(env string) string { + if env == "VISUAL" { + return "nano" + } + + return "" + }, + func(cf string) (string, error) { + return "", nil + }, + func(cmd *exec.Cmd, err error) { + assert.NoError(t, err) + }, + }, + { + "test", + func(name string, arg ...string) *exec.Cmd { + if name == "which" { + return exec.Command("exit", "1") + } + + assert.EqualValues(t, "emacs", name) + + return nil + }, + func(env string) string { + if env == "EDITOR" { + return "emacs" + } + + return "" + }, + func(cf string) (string, error) { + return "", nil + }, + func(cmd *exec.Cmd, err error) { + assert.NoError(t, err) + }, + }, + { + "test", + func(name string, arg ...string) *exec.Cmd { + if name == "which" { + return exec.Command("echo") + } + + assert.EqualValues(t, "vi", name) + + return nil + }, + func(env string) string { + return "" + }, + func(cf string) (string, error) { + return "", nil + }, + func(cmd *exec.Cmd, err error) { + assert.NoError(t, err) + }, + }, + } + + for _, s := range scenarios { + OSCmd := newDummyOSCommand() + OSCmd.command = s.command + OSCmd.getGlobalGitConfig = s.getGlobalGitConfig + OSCmd.getenv = s.getenv + + s.test(OSCmd.EditFile(s.filename)) + } +} + +func TestOSCommandQuote(t *testing.T) { + osCommand := newDummyOSCommand() + + actual := osCommand.Quote("hello `test`") + + expected := osCommand.Platform.escapedQuote + "hello \\`test\\`" + osCommand.Platform.escapedQuote + + assert.EqualValues(t, expected, actual) +} + +func TestOSCommandUnquote(t *testing.T) { + osCommand := newDummyOSCommand() + + actual := osCommand.Unquote(`hello "test"`) + + expected := "hello test" + + assert.EqualValues(t, expected, actual) +} + +func TestOSCommandFileType(t *testing.T) { + type scenario struct { + path string + setup func() + test func(string) + } + + scenarios := []scenario{ + { + "testFile", + func() { + if _, err := os.Create("testFile"); err != nil { + panic(err) + } + }, + func(output string) { + assert.EqualValues(t, "file", output) + }, + }, + { + "file with spaces", + func() { + if _, err := os.Create("file with spaces"); err != nil { + panic(err) + } + }, + func(output string) { + assert.EqualValues(t, "file", output) + }, + }, + { + "testDirectory", + func() { + if err := os.Mkdir("testDirectory", 0644); err != nil { + panic(err) + } + }, + func(output string) { + assert.EqualValues(t, "directory", output) + }, + }, + { + "nonExistant", + func() {}, + func(output string) { + assert.EqualValues(t, "other", output) + }, + }, + } + + for _, s := range scenarios { + s.setup() + s.test(newDummyOSCommand().FileType(s.path)) + _ = os.RemoveAll(s.path) } } diff --git a/pkg/commands/os_windows.go b/pkg/commands/os_windows.go new file mode 100644 index 000000000..1658e5f36 --- /dev/null +++ b/pkg/commands/os_windows.go @@ -0,0 +1,10 @@ +package commands + +func getPlatform() *Platform { + return &Platform{ + os: "windows", + shell: "cmd", + shellArg: "/c", + escapedQuote: `\"`, + } +} diff --git a/pkg/config/app_config.go b/pkg/config/app_config.go index 9f258d4a6..7cde63de1 100644 --- a/pkg/config/app_config.go +++ b/pkg/config/app_config.go @@ -2,19 +2,24 @@ package config import ( "bytes" + "io/ioutil" + "path/filepath" "github.com/shibukawa/configdir" "github.com/spf13/viper" + yaml "gopkg.in/yaml.v2" ) // AppConfig contains the base configuration fields required for lazygit. type AppConfig struct { - Debug bool `long:"debug" env:"DEBUG" default:"false"` - Version string `long:"version" env:"VERSION" default:"unversioned"` - Commit string `long:"commit" env:"COMMIT"` - BuildDate string `long:"build-date" env:"BUILD_DATE"` - Name string `long:"name" env:"NAME" default:"lazygit"` - UserConfig *viper.Viper + Debug bool `long:"debug" env:"DEBUG" default:"false"` + Version string `long:"version" env:"VERSION" default:"unversioned"` + Commit string `long:"commit" env:"COMMIT"` + BuildDate string `long:"build-date" env:"BUILD_DATE"` + Name string `long:"name" env:"NAME" default:"lazygit"` + BuildSource string `long:"build-source" env:"BUILD_SOURCE" default:""` + UserConfig *viper.Viper + AppState *AppState } // AppConfigurer interface allows individual app config structs to inherit Fields @@ -25,25 +30,36 @@ type AppConfigurer interface { GetCommit() string GetBuildDate() string GetName() string + GetBuildSource() string GetUserConfig() *viper.Viper - InsertToUserConfig(string, string) error + GetAppState() *AppState + WriteToUserConfig(string, string) error + SaveAppState() error + LoadAppState() error } // NewAppConfig makes a new app config -func NewAppConfig(name, version, commit, date string, debuggingFlag *bool) (*AppConfig, error) { - userConfig, err := LoadUserConfig() +func NewAppConfig(name, version, commit, date string, buildSource string, debuggingFlag *bool) (*AppConfig, error) { + userConfig, err := LoadConfig("config", true) if err != nil { - panic(err) + return nil, err } appConfig := &AppConfig{ - Name: "lazygit", - Version: version, - Commit: commit, - BuildDate: date, - Debug: *debuggingFlag, - UserConfig: userConfig, + Name: "lazygit", + Version: version, + Commit: commit, + BuildDate: date, + Debug: *debuggingFlag, + BuildSource: buildSource, + UserConfig: userConfig, + AppState: &AppState{}, } + + if err := appConfig.LoadAppState(); err != nil { + return nil, err + } + return appConfig, nil } @@ -72,97 +88,161 @@ func (c *AppConfig) GetName() string { return c.Name } +// GetBuildSource returns the source of the build. For builds from goreleaser +// this will be binaryBuild +func (c *AppConfig) GetBuildSource() string { + return c.BuildSource +} + // GetUserConfig returns the user config func (c *AppConfig) GetUserConfig() *viper.Viper { return c.UserConfig } -func newViper() (*viper.Viper, error) { +// GetAppState returns the app state +func (c *AppConfig) GetAppState() *AppState { + return c.AppState +} + +func newViper(filename string) (*viper.Viper, error) { v := viper.New() v.SetConfigType("yaml") - v.SetConfigName("config") + v.SetConfigName(filename) return v, nil } -// LoadUserConfig gets the user's config -func LoadUserConfig() (*viper.Viper, error) { - v, err := newViper() +// LoadConfig gets the user's config +func LoadConfig(filename string, withDefaults bool) (*viper.Viper, error) { + v, err := newViper(filename) if err != nil { - panic(err) - } - if err = LoadDefaultConfig(v); err != nil { return nil, err } - if err = LoadUserConfigFromFile(v); err != nil { + if withDefaults { + if err = LoadDefaults(v, GetDefaultConfig()); err != nil { + return nil, err + } + if err = LoadDefaults(v, GetPlatformDefaultConfig()); err != nil { + return nil, err + } + } + if err = LoadAndMergeFile(v, filename+".yml"); err != nil { return nil, err } return v, nil } -// LoadDefaultConfig loads in the defaults defined in this file -func LoadDefaultConfig(v *viper.Viper) error { - defaults := getDefaultConfig() - return v.ReadConfig(bytes.NewBuffer(defaults)) +// LoadDefaults loads in the defaults defined in this file +func LoadDefaults(v *viper.Viper, defaults []byte) error { + return v.MergeConfig(bytes.NewBuffer(defaults)) } -// LoadUserConfigFromFile Loads the user config from their config file, creating -// the file as an empty config if it does not exist -func LoadUserConfigFromFile(v *viper.Viper) error { +func prepareConfigFile(filename string) (string, error) { // chucking my name there is not for vanity purposes, the xdg spec (and that // function) requires a vendor name. May as well line up with github configDirs := configdir.New("jesseduffield", "lazygit") - folder := configDirs.QueryFolderContainsFile("config.yml") + folder := configDirs.QueryFolderContainsFile(filename) if folder == nil { - // create the file as an empty config and load it + // create the file as empty folders := configDirs.QueryFolders(configdir.Global) - if err := folders[0].WriteFile("config.yml", []byte{}); err != nil { - return err + if err := folders[0].WriteFile(filename, []byte{}); err != nil { + return "", err } - folder = configDirs.QueryFolderContainsFile("config.yml") + folder = configDirs.QueryFolderContainsFile(filename) } - v.AddConfigPath(folder.Path) - if err := v.MergeInConfig(); err != nil { - return err - } - return nil + return filepath.Join(folder.Path, filename), nil } -// InsertToUserConfig adds a key/value pair to the user's config and saves it -func (c *AppConfig) InsertToUserConfig(key, value string) error { - // making a new viper object so that we're not writing any defaults back - // to the user's config file - v, err := newViper() +// LoadAndMergeFile Loads the config/state file, creating +// the file as an empty one if it does not exist +func LoadAndMergeFile(v *viper.Viper, filename string) error { + configPath, err := prepareConfigFile(filename) if err != nil { return err } - if err = LoadUserConfigFromFile(v); err != nil { - return err - } - v.Set(key, value) - if err := v.WriteConfig(); err != nil { - return err - } - return nil + + v.AddConfigPath(filepath.Dir(configPath)) + return v.MergeInConfig() } -func getDefaultConfig() []byte { - return []byte(` - gui: - ## stuff relating to the UI - scrollHeight: 2 - theme: - activeBorderColor: - - white - - bold - inactiveBorderColor: - - white - optionsTextColor: - - blue - git: - # stuff relating to git - os: - # stuff relating to the OS +// WriteToUserConfig adds a key/value pair to the user's config and saves it +func (c *AppConfig) WriteToUserConfig(key, value string) error { + // reloading the user config directly (without defaults) so that we're not + // writing any defaults back to the user's config + v, err := LoadConfig("config", false) + if err != nil { + return err + } + v.Set(key, value) + return v.WriteConfig() +} + +// SaveAppState marhsalls the AppState struct and writes it to the disk +func (c *AppConfig) SaveAppState() error { + marshalledAppState, err := yaml.Marshal(c.AppState) + if err != nil { + return err + } + + filepath, err := prepareConfigFile("state.yml") + if err != nil { + return err + } + + return ioutil.WriteFile(filepath, marshalledAppState, 0644) +} + +// LoadAppState loads recorded AppState from file +func (c *AppConfig) LoadAppState() error { + filepath, err := prepareConfigFile("state.yml") + if err != nil { + return err + } + appStateBytes, err := ioutil.ReadFile(filepath) + if err != nil { + return err + } + if len(appStateBytes) == 0 { + return yaml.Unmarshal(getDefaultAppState(), c.AppState) + } + return yaml.Unmarshal(appStateBytes, c.AppState) +} + +// GetDefaultConfig returns the application default configuration +func GetDefaultConfig() []byte { + return []byte( + `gui: + ## stuff relating to the UI + scrollHeight: 2 + theme: + activeBorderColor: + - white + - bold + inactiveBorderColor: + - white + optionsTextColor: + - blue + commitLength: + show: true +update: + method: prompt # can be: prompt | background | never + days: 14 # how often a update is checked for +reporting: 'undetermined' # one of: 'on' | 'off' | 'undetermined' +confirmOnQuit: false +`) +} + +// AppState stores data between runs of the app like when the last update check +// was performed and which other repos have been checked out +type AppState struct { + LastUpdateCheck int64 + RecentRepos []string +} + +func getDefaultAppState() []byte { + return []byte(` + lastUpdateCheck: 0 + recentRepos: [] `) } diff --git a/pkg/config/config_default_platform.go b/pkg/config/config_default_platform.go new file mode 100644 index 000000000..f3c1a36e5 --- /dev/null +++ b/pkg/config/config_default_platform.go @@ -0,0 +1,10 @@ +// +build !windows,!linux + +package config + +// GetPlatformDefaultConfig gets the defaults for the platform +func GetPlatformDefaultConfig() []byte { + return []byte( + `os: + openCommand: 'open {{filename}}'`) +} diff --git a/pkg/config/config_linux.go b/pkg/config/config_linux.go new file mode 100644 index 000000000..90e922416 --- /dev/null +++ b/pkg/config/config_linux.go @@ -0,0 +1,8 @@ +package config + +// GetPlatformDefaultConfig gets the defaults for the platform +func GetPlatformDefaultConfig() []byte { + return []byte( + `os: + openCommand: 'sh -c "xdg-open {{filename}} >/dev/null"'`) +} diff --git a/pkg/config/config_windows.go b/pkg/config/config_windows.go new file mode 100644 index 000000000..b81a5fdb5 --- /dev/null +++ b/pkg/config/config_windows.go @@ -0,0 +1,8 @@ +package config + +// GetPlatformDefaultConfig gets the defaults for the platform +func GetPlatformDefaultConfig() []byte { + return []byte( + `os: + openCommand: 'cmd /c "start "" {{filename}}"'`) +} diff --git a/pkg/git/branch_list_builder.go b/pkg/git/branch_list_builder.go index 869e05c98..651b684f5 100644 --- a/pkg/git/branch_list_builder.go +++ b/pkg/git/branch_list_builder.go @@ -7,7 +7,7 @@ import ( "github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/utils" - "github.com/Sirupsen/logrus" + "github.com/sirupsen/logrus" "gopkg.in/src-d/go-git.v4/plumbing" ) @@ -22,12 +22,12 @@ import ( // BranchListBuilder returns a list of Branch objects for the current repo type BranchListBuilder struct { - Log *logrus.Logger + Log *logrus.Entry GitCommand *commands.GitCommand } // NewBranchListBuilder builds a new branch list builder -func NewBranchListBuilder(log *logrus.Logger, gitCommand *commands.GitCommand) (*BranchListBuilder, error) { +func NewBranchListBuilder(log *logrus.Entry, gitCommand *commands.GitCommand) (*BranchListBuilder, error) { return &BranchListBuilder{ Log: log, GitCommand: gitCommand, diff --git a/pkg/gui/app_status_manager.go b/pkg/gui/app_status_manager.go new file mode 100644 index 000000000..2d479e42f --- /dev/null +++ b/pkg/gui/app_status_manager.go @@ -0,0 +1,44 @@ +package gui + +import "github.com/jesseduffield/lazygit/pkg/utils" + +type appStatus struct { + name string + statusType string + duration int +} + +type statusManager struct { + statuses []appStatus +} + +func (m *statusManager) removeStatus(name string) { + newStatuses := []appStatus{} + for _, status := range m.statuses { + if status.name != name { + newStatuses = append(newStatuses, status) + } + } + m.statuses = newStatuses +} + +func (m *statusManager) addWaitingStatus(name string) { + m.removeStatus(name) + newStatus := appStatus{ + name: name, + statusType: "waiting", + duration: 0, + } + m.statuses = append([]appStatus{newStatus}, m.statuses...) +} + +func (m *statusManager) getStatusString() string { + if len(m.statuses) == 0 { + return "" + } + topStatus := m.statuses[0] + if topStatus.statusType == "waiting" { + return topStatus.name + " " + utils.Loader() + } + return topStatus.name +} diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go index 67e0ceb07..26c3c5618 100644 --- a/pkg/gui/branches_panel.go +++ b/pkg/gui/branches_panel.go @@ -10,11 +10,11 @@ import ( ) func (gui *Gui) handleBranchPress(g *gocui.Gui, v *gocui.View) error { - index := gui.getItemPosition(v) + index := gui.getItemPosition(gui.getBranchesView(g)) if index == 0 { return gui.createErrorPanel(g, gui.Tr.SLocalize("AlreadyCheckedOutBranch")) } - branch := gui.getSelectedBranch(v) + branch := gui.getSelectedBranch(gui.getBranchesView(g)) if err := gui.GitCommand.Checkout(branch.Name, false); err != nil { gui.createErrorPanel(g, err.Error()) } @@ -62,20 +62,34 @@ func (gui *Gui) handleNewBranch(g *gocui.Gui, v *gocui.View) error { } func (gui *Gui) handleDeleteBranch(g *gocui.Gui, v *gocui.View) error { + return gui.deleteBranch(g, v, false) +} + +func (gui *Gui) handleForceDeleteBranch(g *gocui.Gui, v *gocui.View) error { + return gui.deleteBranch(g, v, true) +} + +func (gui *Gui) deleteBranch(g *gocui.Gui, v *gocui.View, force bool) error { checkedOutBranch := gui.State.Branches[0] selectedBranch := gui.getSelectedBranch(v) if checkedOutBranch.Name == selectedBranch.Name { return gui.createErrorPanel(g, gui.Tr.SLocalize("CantDeleteCheckOutBranch")) } + title := gui.Tr.SLocalize("DeleteBranch") + var messageId string + if force { + messageId = "ForceDeleteBranchMessage" + } else { + messageId = "DeleteBranchMessage" + } message := gui.Tr.TemplateLocalize( - "DeleteBranchMessage", + messageId, Teml{ "selectedBranchName": selectedBranch.Name, }, ) - title := gui.Tr.SLocalize("DeleteBranch") return gui.createConfirmationPanel(g, v, title, message, func(g *gocui.Gui, v *gocui.View) error { - if err := gui.GitCommand.DeleteBranch(selectedBranch.Name); err != nil { + if err := gui.GitCommand.DeleteBranch(selectedBranch.Name, force); err != nil { return gui.createErrorPanel(g, err.Error()) } return gui.refreshSidePanels(g) @@ -101,15 +115,7 @@ func (gui *Gui) getSelectedBranch(v *gocui.View) commands.Branch { } func (gui *Gui) renderBranchesOptions(g *gocui.Gui) error { - return gui.renderOptionsMap(g, map[string]string{ - "space": gui.Tr.SLocalize("checkout"), - "f": gui.Tr.SLocalize("forceCheckout"), - "m": gui.Tr.SLocalize("merge"), - "c": gui.Tr.SLocalize("checkoutByName"), - "n": gui.Tr.SLocalize("newBranch"), - "d": gui.Tr.SLocalize("deleteBranch"), - "← → ↑ ↓": gui.Tr.SLocalize("navigate"), - }) + return gui.renderGlobalOptions(g) } // may want to standardise how these select methods work diff --git a/pkg/gui/commit_message_panel.go b/pkg/gui/commit_message_panel.go index 26db703f0..99d649102 100644 --- a/pkg/gui/commit_message_panel.go +++ b/pkg/gui/commit_message_panel.go @@ -1,6 +1,9 @@ package gui import ( + "strconv" + "strings" + "github.com/jesseduffield/gocui" ) @@ -33,20 +36,6 @@ func (gui *Gui) handleCommitClose(g *gocui.Gui, v *gocui.View) error { return gui.switchFocus(g, v, gui.getFilesView(g)) } -func (gui *Gui) handleNewlineCommitMessage(g *gocui.Gui, v *gocui.View) error { - // resising ahead of time so that the top line doesn't get hidden to make - // room for the cursor on the second line - x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(g, v.Buffer()) - if _, err := g.SetView("commitMessage", x0, y0, x1, y1+1, 0); err != nil { - if err != gocui.ErrUnknownView { - return err - } - } - - v.EditNewLine() - return nil -} - func (gui *Gui) handleCommitFocused(g *gocui.Gui, v *gocui.View) error { message := gui.Tr.TemplateLocalize( "CloseConfirm", @@ -57,3 +46,42 @@ func (gui *Gui) handleCommitFocused(g *gocui.Gui, v *gocui.View) error { ) return gui.renderString(g, "options", message) } + +func (gui *Gui) simpleEditor(v *gocui.View, key gocui.Key, ch rune, mod gocui.Modifier) { + switch { + case key == gocui.KeyBackspace || key == gocui.KeyBackspace2: + v.EditDelete(true) + case key == gocui.KeyDelete: + v.EditDelete(false) + case key == gocui.KeyArrowDown: + v.MoveCursor(0, 1, false) + case key == gocui.KeyArrowUp: + v.MoveCursor(0, -1, false) + case key == gocui.KeyArrowLeft: + v.MoveCursor(-1, 0, false) + case key == gocui.KeyArrowRight: + v.MoveCursor(1, 0, false) + case key == gocui.KeyTab: + v.EditNewLine() + case key == gocui.KeySpace: + v.EditWrite(' ') + case key == gocui.KeyInsert: + v.Overwrite = !v.Overwrite + default: + v.EditWrite(ch) + } + + gui.RenderCommitLength() +} + +func (gui *Gui) getBufferLength(view *gocui.View) string { + return " " + strconv.Itoa(strings.Count(view.Buffer(), "")-1) + " " +} + +func (gui *Gui) RenderCommitLength() { + if !gui.Config.GetUserConfig().GetBool("gui.commitLength.show") { + return + } + v := gui.getCommitMessageView(gui.g) + v.Subtitle = gui.getBufferLength(v) +} diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go index 417b947a2..1c1662475 100644 --- a/pkg/gui/commits_panel.go +++ b/pkg/gui/commits_panel.go @@ -59,13 +59,7 @@ func (gui *Gui) handleResetToCommit(g *gocui.Gui, commitView *gocui.View) error } func (gui *Gui) renderCommitsOptions(g *gocui.Gui) error { - return gui.renderOptionsMap(g, map[string]string{ - "s": gui.Tr.SLocalize("squashDown"), - "r": gui.Tr.SLocalize("rename"), - "g": gui.Tr.SLocalize("resetToThisCommit"), - "f": gui.Tr.SLocalize("fixupCommit"), - "← → ↑ ↓": gui.Tr.SLocalize("navigate"), - }) + return gui.renderGlobalOptions(g) } func (gui *Gui) handleCommitSelect(g *gocui.Gui, v *gocui.View) error { @@ -74,7 +68,7 @@ func (gui *Gui) handleCommitSelect(g *gocui.Gui, v *gocui.View) error { } commit, err := gui.getSelectedCommit(g) if err != nil { - if err != errors.New(gui.Tr.SLocalize("NoCommitsThisBranch")) { + if err.Error() != gui.Tr.SLocalize("NoCommitsThisBranch") { return err } return gui.renderString(g, "main", gui.Tr.SLocalize("NoCommitsThisBranch")) @@ -140,10 +134,10 @@ func (gui *Gui) handleCommitFixup(g *gocui.Gui, v *gocui.View) error { } func (gui *Gui) handleRenameCommit(g *gocui.Gui, v *gocui.View) error { - if gui.getItemPosition(v) != 0 { + if gui.getItemPosition(gui.getCommitsView(g)) != 0 { return gui.createErrorPanel(g, gui.Tr.SLocalize("OnlyRenameTopCommit")) } - gui.createPromptPanel(g, v, gui.Tr.SLocalize("RenameCommit"), func(g *gocui.Gui, v *gocui.View) error { + return gui.createPromptPanel(g, v, gui.Tr.SLocalize("renameCommit"), func(g *gocui.Gui, v *gocui.View) error { if err := gui.GitCommand.RenameCommit(v.Buffer()); err != nil { return gui.createErrorPanel(g, err.Error()) } @@ -155,6 +149,19 @@ func (gui *Gui) handleRenameCommit(g *gocui.Gui, v *gocui.View) error { return nil } +func (gui *Gui) handleRenameCommitEditor(g *gocui.Gui, v *gocui.View) error { + if gui.getItemPosition(gui.getCommitsView(g)) != 0 { + return gui.createErrorPanel(g, gui.Tr.SLocalize("OnlyRenameTopCommit")) + } + + gui.SubProcess = gui.GitCommand.PrepareCommitAmendSubProcess() + g.Update(func(g *gocui.Gui) error { + return gui.Errors.ErrSubProcess + }) + + return nil +} + func (gui *Gui) getSelectedCommit(g *gocui.Gui) (commands.Commit, error) { v, err := g.View("commits") if err != nil { diff --git a/pkg/gui/confirmation_panel.go b/pkg/gui/confirmation_panel.go index 025753d56..58577e430 100644 --- a/pkg/gui/confirmation_panel.go +++ b/pkg/gui/confirmation_panel.go @@ -11,14 +11,13 @@ import ( "github.com/fatih/color" "github.com/jesseduffield/gocui" - "github.com/jesseduffield/lazygit/pkg/utils" ) func (gui *Gui) wrappedConfirmationFunction(function func(*gocui.Gui, *gocui.View) error) func(*gocui.Gui, *gocui.View) error { return func(g *gocui.Gui, v *gocui.View) error { if function != nil { if err := function(g, v); err != nil { - panic(err) + return err } } return gui.closeConfirmationPrompt(g) @@ -58,20 +57,30 @@ func (gui *Gui) getConfirmationPanelDimensions(g *gocui.Gui, prompt string) (int func (gui *Gui) createPromptPanel(g *gocui.Gui, currentView *gocui.View, title string, handleConfirm func(*gocui.Gui, *gocui.View) error) error { gui.onNewPopupPanel() - // only need to fit one line - x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(g, "") - if confirmationView, err := g.SetView("confirmation", x0, y0, x1, y1, 0); err != nil { - if err != gocui.ErrUnknownView { - return err - } + confirmationView, err := gui.prepareConfirmationPanel(currentView, title, "") + if err != nil { + return err + } + confirmationView.Editable = true + return gui.setKeyBindings(g, handleConfirm, nil) +} - confirmationView.Editable = true +func (gui *Gui) prepareConfirmationPanel(currentView *gocui.View, title, prompt string) (*gocui.View, error) { + x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(gui.g, prompt) + confirmationView, err := gui.g.SetView("confirmation", x0, y0, x1, y1, 0) + if err != nil { + if err != gocui.ErrUnknownView { + return nil, err + } confirmationView.Title = title confirmationView.FgColor = gocui.ColorWhite - gui.switchFocus(g, currentView, confirmationView) - return gui.setKeyBindings(g, handleConfirm, nil) } - return nil + confirmationView.Clear() + + if err := gui.switchFocus(gui.g, currentView, confirmationView); err != nil { + return nil, err + } + return confirmationView, nil } func (gui *Gui) onNewPopupPanel() { @@ -93,33 +102,16 @@ func (gui *Gui) createConfirmationPanel(g *gocui.Gui, currentView *gocui.View, t gui.Log.Error(errMessage) } } - x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(g, prompt) - if confirmationView, err := g.SetView("confirmation", x0, y0, x1, y1, 0); err != nil { - if err != gocui.ErrUnknownView { - return err - } - confirmationView.Title = title - confirmationView.FgColor = gocui.ColorWhite - gui.renderString(g, "confirmation", prompt) - gui.switchFocus(g, currentView, confirmationView) - return gui.setKeyBindings(g, handleConfirm, handleClose) - } - return nil - }) - return nil -} - -func (gui *Gui) handleNewline(g *gocui.Gui, v *gocui.View) error { - // resising ahead of time so that the top line doesn't get hidden to make - // room for the cursor on the second line - x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(g, v.Buffer()) - if _, err := g.SetView("confirmation", x0, y0, x1, y1+1, 0); err != nil { - if err != gocui.ErrUnknownView { + confirmationView, err := gui.prepareConfirmationPanel(currentView, title, prompt) + if err != nil { return err } - } - - v.EditNewLine() + confirmationView.Editable = false + if err := gui.renderString(g, "confirmation", prompt); err != nil { + return err + } + return gui.setKeyBindings(g, handleConfirm, handleClose) + }) return nil } @@ -131,11 +123,10 @@ func (gui *Gui) setKeyBindings(g *gocui.Gui, handleConfirm, handleClose func(*go "keyBindConfirm": "enter", }, ) - gui.renderString(g, "options", actions) - if err := g.SetKeybinding("confirmation", gocui.KeyEnter, gocui.ModNone, gui.wrappedConfirmationFunction(handleConfirm)); err != nil { + if err := gui.renderString(g, "options", actions); err != nil { return err } - if err := g.SetKeybinding("confirmation", gocui.KeyTab, gocui.ModNone, gui.handleNewline); err != nil { + if err := g.SetKeybinding("confirmation", gocui.KeyEnter, gocui.ModNone, gui.wrappedConfirmationFunction(handleConfirm)); err != nil { return err } return g.SetKeybinding("confirmation", gocui.KeyEsc, gocui.ModNone, gui.wrappedConfirmationFunction(handleClose)) @@ -146,22 +137,9 @@ func (gui *Gui) createMessagePanel(g *gocui.Gui, currentView *gocui.View, title, } func (gui *Gui) createErrorPanel(g *gocui.Gui, message string) error { + gui.Log.Error(message) currentView := g.CurrentView() colorFunction := color.New(color.FgRed).SprintFunc() coloredMessage := colorFunction(strings.TrimSpace(message)) return gui.createConfirmationPanel(g, currentView, gui.Tr.SLocalize("Error"), coloredMessage, nil, nil) } - -func (gui *Gui) resizePopupPanel(g *gocui.Gui, v *gocui.View) error { - // If the confirmation panel is already displayed, just resize the width, - // otherwise continue - content := utils.TrimTrailingNewline(v.Buffer()) - x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(g, content) - vx0, vy0, vx1, vy1 := v.Dimensions() - if vx0 == x0 && vy0 == y0 && vx1 == x1 && vy1 == y1 { - return nil - } - gui.Log.Info(gui.Tr.SLocalize("resizingPopupPanel")) - _, err := g.SetView(v.Name(), x0, y0, x1, y1, 0) - return err -} diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go index 596eb80cc..bfcc938bb 100644 --- a/pkg/gui/files_panel.go +++ b/pkg/gui/files_panel.go @@ -7,7 +7,6 @@ import ( // "strings" - "os/exec" "strings" "github.com/fatih/color" @@ -71,6 +70,33 @@ func (gui *Gui) handleFilePress(g *gocui.Gui, v *gocui.View) error { return gui.handleFileSelect(g, v) } +func (gui *Gui) allFilesStaged() bool { + for _, file := range gui.State.Files { + if file.HasUnstagedChanges { + return false + } + } + return true +} + +func (gui *Gui) handleStageAll(g *gocui.Gui, v *gocui.View) error { + var err error + if gui.allFilesStaged() { + err = gui.GitCommand.UnstageAll() + } else { + err = gui.GitCommand.StageAll() + } + if err != nil { + _ = gui.createErrorPanel(g, err.Error()) + } + + if err := gui.refreshFiles(g); err != nil { + return err + } + + return gui.handleFileSelect(g, v) +} + func (gui *Gui) handleAddPatch(g *gocui.Gui, v *gocui.View) error { file, err := gui.getSelectedFile(g) if err != nil { @@ -85,11 +111,8 @@ func (gui *Gui) handleAddPatch(g *gocui.Gui, v *gocui.View) error { if !file.Tracked { return gui.createErrorPanel(g, gui.Tr.SLocalize("CannotGitAdd")) } - sub, err := gui.GitCommand.AddPatch(file.Name) - if err != nil { - return err - } - gui.SubProcess = sub + + gui.SubProcess = gui.GitCommand.AddPatch(file.Name) return gui.Errors.ErrSubProcess } @@ -142,35 +165,14 @@ func (gui *Gui) handleIgnoreFile(g *gocui.Gui, v *gocui.View) error { if file.Tracked { return gui.createErrorPanel(g, gui.Tr.SLocalize("CantIgnoreTrackFiles")) } - gui.GitCommand.Ignore(file.Name) + if err := gui.GitCommand.Ignore(file.Name); err != nil { + return gui.createErrorPanel(g, err.Error()) + } return gui.refreshFiles(g) } func (gui *Gui) renderfilesOptions(g *gocui.Gui, file *commands.File) error { - optionsMap := map[string]string{ - "← → ↑ ↓": gui.Tr.SLocalize("navigate"), - "S": gui.Tr.SLocalize("stashFiles"), - "c": gui.Tr.SLocalize("CommitChanges"), - "o": gui.Tr.SLocalize("open"), - "i": gui.Tr.SLocalize("ignore"), - "d": gui.Tr.SLocalize("delete"), - "space": gui.Tr.SLocalize("toggleStaged"), - "R": gui.Tr.SLocalize("refresh"), - "t": gui.Tr.SLocalize("addPatch"), - "e": gui.Tr.SLocalize("edit"), - "PgUp/PgDn": gui.Tr.SLocalize("scroll"), - } - if gui.State.HasMergeConflicts { - optionsMap["a"] = gui.Tr.SLocalize("abortMerge") - optionsMap["m"] = gui.Tr.SLocalize("resolveMergeConflicts") - } - if file == nil { - return gui.renderOptionsMap(g, optionsMap) - } - if file.Tracked { - optionsMap["d"] = gui.Tr.SLocalize("checkout") - } - return gui.renderOptionsMap(g, optionsMap) + return gui.renderGlobalOptions(g) } func (gui *Gui) handleFileSelect(g *gocui.Gui, v *gocui.View) error { @@ -200,6 +202,7 @@ func (gui *Gui) handleCommitPress(g *gocui.Gui, filesView *gocui.View) error { g.Update(func(g *gocui.Gui) error { g.SetViewOnTop("commitMessage") gui.switchFocus(g, filesView, commitMessageView) + gui.RenderCommitLength() return nil }) return nil @@ -216,23 +219,17 @@ func (gui *Gui) handleCommitEditorPress(g *gocui.Gui, filesView *gocui.View) err } // PrepareSubProcess - prepare a subprocess for execution and tell the gui to switch to it -func (gui *Gui) PrepareSubProcess(g *gocui.Gui, commands ...string) error { - sub, err := gui.GitCommand.PrepareCommitSubProcess() - if err != nil { - return err - } - gui.SubProcess = sub +func (gui *Gui) PrepareSubProcess(g *gocui.Gui, commands ...string) { + gui.SubProcess = gui.GitCommand.PrepareCommitSubProcess() g.Update(func(g *gocui.Gui) error { return gui.Errors.ErrSubProcess }) - return nil } -func (gui *Gui) genericFileOpen(g *gocui.Gui, v *gocui.View, filename string, open func(string) (*exec.Cmd, error)) error { - - sub, err := open(filename) +func (gui *Gui) editFile(filename string) error { + sub, err := gui.OSCommand.EditFile(filename) if err != nil { - return gui.createErrorPanel(g, err.Error()) + return gui.createErrorPanel(gui.g, err.Error()) } if sub != nil { gui.SubProcess = sub @@ -246,7 +243,8 @@ func (gui *Gui) handleFileEdit(g *gocui.Gui, v *gocui.View) error { if err != nil { return err } - return gui.genericFileOpen(g, v, file.Name, gui.OSCommand.EditFile) + + return gui.editFile(file.Name) } func (gui *Gui) handleFileOpen(g *gocui.Gui, v *gocui.View) error { @@ -254,23 +252,7 @@ func (gui *Gui) handleFileOpen(g *gocui.Gui, v *gocui.View) error { if err != nil { return err } - return gui.genericFileOpen(g, v, file.Name, gui.OSCommand.OpenFile) -} - -func (gui *Gui) handleSublimeFileOpen(g *gocui.Gui, v *gocui.View) error { - file, err := gui.getSelectedFile(g) - if err != nil { - return err - } - return gui.genericFileOpen(g, v, file.Name, gui.OSCommand.SublimeOpenFile) -} - -func (gui *Gui) handleVsCodeFileOpen(g *gocui.Gui, v *gocui.View) error { - file, err := gui.getSelectedFile(g) - if err != nil { - return err - } - return gui.genericFileOpen(g, v, file.Name, gui.OSCommand.VsCodeOpenFile) + return gui.openFile(file.Name) } func (gui *Gui) handleRefreshFiles(g *gocui.Gui, v *gocui.View) error { @@ -319,9 +301,13 @@ func (gui *Gui) catSelectedFile(g *gocui.Gui) (string, error) { } return "", gui.renderString(g, "main", gui.Tr.SLocalize("NoFilesDisplay")) } + if item.Type != "file" { + return "", gui.renderString(g, "main", gui.Tr.SLocalize("NotAFile")) + } cat, err := gui.GitCommand.CatFile(item.Name) if err != nil { - panic(err) + gui.Log.Error(err) + return "", gui.renderString(g, "main", err.Error()) } return cat, nil } @@ -358,21 +344,35 @@ func (gui *Gui) pullFiles(g *gocui.Gui, v *gocui.View) error { return nil } -func (gui *Gui) pushFiles(g *gocui.Gui, v *gocui.View) error { - gui.createMessagePanel(g, v, "", gui.Tr.SLocalize("PushWait")) +func (gui *Gui) pushWithForceFlag(currentView *gocui.View, force bool) error { + if err := gui.createMessagePanel(gui.g, currentView, "", gui.Tr.SLocalize("PushWait")); err != nil { + return err + } go func() { branchName := gui.State.Branches[0].Name - if err := gui.GitCommand.Push(branchName); err != nil { - gui.createErrorPanel(g, err.Error()) + if err := gui.GitCommand.Push(branchName, force); err != nil { + _ = gui.createErrorPanel(gui.g, err.Error()) } else { - gui.closeConfirmationPrompt(g) - gui.refreshCommits(g) - gui.refreshStatus(g) + _ = gui.closeConfirmationPrompt(gui.g) + _ = gui.refreshCommits(gui.g) + _ = gui.refreshStatus(gui.g) } }() return nil } +func (gui *Gui) pushFiles(g *gocui.Gui, v *gocui.View) error { + // if we have pullables we'll ask if the user wants to force push + _, pullables := gui.GitCommand.UpstreamDifferenceCount() + if pullables == "?" || pullables == "0" { + return gui.pushWithForceFlag(v, false) + } + err := gui.createConfirmationPanel(g, nil, gui.Tr.SLocalize("ForcePush"), gui.Tr.SLocalize("ForcePushPrompt"), func(g *gocui.Gui, v *gocui.View) error { + return gui.pushWithForceFlag(v, true) + }, nil) + return err +} + func (gui *Gui) handleSwitchToMerge(g *gocui.Gui, v *gocui.View) error { mergeView, err := g.View("main") if err != nil { @@ -409,3 +409,10 @@ func (gui *Gui) handleResetHard(g *gocui.Gui, v *gocui.View) error { return gui.refreshFiles(g) }, nil) } + +func (gui *Gui) openFile(filename string) error { + if err := gui.OSCommand.OpenFile(filename); err != nil { + return gui.createErrorPanel(gui.g, err.Error()) + } + return nil +} diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index 1e7b6156b..e3cc61529 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -15,12 +15,14 @@ import ( // "strings" - "github.com/Sirupsen/logrus" "github.com/golang-collections/collections/stack" "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/i18n" + "github.com/jesseduffield/lazygit/pkg/updates" + "github.com/jesseduffield/lazygit/pkg/utils" + "github.com/sirupsen/logrus" ) // OverlappingEdges determines if panel edges overlap @@ -55,15 +57,17 @@ type Teml i18n.Teml // Gui wraps the gocui Gui object which handles rendering and events type Gui struct { - g *gocui.Gui - Log *logrus.Logger - GitCommand *commands.GitCommand - OSCommand *commands.OSCommand - SubProcess *exec.Cmd - State guiState - Config config.AppConfigurer - Tr *i18n.Localizer - Errors SentinelErrors + g *gocui.Gui + Log *logrus.Entry + GitCommand *commands.GitCommand + OSCommand *commands.OSCommand + SubProcess *exec.Cmd + State guiState + Config config.AppConfigurer + Tr *i18n.Localizer + Errors SentinelErrors + Updater *updates.Updater + statusManager *statusManager } type guiState struct { @@ -78,10 +82,13 @@ type guiState struct { Conflicts []commands.Conflict EditHistory *stack.Stack Platform commands.Platform + Updating bool + Keys []Binding } // NewGui builds a new gui handler -func NewGui(log *logrus.Logger, gitCommand *commands.GitCommand, oSCommand *commands.OSCommand, tr *i18n.Localizer, config config.AppConfigurer) (*Gui, error) { +func NewGui(log *logrus.Entry, gitCommand *commands.GitCommand, oSCommand *commands.OSCommand, tr *i18n.Localizer, config config.AppConfigurer, updater *updates.Updater) (*Gui, error) { + initialState := guiState{ Files: make([]commands.File, 0), PreviousView: "files", @@ -95,12 +102,14 @@ func NewGui(log *logrus.Logger, gitCommand *commands.GitCommand, oSCommand *comm } gui := &Gui{ - Log: log, - GitCommand: gitCommand, - OSCommand: oSCommand, - State: initialState, - Config: config, - Tr: tr, + Log: log, + GitCommand: gitCommand, + OSCommand: oSCommand, + State: initialState, + Config: config, + Tr: tr, + Updater: updater, + statusManager: &statusManager{}, } gui.GenerateSentinelErrors() @@ -141,14 +150,21 @@ func max(a, b int) int { func (gui *Gui) layout(g *gocui.Gui) error { g.Highlight = true width, height := g.Size() + version := gui.Config.GetVersion() leftSideWidth := width / 3 statusFilesBoundary := 2 filesBranchesBoundary := 2 * height / 5 // height - 20 commitsBranchesBoundary := 3 * height / 5 // height - 10 commitsStashBoundary := height - 5 // height - 5 + optionsVersionBoundary := width - max(len(version), 1) minimumHeight := 16 minimumWidth := 10 - version := gui.Config.GetVersion() + + appStatus := gui.statusManager.getStatusString() + appStatusOptionsBoundary := 0 + if appStatus != "" { + appStatusOptionsBoundary = len(appStatus) + 2 + } panelSpacing := 1 if OverlappingEdges { @@ -227,7 +243,7 @@ func (gui *Gui) layout(g *gocui.Gui) error { v.FgColor = gocui.ColorWhite } - if v, err := g.SetView("options", -1, optionsTop, width-len(version)-2, optionsTop+2, 0); err != nil { + if v, err := g.SetView("options", appStatusOptionsBoundary-1, optionsTop, optionsVersionBoundary-1, optionsTop+2, 0); err != nil { if err != gocui.ErrUnknownView { return err } @@ -239,7 +255,7 @@ func (gui *Gui) layout(g *gocui.Gui) error { if gui.getCommitMessageView(g) == nil { // doesn't matter where this view starts because it will be hidden - if commitMessageView, err := g.SetView("commitMessage", 0, 0, width, height, 0); err != nil { + if commitMessageView, err := g.SetView("commitMessage", 0, 0, width/2, height/2, 0); err != nil { if err != gocui.ErrUnknownView { return err } @@ -247,10 +263,23 @@ func (gui *Gui) layout(g *gocui.Gui) error { commitMessageView.Title = gui.Tr.SLocalize("CommitMessage") commitMessageView.FgColor = gocui.ColorWhite commitMessageView.Editable = true + commitMessageView.Editor = gocui.EditorFunc(gui.simpleEditor) } } - if v, err := g.SetView("version", width-len(version)-1, optionsTop, width, optionsTop+2, 0); err != nil { + if appStatusView, err := g.SetView("appStatus", -1, optionsTop, width, optionsTop+2, 0); err != nil { + if err != gocui.ErrUnknownView { + return err + } + appStatusView.BgColor = gocui.ColorDefault + appStatusView.FgColor = gocui.ColorCyan + appStatusView.Frame = false + if _, err := g.SetViewOnBottom("appStatus"); err != nil { + return err + } + } + + if v, err := g.SetView("version", optionsVersionBoundary-1, optionsTop, width, optionsTop+2, 0); err != nil { if err != gocui.ErrUnknownView { return err } @@ -261,7 +290,9 @@ func (gui *Gui) layout(g *gocui.Gui) error { return err } - // these are only called once + // these are only called once (it's a place to put all the things you want + // to happen on startup after the screen is first rendered) + gui.Updater.CheckForNewUpdate(gui.onBackgroundUpdateCheckFinish, false) gui.handleFileSelect(g, filesView) gui.refreshFiles(g) gui.refreshBranches(g) @@ -270,11 +301,23 @@ func (gui *Gui) layout(g *gocui.Gui) error { if err := gui.switchFocus(g, nil, filesView); err != nil { return err } + + if gui.Config.GetUserConfig().GetString("reporting") == "undetermined" { + if err := gui.promptAnonymousReporting(); err != nil { + return err + } + } } - gui.resizePopupPanels(g) + return gui.resizeCurrentPopupPanel(g) +} - return nil +func (gui *Gui) promptAnonymousReporting() error { + return gui.createConfirmationPanel(gui.g, nil, gui.Tr.SLocalize("AnonymousReportingTitle"), gui.Tr.SLocalize("AnonymousReportingPrompt"), func(g *gocui.Gui, v *gocui.View) error { + return gui.Config.WriteToUserConfig("reporting", "on") + }, func(g *gocui.Gui, v *gocui.View) error { + return gui.Config.WriteToUserConfig("reporting", "off") + }) } func (gui *Gui) fetch(g *gocui.Gui) error { @@ -284,16 +327,35 @@ func (gui *Gui) fetch(g *gocui.Gui) error { } func (gui *Gui) updateLoader(g *gocui.Gui) error { - if confirmationView, _ := g.View("confirmation"); confirmationView != nil { - content := gui.trimmedContent(confirmationView) + if view, _ := g.View("confirmation"); view != nil { + content := gui.trimmedContent(view) if strings.Contains(content, "...") { staticContent := strings.Split(content, "...")[0] + "..." - gui.renderString(g, "confirmation", staticContent+" "+gui.loader()) + if err := gui.renderString(g, "confirmation", staticContent+" "+utils.Loader()); err != nil { + return err + } } } return nil } +func (gui *Gui) renderAppStatus(g *gocui.Gui) error { + appStatus := gui.statusManager.getStatusString() + if appStatus != "" { + return gui.renderString(gui.g, "appStatus", appStatus) + } + return nil +} + +func (gui *Gui) renderGlobalOptions(g *gocui.Gui) error { + return gui.renderOptionsMap(g, map[string]string{ + "PgUp/PgDn": gui.Tr.SLocalize("scroll"), + "← → ↑ ↓": gui.Tr.SLocalize("navigate"), + "esc/q": gui.Tr.SLocalize("close"), + "x": gui.Tr.SLocalize("menu"), + }) +} + func (gui *Gui) goEvery(g *gocui.Gui, interval time.Duration, function func(*gocui.Gui) error) { go func() { for range time.Tick(interval) { @@ -302,14 +364,6 @@ func (gui *Gui) goEvery(g *gocui.Gui, interval time.Duration, function func(*goc }() } -func (gui *Gui) resizePopupPanels(g *gocui.Gui) error { - v := g.CurrentView() - if v.Name() == "commitMessage" || v.Name() == "confirmation" { - return gui.resizePopupPanel(g, v) - } - return nil -} - // Run setup the gui with keybindings and start the mainloop func (gui *Gui) Run() error { g, err := gocui.NewGui(gocui.OutputNormal, OverlappingEdges) @@ -326,7 +380,8 @@ func (gui *Gui) Run() error { gui.goEvery(g, time.Second*60, gui.fetch) gui.goEvery(g, time.Second*10, gui.refreshFiles) - gui.goEvery(g, time.Millisecond*10, gui.updateLoader) + gui.goEvery(g, time.Millisecond*50, gui.updateLoader) + gui.goEvery(g, time.Millisecond*50, gui.renderAppStatus) g.SetManagerFunc(gui.layout) @@ -363,5 +418,13 @@ func (gui *Gui) RunWithSubprocesses() { } func (gui *Gui) quit(g *gocui.Gui, v *gocui.View) error { + if gui.State.Updating { + return gui.createUpdateQuitConfirmation(g, v) + } + if gui.Config.GetUserConfig().GetBool("confirmOnQuit") { + return gui.createConfirmationPanel(g, v, "", gui.Tr.SLocalize("ConfirmQuit"), func(g *gocui.Gui, v *gocui.View) error { + return gocui.ErrQuit + }, nil) + } return gocui.ErrQuit } diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 68cccda6b..c8ed7d3c8 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -6,73 +6,360 @@ import "github.com/jesseduffield/gocui" // is only handled if the given view has focus, or handled globally if the view // is "" type Binding struct { - ViewName string - Handler func(*gocui.Gui, *gocui.View) error - Key interface{} // FIXME: find out how to get `gocui.Key | rune` - Modifier gocui.Modifier + ViewName string + Handler func(*gocui.Gui, *gocui.View) error + Key interface{} // FIXME: find out how to get `gocui.Key | rune` + Modifier gocui.Modifier + KeyReadable string + Description string } -func (gui *Gui) keybindings(g *gocui.Gui) error { +func (gui *Gui) GetKeybindings() []Binding { bindings := []Binding{ - {ViewName: "", Key: 'q', Modifier: gocui.ModNone, Handler: gui.quit}, - {ViewName: "", Key: gocui.KeyCtrlC, Modifier: gocui.ModNone, Handler: gui.quit}, - {ViewName: "", Key: gocui.KeyPgup, Modifier: gocui.ModNone, Handler: gui.scrollUpMain}, - {ViewName: "", Key: gocui.KeyPgdn, Modifier: gocui.ModNone, Handler: gui.scrollDownMain}, - {ViewName: "", Key: gocui.KeyCtrlU, Modifier: gocui.ModNone, Handler: gui.scrollUpMain}, - {ViewName: "", Key: gocui.KeyCtrlD, Modifier: gocui.ModNone, Handler: gui.scrollDownMain}, - {ViewName: "", Key: 'P', Modifier: gocui.ModNone, Handler: gui.pushFiles}, - {ViewName: "", Key: 'p', Modifier: gocui.ModNone, Handler: gui.pullFiles}, - {ViewName: "", Key: 'R', Modifier: gocui.ModNone, Handler: gui.handleRefresh}, - {ViewName: "status", Key: 'e', Modifier: gocui.ModNone, Handler: gui.handleEditConfig}, - {ViewName: "status", Key: 'o', Modifier: gocui.ModNone, Handler: gui.handleOpenConfig}, - {ViewName: "files", Key: 'c', Modifier: gocui.ModNone, Handler: gui.handleCommitPress}, - {ViewName: "files", Key: 'C', Modifier: gocui.ModNone, Handler: gui.handleCommitEditorPress}, - {ViewName: "files", Key: gocui.KeySpace, Modifier: gocui.ModNone, Handler: gui.handleFilePress}, - {ViewName: "files", Key: 'd', Modifier: gocui.ModNone, Handler: gui.handleFileRemove}, - {ViewName: "files", Key: 'm', Modifier: gocui.ModNone, Handler: gui.handleSwitchToMerge}, - {ViewName: "files", Key: 'e', Modifier: gocui.ModNone, Handler: gui.handleFileEdit}, - {ViewName: "files", Key: 'o', Modifier: gocui.ModNone, Handler: gui.handleFileOpen}, - {ViewName: "files", Key: 's', Modifier: gocui.ModNone, Handler: gui.handleSublimeFileOpen}, - {ViewName: "files", Key: 'v', Modifier: gocui.ModNone, Handler: gui.handleVsCodeFileOpen}, - {ViewName: "files", Key: 'i', Modifier: gocui.ModNone, Handler: gui.handleIgnoreFile}, - {ViewName: "files", Key: 'r', Modifier: gocui.ModNone, Handler: gui.handleRefreshFiles}, - {ViewName: "files", Key: 'S', Modifier: gocui.ModNone, Handler: gui.handleStashSave}, - {ViewName: "files", Key: 'a', Modifier: gocui.ModNone, Handler: gui.handleAbortMerge}, - {ViewName: "files", Key: 't', Modifier: gocui.ModNone, Handler: gui.handleAddPatch}, - {ViewName: "files", Key: 'D', Modifier: gocui.ModNone, Handler: gui.handleResetHard}, - {ViewName: "main", Key: gocui.KeyEsc, Modifier: gocui.ModNone, Handler: gui.handleEscapeMerge}, - {ViewName: "main", Key: gocui.KeySpace, Modifier: gocui.ModNone, Handler: gui.handlePickHunk}, - {ViewName: "main", Key: 'b', Modifier: gocui.ModNone, Handler: gui.handlePickBothHunks}, - {ViewName: "main", Key: gocui.KeyArrowLeft, Modifier: gocui.ModNone, Handler: gui.handleSelectPrevConflict}, - {ViewName: "main", Key: gocui.KeyArrowRight, Modifier: gocui.ModNone, Handler: gui.handleSelectNextConflict}, - {ViewName: "main", Key: gocui.KeyArrowUp, Modifier: gocui.ModNone, Handler: gui.handleSelectTop}, - {ViewName: "main", Key: gocui.KeyArrowDown, Modifier: gocui.ModNone, Handler: gui.handleSelectBottom}, - {ViewName: "main", Key: 'h', Modifier: gocui.ModNone, Handler: gui.handleSelectPrevConflict}, - {ViewName: "main", Key: 'l', Modifier: gocui.ModNone, Handler: gui.handleSelectNextConflict}, - {ViewName: "main", Key: 'k', Modifier: gocui.ModNone, Handler: gui.handleSelectTop}, - {ViewName: "main", Key: 'j', Modifier: gocui.ModNone, Handler: gui.handleSelectBottom}, - {ViewName: "main", Key: 'z', Modifier: gocui.ModNone, Handler: gui.handlePopFileSnapshot}, - {ViewName: "branches", Key: gocui.KeySpace, Modifier: gocui.ModNone, Handler: gui.handleBranchPress}, - {ViewName: "branches", Key: 'c', Modifier: gocui.ModNone, Handler: gui.handleCheckoutByName}, - {ViewName: "branches", Key: 'F', Modifier: gocui.ModNone, Handler: gui.handleForceCheckout}, - {ViewName: "branches", Key: 'n', Modifier: gocui.ModNone, Handler: gui.handleNewBranch}, - {ViewName: "branches", Key: 'd', Modifier: gocui.ModNone, Handler: gui.handleDeleteBranch}, - {ViewName: "branches", Key: 'm', Modifier: gocui.ModNone, Handler: gui.handleMerge}, - {ViewName: "commits", Key: 's', Modifier: gocui.ModNone, Handler: gui.handleCommitSquashDown}, - {ViewName: "commits", Key: 'r', Modifier: gocui.ModNone, Handler: gui.handleRenameCommit}, - {ViewName: "commits", Key: 'g', Modifier: gocui.ModNone, Handler: gui.handleResetToCommit}, - {ViewName: "commits", Key: 'f', Modifier: gocui.ModNone, Handler: gui.handleCommitFixup}, - {ViewName: "stash", Key: gocui.KeySpace, Modifier: gocui.ModNone, Handler: gui.handleStashApply}, - {ViewName: "stash", Key: 'g', Modifier: gocui.ModNone, Handler: gui.handleStashPop}, - {ViewName: "stash", Key: 'd', Modifier: gocui.ModNone, Handler: gui.handleStashDrop}, - {ViewName: "commitMessage", Key: gocui.KeyEnter, Modifier: gocui.ModNone, Handler: gui.handleCommitConfirm}, - {ViewName: "commitMessage", Key: gocui.KeyEsc, Modifier: gocui.ModNone, Handler: gui.handleCommitClose}, - {ViewName: "commitMessage", Key: gocui.KeyTab, Modifier: gocui.ModNone, Handler: gui.handleNewlineCommitMessage}, + { + ViewName: "", + Key: 'q', + Modifier: gocui.ModNone, + Handler: gui.quit, + }, { + ViewName: "", + Key: gocui.KeyCtrlC, + Modifier: gocui.ModNone, + Handler: gui.quit, + }, { + ViewName: "", + Key: gocui.KeyEsc, + Modifier: gocui.ModNone, + Handler: gui.quit, + }, { + ViewName: "", + Key: gocui.KeyPgup, + Modifier: gocui.ModNone, + Handler: gui.scrollUpMain, + }, { + ViewName: "", + Key: gocui.KeyPgdn, + Modifier: gocui.ModNone, + Handler: gui.scrollDownMain, + }, { + ViewName: "", + Key: gocui.KeyCtrlU, + Modifier: gocui.ModNone, + Handler: gui.scrollUpMain, + }, { + ViewName: "", + Key: gocui.KeyCtrlD, + Modifier: gocui.ModNone, + Handler: gui.scrollDownMain, + }, { + ViewName: "", + Key: 'P', + Modifier: gocui.ModNone, + Handler: gui.pushFiles, + Description: gui.Tr.SLocalize("push"), + }, { + ViewName: "", + Key: 'p', + Modifier: gocui.ModNone, + Handler: gui.pullFiles, + Description: gui.Tr.SLocalize("pull"), + }, { + ViewName: "", + Key: 'R', + Modifier: gocui.ModNone, + Handler: gui.handleRefresh, + Description: gui.Tr.SLocalize("refresh"), + }, { + ViewName: "", + Key: 'x', + Modifier: gocui.ModNone, + Handler: gui.handleMenu, + }, { + ViewName: "status", + Key: 'e', + Modifier: gocui.ModNone, + Handler: gui.handleEditConfig, + Description: gui.Tr.SLocalize("EditConfig"), + }, { + ViewName: "status", + Key: 'o', + Modifier: gocui.ModNone, + Handler: gui.handleOpenConfig, + Description: gui.Tr.SLocalize("OpenConfig"), + }, { + ViewName: "status", + Key: 'u', + Modifier: gocui.ModNone, + Handler: gui.handleCheckForUpdate, + Description: gui.Tr.SLocalize("checkForUpdate"), + }, { + ViewName: "files", + Key: 'c', + Modifier: gocui.ModNone, + Handler: gui.handleCommitPress, + Description: gui.Tr.SLocalize("CommitChanges"), + }, { + ViewName: "files", + Key: 'C', + Modifier: gocui.ModNone, + Handler: gui.handleCommitEditorPress, + Description: gui.Tr.SLocalize("CommitChangesWithEditor"), + }, { + ViewName: "files", + Key: gocui.KeySpace, + Modifier: gocui.ModNone, + Handler: gui.handleFilePress, + KeyReadable: "space", + Description: gui.Tr.SLocalize("toggleStaged"), + }, { + ViewName: "files", + Key: 'd', + Modifier: gocui.ModNone, + Handler: gui.handleFileRemove, + Description: gui.Tr.SLocalize("removeFile"), + }, { + ViewName: "files", + Key: 'm', + Modifier: gocui.ModNone, + Handler: gui.handleSwitchToMerge, + Description: gui.Tr.SLocalize("resolveMergeConflicts"), + }, { + ViewName: "files", + Key: 'e', + Modifier: gocui.ModNone, + Handler: gui.handleFileEdit, + Description: gui.Tr.SLocalize("editFile"), + }, { + ViewName: "files", + Key: 'o', + Modifier: gocui.ModNone, + Handler: gui.handleFileOpen, + Description: gui.Tr.SLocalize("openFile"), + }, { + ViewName: "files", + Key: 'i', + Modifier: gocui.ModNone, + Handler: gui.handleIgnoreFile, + Description: gui.Tr.SLocalize("ignoreFile"), + }, { + ViewName: "files", + Key: 'r', + Modifier: gocui.ModNone, + Handler: gui.handleRefreshFiles, + Description: gui.Tr.SLocalize("refreshFiles"), + }, { + ViewName: "files", + Key: 'S', + Modifier: gocui.ModNone, + Handler: gui.handleStashSave, + Description: gui.Tr.SLocalize("stashFiles"), + }, { + ViewName: "files", + Key: 'A', + Modifier: gocui.ModNone, + Handler: gui.handleAbortMerge, + Description: gui.Tr.SLocalize("abortMerge"), + }, { + ViewName: "files", + Key: 'a', + Modifier: gocui.ModNone, + Handler: gui.handleStageAll, + Description: gui.Tr.SLocalize("toggleStagedAll"), + }, { + ViewName: "files", + Key: 't', + Modifier: gocui.ModNone, + Handler: gui.handleAddPatch, + Description: gui.Tr.SLocalize("addPatch"), + }, { + ViewName: "files", + Key: 'D', + Modifier: gocui.ModNone, + Handler: gui.handleResetHard, + Description: gui.Tr.SLocalize("resetHard"), + }, { + ViewName: "main", + Key: gocui.KeyEsc, + Modifier: gocui.ModNone, + Handler: gui.handleEscapeMerge, + }, { + ViewName: "main", + Key: gocui.KeySpace, + Modifier: gocui.ModNone, + Handler: gui.handlePickHunk, + }, { + ViewName: "main", + Key: 'b', + Modifier: gocui.ModNone, + Handler: gui.handlePickBothHunks, + }, { + ViewName: "main", + Key: gocui.KeyArrowLeft, + Modifier: gocui.ModNone, + Handler: gui.handleSelectPrevConflict, + }, { + ViewName: "main", + Key: gocui.KeyArrowRight, + Modifier: gocui.ModNone, + Handler: gui.handleSelectNextConflict, + }, { + ViewName: "main", + Key: gocui.KeyArrowUp, + Modifier: gocui.ModNone, + Handler: gui.handleSelectTop, + }, { + ViewName: "main", + Key: gocui.KeyArrowDown, + Modifier: gocui.ModNone, + Handler: gui.handleSelectBottom, + }, { + ViewName: "main", + Key: 'h', + Modifier: gocui.ModNone, + Handler: gui.handleSelectPrevConflict, + }, { + ViewName: "main", + Key: 'l', + Modifier: gocui.ModNone, + Handler: gui.handleSelectNextConflict, + }, { + ViewName: "main", + Key: 'k', + Modifier: gocui.ModNone, + Handler: gui.handleSelectTop, + }, { + ViewName: "main", + Key: 'j', + Modifier: gocui.ModNone, + Handler: gui.handleSelectBottom, + }, { + ViewName: "main", + Key: 'z', + Modifier: gocui.ModNone, + Handler: gui.handlePopFileSnapshot, + }, { + ViewName: "branches", + Key: gocui.KeySpace, + Modifier: gocui.ModNone, + Handler: gui.handleBranchPress, + KeyReadable: "space", + Description: gui.Tr.SLocalize("checkout"), + }, { + ViewName: "branches", + Key: 'c', + Modifier: gocui.ModNone, + Handler: gui.handleCheckoutByName, + Description: gui.Tr.SLocalize("checkoutByName"), + }, { + ViewName: "branches", + Key: 'F', + Modifier: gocui.ModNone, + Handler: gui.handleForceCheckout, + Description: gui.Tr.SLocalize("forceCheckout"), + }, { + ViewName: "branches", + Key: 'n', + Modifier: gocui.ModNone, + Handler: gui.handleNewBranch, + Description: gui.Tr.SLocalize("newBranch"), + }, { + ViewName: "branches", + Key: 'd', + Modifier: gocui.ModNone, + Handler: gui.handleDeleteBranch, + Description: gui.Tr.SLocalize("deleteBranch"), + }, { + ViewName: "branches", + Key: 'D', + Modifier: gocui.ModNone, + Handler: gui.handleForceDeleteBranch, + Description: gui.Tr.SLocalize("forceDeleteBranch"), + }, { + ViewName: "branches", + Key: 'm', + Modifier: gocui.ModNone, + Handler: gui.handleMerge, + Description: gui.Tr.SLocalize("mergeIntoCurrentBranch"), + }, { + ViewName: "commits", + Key: 's', + Modifier: gocui.ModNone, + Handler: gui.handleCommitSquashDown, + Description: gui.Tr.SLocalize("squashDown"), + }, { + ViewName: "commits", + Key: 'r', + Modifier: gocui.ModNone, + Handler: gui.handleRenameCommit, + Description: gui.Tr.SLocalize("renameCommit"), + }, { + ViewName: "commits", + Key: 'R', + Modifier: gocui.ModNone, + Handler: gui.handleRenameCommitEditor, + Description: gui.Tr.SLocalize("renameCommitEditor"), + }, { + ViewName: "commits", + Key: 'g', + Modifier: gocui.ModNone, + Handler: gui.handleResetToCommit, + Description: gui.Tr.SLocalize("resetToThisCommit"), + }, { + ViewName: "commits", + Key: 'f', + Modifier: gocui.ModNone, + Handler: gui.handleCommitFixup, + Description: gui.Tr.SLocalize("fixupCommit"), + }, { + ViewName: "stash", + Key: gocui.KeySpace, + Modifier: gocui.ModNone, + Handler: gui.handleStashApply, + KeyReadable: "space", + Description: gui.Tr.SLocalize("apply"), + }, { + ViewName: "stash", + Key: 'g', + Modifier: gocui.ModNone, + Handler: gui.handleStashPop, + Description: gui.Tr.SLocalize("pop"), + }, { + ViewName: "stash", + Key: 'd', + Modifier: gocui.ModNone, + Handler: gui.handleStashDrop, + Description: gui.Tr.SLocalize("drop"), + }, { + ViewName: "commitMessage", + Key: gocui.KeyEnter, + Modifier: gocui.ModNone, + Handler: gui.handleCommitConfirm, + }, { + ViewName: "commitMessage", + Key: gocui.KeyEsc, + Modifier: gocui.ModNone, + Handler: gui.handleCommitClose, + }, { + ViewName: "menu", + Key: gocui.KeyEsc, + Modifier: gocui.ModNone, + Handler: gui.handleMenuClose, + }, { + ViewName: "menu", + Key: 'q', + Modifier: gocui.ModNone, + Handler: gui.handleMenuClose, + }, { + ViewName: "menu", + Key: gocui.KeySpace, + Modifier: gocui.ModNone, + Handler: gui.handleMenuPress, + }, } // Would make these keybindings global but that interferes with editing // input in the confirmation panel - for _, viewName := range []string{"status", "files", "branches", "commits", "stash"} { + for _, viewName := range []string{"status", "files", "branches", "commits", "stash", "menu"} { bindings = append(bindings, []Binding{ {ViewName: viewName, Key: gocui.KeyTab, Modifier: gocui.ModNone, Handler: gui.nextView}, {ViewName: viewName, Key: gocui.KeyArrowLeft, Modifier: gocui.ModNone, Handler: gui.previousView}, @@ -86,6 +373,12 @@ func (gui *Gui) keybindings(g *gocui.Gui) error { }...) } + return bindings +} + +func (gui *Gui) keybindings(g *gocui.Gui) error { + bindings := gui.GetKeybindings() + for _, binding := range bindings { if err := g.SetKeybinding(binding.ViewName, binding.Key, binding.Modifier, binding.Handler); err != nil { return err diff --git a/pkg/gui/menu_panel.go b/pkg/gui/menu_panel.go new file mode 100644 index 000000000..68041390d --- /dev/null +++ b/pkg/gui/menu_panel.go @@ -0,0 +1,131 @@ +package gui + +import ( + "fmt" + "strings" + + "github.com/jesseduffield/gocui" + "github.com/jesseduffield/lazygit/pkg/utils" +) + +func (gui *Gui) handleMenuPress(g *gocui.Gui, v *gocui.View) error { + lineNumber := gui.getItemPosition(v) + if gui.State.Keys[lineNumber].Key == nil { + return nil + } + if len(gui.State.Keys) > lineNumber { + err := gui.handleMenuClose(g, v) + if err != nil { + return err + } + return gui.State.Keys[lineNumber].Handler(g, v) + } + return nil +} + +func (gui *Gui) handleMenuSelect(g *gocui.Gui, v *gocui.View) error { + // doing nothing for now + // but it is needed for switch in newLineFocused + return nil +} + +func (gui *Gui) renderMenuOptions(g *gocui.Gui) error { + optionsMap := map[string]string{ + "esc/q": gui.Tr.SLocalize("close"), + "↑ ↓": gui.Tr.SLocalize("navigate"), + "space": gui.Tr.SLocalize("execute"), + } + return gui.renderOptionsMap(g, optionsMap) +} + +func (gui *Gui) handleMenuClose(g *gocui.Gui, v *gocui.View) error { + // better to delete because for example after closing update confirmation panel, + // the focus isn't set back to any of panels and one is unable to even quit + //_, err := g.SetViewOnBottom(v.Name()) + err := g.DeleteView("menu") + if err != nil { + return err + } + return gui.returnFocus(g, v) +} + +func (gui *Gui) GetKey(binding Binding) string { + r, ok := binding.Key.(rune) + key := "" + + if ok { + key = string(r) + } else if binding.KeyReadable != "" { + key = binding.KeyReadable + } + + return key +} + +func (gui *Gui) GetMaxKeyLength(bindings []Binding) int { + max := 0 + for _, binding := range bindings { + keyLength := len(gui.GetKey(binding)) + if keyLength > max { + max = keyLength + } + } + return max +} + +func (gui *Gui) handleMenu(g *gocui.Gui, v *gocui.View) error { + var ( + contentGlobal, contentPanel []string + bindingsGlobal, bindingsPanel []Binding + ) + // clear keys slice, so we don't have ghost elements + gui.State.Keys = gui.State.Keys[:0] + bindings := gui.GetKeybindings() + padWidth := gui.GetMaxKeyLength(bindings) + + for _, binding := range bindings { + key := gui.GetKey(binding) + if key != "" && binding.Description != "" { + content := fmt.Sprintf("%s %s", utils.WithPadding(key, padWidth), binding.Description) + switch binding.ViewName { + case "": + contentGlobal = append(contentGlobal, content) + bindingsGlobal = append(bindingsGlobal, binding) + case v.Name(): + contentPanel = append(contentPanel, content) + bindingsPanel = append(bindingsPanel, binding) + } + } + } + + // append dummy element to have a separator between + // panel and global keybindings + contentPanel = append(contentPanel, "") + bindingsPanel = append(bindingsPanel, Binding{}) + + content := append(contentPanel, contentGlobal...) + gui.State.Keys = append(bindingsPanel, bindingsGlobal...) + // append newline at the end so the last line would be selectable + contentJoined := strings.Join(content, "\n") + "\n" + + // y1-1 so there will not be an extra space at the end of panel + x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(g, contentJoined) + menuView, _ := g.SetView("menu", x0, y0, x1, y1-1, 0) + menuView.Title = strings.Title(gui.Tr.SLocalize("menu")) + menuView.FgColor = gocui.ColorWhite + + if err := gui.renderMenuOptions(g); err != nil { + return err + } + + fmt.Fprint(menuView, contentJoined) + + g.Update(func(g *gocui.Gui) error { + _, err := g.SetViewOnTop("menu") + if err != nil { + return err + } + return gui.switchFocus(g, v, menuView) + }) + return nil +} diff --git a/pkg/gui/merge_panel.go b/pkg/gui/merge_panel.go index 1efea16da..e3da82f3c 100644 --- a/pkg/gui/merge_panel.go +++ b/pkg/gui/merge_panel.go @@ -180,6 +180,9 @@ func (gui *Gui) refreshMergePanel(g *gocui.Gui) error { if err != nil { return err } + if cat == "" { + return nil + } gui.State.Conflicts, err = gui.findConflicts(cat) if err != nil { return err diff --git a/pkg/gui/stash_panel.go b/pkg/gui/stash_panel.go index 0c323e254..9ca07717b 100644 --- a/pkg/gui/stash_panel.go +++ b/pkg/gui/stash_panel.go @@ -27,17 +27,13 @@ func (gui *Gui) getSelectedStashEntry(v *gocui.View) *commands.StashEntry { if len(gui.State.StashEntries) == 0 { return nil } - lineNumber := gui.getItemPosition(v) + stashView, _ := gui.g.View("stash") + lineNumber := gui.getItemPosition(stashView) return &gui.State.StashEntries[lineNumber] } func (gui *Gui) renderStashOptions(g *gocui.Gui) error { - return gui.renderOptionsMap(g, map[string]string{ - "space": gui.Tr.SLocalize("apply"), - "g": gui.Tr.SLocalize("pop"), - "d": gui.Tr.SLocalize("drop"), - "← → ↑ ↓": gui.Tr.SLocalize("navigate"), - }) + return gui.renderGlobalOptions(g) } func (gui *Gui) handleStashEntrySelect(g *gocui.Gui, v *gocui.View) error { diff --git a/pkg/gui/status_panel.go b/pkg/gui/status_panel.go index 88134096e..6948e9678 100644 --- a/pkg/gui/status_panel.go +++ b/pkg/gui/status_panel.go @@ -42,10 +42,12 @@ func (gui *Gui) refreshStatus(g *gocui.Gui) error { } func (gui *Gui) renderStatusOptions(g *gocui.Gui) error { - return gui.renderOptionsMap(g, map[string]string{ - "o": gui.Tr.SLocalize("OpenConfig"), - "e": gui.Tr.SLocalize("EditConfig"), - }) + return gui.renderGlobalOptions(g) +} + +func (gui *Gui) handleCheckForUpdate(g *gocui.Gui, v *gocui.View) error { + gui.Updater.CheckForNewUpdate(gui.onUserUpdateCheckFinish, true) + return gui.createMessagePanel(gui.g, v, "", gui.Tr.SLocalize("CheckingForUpdates")) } func (gui *Gui) handleStatusSelect(g *gocui.Gui, v *gocui.View) error { @@ -65,13 +67,12 @@ func (gui *Gui) handleStatusSelect(g *gocui.Gui, v *gocui.View) error { } func (gui *Gui) handleOpenConfig(g *gocui.Gui, v *gocui.View) error { - filename := gui.Config.GetUserConfig().ConfigFileUsed() - return gui.genericFileOpen(g, v, filename, gui.OSCommand.OpenFile) + return gui.openFile(gui.Config.GetUserConfig().ConfigFileUsed()) } func (gui *Gui) handleEditConfig(g *gocui.Gui, v *gocui.View) error { filename := gui.Config.GetUserConfig().ConfigFileUsed() - return gui.genericFileOpen(g, v, filename, gui.OSCommand.EditFile) + return gui.editFile(filename) } func lazygitTitle() string { diff --git a/pkg/gui/updates.go b/pkg/gui/updates.go new file mode 100644 index 000000000..ff5a0afba --- /dev/null +++ b/pkg/gui/updates.go @@ -0,0 +1,65 @@ +package gui + +import "github.com/jesseduffield/gocui" + +func (gui *Gui) showUpdatePrompt(newVersion string) error { + title := "New version available!" + message := "Download latest version? (enter/esc)" + currentView := gui.g.CurrentView() + return gui.createConfirmationPanel(gui.g, currentView, title, message, func(g *gocui.Gui, v *gocui.View) error { + gui.startUpdating(newVersion) + return nil + }, nil) +} + +func (gui *Gui) onUserUpdateCheckFinish(newVersion string, err error) error { + if err != nil { + return gui.createErrorPanel(gui.g, err.Error()) + } + if newVersion == "" { + return gui.createErrorPanel(gui.g, "New version not found") + } + return gui.showUpdatePrompt(newVersion) +} + +func (gui *Gui) onBackgroundUpdateCheckFinish(newVersion string, err error) error { + if err != nil { + // ignoring the error for now so that I'm not annoying users + gui.Log.Error(err.Error()) + return nil + } + if newVersion == "" { + return nil + } + if gui.Config.GetUserConfig().Get("update.method") == "background" { + gui.startUpdating(newVersion) + return nil + } + return gui.showUpdatePrompt(newVersion) +} + +func (gui *Gui) startUpdating(newVersion string) { + gui.State.Updating = true + gui.statusManager.addWaitingStatus("updating") + gui.Updater.Update(newVersion, gui.onUpdateFinish) +} + +func (gui *Gui) onUpdateFinish(err error) error { + gui.State.Updating = false + gui.statusManager.removeStatus("updating") + if err := gui.renderString(gui.g, "appStatus", ""); err != nil { + return err + } + if err != nil { + return gui.createErrorPanel(gui.g, "Update failed: "+err.Error()) + } + return nil +} + +func (gui *Gui) createUpdateQuitConfirmation(g *gocui.Gui, v *gocui.View) error { + title := "Currently Updating" + message := "An update is in progress. Are you sure you want to quit?" + return gui.createConfirmationPanel(gui.g, v, title, message, func(g *gocui.Gui, v *gocui.View) error { + return gocui.ErrQuit + }, nil) +} diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go index 46fc79e40..7a5bd8874 100644 --- a/pkg/gui/view_helpers.go +++ b/pkg/gui/view_helpers.go @@ -4,9 +4,10 @@ import ( "fmt" "sort" "strings" - "time" "github.com/jesseduffield/gocui" + "github.com/jesseduffield/lazygit/pkg/utils" + "github.com/spkg/bom" ) var cyclableViews = []string{"status", "files", "branches", "commits", "stash"} @@ -81,6 +82,8 @@ func (gui *Gui) newLineFocused(g *gocui.Gui, v *gocui.View) error { mainView.SetOrigin(0, 0) switch v.Name() { + case "menu": + return gui.handleMenuSelect(g, v) case "status": return gui.handleStatusSelect(g, v) case "files": @@ -108,7 +111,11 @@ func (gui *Gui) newLineFocused(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) returnFocus(g *gocui.Gui, v *gocui.View) error { previousView, err := g.View(gui.State.PreviousView) if err != nil { - panic(err) + // always fall back to files view if there's no 'previous' view stored + previousView, err = g.View("files") + if err != nil { + gui.Log.Error(err) + } } return gui.switchFocus(g, v, previousView) } @@ -140,6 +147,7 @@ func (gui *Gui) switchFocus(g *gocui.Gui, oldView, newView *gocui.View) error { return err } g.Cursor = newView.Editable + return gui.newLineFocused(g, newView) } @@ -217,7 +225,9 @@ func (gui *Gui) renderString(g *gocui.Gui, viewName, s string) error { return nil } v.Clear() - fmt.Fprint(v, s) + output := string(bom.Clean([]byte(s))) + output = utils.NormalizeLinefeeds(output) + fmt.Fprint(v, output) v.Wrap = true return nil }) @@ -237,15 +247,8 @@ func (gui *Gui) renderOptionsMap(g *gocui.Gui, optionsMap map[string]string) err return gui.renderString(g, "options", gui.optionsMapToString(optionsMap)) } -func (gui *Gui) loader() string { - characters := "|/-\\" - now := time.Now() - nanos := now.UnixNano() - index := nanos / 50000000 % int64(len(characters)) - return characters[index : index+1] -} - // TODO: refactor properly +// i'm so sorry but had to add this getBranchesView func (gui *Gui) getFilesView(g *gocui.Gui) *gocui.View { v, _ := g.View("files") return v @@ -261,6 +264,11 @@ func (gui *Gui) getCommitMessageView(g *gocui.Gui) *gocui.View { return v } +func (gui *Gui) getBranchesView(g *gocui.Gui) *gocui.View { + v, _ := g.View("branches") + return v +} + func (gui *Gui) trimmedContent(v *gocui.View) string { return strings.TrimSpace(v.Buffer()) } @@ -269,3 +277,25 @@ func (gui *Gui) currentViewName(g *gocui.Gui) string { currentView := g.CurrentView() return currentView.Name() } + +func (gui *Gui) resizeCurrentPopupPanel(g *gocui.Gui) error { + v := g.CurrentView() + if v.Name() == "commitMessage" || v.Name() == "confirmation" { + return gui.resizePopupPanel(g, v) + } + return nil +} + +func (gui *Gui) resizePopupPanel(g *gocui.Gui, v *gocui.View) error { + // If the confirmation panel is already displayed, just resize the width, + // otherwise continue + content := v.Buffer() + x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(g, content) + vx0, vy0, vx1, vy1 := v.Dimensions() + if vx0 == x0 && vy0 == y0 && vx1 == x1 && vy1 == y1 { + return nil + } + gui.Log.Info(gui.Tr.SLocalize("resizingPopupPanel")) + _, err := g.SetView(v.Name(), x0, y0, x1, y1, 0) + return err +} diff --git a/pkg/i18n/dutch.go b/pkg/i18n/dutch.go index 60133e662..21330e55c 100644 --- a/pkg/i18n/dutch.go +++ b/pkg/i18n/dutch.go @@ -34,12 +34,24 @@ func addDutch(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "CommitChanges", Other: "Commit Veranderingen", + }, &i18n.Message{ + ID: "CommitChangesWithEditor", + Other: "commit changes using git editor", }, &i18n.Message{ ID: "StatusTitle", Other: "Status", + }, &i18n.Message{ + ID: "GlobalTitle", + Other: "Global", }, &i18n.Message{ ID: "navigate", Other: "navigeer", + }, &i18n.Message{ + ID: "menu", + Other: "menu", + }, &i18n.Message{ + ID: "execute", + Other: "execute", }, &i18n.Message{ ID: "stashFiles", Other: "stash-bestanden", @@ -55,6 +67,9 @@ func addDutch(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "toggleStaged", Other: "toggle staged", + }, &i18n.Message{ + ID: "toggleStagedAll", + Other: "toggle staged alle", }, &i18n.Message{ ID: "refresh", Other: "verversen", @@ -132,7 +147,10 @@ func addDutch(i18nObject *i18n.Bundle) error { Other: "Verwijder branch", }, &i18n.Message{ ID: "DeleteBranchMessage", - Other: "Weet je zeker dat je {{.selectedBranchName}} branch wil verwijderen?", + Other: "Weet je zeker dat je branch {{.selectedBranchName}} wil verwijderen?", + }, &i18n.Message{ + ID: "ForceDeleteBranchMessage", + Other: "Weet je zeker dat je branch {{.selectedBranchName}} geforceerd wil verwijderen?", }, &i18n.Message{ ID: "CantMergeBranchIntoItself", Other: "Je kan niet een branch in zichzelf mergen", @@ -151,6 +169,9 @@ func addDutch(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "deleteBranch", Other: "verwijder branch", + }, &i18n.Message{ + ID: "forceDeleteBranch", + Other: "verwijder branch (forceer)", }, &i18n.Message{ ID: "NoBranchesThisRepo", Other: "Geen branches voor deze repo", @@ -163,6 +184,9 @@ func addDutch(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "CloseConfirm", Other: "{{.keyBindClose}}: Sluiten, {{.keyBindConfirm}}: Bevestigen", + }, &i18n.Message{ + ID: "close", + Other: "close", }, &i18n.Message{ ID: "SureResetThisCommit", Other: "Weet je het zeker dat je wil resetten naar deze commit?", @@ -203,8 +227,11 @@ func addDutch(i18nObject *i18n.Bundle) error { ID: "OnlyRenameTopCommit", Other: "Je kan alleen de bovenste commit hernoemen", }, &i18n.Message{ - ID: "RenameCommit", - Other: "Hernoem Commit", + ID: "renameCommit", + Other: "hernoem commit", + }, &i18n.Message{ + ID: "renameCommitEditor", + Other: "rename commit with editor", }, &i18n.Message{ ID: "PotentialErrInGetselectedCommit", Other: "Er is mogelijk een error in getSelected Commit (geen match tussen ui en state)", @@ -286,6 +313,63 @@ func addDutch(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "MergeAborted", Other: "Merge afgebroken", + }, &i18n.Message{ + ID: "OpenConfig", + Other: "open config file", + }, &i18n.Message{ + ID: "EditConfig", + Other: "edit config file", + }, &i18n.Message{ + ID: "ForcePush", + Other: "Force push", + }, &i18n.Message{ + ID: "ForcePushPrompt", + Other: "Your branch has diverged from the remote branch. Press 'esc' to cancel, or 'enter' to force push.", + }, &i18n.Message{ + ID: "checkForUpdate", + Other: "check for update", + }, &i18n.Message{ + ID: "CheckingForUpdates", + Other: "Checking for updates...", + }, &i18n.Message{ + ID: "OnLatestVersionErr", + Other: "You already have the latest version", + }, &i18n.Message{ + ID: "MajorVersionErr", + Other: "New version ({{.newVersion}}) has non-backwards compatible changes compared to the current version ({{.currentVersion}})", + }, &i18n.Message{ + ID: "CouldNotFindBinaryErr", + Other: "Could not find any binary at {{.url}}", + }, &i18n.Message{ + ID: "AnonymousReportingTitle", + Other: "Help make lazygit better", + }, &i18n.Message{ + ID: "AnonymousReportingPrompt", + Other: "Would you like to enable anonymous reporting data to help improve lazygit? (enter/esc)", + }, &i18n.Message{ + ID: "removeFile", + Other: `delete if untracked / checkout if tracked (aka go away)`, + }, &i18n.Message{ + ID: "editFile", + Other: `edit file`, + }, &i18n.Message{ + ID: "openFile", + Other: `open file`, + }, &i18n.Message{ + ID: "ignoreFile", + Other: `add to .gitignore`, + }, &i18n.Message{ + ID: "refreshFiles", + Other: `refresh files`, + }, &i18n.Message{ + ID: "resetHard", + Other: `reset hard`, + }, &i18n.Message{ + ID: "mergeIntoCurrentBranch", + Other: `merge into currently checked out branch`, + }, &i18n.Message{ + ID: "ConfirmQuit", + Other: `Are you sure you want to quit?`, }, ) } diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index bebe9b282..4f009c075 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -42,12 +42,24 @@ func addEnglish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "CommitChanges", Other: "commit changes", + }, &i18n.Message{ + ID: "CommitChangesWithEditor", + Other: "commit changes using git editor", }, &i18n.Message{ ID: "StatusTitle", Other: "Status", + }, &i18n.Message{ + ID: "GlobalTitle", + Other: "Global", }, &i18n.Message{ ID: "navigate", Other: "navigate", + }, &i18n.Message{ + ID: "menu", + Other: "menu", + }, &i18n.Message{ + ID: "execute", + Other: "execute", }, &i18n.Message{ ID: "stashFiles", Other: "stash files", @@ -63,9 +75,18 @@ func addEnglish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "toggleStaged", Other: "toggle staged", + }, &i18n.Message{ + ID: "toggleStagedAll", + Other: "stage/unstage all", }, &i18n.Message{ ID: "refresh", Other: "refresh", + }, &i18n.Message{ + ID: "push", + Other: "push", + }, &i18n.Message{ + ID: "pull", + Other: "pull", }, &i18n.Message{ ID: "addPatch", Other: "add patch", @@ -102,6 +123,9 @@ func addEnglish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "NoFilesDisplay", Other: "No file to display", + }, &i18n.Message{ + ID: "NotAFile", + Other: "Not a file", }, &i18n.Message{ ID: "PullWait", Other: "Pulling...", @@ -140,7 +164,10 @@ func addEnglish(i18nObject *i18n.Bundle) error { Other: "Delete Branch", }, &i18n.Message{ ID: "DeleteBranchMessage", - Other: "Are you sure you want delete the branch {{.selectedBranchName}} ?", + Other: "Are you sure you want to delete the branch {{.selectedBranchName}}?", + }, &i18n.Message{ + ID: "ForceDeleteBranchMessage", + Other: "Are you sure you want to force delete the branch {{.selectedBranchName}}?", }, &i18n.Message{ ID: "CantMergeBranchIntoItself", Other: "You cannot merge a branch into itself", @@ -159,6 +186,9 @@ func addEnglish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "deleteBranch", Other: "delete branch", + }, &i18n.Message{ + ID: "forceDeleteBranch", + Other: "delete branch (force)", }, &i18n.Message{ ID: "NoBranchesThisRepo", Other: "No branches for this repo", @@ -171,6 +201,9 @@ func addEnglish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "CloseConfirm", Other: "{{.keyBindClose}}: close, {{.keyBindConfirm}}: confirm", + }, &i18n.Message{ + ID: "close", + Other: "close", }, &i18n.Message{ ID: "SureResetThisCommit", Other: "Are you sure you want to reset to this commit?", @@ -211,8 +244,11 @@ func addEnglish(i18nObject *i18n.Bundle) error { ID: "OnlyRenameTopCommit", Other: "Can only rename topmost commit", }, &i18n.Message{ - ID: "RenameCommit", - Other: "Rename Commit", + ID: "renameCommit", + Other: "rename commit", + }, &i18n.Message{ + ID: "renameCommitEditor", + Other: "rename commit with editor", }, &i18n.Message{ ID: "PotentialErrInGetselectedCommit", Other: "potential error in getSelected Commit (mismatched ui and state)", @@ -300,6 +336,60 @@ func addEnglish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "EditConfig", Other: "edit config file", + }, &i18n.Message{ + ID: "ForcePush", + Other: "Force push", + }, &i18n.Message{ + ID: "ForcePushPrompt", + Other: "Your branch has diverged from the remote branch. Press 'esc' to cancel, or 'enter' to force push.", + }, &i18n.Message{ + ID: "checkForUpdate", + Other: "check for update", + }, &i18n.Message{ + ID: "CheckingForUpdates", + Other: "Checking for updates...", + }, &i18n.Message{ + ID: "OnLatestVersionErr", + Other: "You already have the latest version", + }, &i18n.Message{ + ID: "MajorVersionErr", + Other: "New version ({{.newVersion}}) has non-backwards compatible changes compared to the current version ({{.currentVersion}})", + }, &i18n.Message{ + ID: "CouldNotFindBinaryErr", + Other: "Could not find any binary at {{.url}}", + }, &i18n.Message{ + ID: "AnonymousReportingTitle", + Other: "Help make lazygit better", + }, &i18n.Message{ + ID: "AnonymousReportingPrompt", + Other: "Would you like to enable anonymous reporting data to help improve lazygit? (enter/esc)", + }, &i18n.Message{ + ID: "GitconfigParseErr", + Other: `Gogit failed to parse your gitconfig file due to the presence of unquoted '\' characters. Removing these should fix the issue.`, + }, &i18n.Message{ + ID: "removeFile", + Other: `delete if untracked / checkout if tracked`, + }, &i18n.Message{ + ID: "editFile", + Other: `edit file`, + }, &i18n.Message{ + ID: "openFile", + Other: `open file`, + }, &i18n.Message{ + ID: "ignoreFile", + Other: `add to .gitignore`, + }, &i18n.Message{ + ID: "refreshFiles", + Other: `refresh files`, + }, &i18n.Message{ + ID: "resetHard", + Other: `reset hard`, + }, &i18n.Message{ + ID: "mergeIntoCurrentBranch", + Other: `merge into currently checked out branch`, + }, &i18n.Message{ + ID: "ConfirmQuit", + Other: `Are you sure you want to quit?`, }, ) } diff --git a/pkg/i18n/i18n.go b/pkg/i18n/i18n.go index f2bd2839e..1628df707 100644 --- a/pkg/i18n/i18n.go +++ b/pkg/i18n/i18n.go @@ -1,9 +1,9 @@ package i18n import ( - "github.com/Sirupsen/logrus" "github.com/cloudfoundry/jibber_jabber" "github.com/nicksnyder/go-i18n/v2/i18n" + "github.com/sirupsen/logrus" "golang.org/x/text/language" ) @@ -14,34 +14,16 @@ type Teml map[string]interface{} type Localizer struct { i18nLocalizer *i18n.Localizer language string - Log *logrus.Logger + Log *logrus.Entry } // NewLocalizer creates a new Localizer -func NewLocalizer(log *logrus.Logger) (*Localizer, error) { +func NewLocalizer(log *logrus.Entry) *Localizer { + userLang := detectLanguage(jibber_jabber.DetectLanguage) - // detect the user's language - userLang, err := jibber_jabber.DetectLanguage() - if err != nil { - return nil, err - } log.Info("language: " + userLang) - // create a i18n bundle that can be used to add translations and other things - i18nBundle := &i18n.Bundle{DefaultLanguage: language.English} - - addBundles(log, i18nBundle) - - // return the new localizer that can be used to translate text - i18nLocalizer := i18n.NewLocalizer(i18nBundle, userLang) - - localizer := &Localizer{ - i18nLocalizer: i18nLocalizer, - language: userLang, - Log: log, - } - - return localizer, nil + return setupLocalizer(log, userLang) } // Localize handels the translations @@ -78,18 +60,43 @@ func (l *Localizer) GetLanguage() string { } // add translation file(s) -func addBundles(log *logrus.Logger, i18nBundle *i18n.Bundle) { - err := addPolish(i18nBundle) - if err != nil { - log.Fatal(err) - } - err = addDutch(i18nBundle) - if err != nil { - log.Fatal(err) - } - err = addEnglish(i18nBundle) - if err != nil { - log.Fatal(err) +func addBundles(log *logrus.Entry, i18nBundle *i18n.Bundle) { + fs := []func(*i18n.Bundle) error{ + addPolish, + addDutch, + addEnglish, } + for _, f := range fs { + if err := f(i18nBundle); err != nil { + log.Fatal(err) + + } + } +} + +// detectLanguage extracts user language from environment +func detectLanguage(langDetector func() (string, error)) string { + if userLang, err := langDetector(); err == nil { + return userLang + } + + return "C" +} + +// setupLocalizer creates a new localizer using given userLang +func setupLocalizer(log *logrus.Entry, userLang string) *Localizer { + // create a i18n bundle that can be used to add translations and other things + i18nBundle := &i18n.Bundle{DefaultLanguage: language.English} + + addBundles(log, i18nBundle) + + // return the new localizer that can be used to translate text + i18nLocalizer := i18n.NewLocalizer(i18nBundle, userLang) + + return &Localizer{ + i18nLocalizer: i18nLocalizer, + language: userLang, + Log: log, + } } diff --git a/pkg/i18n/i18n_test.go b/pkg/i18n/i18n_test.go new file mode 100644 index 000000000..e26b7d1dc --- /dev/null +++ b/pkg/i18n/i18n_test.go @@ -0,0 +1,87 @@ +package i18n + +import ( + "fmt" + "io/ioutil" + "testing" + + "github.com/nicksnyder/go-i18n/v2/i18n" + + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" +) + +func getDummyLog() *logrus.Entry { + log := logrus.New() + log.Out = ioutil.Discard + return log.WithField("test", "test") +} +func TestNewLocalizer(t *testing.T) { + assert.NotNil(t, NewLocalizer(getDummyLog())) +} + +func TestDetectLanguage(t *testing.T) { + type scenario struct { + langDetector func() (string, error) + expected string + } + + scenarios := []scenario{ + { + func() (string, error) { + return "", fmt.Errorf("An error occurred") + }, + "C", + }, + { + func() (string, error) { + return "en", nil + }, + "en", + }, + } + + for _, s := range scenarios { + assert.EqualValues(t, s.expected, detectLanguage(s.langDetector)) + } +} + +func TestLocalizer(t *testing.T) { + type scenario struct { + userLang string + test func(*Localizer) + } + + scenarios := []scenario{ + { + "C", + func(l *Localizer) { + assert.EqualValues(t, "C", l.GetLanguage()) + assert.Equal(t, "Diff", l.Localize(&i18n.LocalizeConfig{ + DefaultMessage: &i18n.Message{ + ID: "DiffTitle", + }, + })) + assert.Equal(t, "Diff", l.SLocalize("DiffTitle")) + assert.Equal(t, "Are you sure you want to delete the branch test?", l.TemplateLocalize("DeleteBranchMessage", Teml{"selectedBranchName": "test"})) + }, + }, + { + "nl", + func(l *Localizer) { + assert.EqualValues(t, "nl", l.GetLanguage()) + assert.Equal(t, "Diff", l.Localize(&i18n.LocalizeConfig{ + DefaultMessage: &i18n.Message{ + ID: "DiffTitle", + }, + })) + assert.Equal(t, "Diff", l.SLocalize("DiffTitle")) + assert.Equal(t, "Weet je zeker dat je branch test wil verwijderen?", l.TemplateLocalize("DeleteBranchMessage", Teml{"selectedBranchName": "test"})) + }, + }, + } + + for _, s := range scenarios { + s.test(setupLocalizer(getDummyLog(), s.userLang)) + } +} diff --git a/pkg/i18n/polish.go b/pkg/i18n/polish.go index 9b9fa19e1..c64ab87b8 100644 --- a/pkg/i18n/polish.go +++ b/pkg/i18n/polish.go @@ -32,12 +32,24 @@ func addPolish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "CommitChanges", Other: "commituj zmiany", + }, &i18n.Message{ + ID: "CommitChangesWithEditor", + Other: "commituj zmiany używając edytora z gita", }, &i18n.Message{ ID: "StatusTitle", Other: "Status", + }, &i18n.Message{ + ID: "GlobalTitle", + Other: "Globalne", }, &i18n.Message{ ID: "navigate", Other: "nawiguj", + }, &i18n.Message{ + ID: "menu", + Other: "menu", + }, &i18n.Message{ + ID: "execute", + Other: "wykonaj", }, &i18n.Message{ ID: "stashFiles", Other: "przechowaj pliki", @@ -53,6 +65,9 @@ func addPolish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "toggleStaged", Other: "przełącz zatwierdzenie", + }, &i18n.Message{ + ID: "toggleStagedAll", + Other: "przełącz wszystkie zatwierdzenia", }, &i18n.Message{ ID: "refresh", Other: "odśwież", @@ -131,6 +146,9 @@ func addPolish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "DeleteBranchMessage", Other: "Jesteś pewien, że chcesz usunąć gałąź {{.selectedBranchName}} ?", + }, &i18n.Message{ + ID: "ForceDeleteBranchMessage", + Other: "Na pewno wymusić usunięcie gałęzi {{.selectedBranchName}}?", }, &i18n.Message{ ID: "CantMergeBranchIntoItself", Other: "Nie możesz scalić gałęzi do samej siebie", @@ -149,6 +167,9 @@ func addPolish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "deleteBranch", Other: "usuń gałąź", + }, &i18n.Message{ + ID: "forceDeleteBranch", + Other: "usuń gałąź (wymuś)", }, &i18n.Message{ ID: "NoBranchesThisRepo", Other: "Brak gałęzi dla tego repozytorium", @@ -161,6 +182,9 @@ func addPolish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "CloseConfirm", Other: "{{.keyBindClose}}: zamknij, {{.keyBindConfirm}}: potwierdź", + }, &i18n.Message{ + ID: "close", + Other: "zamknij", }, &i18n.Message{ ID: "SureResetThisCommit", Other: "Jesteś pewny, że chcesz zresetować ten commit?", @@ -201,8 +225,11 @@ func addPolish(i18nObject *i18n.Bundle) error { ID: "OnlyRenameTopCommit", Other: "Można przmianować tylko najwyższy commit", }, &i18n.Message{ - ID: "RenameCommit", - Other: "Przemianuj commit", + ID: "renameCommit", + Other: "przemianuj commit", + }, &i18n.Message{ + ID: "renameCommitEditor", + Other: "przemianuj commit w edytorze", }, &i18n.Message{ ID: "PotentialErrInGetselectedCommit", Other: "potencjalny błąd w getSelected Commit (niedopasowane ui i stan)", @@ -284,6 +311,63 @@ func addPolish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "MergeAborted", Other: "Scalanie anulowane", + }, &i18n.Message{ + ID: "OpenConfig", + Other: "otwórz plik konfiguracyjny", + }, &i18n.Message{ + ID: "EditConfig", + Other: "edytuj plik konfiguracyjny", + }, &i18n.Message{ + ID: "ForcePush", + Other: "Wymuś wypchnięcie", + }, &i18n.Message{ + ID: "ForcePushPrompt", + Other: "Twoja gałąź rozeszła się z gałęzią zdalną. Wciśnij 'esc' aby anulować lub 'enter' aby wymusić wypchnięcie.", + }, &i18n.Message{ + ID: "checkForUpdate", + Other: "sprawdź aktualizacje", + }, &i18n.Message{ + ID: "CheckingForUpdates", + Other: "Sprawdzanie aktualizacji...", + }, &i18n.Message{ + ID: "OnLatestVersionErr", + Other: "Już posiadasz najnowszą wersję", + }, &i18n.Message{ + ID: "MajorVersionErr", + Other: "Nowa wersja ({{.newVersion}}) posiada niekompatybilne zmiany w porównaniu do obecnej wersji ({{.currentVersion}})", + }, &i18n.Message{ + ID: "CouldNotFindBinaryErr", + Other: "Nie można znaleźć pliku binarnego w {{.url}}", + }, &i18n.Message{ + ID: "AnonymousReportingTitle", + Other: "Help make lazygit better", + }, &i18n.Message{ + ID: "AnonymousReportingPrompt", + Other: "Włączyć anonimowe raportowanie błędów w celu pomocy w usprawnianiu lazygita (enter/esc)?", + }, &i18n.Message{ + ID: "removeFile", + Other: `usuń jeśli nie śledzony / przełącz jeśli śledzony`, + }, &i18n.Message{ + ID: "editFile", + Other: `edytuj plik`, + }, &i18n.Message{ + ID: "openFile", + Other: `otwórz plik`, + }, &i18n.Message{ + ID: "ignoreFile", + Other: `dodaj do .gitignore`, + }, &i18n.Message{ + ID: "refreshFiles", + Other: `odśwież pliki`, + }, &i18n.Message{ + ID: "resetHard", + Other: `zresetuj twardo`, + }, &i18n.Message{ + ID: "mergeIntoCurrentBranch", + Other: `scal do obecnej gałęzi`, + }, &i18n.Message{ + ID: "ConfirmQuit", + Other: `Na pewno chcesz wyjść z programu?`, }, ) } diff --git a/pkg/test/test.go b/pkg/test/test.go new file mode 100644 index 000000000..6346ac556 --- /dev/null +++ b/pkg/test/test.go @@ -0,0 +1,31 @@ +package test + +import ( + "errors" + "os" + "os/exec" + "path/filepath" + + "github.com/jesseduffield/lazygit/pkg/utils" +) + +// GenerateRepo generates a repo from test/repos and changes the directory to be +// inside the newly made repo +func GenerateRepo(filename string) error { + reposDir := "/test/repos/" + testPath := utils.GetProjectRoot() + reposDir + + // workaround for debian packaging + if _, err := os.Stat(testPath); os.IsNotExist(err) { + cwd, _ := os.Getwd() + testPath = filepath.Dir(filepath.Dir(cwd)) + reposDir + } + if err := os.Chdir(testPath); err != nil { + return err + } + if output, err := exec.Command("bash", filename).CombinedOutput(); err != nil { + return errors.New(string(output)) + } + + return os.Chdir(testPath + "repo") +} diff --git a/pkg/updates/updates.go b/pkg/updates/updates.go new file mode 100644 index 000000000..4ec374616 --- /dev/null +++ b/pkg/updates/updates.go @@ -0,0 +1,314 @@ +package updates + +import ( + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "os" + "path/filepath" + "runtime" + "strings" + "time" + + "github.com/kardianos/osext" + + getter "github.com/jesseduffield/go-getter" + "github.com/jesseduffield/lazygit/pkg/commands" + "github.com/jesseduffield/lazygit/pkg/config" + "github.com/jesseduffield/lazygit/pkg/i18n" + "github.com/sirupsen/logrus" +) + +// Updater checks for updates and does updates +type Updater struct { + Log *logrus.Entry + Config config.AppConfigurer + OSCommand *commands.OSCommand + Tr *i18n.Localizer +} + +// Updaterer implements the check and update methods +type Updaterer interface { + CheckForNewUpdate() + Update() +} + +var ( + projectUrl = "https://github.com/jesseduffield/lazygit" +) + +// NewUpdater creates a new updater +func NewUpdater(log *logrus.Entry, config config.AppConfigurer, osCommand *commands.OSCommand, tr *i18n.Localizer) (*Updater, error) { + contextLogger := log.WithField("context", "updates") + + updater := &Updater{ + Log: contextLogger, + Config: config, + OSCommand: osCommand, + Tr: tr, + } + return updater, nil +} + +func (u *Updater) getLatestVersionNumber() (string, error) { + req, err := http.NewRequest("GET", projectUrl+"/releases/latest", nil) + if err != nil { + return "", err + } + req.Header.Set("Accept", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return "", err + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + + byt := []byte(body) + var dat map[string]interface{} + if err := json.Unmarshal(byt, &dat); err != nil { + return "", err + } + return dat["tag_name"].(string), nil +} + +// RecordLastUpdateCheck records last time an update check was performed +func (u *Updater) RecordLastUpdateCheck() error { + u.Config.GetAppState().LastUpdateCheck = time.Now().Unix() + return u.Config.SaveAppState() +} + +// expecting version to be of the form `v12.34.56` +func (u *Updater) majorVersionDiffers(oldVersion, newVersion string) bool { + if oldVersion == "unversioned" { + return false + } + oldVersion = strings.TrimPrefix(oldVersion, "v") + newVersion = strings.TrimPrefix(newVersion, "v") + return strings.Split(oldVersion, ".")[0] != strings.Split(newVersion, ".")[0] +} + +func (u *Updater) checkForNewUpdate() (string, error) { + u.Log.Info("Checking for an updated version") + currentVersion := u.Config.GetVersion() + if err := u.RecordLastUpdateCheck(); err != nil { + return "", err + } + + newVersion, err := u.getLatestVersionNumber() + if err != nil { + return "", err + } + u.Log.Info("Current version is " + currentVersion) + u.Log.Info("New version is " + newVersion) + + if newVersion == currentVersion { + return "", errors.New(u.Tr.SLocalize("OnLatestVersionErr")) + } + + if u.majorVersionDiffers(currentVersion, newVersion) { + errMessage := u.Tr.TemplateLocalize( + "MajorVersionErr", + i18n.Teml{ + "newVersion": newVersion, + "currentVersion": currentVersion, + }, + ) + return "", errors.New(errMessage) + } + + rawUrl, err := u.getBinaryUrl(newVersion) + if err != nil { + return "", err + } + u.Log.Info("Checking for resource at url " + rawUrl) + if !u.verifyResourceFound(rawUrl) { + errMessage := u.Tr.TemplateLocalize( + "CouldNotFindBinaryErr", + i18n.Teml{ + "url": rawUrl, + }, + ) + return "", errors.New(errMessage) + } + u.Log.Info("Verified resource is available, ready to update") + + return newVersion, nil +} + +// CheckForNewUpdate checks if there is an available update +func (u *Updater) CheckForNewUpdate(onFinish func(string, error) error, userRequested bool) { + if !userRequested && u.skipUpdateCheck() { + return + } + + go func() { + newVersion, err := u.checkForNewUpdate() + if err = onFinish(newVersion, err); err != nil { + u.Log.Error(err) + } + }() +} + +func (u *Updater) skipUpdateCheck() bool { + // will remove the check for windows after adding a manifest file asking for + // the required permissions + if runtime.GOOS == "windows" { + u.Log.Info("Updating is currently not supported for windows until we can fix permission issues") + return true + } + + if u.Config.GetVersion() == "unversioned" { + u.Log.Info("Current version is not built from an official release so we won't check for an update") + return true + } + + if u.Config.GetBuildSource() != "buildBinary" { + u.Log.Info("Binary is not built with the buildBinary flag so we won't check for an update") + return true + } + + userConfig := u.Config.GetUserConfig() + if userConfig.Get("update.method") == "never" { + u.Log.Info("Update method is set to never so we won't check for an update") + return true + } + + currentTimestamp := time.Now().Unix() + lastUpdateCheck := u.Config.GetAppState().LastUpdateCheck + days := userConfig.GetInt64("update.days") + + if (currentTimestamp-lastUpdateCheck)/(60*60*24) < days { + u.Log.Info("Last update was too recent so we won't check for an update") + return true + } + + return false +} + +func (u *Updater) mappedOs(os string) string { + osMap := map[string]string{ + "darwin": "Darwin", + "linux": "Linux", + "windows": "Windows", + } + result, found := osMap[os] + if found { + return result + } + return os +} + +func (u *Updater) mappedArch(arch string) string { + archMap := map[string]string{ + "386": "32-bit", + "amd64": "x86_64", + } + result, found := archMap[arch] + if found { + return result + } + return arch +} + +// example: https://github.com/jesseduffield/lazygit/releases/download/v0.1.73/lazygit_0.1.73_Darwin_x86_64.tar.gz +func (u *Updater) getBinaryUrl(newVersion string) (string, error) { + extension := "tar.gz" + if runtime.GOOS == "windows" { + extension = "zip" + } + url := fmt.Sprintf( + "%s/releases/download/%s/lazygit_%s_%s_%s.%s", + projectUrl, + newVersion, + newVersion[1:], + u.mappedOs(runtime.GOOS), + u.mappedArch(runtime.GOARCH), + extension, + ) + u.Log.Info("url for latest release is " + url) + return url, nil +} + +// Update downloads the latest binary and replaces the current binary with it +func (u *Updater) Update(newVersion string, onFinish func(error) error) { + go func() { + err := u.update(newVersion) + if err = onFinish(err); err != nil { + u.Log.Error(err) + } + }() +} + +func (u *Updater) update(newVersion string) error { + rawUrl, err := u.getBinaryUrl(newVersion) + if err != nil { + return err + } + u.Log.Info("updating with url " + rawUrl) + return u.downloadAndInstall(rawUrl) +} + +func (u *Updater) downloadAndInstall(rawUrl string) error { + url, err := url.Parse(rawUrl) + if err != nil { + return err + } + + g := new(getter.HttpGetter) + tempDir, err := ioutil.TempDir("", "lazygit") + if err != nil { + return err + } + defer os.RemoveAll(tempDir) + u.Log.Info("temp directory is " + tempDir) + + // Get it! + if err := g.Get(tempDir, url); err != nil { + return err + } + + // get the path of the current binary + binaryPath, err := osext.Executable() + if err != nil { + return err + } + u.Log.Info("binary path is " + binaryPath) + + binaryName := filepath.Base(binaryPath) + u.Log.Info("binary name is " + binaryName) + + // Verify the main file exists + tempPath := filepath.Join(tempDir, binaryName) + u.Log.Info("temp path to binary is " + tempPath) + if _, err := os.Stat(tempPath); err != nil { + return err + } + + // swap out the old binary for the new one + err = os.Rename(tempPath, binaryPath) + if err != nil { + return err + } + u.Log.Info("update complete!") + + return nil +} + +func (u *Updater) verifyResourceFound(rawUrl string) bool { + resp, err := http.Head(rawUrl) + if err != nil { + return false + } + defer resp.Body.Close() + u.Log.Info("Received status code ", resp.StatusCode) + // 403 means the resource is there (not going to bother adding extra request headers) + // 404 means its not + return resp.StatusCode == 403 +} diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 68438246a..e28ab1824 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -6,6 +6,7 @@ import ( "os" "path/filepath" "strings" + "time" "github.com/fatih/color" ) @@ -63,3 +64,38 @@ func TrimTrailingNewline(str string) string { } return str } + +// NormalizeLinefeeds - Removes all Windows and Mac style line feeds +func NormalizeLinefeeds(str string) string { + str = strings.Replace(str, "\r\n", "\n", -1) + str = strings.Replace(str, "\r", "", -1) + return str +} + +// GetProjectRoot returns the path to the root of the project. Only to be used +// in testing contexts, as with binaries it's unlikely this path will exist on +// the machine +func GetProjectRoot() string { + dir, err := os.Getwd() + if err != nil { + panic(err) + } + return strings.Split(dir, "lazygit")[0] + "lazygit" +} + +// Loader dumps a string to be displayed as a loader +func Loader() string { + characters := "|/-\\" + now := time.Now() + nanos := now.UnixNano() + index := nanos / 50000000 % int64(len(characters)) + return characters[index : index+1] +} + +// ResolvePlaceholderString populates a template with values +func ResolvePlaceholderString(str string, arguments map[string]string) string { + for key, value := range arguments { + str = strings.Replace(str, "{{"+key+"}}", value, -1) + } + return str +} diff --git a/pkg/utils/utils_test.go b/pkg/utils/utils_test.go new file mode 100644 index 000000000..0b2d35959 --- /dev/null +++ b/pkg/utils/utils_test.go @@ -0,0 +1,169 @@ +package utils + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestSplitLines(t *testing.T) { + type scenario struct { + multilineString string + expected []string + } + + scenarios := []scenario{ + { + "", + []string{}, + }, + { + "\n", + []string{}, + }, + { + "hello world !\nhello universe !\n", + []string{ + "hello world !", + "hello universe !", + }, + }, + } + + for _, s := range scenarios { + assert.EqualValues(t, s.expected, SplitLines(s.multilineString)) + } +} + +func TestWithPadding(t *testing.T) { + type scenario struct { + str string + padding int + expected string + } + + scenarios := []scenario{ + { + "hello world !", + 1, + "hello world !", + }, + { + "hello world !", + 14, + "hello world ! ", + }, + } + + for _, s := range scenarios { + assert.EqualValues(t, s.expected, WithPadding(s.str, s.padding)) + } +} + +func TestTrimTrailingNewline(t *testing.T) { + type scenario struct { + str string + expected string + } + + scenarios := []scenario{ + { + "hello world !\n", + "hello world !", + }, + { + "hello world !", + "hello world !", + }, + } + + for _, s := range scenarios { + assert.EqualValues(t, s.expected, TrimTrailingNewline(s.str)) + } +} + +func TestNormalizeLinefeeds(t *testing.T) { + type scenario struct { + byteArray []byte + expected []byte + } + var scenarios = []scenario{ + { + // \r\n + []byte{97, 115, 100, 102, 13, 10}, + []byte{97, 115, 100, 102, 10}, + }, + { + // bash\r\nblah + []byte{97, 115, 100, 102, 13, 10, 97, 115, 100, 102}, + []byte{97, 115, 100, 102, 10, 97, 115, 100, 102}, + }, + { + // \r + []byte{97, 115, 100, 102, 13}, + []byte{97, 115, 100, 102}, + }, + { + // \n + []byte{97, 115, 100, 102, 10}, + []byte{97, 115, 100, 102, 10}, + }, + } + + for _, s := range scenarios { + assert.EqualValues(t, string(s.expected), NormalizeLinefeeds(string(s.byteArray))) + } +} + +func TestResolvePlaceholderString(t *testing.T) { + type scenario struct { + templateString string + arguments map[string]string + expected string + } + + scenarios := []scenario{ + { + "", + map[string]string{}, + "", + }, + { + "hello", + map[string]string{}, + "hello", + }, + { + "hello {{arg}}", + map[string]string{}, + "hello {{arg}}", + }, + { + "hello {{arg}}", + map[string]string{"arg": "there"}, + "hello there", + }, + { + "hello", + map[string]string{"arg": "there"}, + "hello", + }, + { + "{{nothing}}", + map[string]string{"nothing": ""}, + "", + }, + { + "{{}} {{ this }} { should not throw}} an {{{{}}}} error", + map[string]string{ + "blah": "blah", + "this": "won't match", + }, + "{{}} {{ this }} { should not throw}} an {{{{}}}} error", + }, + } + + for _, s := range scenarios { + assert.EqualValues(t, string(s.expected), ResolvePlaceholderString(s.templateString, s.arguments)) + } +} diff --git a/scripts/generate_cheatsheet.go b/scripts/generate_cheatsheet.go new file mode 100644 index 000000000..cfa6d92ad --- /dev/null +++ b/scripts/generate_cheatsheet.go @@ -0,0 +1,54 @@ +// run: +// LANG=en go run generate_cheatsheet.go +// to generate Keybindings_en.md file in current directory +// change LANG to generate cheatsheet in different language (if supported) + +package main + +import ( + "fmt" + "os" + "strings" + + "github.com/jesseduffield/lazygit/pkg/app" + "github.com/jesseduffield/lazygit/pkg/config" + "github.com/jesseduffield/lazygit/pkg/utils" +) + +func main() { + appConfig, _ := config.NewAppConfig("", "", "", "", "", new(bool)) + a, _ := app.NewApp(appConfig) + lang := a.Tr.GetLanguage() + name := "Keybindings_" + lang + ".md" + bindings := a.Gui.GetKeybindings() + padWidth := a.Gui.GetMaxKeyLength(bindings) + file, _ := os.Create(name) + current := "v" + content := "" + title := "" + + file.WriteString("# Lazygit " + a.Tr.SLocalize("menu")) + + for _, binding := range bindings { + if key := a.Gui.GetKey(binding); key != "" && (binding.Description != "" || key == "x") { + if binding.ViewName != current { + current = binding.ViewName + if current == "" { + title = a.Tr.SLocalize("GlobalTitle") + } else { + title = a.Tr.SLocalize(strings.Title(current) + "Title") + } + content = fmt.Sprintf("\n\n## %s\n
\n", title)
+				file.WriteString(content)
+			}
+			// workaround to include menu keybinding in cheatsheet
+			// could not add this Description field directly to keybindings.go,
+			// because then menu key would be displayed in menu itself and that is undesirable
+			if key == "x" {
+				binding.Description = a.Tr.SLocalize("menu")
+			}
+			content = fmt.Sprintf("\t%s%s  %s\n", key, strings.TrimPrefix(utils.WithPadding(key, padWidth), key), binding.Description)
+			file.WriteString(content)
+		}
+	}
+}
diff --git a/test.sh b/test.sh
new file mode 100755
index 000000000..a1ab4301f
--- /dev/null
+++ b/test.sh
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+
+set -e
+echo "" > coverage.txt
+
+for d in $( find ./* -maxdepth 10 ! -path "./vendor*" ! -path "./.git*" ! -path "./scripts*" -type d); do
+    if ls $d/*.go &> /dev/null; then
+        go test -v -race -coverprofile=profile.out -covermode=atomic $d
+        if [ -f profile.out ]; then
+            cat profile.out >> coverage.txt
+            rm profile.out
+        fi
+    fi
+done
diff --git a/test/repos/bom.sh b/test/repos/bom.sh
new file mode 100755
index 000000000..190f501a1
--- /dev/null
+++ b/test/repos/bom.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+set -ex; rm -rf repo; mkdir repo; cd repo
+
+git init
+
+cat <> windowslf.txt
+asdf
+asdf
+EOT
+
+cat <> linuxlf.txt
+asdf
+asdf
+EOT
+
+cat <> bomtest.txt
+A,B,C,D,E
+F,G,H,I,J
+K,L,M,N,O
+P,Q,R,S,T
+U,V,W,X,Y
+Z,1,2,3,4
+EOT
diff --git a/test/repos/case_insensitive_checkouts.sh b/test/repos/case_insensitive_checkouts.sh
index 23997a670..1a2b83403 100755
--- a/test/repos/case_insensitive_checkouts.sh
+++ b/test/repos/case_insensitive_checkouts.sh
@@ -2,6 +2,9 @@
 set -ex; rm -rf repo; mkdir repo; cd repo
 
 git init
+git config user.email "test@example.com"
+git config user.name "Lazygit Tester"
+
 
 touch foo
 git add foo
diff --git a/test/repos/gpg.sh b/test/repos/gpg.sh
index 719c6467b..646f785b1 100755
--- a/test/repos/gpg.sh
+++ b/test/repos/gpg.sh
@@ -2,6 +2,9 @@
 set -ex; rm -rf repo; mkdir repo; cd repo
 
 git init
+git config user.email "test@example.com"
+git config user.name "Lazygit Tester"
+
 
 git config gpg.program $(which gpg)
 git config user.signingkey E304229F # test key
diff --git a/test/repos/lots_of_commits.sh b/test/repos/lots_of_commits.sh
index 7c271f751..ad55864c3 100755
--- a/test/repos/lots_of_commits.sh
+++ b/test/repos/lots_of_commits.sh
@@ -2,6 +2,9 @@
 set -ex; rm -rf repo; mkdir repo; cd repo
 
 git init
+git config user.email "test@example.com"
+git config user.name "Lazygit Tester"
+
 
 i=2
 end=100
diff --git a/test/repos/lots_of_diffs.sh b/test/repos/lots_of_diffs.sh
new file mode 100755
index 000000000..08c743f35
--- /dev/null
+++ b/test/repos/lots_of_diffs.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+set -ex; rm -rf repo; mkdir repo; cd repo
+
+git init
+git config user.email "test@example.com"
+git config user.name "Lazygit Tester"
+
+
+echo "deleted" > deleted_staged
+echo "deleted_unstaged" > deleted_unstaged
+echo "modified_staged" > modified_staged
+echo "modified_unstaged" > modified_unstaged
+echo "renamed" > renamed_before
+
+git add .
+git commit -m "files to delete"
+rm deleted_staged
+rm deleted_unstaged
+
+rm renamed_before
+echo "renamed" > renamed_after
+echo "more" >> modified_staged
+echo "more" >> modified_unstaged
+echo "untracked_staged" > untracked_staged
+echo "untracked_unstaged" > untracked_unstaged
+echo "blah" > "file with space staged"
+echo "blah" > "file with space unstaged"
+echo "same name as branch" > master
+
+git add deleted_staged
+git add modified_staged
+git add untracked_staged
+git add "file with space staged"
+git add renamed_before
+git add renamed_after
\ No newline at end of file
diff --git a/test/repos/merge_conflict.sh b/test/repos/merge_conflict.sh
index 8ba234203..357597719 100755
--- a/test/repos/merge_conflict.sh
+++ b/test/repos/merge_conflict.sh
@@ -2,6 +2,9 @@
 set -ex; rm -rf repo; mkdir repo; cd repo
 
 git init
+git config user.email "test@example.com"
+git config user.name "Lazygit Tester"
+
 
 function add_spacing {
   for i in {1..60}
@@ -10,9 +13,15 @@ function add_spacing {
   done
 }
 
+mkdir directory
+echo "test1" > directory/file
+echo "test1" > directory/file2
+
+
 echo "Here is a story that has been told throuhg the ages" >> file1
 
 git add file1
+git add directory
 git commit -m "first commit"
 
 git checkout -b develop
@@ -21,6 +30,11 @@ echo "once upon a time there was a dog" >> file1
 add_spacing file1
 echo "once upon a time there was another dog" >> file1
 git add file1
+
+echo "test2" > directory/file
+echo "test2" > directory/file2
+git add directory
+
 git commit -m "first commit on develop"
 
 git checkout master
@@ -29,6 +43,11 @@ echo "once upon a time there was a cat" >> file1
 add_spacing file1
 echo "once upon a time there was another cat" >> file1
 git add file1
+
+echo "test3" > directory/file
+echo "test3" > directory/file2
+git add directory
+
 git commit -m "first commit on develop"
 
 git merge develop # should have a merge conflict here
diff --git a/test/repos/pre_commit_hook.sh b/test/repos/pre_commit_hook.sh
index 1c24bf19f..f1b76b56a 100755
--- a/test/repos/pre_commit_hook.sh
+++ b/test/repos/pre_commit_hook.sh
@@ -2,6 +2,9 @@
 set -ex; rm -rf repo; mkdir repo; cd repo
 
 git init
+git config user.email "test@example.com"
+git config user.name "Lazygit Tester"
+
 cp ../extras/pre-commit .git/hooks/pre-commit
 chmod +x .git/hooks/pre-commit
 
diff --git a/test/repos/unicode_characters.sh b/test/repos/unicode_characters.sh
index 69ac5e622..3ae129751 100755
--- a/test/repos/unicode_characters.sh
+++ b/test/repos/unicode_characters.sh
@@ -2,6 +2,9 @@
 set -ex; rm -rf repo; mkdir repo; cd repo
 
 git init
+git config user.email "test@example.com"
+git config user.name "Lazygit Tester"
+
 
 # Add some ansi, unicode, zero width joiner caracters
 cat <> charstest.txt
@@ -12,9 +15,8 @@ ZWJ       https://en.wikipedia.org/wiki/Zero-width_joiner / https://unicode.org/
 UNICODE   ☆ 🤓 え 术
 EOT
 git add charstest.txt
-git commit -m "Test chars Œ¥ƒ👶👨‍👦☆ 🤓 え 术 commit"
+git commit -m "Test chars Œ¥ƒ👶👨‍👦☆ 🤓 え 术👩‍💻👩🏻‍💻👩🏽‍💻👩🏼‍💻👩🏾‍💻👩🏿‍💻👨‍💻👨🏻‍💻👨🏼‍💻👨🏽‍💻👨🏾‍💻👨🏿‍💻 commit"
 echo "我喜歡編碼" >> charstest.txt
 echo "நான் குறியீடு விரும்புகிறேன்" >> charstest.txt
 git add charstest.txt
 git commit -m "Test chars 我喜歡編碼 நான் குறியீடு விரும்புகிறேன் commit"
-
diff --git a/vendor/github.com/aws/aws-sdk-go/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go/LICENSE.txt
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/LICENSE.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/vendor/github.com/aws/aws-sdk-go/NOTICE.txt b/vendor/github.com/aws/aws-sdk-go/NOTICE.txt
new file mode 100644
index 000000000..5f14d1162
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/NOTICE.txt
@@ -0,0 +1,3 @@
+AWS SDK for Go
+Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. 
+Copyright 2014-2015 Stripe, Inc.
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go b/vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go
new file mode 100644
index 000000000..56fdfc2bf
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go
@@ -0,0 +1,145 @@
+// Package awserr represents API error interface accessors for the SDK.
+package awserr
+
+// An Error wraps lower level errors with code, message and an original error.
+// The underlying concrete error type may also satisfy other interfaces which
+// can be to used to obtain more specific information about the error.
+//
+// Calling Error() or String() will always include the full information about
+// an error based on its underlying type.
+//
+// Example:
+//
+//     output, err := s3manage.Upload(svc, input, opts)
+//     if err != nil {
+//         if awsErr, ok := err.(awserr.Error); ok {
+//             // Get error details
+//             log.Println("Error:", awsErr.Code(), awsErr.Message())
+//
+//             // Prints out full error message, including original error if there was one.
+//             log.Println("Error:", awsErr.Error())
+//
+//             // Get original error
+//             if origErr := awsErr.OrigErr(); origErr != nil {
+//                 // operate on original error.
+//             }
+//         } else {
+//             fmt.Println(err.Error())
+//         }
+//     }
+//
+type Error interface {
+	// Satisfy the generic error interface.
+	error
+
+	// Returns the short phrase depicting the classification of the error.
+	Code() string
+
+	// Returns the error details message.
+	Message() string
+
+	// Returns the original error if one was set.  Nil is returned if not set.
+	OrigErr() error
+}
+
+// BatchError is a batch of errors which also wraps lower level errors with
+// code, message, and original errors. Calling Error() will include all errors
+// that occurred in the batch.
+//
+// Deprecated: Replaced with BatchedErrors. Only defined for backwards
+// compatibility.
+type BatchError interface {
+	// Satisfy the generic error interface.
+	error
+
+	// Returns the short phrase depicting the classification of the error.
+	Code() string
+
+	// Returns the error details message.
+	Message() string
+
+	// Returns the original error if one was set.  Nil is returned if not set.
+	OrigErrs() []error
+}
+
+// BatchedErrors is a batch of errors which also wraps lower level errors with
+// code, message, and original errors. Calling Error() will include all errors
+// that occurred in the batch.
+//
+// Replaces BatchError
+type BatchedErrors interface {
+	// Satisfy the base Error interface.
+	Error
+
+	// Returns the original error if one was set.  Nil is returned if not set.
+	OrigErrs() []error
+}
+
+// New returns an Error object described by the code, message, and origErr.
+//
+// If origErr satisfies the Error interface it will not be wrapped within a new
+// Error object and will instead be returned.
+func New(code, message string, origErr error) Error {
+	var errs []error
+	if origErr != nil {
+		errs = append(errs, origErr)
+	}
+	return newBaseError(code, message, errs)
+}
+
+// NewBatchError returns an BatchedErrors with a collection of errors as an
+// array of errors.
+func NewBatchError(code, message string, errs []error) BatchedErrors {
+	return newBaseError(code, message, errs)
+}
+
+// A RequestFailure is an interface to extract request failure information from
+// an Error such as the request ID of the failed request returned by a service.
+// RequestFailures may not always have a requestID value if the request failed
+// prior to reaching the service such as a connection error.
+//
+// Example:
+//
+//     output, err := s3manage.Upload(svc, input, opts)
+//     if err != nil {
+//         if reqerr, ok := err.(RequestFailure); ok {
+//             log.Println("Request failed", reqerr.Code(), reqerr.Message(), reqerr.RequestID())
+//         } else {
+//             log.Println("Error:", err.Error())
+//         }
+//     }
+//
+// Combined with awserr.Error:
+//
+//    output, err := s3manage.Upload(svc, input, opts)
+//    if err != nil {
+//        if awsErr, ok := err.(awserr.Error); ok {
+//            // Generic AWS Error with Code, Message, and original error (if any)
+//            fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr())
+//
+//            if reqErr, ok := err.(awserr.RequestFailure); ok {
+//                // A service error occurred
+//                fmt.Println(reqErr.StatusCode(), reqErr.RequestID())
+//            }
+//        } else {
+//            fmt.Println(err.Error())
+//        }
+//    }
+//
+type RequestFailure interface {
+	Error
+
+	// The status code of the HTTP response.
+	StatusCode() int
+
+	// The request ID returned by the service for a request failure. This will
+	// be empty if no request ID is available such as the request failed due
+	// to a connection error.
+	RequestID() string
+}
+
+// NewRequestFailure returns a new request error wrapper for the given Error
+// provided.
+func NewRequestFailure(err Error, statusCode int, reqID string) RequestFailure {
+	return newRequestError(err, statusCode, reqID)
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go b/vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go
new file mode 100644
index 000000000..0202a008f
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go
@@ -0,0 +1,194 @@
+package awserr
+
+import "fmt"
+
+// SprintError returns a string of the formatted error code.
+//
+// Both extra and origErr are optional.  If they are included their lines
+// will be added, but if they are not included their lines will be ignored.
+func SprintError(code, message, extra string, origErr error) string {
+	msg := fmt.Sprintf("%s: %s", code, message)
+	if extra != "" {
+		msg = fmt.Sprintf("%s\n\t%s", msg, extra)
+	}
+	if origErr != nil {
+		msg = fmt.Sprintf("%s\ncaused by: %s", msg, origErr.Error())
+	}
+	return msg
+}
+
+// A baseError wraps the code and message which defines an error. It also
+// can be used to wrap an original error object.
+//
+// Should be used as the root for errors satisfying the awserr.Error. Also
+// for any error which does not fit into a specific error wrapper type.
+type baseError struct {
+	// Classification of error
+	code string
+
+	// Detailed information about error
+	message string
+
+	// Optional original error this error is based off of. Allows building
+	// chained errors.
+	errs []error
+}
+
+// newBaseError returns an error object for the code, message, and errors.
+//
+// code is a short no whitespace phrase depicting the classification of
+// the error that is being created.
+//
+// message is the free flow string containing detailed information about the
+// error.
+//
+// origErrs is the error objects which will be nested under the new errors to
+// be returned.
+func newBaseError(code, message string, origErrs []error) *baseError {
+	b := &baseError{
+		code:    code,
+		message: message,
+		errs:    origErrs,
+	}
+
+	return b
+}
+
+// Error returns the string representation of the error.
+//
+// See ErrorWithExtra for formatting.
+//
+// Satisfies the error interface.
+func (b baseError) Error() string {
+	size := len(b.errs)
+	if size > 0 {
+		return SprintError(b.code, b.message, "", errorList(b.errs))
+	}
+
+	return SprintError(b.code, b.message, "", nil)
+}
+
+// String returns the string representation of the error.
+// Alias for Error to satisfy the stringer interface.
+func (b baseError) String() string {
+	return b.Error()
+}
+
+// Code returns the short phrase depicting the classification of the error.
+func (b baseError) Code() string {
+	return b.code
+}
+
+// Message returns the error details message.
+func (b baseError) Message() string {
+	return b.message
+}
+
+// OrigErr returns the original error if one was set. Nil is returned if no
+// error was set. This only returns the first element in the list. If the full
+// list is needed, use BatchedErrors.
+func (b baseError) OrigErr() error {
+	switch len(b.errs) {
+	case 0:
+		return nil
+	case 1:
+		return b.errs[0]
+	default:
+		if err, ok := b.errs[0].(Error); ok {
+			return NewBatchError(err.Code(), err.Message(), b.errs[1:])
+		}
+		return NewBatchError("BatchedErrors",
+			"multiple errors occurred", b.errs)
+	}
+}
+
+// OrigErrs returns the original errors if one was set. An empty slice is
+// returned if no error was set.
+func (b baseError) OrigErrs() []error {
+	return b.errs
+}
+
+// So that the Error interface type can be included as an anonymous field
+// in the requestError struct and not conflict with the error.Error() method.
+type awsError Error
+
+// A requestError wraps a request or service error.
+//
+// Composed of baseError for code, message, and original error.
+type requestError struct {
+	awsError
+	statusCode int
+	requestID  string
+}
+
+// newRequestError returns a wrapped error with additional information for
+// request status code, and service requestID.
+//
+// Should be used to wrap all request which involve service requests. Even if
+// the request failed without a service response, but had an HTTP status code
+// that may be meaningful.
+//
+// Also wraps original errors via the baseError.
+func newRequestError(err Error, statusCode int, requestID string) *requestError {
+	return &requestError{
+		awsError:   err,
+		statusCode: statusCode,
+		requestID:  requestID,
+	}
+}
+
+// Error returns the string representation of the error.
+// Satisfies the error interface.
+func (r requestError) Error() string {
+	extra := fmt.Sprintf("status code: %d, request id: %s",
+		r.statusCode, r.requestID)
+	return SprintError(r.Code(), r.Message(), extra, r.OrigErr())
+}
+
+// String returns the string representation of the error.
+// Alias for Error to satisfy the stringer interface.
+func (r requestError) String() string {
+	return r.Error()
+}
+
+// StatusCode returns the wrapped status code for the error
+func (r requestError) StatusCode() int {
+	return r.statusCode
+}
+
+// RequestID returns the wrapped requestID
+func (r requestError) RequestID() string {
+	return r.requestID
+}
+
+// OrigErrs returns the original errors if one was set. An empty slice is
+// returned if no error was set.
+func (r requestError) OrigErrs() []error {
+	if b, ok := r.awsError.(BatchedErrors); ok {
+		return b.OrigErrs()
+	}
+	return []error{r.OrigErr()}
+}
+
+// An error list that satisfies the golang interface
+type errorList []error
+
+// Error returns the string representation of the error.
+//
+// Satisfies the error interface.
+func (e errorList) Error() string {
+	msg := ""
+	// How do we want to handle the array size being zero
+	if size := len(e); size > 0 {
+		for i := 0; i < size; i++ {
+			msg += fmt.Sprintf("%s", e[i].Error())
+			// We check the next index to see if it is within the slice.
+			// If it is, then we append a newline. We do this, because unit tests
+			// could be broken with the additional '\n'
+			if i+1 < size {
+				msg += "\n"
+			}
+		}
+	}
+	return msg
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go
new file mode 100644
index 000000000..1a3d106d5
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go
@@ -0,0 +1,108 @@
+package awsutil
+
+import (
+	"io"
+	"reflect"
+	"time"
+)
+
+// Copy deeply copies a src structure to dst. Useful for copying request and
+// response structures.
+//
+// Can copy between structs of different type, but will only copy fields which
+// are assignable, and exist in both structs. Fields which are not assignable,
+// or do not exist in both structs are ignored.
+func Copy(dst, src interface{}) {
+	dstval := reflect.ValueOf(dst)
+	if !dstval.IsValid() {
+		panic("Copy dst cannot be nil")
+	}
+
+	rcopy(dstval, reflect.ValueOf(src), true)
+}
+
+// CopyOf returns a copy of src while also allocating the memory for dst.
+// src must be a pointer type or this operation will fail.
+func CopyOf(src interface{}) (dst interface{}) {
+	dsti := reflect.New(reflect.TypeOf(src).Elem())
+	dst = dsti.Interface()
+	rcopy(dsti, reflect.ValueOf(src), true)
+	return
+}
+
+// rcopy performs a recursive copy of values from the source to destination.
+//
+// root is used to skip certain aspects of the copy which are not valid
+// for the root node of a object.
+func rcopy(dst, src reflect.Value, root bool) {
+	if !src.IsValid() {
+		return
+	}
+
+	switch src.Kind() {
+	case reflect.Ptr:
+		if _, ok := src.Interface().(io.Reader); ok {
+			if dst.Kind() == reflect.Ptr && dst.Elem().CanSet() {
+				dst.Elem().Set(src)
+			} else if dst.CanSet() {
+				dst.Set(src)
+			}
+		} else {
+			e := src.Type().Elem()
+			if dst.CanSet() && !src.IsNil() {
+				if _, ok := src.Interface().(*time.Time); !ok {
+					dst.Set(reflect.New(e))
+				} else {
+					tempValue := reflect.New(e)
+					tempValue.Elem().Set(src.Elem())
+					// Sets time.Time's unexported values
+					dst.Set(tempValue)
+				}
+			}
+			if src.Elem().IsValid() {
+				// Keep the current root state since the depth hasn't changed
+				rcopy(dst.Elem(), src.Elem(), root)
+			}
+		}
+	case reflect.Struct:
+		t := dst.Type()
+		for i := 0; i < t.NumField(); i++ {
+			name := t.Field(i).Name
+			srcVal := src.FieldByName(name)
+			dstVal := dst.FieldByName(name)
+			if srcVal.IsValid() && dstVal.CanSet() {
+				rcopy(dstVal, srcVal, false)
+			}
+		}
+	case reflect.Slice:
+		if src.IsNil() {
+			break
+		}
+
+		s := reflect.MakeSlice(src.Type(), src.Len(), src.Cap())
+		dst.Set(s)
+		for i := 0; i < src.Len(); i++ {
+			rcopy(dst.Index(i), src.Index(i), false)
+		}
+	case reflect.Map:
+		if src.IsNil() {
+			break
+		}
+
+		s := reflect.MakeMap(src.Type())
+		dst.Set(s)
+		for _, k := range src.MapKeys() {
+			v := src.MapIndex(k)
+			v2 := reflect.New(v.Type()).Elem()
+			rcopy(v2, v, false)
+			dst.SetMapIndex(k, v2)
+		}
+	default:
+		// Assign the value if possible. If its not assignable, the value would
+		// need to be converted and the impact of that may be unexpected, or is
+		// not compatible with the dst type.
+		if src.Type().AssignableTo(dst.Type()) {
+			dst.Set(src)
+		}
+	}
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go
new file mode 100644
index 000000000..59fa4a558
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go
@@ -0,0 +1,27 @@
+package awsutil
+
+import (
+	"reflect"
+)
+
+// DeepEqual returns if the two values are deeply equal like reflect.DeepEqual.
+// In addition to this, this method will also dereference the input values if
+// possible so the DeepEqual performed will not fail if one parameter is a
+// pointer and the other is not.
+//
+// DeepEqual will not perform indirection of nested values of the input parameters.
+func DeepEqual(a, b interface{}) bool {
+	ra := reflect.Indirect(reflect.ValueOf(a))
+	rb := reflect.Indirect(reflect.ValueOf(b))
+
+	if raValid, rbValid := ra.IsValid(), rb.IsValid(); !raValid && !rbValid {
+		// If the elements are both nil, and of the same type the are equal
+		// If they are of different types they are not equal
+		return reflect.TypeOf(a) == reflect.TypeOf(b)
+	} else if raValid != rbValid {
+		// Both values must be valid to be equal
+		return false
+	}
+
+	return reflect.DeepEqual(ra.Interface(), rb.Interface())
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go
new file mode 100644
index 000000000..11c52c389
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go
@@ -0,0 +1,222 @@
+package awsutil
+
+import (
+	"reflect"
+	"regexp"
+	"strconv"
+	"strings"
+
+	"github.com/jmespath/go-jmespath"
+)
+
+var indexRe = regexp.MustCompile(`(.+)\[(-?\d+)?\]$`)
+
+// rValuesAtPath returns a slice of values found in value v. The values
+// in v are explored recursively so all nested values are collected.
+func rValuesAtPath(v interface{}, path string, createPath, caseSensitive, nilTerm bool) []reflect.Value {
+	pathparts := strings.Split(path, "||")
+	if len(pathparts) > 1 {
+		for _, pathpart := range pathparts {
+			vals := rValuesAtPath(v, pathpart, createPath, caseSensitive, nilTerm)
+			if len(vals) > 0 {
+				return vals
+			}
+		}
+		return nil
+	}
+
+	values := []reflect.Value{reflect.Indirect(reflect.ValueOf(v))}
+	components := strings.Split(path, ".")
+	for len(values) > 0 && len(components) > 0 {
+		var index *int64
+		var indexStar bool
+		c := strings.TrimSpace(components[0])
+		if c == "" { // no actual component, illegal syntax
+			return nil
+		} else if caseSensitive && c != "*" && strings.ToLower(c[0:1]) == c[0:1] {
+			// TODO normalize case for user
+			return nil // don't support unexported fields
+		}
+
+		// parse this component
+		if m := indexRe.FindStringSubmatch(c); m != nil {
+			c = m[1]
+			if m[2] == "" {
+				index = nil
+				indexStar = true
+			} else {
+				i, _ := strconv.ParseInt(m[2], 10, 32)
+				index = &i
+				indexStar = false
+			}
+		}
+
+		nextvals := []reflect.Value{}
+		for _, value := range values {
+			// pull component name out of struct member
+			if value.Kind() != reflect.Struct {
+				continue
+			}
+
+			if c == "*" { // pull all members
+				for i := 0; i < value.NumField(); i++ {
+					if f := reflect.Indirect(value.Field(i)); f.IsValid() {
+						nextvals = append(nextvals, f)
+					}
+				}
+				continue
+			}
+
+			value = value.FieldByNameFunc(func(name string) bool {
+				if c == name {
+					return true
+				} else if !caseSensitive && strings.ToLower(name) == strings.ToLower(c) {
+					return true
+				}
+				return false
+			})
+
+			if nilTerm && value.Kind() == reflect.Ptr && len(components[1:]) == 0 {
+				if !value.IsNil() {
+					value.Set(reflect.Zero(value.Type()))
+				}
+				return []reflect.Value{value}
+			}
+
+			if createPath && value.Kind() == reflect.Ptr && value.IsNil() {
+				// TODO if the value is the terminus it should not be created
+				// if the value to be set to its position is nil.
+				value.Set(reflect.New(value.Type().Elem()))
+				value = value.Elem()
+			} else {
+				value = reflect.Indirect(value)
+			}
+
+			if value.Kind() == reflect.Slice || value.Kind() == reflect.Map {
+				if !createPath && value.IsNil() {
+					value = reflect.ValueOf(nil)
+				}
+			}
+
+			if value.IsValid() {
+				nextvals = append(nextvals, value)
+			}
+		}
+		values = nextvals
+
+		if indexStar || index != nil {
+			nextvals = []reflect.Value{}
+			for _, valItem := range values {
+				value := reflect.Indirect(valItem)
+				if value.Kind() != reflect.Slice {
+					continue
+				}
+
+				if indexStar { // grab all indices
+					for i := 0; i < value.Len(); i++ {
+						idx := reflect.Indirect(value.Index(i))
+						if idx.IsValid() {
+							nextvals = append(nextvals, idx)
+						}
+					}
+					continue
+				}
+
+				// pull out index
+				i := int(*index)
+				if i >= value.Len() { // check out of bounds
+					if createPath {
+						// TODO resize slice
+					} else {
+						continue
+					}
+				} else if i < 0 { // support negative indexing
+					i = value.Len() + i
+				}
+				value = reflect.Indirect(value.Index(i))
+
+				if value.Kind() == reflect.Slice || value.Kind() == reflect.Map {
+					if !createPath && value.IsNil() {
+						value = reflect.ValueOf(nil)
+					}
+				}
+
+				if value.IsValid() {
+					nextvals = append(nextvals, value)
+				}
+			}
+			values = nextvals
+		}
+
+		components = components[1:]
+	}
+	return values
+}
+
+// ValuesAtPath returns a list of values at the case insensitive lexical
+// path inside of a structure.
+func ValuesAtPath(i interface{}, path string) ([]interface{}, error) {
+	result, err := jmespath.Search(path, i)
+	if err != nil {
+		return nil, err
+	}
+
+	v := reflect.ValueOf(result)
+	if !v.IsValid() || (v.Kind() == reflect.Ptr && v.IsNil()) {
+		return nil, nil
+	}
+	if s, ok := result.([]interface{}); ok {
+		return s, err
+	}
+	if v.Kind() == reflect.Map && v.Len() == 0 {
+		return nil, nil
+	}
+	if v.Kind() == reflect.Slice {
+		out := make([]interface{}, v.Len())
+		for i := 0; i < v.Len(); i++ {
+			out[i] = v.Index(i).Interface()
+		}
+		return out, nil
+	}
+
+	return []interface{}{result}, nil
+}
+
+// SetValueAtPath sets a value at the case insensitive lexical path inside
+// of a structure.
+func SetValueAtPath(i interface{}, path string, v interface{}) {
+	if rvals := rValuesAtPath(i, path, true, false, v == nil); rvals != nil {
+		for _, rval := range rvals {
+			if rval.Kind() == reflect.Ptr && rval.IsNil() {
+				continue
+			}
+			setValue(rval, v)
+		}
+	}
+}
+
+func setValue(dstVal reflect.Value, src interface{}) {
+	if dstVal.Kind() == reflect.Ptr {
+		dstVal = reflect.Indirect(dstVal)
+	}
+	srcVal := reflect.ValueOf(src)
+
+	if !srcVal.IsValid() { // src is literal nil
+		if dstVal.CanAddr() {
+			// Convert to pointer so that pointer's value can be nil'ed
+			//                     dstVal = dstVal.Addr()
+		}
+		dstVal.Set(reflect.Zero(dstVal.Type()))
+
+	} else if srcVal.Kind() == reflect.Ptr {
+		if srcVal.IsNil() {
+			srcVal = reflect.Zero(dstVal.Type())
+		} else {
+			srcVal = reflect.ValueOf(src).Elem()
+		}
+		dstVal.Set(srcVal)
+	} else {
+		dstVal.Set(srcVal)
+	}
+
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go
new file mode 100644
index 000000000..710eb432f
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go
@@ -0,0 +1,113 @@
+package awsutil
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"reflect"
+	"strings"
+)
+
+// Prettify returns the string representation of a value.
+func Prettify(i interface{}) string {
+	var buf bytes.Buffer
+	prettify(reflect.ValueOf(i), 0, &buf)
+	return buf.String()
+}
+
+// prettify will recursively walk value v to build a textual
+// representation of the value.
+func prettify(v reflect.Value, indent int, buf *bytes.Buffer) {
+	for v.Kind() == reflect.Ptr {
+		v = v.Elem()
+	}
+
+	switch v.Kind() {
+	case reflect.Struct:
+		strtype := v.Type().String()
+		if strtype == "time.Time" {
+			fmt.Fprintf(buf, "%s", v.Interface())
+			break
+		} else if strings.HasPrefix(strtype, "io.") {
+			buf.WriteString("")
+			break
+		}
+
+		buf.WriteString("{\n")
+
+		names := []string{}
+		for i := 0; i < v.Type().NumField(); i++ {
+			name := v.Type().Field(i).Name
+			f := v.Field(i)
+			if name[0:1] == strings.ToLower(name[0:1]) {
+				continue // ignore unexported fields
+			}
+			if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice || f.Kind() == reflect.Map) && f.IsNil() {
+				continue // ignore unset fields
+			}
+			names = append(names, name)
+		}
+
+		for i, n := range names {
+			val := v.FieldByName(n)
+			buf.WriteString(strings.Repeat(" ", indent+2))
+			buf.WriteString(n + ": ")
+			prettify(val, indent+2, buf)
+
+			if i < len(names)-1 {
+				buf.WriteString(",\n")
+			}
+		}
+
+		buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
+	case reflect.Slice:
+		strtype := v.Type().String()
+		if strtype == "[]uint8" {
+			fmt.Fprintf(buf, " len %d", v.Len())
+			break
+		}
+
+		nl, id, id2 := "", "", ""
+		if v.Len() > 3 {
+			nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2)
+		}
+		buf.WriteString("[" + nl)
+		for i := 0; i < v.Len(); i++ {
+			buf.WriteString(id2)
+			prettify(v.Index(i), indent+2, buf)
+
+			if i < v.Len()-1 {
+				buf.WriteString("," + nl)
+			}
+		}
+
+		buf.WriteString(nl + id + "]")
+	case reflect.Map:
+		buf.WriteString("{\n")
+
+		for i, k := range v.MapKeys() {
+			buf.WriteString(strings.Repeat(" ", indent+2))
+			buf.WriteString(k.String() + ": ")
+			prettify(v.MapIndex(k), indent+2, buf)
+
+			if i < v.Len()-1 {
+				buf.WriteString(",\n")
+			}
+		}
+
+		buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
+	default:
+		if !v.IsValid() {
+			fmt.Fprint(buf, "")
+			return
+		}
+		format := "%v"
+		switch v.Interface().(type) {
+		case string:
+			format = "%q"
+		case io.ReadSeeker, io.Reader:
+			format = "buffer(%p)"
+		}
+		fmt.Fprintf(buf, format, v.Interface())
+	}
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go
new file mode 100644
index 000000000..b6432f1a1
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go
@@ -0,0 +1,89 @@
+package awsutil
+
+import (
+	"bytes"
+	"fmt"
+	"reflect"
+	"strings"
+)
+
+// StringValue returns the string representation of a value.
+func StringValue(i interface{}) string {
+	var buf bytes.Buffer
+	stringValue(reflect.ValueOf(i), 0, &buf)
+	return buf.String()
+}
+
+func stringValue(v reflect.Value, indent int, buf *bytes.Buffer) {
+	for v.Kind() == reflect.Ptr {
+		v = v.Elem()
+	}
+
+	switch v.Kind() {
+	case reflect.Struct:
+		buf.WriteString("{\n")
+
+		names := []string{}
+		for i := 0; i < v.Type().NumField(); i++ {
+			name := v.Type().Field(i).Name
+			f := v.Field(i)
+			if name[0:1] == strings.ToLower(name[0:1]) {
+				continue // ignore unexported fields
+			}
+			if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice) && f.IsNil() {
+				continue // ignore unset fields
+			}
+			names = append(names, name)
+		}
+
+		for i, n := range names {
+			val := v.FieldByName(n)
+			buf.WriteString(strings.Repeat(" ", indent+2))
+			buf.WriteString(n + ": ")
+			stringValue(val, indent+2, buf)
+
+			if i < len(names)-1 {
+				buf.WriteString(",\n")
+			}
+		}
+
+		buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
+	case reflect.Slice:
+		nl, id, id2 := "", "", ""
+		if v.Len() > 3 {
+			nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2)
+		}
+		buf.WriteString("[" + nl)
+		for i := 0; i < v.Len(); i++ {
+			buf.WriteString(id2)
+			stringValue(v.Index(i), indent+2, buf)
+
+			if i < v.Len()-1 {
+				buf.WriteString("," + nl)
+			}
+		}
+
+		buf.WriteString(nl + id + "]")
+	case reflect.Map:
+		buf.WriteString("{\n")
+
+		for i, k := range v.MapKeys() {
+			buf.WriteString(strings.Repeat(" ", indent+2))
+			buf.WriteString(k.String() + ": ")
+			stringValue(v.MapIndex(k), indent+2, buf)
+
+			if i < v.Len()-1 {
+				buf.WriteString(",\n")
+			}
+		}
+
+		buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
+	default:
+		format := "%v"
+		switch v.Interface().(type) {
+		case string:
+			format = "%q"
+		}
+		fmt.Fprintf(buf, format, v.Interface())
+	}
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/client.go b/vendor/github.com/aws/aws-sdk-go/aws/client/client.go
new file mode 100644
index 000000000..212fe25e7
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/client/client.go
@@ -0,0 +1,96 @@
+package client
+
+import (
+	"fmt"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/client/metadata"
+	"github.com/aws/aws-sdk-go/aws/request"
+)
+
+// A Config provides configuration to a service client instance.
+type Config struct {
+	Config        *aws.Config
+	Handlers      request.Handlers
+	Endpoint      string
+	SigningRegion string
+	SigningName   string
+
+	// States that the signing name did not come from a modeled source but
+	// was derived based on other data. Used by service client constructors
+	// to determine if the signin name can be overriden based on metadata the
+	// service has.
+	SigningNameDerived bool
+}
+
+// ConfigProvider provides a generic way for a service client to receive
+// the ClientConfig without circular dependencies.
+type ConfigProvider interface {
+	ClientConfig(serviceName string, cfgs ...*aws.Config) Config
+}
+
+// ConfigNoResolveEndpointProvider same as ConfigProvider except it will not
+// resolve the endpoint automatically. The service client's endpoint must be
+// provided via the aws.Config.Endpoint field.
+type ConfigNoResolveEndpointProvider interface {
+	ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) Config
+}
+
+// A Client implements the base client request and response handling
+// used by all service clients.
+type Client struct {
+	request.Retryer
+	metadata.ClientInfo
+
+	Config   aws.Config
+	Handlers request.Handlers
+}
+
+// New will return a pointer to a new initialized service client.
+func New(cfg aws.Config, info metadata.ClientInfo, handlers request.Handlers, options ...func(*Client)) *Client {
+	svc := &Client{
+		Config:     cfg,
+		ClientInfo: info,
+		Handlers:   handlers.Copy(),
+	}
+
+	switch retryer, ok := cfg.Retryer.(request.Retryer); {
+	case ok:
+		svc.Retryer = retryer
+	case cfg.Retryer != nil && cfg.Logger != nil:
+		s := fmt.Sprintf("WARNING: %T does not implement request.Retryer; using DefaultRetryer instead", cfg.Retryer)
+		cfg.Logger.Log(s)
+		fallthrough
+	default:
+		maxRetries := aws.IntValue(cfg.MaxRetries)
+		if cfg.MaxRetries == nil || maxRetries == aws.UseServiceDefaultRetries {
+			maxRetries = 3
+		}
+		svc.Retryer = DefaultRetryer{NumMaxRetries: maxRetries}
+	}
+
+	svc.AddDebugHandlers()
+
+	for _, option := range options {
+		option(svc)
+	}
+
+	return svc
+}
+
+// NewRequest returns a new Request pointer for the service API
+// operation and parameters.
+func (c *Client) NewRequest(operation *request.Operation, params interface{}, data interface{}) *request.Request {
+	return request.New(c.Config, c.ClientInfo, c.Handlers, c.Retryer, operation, params, data)
+}
+
+// AddDebugHandlers injects debug logging handlers into the service to log request
+// debug information.
+func (c *Client) AddDebugHandlers() {
+	if !c.Config.LogLevel.AtLeast(aws.LogDebug) {
+		return
+	}
+
+	c.Handlers.Send.PushFrontNamed(LogHTTPRequestHandler)
+	c.Handlers.Send.PushBackNamed(LogHTTPResponseHandler)
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go b/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
new file mode 100644
index 000000000..a397b0d04
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
@@ -0,0 +1,116 @@
+package client
+
+import (
+	"strconv"
+	"time"
+
+	"github.com/aws/aws-sdk-go/aws/request"
+	"github.com/aws/aws-sdk-go/internal/sdkrand"
+)
+
+// DefaultRetryer implements basic retry logic using exponential backoff for
+// most services. If you want to implement custom retry logic, implement the
+// request.Retryer interface or create a structure type that composes this
+// struct and override the specific methods. For example, to override only
+// the MaxRetries method:
+//
+//		type retryer struct {
+//      client.DefaultRetryer
+//    }
+//
+//    // This implementation always has 100 max retries
+//    func (d retryer) MaxRetries() int { return 100 }
+type DefaultRetryer struct {
+	NumMaxRetries int
+}
+
+// MaxRetries returns the number of maximum returns the service will use to make
+// an individual API request.
+func (d DefaultRetryer) MaxRetries() int {
+	return d.NumMaxRetries
+}
+
+// RetryRules returns the delay duration before retrying this request again
+func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration {
+	// Set the upper limit of delay in retrying at ~five minutes
+	minTime := 30
+	throttle := d.shouldThrottle(r)
+	if throttle {
+		if delay, ok := getRetryDelay(r); ok {
+			return delay
+		}
+
+		minTime = 500
+	}
+
+	retryCount := r.RetryCount
+	if throttle && retryCount > 8 {
+		retryCount = 8
+	} else if retryCount > 13 {
+		retryCount = 13
+	}
+
+	delay := (1 << uint(retryCount)) * (sdkrand.SeededRand.Intn(minTime) + minTime)
+	return time.Duration(delay) * time.Millisecond
+}
+
+// ShouldRetry returns true if the request should be retried.
+func (d DefaultRetryer) ShouldRetry(r *request.Request) bool {
+	// If one of the other handlers already set the retry state
+	// we don't want to override it based on the service's state
+	if r.Retryable != nil {
+		return *r.Retryable
+	}
+
+	if r.HTTPResponse.StatusCode >= 500 && r.HTTPResponse.StatusCode != 501 {
+		return true
+	}
+	return r.IsErrorRetryable() || d.shouldThrottle(r)
+}
+
+// ShouldThrottle returns true if the request should be throttled.
+func (d DefaultRetryer) shouldThrottle(r *request.Request) bool {
+	switch r.HTTPResponse.StatusCode {
+	case 429:
+	case 502:
+	case 503:
+	case 504:
+	default:
+		return r.IsErrorThrottle()
+	}
+
+	return true
+}
+
+// This will look in the Retry-After header, RFC 7231, for how long
+// it will wait before attempting another request
+func getRetryDelay(r *request.Request) (time.Duration, bool) {
+	if !canUseRetryAfterHeader(r) {
+		return 0, false
+	}
+
+	delayStr := r.HTTPResponse.Header.Get("Retry-After")
+	if len(delayStr) == 0 {
+		return 0, false
+	}
+
+	delay, err := strconv.Atoi(delayStr)
+	if err != nil {
+		return 0, false
+	}
+
+	return time.Duration(delay) * time.Second, true
+}
+
+// Will look at the status code to see if the retry header pertains to
+// the status code.
+func canUseRetryAfterHeader(r *request.Request) bool {
+	switch r.HTTPResponse.StatusCode {
+	case 429:
+	case 503:
+	default:
+		return false
+	}
+
+	return true
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/logger.go b/vendor/github.com/aws/aws-sdk-go/aws/client/logger.go
new file mode 100644
index 000000000..ce9fb896d
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/client/logger.go
@@ -0,0 +1,184 @@
+package client
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net/http/httputil"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/request"
+)
+
+const logReqMsg = `DEBUG: Request %s/%s Details:
+---[ REQUEST POST-SIGN ]-----------------------------
+%s
+-----------------------------------------------------`
+
+const logReqErrMsg = `DEBUG ERROR: Request %s/%s:
+---[ REQUEST DUMP ERROR ]-----------------------------
+%s
+------------------------------------------------------`
+
+type logWriter struct {
+	// Logger is what we will use to log the payload of a response.
+	Logger aws.Logger
+	// buf stores the contents of what has been read
+	buf *bytes.Buffer
+}
+
+func (logger *logWriter) Write(b []byte) (int, error) {
+	return logger.buf.Write(b)
+}
+
+type teeReaderCloser struct {
+	// io.Reader will be a tee reader that is used during logging.
+	// This structure will read from a body and write the contents to a logger.
+	io.Reader
+	// Source is used just to close when we are done reading.
+	Source io.ReadCloser
+}
+
+func (reader *teeReaderCloser) Close() error {
+	return reader.Source.Close()
+}
+
+// LogHTTPRequestHandler is a SDK request handler to log the HTTP request sent
+// to a service. Will include the HTTP request body if the LogLevel of the
+// request matches LogDebugWithHTTPBody.
+var LogHTTPRequestHandler = request.NamedHandler{
+	Name: "awssdk.client.LogRequest",
+	Fn:   logRequest,
+}
+
+func logRequest(r *request.Request) {
+	logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
+	bodySeekable := aws.IsReaderSeekable(r.Body)
+
+	b, err := httputil.DumpRequestOut(r.HTTPRequest, logBody)
+	if err != nil {
+		r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg,
+			r.ClientInfo.ServiceName, r.Operation.Name, err))
+		return
+	}
+
+	if logBody {
+		if !bodySeekable {
+			r.SetReaderBody(aws.ReadSeekCloser(r.HTTPRequest.Body))
+		}
+		// Reset the request body because dumpRequest will re-wrap the r.HTTPRequest's
+		// Body as a NoOpCloser and will not be reset after read by the HTTP
+		// client reader.
+		r.ResetBody()
+	}
+
+	r.Config.Logger.Log(fmt.Sprintf(logReqMsg,
+		r.ClientInfo.ServiceName, r.Operation.Name, string(b)))
+}
+
+// LogHTTPRequestHeaderHandler is a SDK request handler to log the HTTP request sent
+// to a service. Will only log the HTTP request's headers. The request payload
+// will not be read.
+var LogHTTPRequestHeaderHandler = request.NamedHandler{
+	Name: "awssdk.client.LogRequestHeader",
+	Fn:   logRequestHeader,
+}
+
+func logRequestHeader(r *request.Request) {
+	b, err := httputil.DumpRequestOut(r.HTTPRequest, false)
+	if err != nil {
+		r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg,
+			r.ClientInfo.ServiceName, r.Operation.Name, err))
+		return
+	}
+
+	r.Config.Logger.Log(fmt.Sprintf(logReqMsg,
+		r.ClientInfo.ServiceName, r.Operation.Name, string(b)))
+}
+
+const logRespMsg = `DEBUG: Response %s/%s Details:
+---[ RESPONSE ]--------------------------------------
+%s
+-----------------------------------------------------`
+
+const logRespErrMsg = `DEBUG ERROR: Response %s/%s:
+---[ RESPONSE DUMP ERROR ]-----------------------------
+%s
+-----------------------------------------------------`
+
+// LogHTTPResponseHandler is a SDK request handler to log the HTTP response
+// received from a service. Will include the HTTP response body if the LogLevel
+// of the request matches LogDebugWithHTTPBody.
+var LogHTTPResponseHandler = request.NamedHandler{
+	Name: "awssdk.client.LogResponse",
+	Fn:   logResponse,
+}
+
+func logResponse(r *request.Request) {
+	lw := &logWriter{r.Config.Logger, bytes.NewBuffer(nil)}
+
+	logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
+	if logBody {
+		r.HTTPResponse.Body = &teeReaderCloser{
+			Reader: io.TeeReader(r.HTTPResponse.Body, lw),
+			Source: r.HTTPResponse.Body,
+		}
+	}
+
+	handlerFn := func(req *request.Request) {
+		b, err := httputil.DumpResponse(req.HTTPResponse, false)
+		if err != nil {
+			lw.Logger.Log(fmt.Sprintf(logRespErrMsg,
+				req.ClientInfo.ServiceName, req.Operation.Name, err))
+			return
+		}
+
+		lw.Logger.Log(fmt.Sprintf(logRespMsg,
+			req.ClientInfo.ServiceName, req.Operation.Name, string(b)))
+
+		if logBody {
+			b, err := ioutil.ReadAll(lw.buf)
+			if err != nil {
+				lw.Logger.Log(fmt.Sprintf(logRespErrMsg,
+					req.ClientInfo.ServiceName, req.Operation.Name, err))
+				return
+			}
+
+			lw.Logger.Log(string(b))
+		}
+	}
+
+	const handlerName = "awsdk.client.LogResponse.ResponseBody"
+
+	r.Handlers.Unmarshal.SetBackNamed(request.NamedHandler{
+		Name: handlerName, Fn: handlerFn,
+	})
+	r.Handlers.UnmarshalError.SetBackNamed(request.NamedHandler{
+		Name: handlerName, Fn: handlerFn,
+	})
+}
+
+// LogHTTPResponseHeaderHandler is a SDK request handler to log the HTTP
+// response received from a service. Will only log the HTTP response's headers.
+// The response payload will not be read.
+var LogHTTPResponseHeaderHandler = request.NamedHandler{
+	Name: "awssdk.client.LogResponseHeader",
+	Fn:   logResponseHeader,
+}
+
+func logResponseHeader(r *request.Request) {
+	if r.Config.Logger == nil {
+		return
+	}
+
+	b, err := httputil.DumpResponse(r.HTTPResponse, false)
+	if err != nil {
+		r.Config.Logger.Log(fmt.Sprintf(logRespErrMsg,
+			r.ClientInfo.ServiceName, r.Operation.Name, err))
+		return
+	}
+
+	r.Config.Logger.Log(fmt.Sprintf(logRespMsg,
+		r.ClientInfo.ServiceName, r.Operation.Name, string(b)))
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go b/vendor/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go
new file mode 100644
index 000000000..920e9fddf
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go
@@ -0,0 +1,13 @@
+package metadata
+
+// ClientInfo wraps immutable data from the client.Client structure.
+type ClientInfo struct {
+	ServiceName   string
+	ServiceID     string
+	APIVersion    string
+	Endpoint      string
+	SigningName   string
+	SigningRegion string
+	JSONVersion   string
+	TargetPrefix  string
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/config.go b/vendor/github.com/aws/aws-sdk-go/aws/config.go
new file mode 100644
index 000000000..5421b5d4e
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/config.go
@@ -0,0 +1,492 @@
+package aws
+
+import (
+	"net/http"
+	"time"
+
+	"github.com/aws/aws-sdk-go/aws/credentials"
+	"github.com/aws/aws-sdk-go/aws/endpoints"
+)
+
+// UseServiceDefaultRetries instructs the config to use the service's own
+// default number of retries. This will be the default action if
+// Config.MaxRetries is nil also.
+const UseServiceDefaultRetries = -1
+
+// RequestRetryer is an alias for a type that implements the request.Retryer
+// interface.
+type RequestRetryer interface{}
+
+// A Config provides service configuration for service clients. By default,
+// all clients will use the defaults.DefaultConfig tructure.
+//
+//     // Create Session with MaxRetry configuration to be shared by multiple
+//     // service clients.
+//     sess := session.Must(session.NewSession(&aws.Config{
+//         MaxRetries: aws.Int(3),
+//     }))
+//
+//     // Create S3 service client with a specific Region.
+//     svc := s3.New(sess, &aws.Config{
+//         Region: aws.String("us-west-2"),
+//     })
+type Config struct {
+	// Enables verbose error printing of all credential chain errors.
+	// Should be used when wanting to see all errors while attempting to
+	// retrieve credentials.
+	CredentialsChainVerboseErrors *bool
+
+	// The credentials object to use when signing requests. Defaults to a
+	// chain of credential providers to search for credentials in environment
+	// variables, shared credential file, and EC2 Instance Roles.
+	Credentials *credentials.Credentials
+
+	// An optional endpoint URL (hostname only or fully qualified URI)
+	// that overrides the default generated endpoint for a client. Set this
+	// to `""` to use the default generated endpoint.
+	//
+	// @note You must still provide a `Region` value when specifying an
+	//   endpoint for a client.
+	Endpoint *string
+
+	// The resolver to use for looking up endpoints for AWS service clients
+	// to use based on region.
+	EndpointResolver endpoints.Resolver
+
+	// EnforceShouldRetryCheck is used in the AfterRetryHandler to always call
+	// ShouldRetry regardless of whether or not if request.Retryable is set.
+	// This will utilize ShouldRetry method of custom retryers. If EnforceShouldRetryCheck
+	// is not set, then ShouldRetry will only be called if request.Retryable is nil.
+	// Proper handling of the request.Retryable field is important when setting this field.
+	EnforceShouldRetryCheck *bool
+
+	// The region to send requests to. This parameter is required and must
+	// be configured globally or on a per-client basis unless otherwise
+	// noted. A full list of regions is found in the "Regions and Endpoints"
+	// document.
+	//
+	// @see http://docs.aws.amazon.com/general/latest/gr/rande.html
+	//   AWS Regions and Endpoints
+	Region *string
+
+	// Set this to `true` to disable SSL when sending requests. Defaults
+	// to `false`.
+	DisableSSL *bool
+
+	// The HTTP client to use when sending requests. Defaults to
+	// `http.DefaultClient`.
+	HTTPClient *http.Client
+
+	// An integer value representing the logging level. The default log level
+	// is zero (LogOff), which represents no logging. To enable logging set
+	// to a LogLevel Value.
+	LogLevel *LogLevelType
+
+	// The logger writer interface to write logging messages to. Defaults to
+	// standard out.
+	Logger Logger
+
+	// The maximum number of times that a request will be retried for failures.
+	// Defaults to -1, which defers the max retry setting to the service
+	// specific configuration.
+	MaxRetries *int
+
+	// Retryer guides how HTTP requests should be retried in case of
+	// recoverable failures.
+	//
+	// When nil or the value does not implement the request.Retryer interface,
+	// the client.DefaultRetryer will be used.
+	//
+	// When both Retryer and MaxRetries are non-nil, the former is used and
+	// the latter ignored.
+	//
+	// To set the Retryer field in a type-safe manner and with chaining, use
+	// the request.WithRetryer helper function:
+	//
+	//   cfg := request.WithRetryer(aws.NewConfig(), myRetryer)
+	//
+	Retryer RequestRetryer
+
+	// Disables semantic parameter validation, which validates input for
+	// missing required fields and/or other semantic request input errors.
+	DisableParamValidation *bool
+
+	// Disables the computation of request and response checksums, e.g.,
+	// CRC32 checksums in Amazon DynamoDB.
+	DisableComputeChecksums *bool
+
+	// Set this to `true` to force the request to use path-style addressing,
+	// i.e., `http://s3.amazonaws.com/BUCKET/KEY`. By default, the S3 client
+	// will use virtual hosted bucket addressing when possible
+	// (`http://BUCKET.s3.amazonaws.com/KEY`).
+	//
+	// @note This configuration option is specific to the Amazon S3 service.
+	// @see http://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html
+	//   Amazon S3: Virtual Hosting of Buckets
+	S3ForcePathStyle *bool
+
+	// Set this to `true` to disable the SDK adding the `Expect: 100-Continue`
+	// header to PUT requests over 2MB of content. 100-Continue instructs the
+	// HTTP client not to send the body until the service responds with a
+	// `continue` status. This is useful to prevent sending the request body
+	// until after the request is authenticated, and validated.
+	//
+	// http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html
+	//
+	// 100-Continue is only enabled for Go 1.6 and above. See `http.Transport`'s
+	// `ExpectContinueTimeout` for information on adjusting the continue wait
+	// timeout. https://golang.org/pkg/net/http/#Transport
+	//
+	// You should use this flag to disble 100-Continue if you experience issues
+	// with proxies or third party S3 compatible services.
+	S3Disable100Continue *bool
+
+	// Set this to `true` to enable S3 Accelerate feature. For all operations
+	// compatible with S3 Accelerate will use the accelerate endpoint for
+	// requests. Requests not compatible will fall back to normal S3 requests.
+	//
+	// The bucket must be enable for accelerate to be used with S3 client with
+	// accelerate enabled. If the bucket is not enabled for accelerate an error
+	// will be returned. The bucket name must be DNS compatible to also work
+	// with accelerate.
+	S3UseAccelerate *bool
+
+	// S3DisableContentMD5Validation config option is temporarily disabled,
+	// For S3 GetObject API calls, #1837.
+	//
+	// Set this to `true` to disable the S3 service client from automatically
+	// adding the ContentMD5 to S3 Object Put and Upload API calls. This option
+	// will also disable the SDK from performing object ContentMD5 validation
+	// on GetObject API calls.
+	S3DisableContentMD5Validation *bool
+
+	// Set this to `true` to disable the EC2Metadata client from overriding the
+	// default http.Client's Timeout. This is helpful if you do not want the
+	// EC2Metadata client to create a new http.Client. This options is only
+	// meaningful if you're not already using a custom HTTP client with the
+	// SDK. Enabled by default.
+	//
+	// Must be set and provided to the session.NewSession() in order to disable
+	// the EC2Metadata overriding the timeout for default credentials chain.
+	//
+	// Example:
+	//    sess := session.Must(session.NewSession(aws.NewConfig()
+	//       .WithEC2MetadataDiableTimeoutOverride(true)))
+	//
+	//    svc := s3.New(sess)
+	//
+	EC2MetadataDisableTimeoutOverride *bool
+
+	// Instructs the endpoint to be generated for a service client to
+	// be the dual stack endpoint. The dual stack endpoint will support
+	// both IPv4 and IPv6 addressing.
+	//
+	// Setting this for a service which does not support dual stack will fail
+	// to make requets. It is not recommended to set this value on the session
+	// as it will apply to all service clients created with the session. Even
+	// services which don't support dual stack endpoints.
+	//
+	// If the Endpoint config value is also provided the UseDualStack flag
+	// will be ignored.
+	//
+	// Only supported with.
+	//
+	//     sess := session.Must(session.NewSession())
+	//
+	//     svc := s3.New(sess, &aws.Config{
+	//         UseDualStack: aws.Bool(true),
+	//     })
+	UseDualStack *bool
+
+	// SleepDelay is an override for the func the SDK will call when sleeping
+	// during the lifecycle of a request. Specifically this will be used for
+	// request delays. This value should only be used for testing. To adjust
+	// the delay of a request see the aws/client.DefaultRetryer and
+	// aws/request.Retryer.
+	//
+	// SleepDelay will prevent any Context from being used for canceling retry
+	// delay of an API operation. It is recommended to not use SleepDelay at all
+	// and specify a Retryer instead.
+	SleepDelay func(time.Duration)
+
+	// DisableRestProtocolURICleaning will not clean the URL path when making rest protocol requests.
+	// Will default to false. This would only be used for empty directory names in s3 requests.
+	//
+	// Example:
+	//    sess := session.Must(session.NewSession(&aws.Config{
+	//         DisableRestProtocolURICleaning: aws.Bool(true),
+	//    }))
+	//
+	//    svc := s3.New(sess)
+	//    out, err := svc.GetObject(&s3.GetObjectInput {
+	//    	Bucket: aws.String("bucketname"),
+	//    	Key: aws.String("//foo//bar//moo"),
+	//    })
+	DisableRestProtocolURICleaning *bool
+}
+
+// NewConfig returns a new Config pointer that can be chained with builder
+// methods to set multiple configuration values inline without using pointers.
+//
+//     // Create Session with MaxRetry configuration to be shared by multiple
+//     // service clients.
+//     sess := session.Must(session.NewSession(aws.NewConfig().
+//         WithMaxRetries(3),
+//     ))
+//
+//     // Create S3 service client with a specific Region.
+//     svc := s3.New(sess, aws.NewConfig().
+//         WithRegion("us-west-2"),
+//     )
+func NewConfig() *Config {
+	return &Config{}
+}
+
+// WithCredentialsChainVerboseErrors sets a config verbose errors boolean and returning
+// a Config pointer.
+func (c *Config) WithCredentialsChainVerboseErrors(verboseErrs bool) *Config {
+	c.CredentialsChainVerboseErrors = &verboseErrs
+	return c
+}
+
+// WithCredentials sets a config Credentials value returning a Config pointer
+// for chaining.
+func (c *Config) WithCredentials(creds *credentials.Credentials) *Config {
+	c.Credentials = creds
+	return c
+}
+
+// WithEndpoint sets a config Endpoint value returning a Config pointer for
+// chaining.
+func (c *Config) WithEndpoint(endpoint string) *Config {
+	c.Endpoint = &endpoint
+	return c
+}
+
+// WithEndpointResolver sets a config EndpointResolver value returning a
+// Config pointer for chaining.
+func (c *Config) WithEndpointResolver(resolver endpoints.Resolver) *Config {
+	c.EndpointResolver = resolver
+	return c
+}
+
+// WithRegion sets a config Region value returning a Config pointer for
+// chaining.
+func (c *Config) WithRegion(region string) *Config {
+	c.Region = ®ion
+	return c
+}
+
+// WithDisableSSL sets a config DisableSSL value returning a Config pointer
+// for chaining.
+func (c *Config) WithDisableSSL(disable bool) *Config {
+	c.DisableSSL = &disable
+	return c
+}
+
+// WithHTTPClient sets a config HTTPClient value returning a Config pointer
+// for chaining.
+func (c *Config) WithHTTPClient(client *http.Client) *Config {
+	c.HTTPClient = client
+	return c
+}
+
+// WithMaxRetries sets a config MaxRetries value returning a Config pointer
+// for chaining.
+func (c *Config) WithMaxRetries(max int) *Config {
+	c.MaxRetries = &max
+	return c
+}
+
+// WithDisableParamValidation sets a config DisableParamValidation value
+// returning a Config pointer for chaining.
+func (c *Config) WithDisableParamValidation(disable bool) *Config {
+	c.DisableParamValidation = &disable
+	return c
+}
+
+// WithDisableComputeChecksums sets a config DisableComputeChecksums value
+// returning a Config pointer for chaining.
+func (c *Config) WithDisableComputeChecksums(disable bool) *Config {
+	c.DisableComputeChecksums = &disable
+	return c
+}
+
+// WithLogLevel sets a config LogLevel value returning a Config pointer for
+// chaining.
+func (c *Config) WithLogLevel(level LogLevelType) *Config {
+	c.LogLevel = &level
+	return c
+}
+
+// WithLogger sets a config Logger value returning a Config pointer for
+// chaining.
+func (c *Config) WithLogger(logger Logger) *Config {
+	c.Logger = logger
+	return c
+}
+
+// WithS3ForcePathStyle sets a config S3ForcePathStyle value returning a Config
+// pointer for chaining.
+func (c *Config) WithS3ForcePathStyle(force bool) *Config {
+	c.S3ForcePathStyle = &force
+	return c
+}
+
+// WithS3Disable100Continue sets a config S3Disable100Continue value returning
+// a Config pointer for chaining.
+func (c *Config) WithS3Disable100Continue(disable bool) *Config {
+	c.S3Disable100Continue = &disable
+	return c
+}
+
+// WithS3UseAccelerate sets a config S3UseAccelerate value returning a Config
+// pointer for chaining.
+func (c *Config) WithS3UseAccelerate(enable bool) *Config {
+	c.S3UseAccelerate = &enable
+	return c
+
+}
+
+// WithS3DisableContentMD5Validation sets a config
+// S3DisableContentMD5Validation value returning a Config pointer for chaining.
+func (c *Config) WithS3DisableContentMD5Validation(enable bool) *Config {
+	c.S3DisableContentMD5Validation = &enable
+	return c
+
+}
+
+// WithUseDualStack sets a config UseDualStack value returning a Config
+// pointer for chaining.
+func (c *Config) WithUseDualStack(enable bool) *Config {
+	c.UseDualStack = &enable
+	return c
+}
+
+// WithEC2MetadataDisableTimeoutOverride sets a config EC2MetadataDisableTimeoutOverride value
+// returning a Config pointer for chaining.
+func (c *Config) WithEC2MetadataDisableTimeoutOverride(enable bool) *Config {
+	c.EC2MetadataDisableTimeoutOverride = &enable
+	return c
+}
+
+// WithSleepDelay overrides the function used to sleep while waiting for the
+// next retry. Defaults to time.Sleep.
+func (c *Config) WithSleepDelay(fn func(time.Duration)) *Config {
+	c.SleepDelay = fn
+	return c
+}
+
+// MergeIn merges the passed in configs into the existing config object.
+func (c *Config) MergeIn(cfgs ...*Config) {
+	for _, other := range cfgs {
+		mergeInConfig(c, other)
+	}
+}
+
+func mergeInConfig(dst *Config, other *Config) {
+	if other == nil {
+		return
+	}
+
+	if other.CredentialsChainVerboseErrors != nil {
+		dst.CredentialsChainVerboseErrors = other.CredentialsChainVerboseErrors
+	}
+
+	if other.Credentials != nil {
+		dst.Credentials = other.Credentials
+	}
+
+	if other.Endpoint != nil {
+		dst.Endpoint = other.Endpoint
+	}
+
+	if other.EndpointResolver != nil {
+		dst.EndpointResolver = other.EndpointResolver
+	}
+
+	if other.Region != nil {
+		dst.Region = other.Region
+	}
+
+	if other.DisableSSL != nil {
+		dst.DisableSSL = other.DisableSSL
+	}
+
+	if other.HTTPClient != nil {
+		dst.HTTPClient = other.HTTPClient
+	}
+
+	if other.LogLevel != nil {
+		dst.LogLevel = other.LogLevel
+	}
+
+	if other.Logger != nil {
+		dst.Logger = other.Logger
+	}
+
+	if other.MaxRetries != nil {
+		dst.MaxRetries = other.MaxRetries
+	}
+
+	if other.Retryer != nil {
+		dst.Retryer = other.Retryer
+	}
+
+	if other.DisableParamValidation != nil {
+		dst.DisableParamValidation = other.DisableParamValidation
+	}
+
+	if other.DisableComputeChecksums != nil {
+		dst.DisableComputeChecksums = other.DisableComputeChecksums
+	}
+
+	if other.S3ForcePathStyle != nil {
+		dst.S3ForcePathStyle = other.S3ForcePathStyle
+	}
+
+	if other.S3Disable100Continue != nil {
+		dst.S3Disable100Continue = other.S3Disable100Continue
+	}
+
+	if other.S3UseAccelerate != nil {
+		dst.S3UseAccelerate = other.S3UseAccelerate
+	}
+
+	if other.S3DisableContentMD5Validation != nil {
+		dst.S3DisableContentMD5Validation = other.S3DisableContentMD5Validation
+	}
+
+	if other.UseDualStack != nil {
+		dst.UseDualStack = other.UseDualStack
+	}
+
+	if other.EC2MetadataDisableTimeoutOverride != nil {
+		dst.EC2MetadataDisableTimeoutOverride = other.EC2MetadataDisableTimeoutOverride
+	}
+
+	if other.SleepDelay != nil {
+		dst.SleepDelay = other.SleepDelay
+	}
+
+	if other.DisableRestProtocolURICleaning != nil {
+		dst.DisableRestProtocolURICleaning = other.DisableRestProtocolURICleaning
+	}
+
+	if other.EnforceShouldRetryCheck != nil {
+		dst.EnforceShouldRetryCheck = other.EnforceShouldRetryCheck
+	}
+}
+
+// Copy will return a shallow copy of the Config object. If any additional
+// configurations are provided they will be merged into the new config returned.
+func (c *Config) Copy(cfgs ...*Config) *Config {
+	dst := &Config{}
+	dst.MergeIn(c)
+
+	for _, cfg := range cfgs {
+		dst.MergeIn(cfg)
+	}
+
+	return dst
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/context.go b/vendor/github.com/aws/aws-sdk-go/aws/context.go
new file mode 100644
index 000000000..79f426853
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/context.go
@@ -0,0 +1,71 @@
+package aws
+
+import (
+	"time"
+)
+
+// Context is an copy of the Go v1.7 stdlib's context.Context interface.
+// It is represented as a SDK interface to enable you to use the "WithContext"
+// API methods with Go v1.6 and a Context type such as golang.org/x/net/context.
+//
+// See https://golang.org/pkg/context on how to use contexts.
+type Context interface {
+	// Deadline returns the time when work done on behalf of this context
+	// should be canceled. Deadline returns ok==false when no deadline is
+	// set. Successive calls to Deadline return the same results.
+	Deadline() (deadline time.Time, ok bool)
+
+	// Done returns a channel that's closed when work done on behalf of this
+	// context should be canceled. Done may return nil if this context can
+	// never be canceled. Successive calls to Done return the same value.
+	Done() <-chan struct{}
+
+	// Err returns a non-nil error value after Done is closed. Err returns
+	// Canceled if the context was canceled or DeadlineExceeded if the
+	// context's deadline passed. No other values for Err are defined.
+	// After Done is closed, successive calls to Err return the same value.
+	Err() error
+
+	// Value returns the value associated with this context for key, or nil
+	// if no value is associated with key. Successive calls to Value with
+	// the same key returns the same result.
+	//
+	// Use context values only for request-scoped data that transits
+	// processes and API boundaries, not for passing optional parameters to
+	// functions.
+	Value(key interface{}) interface{}
+}
+
+// BackgroundContext returns a context that will never be canceled, has no
+// values, and no deadline. This context is used by the SDK to provide
+// backwards compatibility with non-context API operations and functionality.
+//
+// Go 1.6 and before:
+// This context function is equivalent to context.Background in the Go stdlib.
+//
+// Go 1.7 and later:
+// The context returned will be the value returned by context.Background()
+//
+// See https://golang.org/pkg/context for more information on Contexts.
+func BackgroundContext() Context {
+	return backgroundCtx
+}
+
+// SleepWithContext will wait for the timer duration to expire, or the context
+// is canceled. Which ever happens first. If the context is canceled the Context's
+// error will be returned.
+//
+// Expects Context to always return a non-nil error if the Done channel is closed.
+func SleepWithContext(ctx Context, dur time.Duration) error {
+	t := time.NewTimer(dur)
+	defer t.Stop()
+
+	select {
+	case <-t.C:
+		break
+	case <-ctx.Done():
+		return ctx.Err()
+	}
+
+	return nil
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/context_1_6.go b/vendor/github.com/aws/aws-sdk-go/aws/context_1_6.go
new file mode 100644
index 000000000..8fdda5303
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/context_1_6.go
@@ -0,0 +1,41 @@
+// +build !go1.7
+
+package aws
+
+import "time"
+
+// An emptyCtx is a copy of the Go 1.7 context.emptyCtx type. This is copied to
+// provide a 1.6 and 1.5 safe version of context that is compatible with Go
+// 1.7's Context.
+//
+// An emptyCtx is never canceled, has no values, and has no deadline. It is not
+// struct{}, since vars of this type must have distinct addresses.
+type emptyCtx int
+
+func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
+	return
+}
+
+func (*emptyCtx) Done() <-chan struct{} {
+	return nil
+}
+
+func (*emptyCtx) Err() error {
+	return nil
+}
+
+func (*emptyCtx) Value(key interface{}) interface{} {
+	return nil
+}
+
+func (e *emptyCtx) String() string {
+	switch e {
+	case backgroundCtx:
+		return "aws.BackgroundContext"
+	}
+	return "unknown empty Context"
+}
+
+var (
+	backgroundCtx = new(emptyCtx)
+)
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/context_1_7.go b/vendor/github.com/aws/aws-sdk-go/aws/context_1_7.go
new file mode 100644
index 000000000..064f75c92
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/context_1_7.go
@@ -0,0 +1,9 @@
+// +build go1.7
+
+package aws
+
+import "context"
+
+var (
+	backgroundCtx = context.Background()
+)
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/convert_types.go b/vendor/github.com/aws/aws-sdk-go/aws/convert_types.go
new file mode 100644
index 000000000..ff5d58e06
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/convert_types.go
@@ -0,0 +1,387 @@
+package aws
+
+import "time"
+
+// String returns a pointer to the string value passed in.
+func String(v string) *string {
+	return &v
+}
+
+// StringValue returns the value of the string pointer passed in or
+// "" if the pointer is nil.
+func StringValue(v *string) string {
+	if v != nil {
+		return *v
+	}
+	return ""
+}
+
+// StringSlice converts a slice of string values into a slice of
+// string pointers
+func StringSlice(src []string) []*string {
+	dst := make([]*string, len(src))
+	for i := 0; i < len(src); i++ {
+		dst[i] = &(src[i])
+	}
+	return dst
+}
+
+// StringValueSlice converts a slice of string pointers into a slice of
+// string values
+func StringValueSlice(src []*string) []string {
+	dst := make([]string, len(src))
+	for i := 0; i < len(src); i++ {
+		if src[i] != nil {
+			dst[i] = *(src[i])
+		}
+	}
+	return dst
+}
+
+// StringMap converts a string map of string values into a string
+// map of string pointers
+func StringMap(src map[string]string) map[string]*string {
+	dst := make(map[string]*string)
+	for k, val := range src {
+		v := val
+		dst[k] = &v
+	}
+	return dst
+}
+
+// StringValueMap converts a string map of string pointers into a string
+// map of string values
+func StringValueMap(src map[string]*string) map[string]string {
+	dst := make(map[string]string)
+	for k, val := range src {
+		if val != nil {
+			dst[k] = *val
+		}
+	}
+	return dst
+}
+
+// Bool returns a pointer to the bool value passed in.
+func Bool(v bool) *bool {
+	return &v
+}
+
+// BoolValue returns the value of the bool pointer passed in or
+// false if the pointer is nil.
+func BoolValue(v *bool) bool {
+	if v != nil {
+		return *v
+	}
+	return false
+}
+
+// BoolSlice converts a slice of bool values into a slice of
+// bool pointers
+func BoolSlice(src []bool) []*bool {
+	dst := make([]*bool, len(src))
+	for i := 0; i < len(src); i++ {
+		dst[i] = &(src[i])
+	}
+	return dst
+}
+
+// BoolValueSlice converts a slice of bool pointers into a slice of
+// bool values
+func BoolValueSlice(src []*bool) []bool {
+	dst := make([]bool, len(src))
+	for i := 0; i < len(src); i++ {
+		if src[i] != nil {
+			dst[i] = *(src[i])
+		}
+	}
+	return dst
+}
+
+// BoolMap converts a string map of bool values into a string
+// map of bool pointers
+func BoolMap(src map[string]bool) map[string]*bool {
+	dst := make(map[string]*bool)
+	for k, val := range src {
+		v := val
+		dst[k] = &v
+	}
+	return dst
+}
+
+// BoolValueMap converts a string map of bool pointers into a string
+// map of bool values
+func BoolValueMap(src map[string]*bool) map[string]bool {
+	dst := make(map[string]bool)
+	for k, val := range src {
+		if val != nil {
+			dst[k] = *val
+		}
+	}
+	return dst
+}
+
+// Int returns a pointer to the int value passed in.
+func Int(v int) *int {
+	return &v
+}
+
+// IntValue returns the value of the int pointer passed in or
+// 0 if the pointer is nil.
+func IntValue(v *int) int {
+	if v != nil {
+		return *v
+	}
+	return 0
+}
+
+// IntSlice converts a slice of int values into a slice of
+// int pointers
+func IntSlice(src []int) []*int {
+	dst := make([]*int, len(src))
+	for i := 0; i < len(src); i++ {
+		dst[i] = &(src[i])
+	}
+	return dst
+}
+
+// IntValueSlice converts a slice of int pointers into a slice of
+// int values
+func IntValueSlice(src []*int) []int {
+	dst := make([]int, len(src))
+	for i := 0; i < len(src); i++ {
+		if src[i] != nil {
+			dst[i] = *(src[i])
+		}
+	}
+	return dst
+}
+
+// IntMap converts a string map of int values into a string
+// map of int pointers
+func IntMap(src map[string]int) map[string]*int {
+	dst := make(map[string]*int)
+	for k, val := range src {
+		v := val
+		dst[k] = &v
+	}
+	return dst
+}
+
+// IntValueMap converts a string map of int pointers into a string
+// map of int values
+func IntValueMap(src map[string]*int) map[string]int {
+	dst := make(map[string]int)
+	for k, val := range src {
+		if val != nil {
+			dst[k] = *val
+		}
+	}
+	return dst
+}
+
+// Int64 returns a pointer to the int64 value passed in.
+func Int64(v int64) *int64 {
+	return &v
+}
+
+// Int64Value returns the value of the int64 pointer passed in or
+// 0 if the pointer is nil.
+func Int64Value(v *int64) int64 {
+	if v != nil {
+		return *v
+	}
+	return 0
+}
+
+// Int64Slice converts a slice of int64 values into a slice of
+// int64 pointers
+func Int64Slice(src []int64) []*int64 {
+	dst := make([]*int64, len(src))
+	for i := 0; i < len(src); i++ {
+		dst[i] = &(src[i])
+	}
+	return dst
+}
+
+// Int64ValueSlice converts a slice of int64 pointers into a slice of
+// int64 values
+func Int64ValueSlice(src []*int64) []int64 {
+	dst := make([]int64, len(src))
+	for i := 0; i < len(src); i++ {
+		if src[i] != nil {
+			dst[i] = *(src[i])
+		}
+	}
+	return dst
+}
+
+// Int64Map converts a string map of int64 values into a string
+// map of int64 pointers
+func Int64Map(src map[string]int64) map[string]*int64 {
+	dst := make(map[string]*int64)
+	for k, val := range src {
+		v := val
+		dst[k] = &v
+	}
+	return dst
+}
+
+// Int64ValueMap converts a string map of int64 pointers into a string
+// map of int64 values
+func Int64ValueMap(src map[string]*int64) map[string]int64 {
+	dst := make(map[string]int64)
+	for k, val := range src {
+		if val != nil {
+			dst[k] = *val
+		}
+	}
+	return dst
+}
+
+// Float64 returns a pointer to the float64 value passed in.
+func Float64(v float64) *float64 {
+	return &v
+}
+
+// Float64Value returns the value of the float64 pointer passed in or
+// 0 if the pointer is nil.
+func Float64Value(v *float64) float64 {
+	if v != nil {
+		return *v
+	}
+	return 0
+}
+
+// Float64Slice converts a slice of float64 values into a slice of
+// float64 pointers
+func Float64Slice(src []float64) []*float64 {
+	dst := make([]*float64, len(src))
+	for i := 0; i < len(src); i++ {
+		dst[i] = &(src[i])
+	}
+	return dst
+}
+
+// Float64ValueSlice converts a slice of float64 pointers into a slice of
+// float64 values
+func Float64ValueSlice(src []*float64) []float64 {
+	dst := make([]float64, len(src))
+	for i := 0; i < len(src); i++ {
+		if src[i] != nil {
+			dst[i] = *(src[i])
+		}
+	}
+	return dst
+}
+
+// Float64Map converts a string map of float64 values into a string
+// map of float64 pointers
+func Float64Map(src map[string]float64) map[string]*float64 {
+	dst := make(map[string]*float64)
+	for k, val := range src {
+		v := val
+		dst[k] = &v
+	}
+	return dst
+}
+
+// Float64ValueMap converts a string map of float64 pointers into a string
+// map of float64 values
+func Float64ValueMap(src map[string]*float64) map[string]float64 {
+	dst := make(map[string]float64)
+	for k, val := range src {
+		if val != nil {
+			dst[k] = *val
+		}
+	}
+	return dst
+}
+
+// Time returns a pointer to the time.Time value passed in.
+func Time(v time.Time) *time.Time {
+	return &v
+}
+
+// TimeValue returns the value of the time.Time pointer passed in or
+// time.Time{} if the pointer is nil.
+func TimeValue(v *time.Time) time.Time {
+	if v != nil {
+		return *v
+	}
+	return time.Time{}
+}
+
+// SecondsTimeValue converts an int64 pointer to a time.Time value
+// representing seconds since Epoch or time.Time{} if the pointer is nil.
+func SecondsTimeValue(v *int64) time.Time {
+	if v != nil {
+		return time.Unix((*v / 1000), 0)
+	}
+	return time.Time{}
+}
+
+// MillisecondsTimeValue converts an int64 pointer to a time.Time value
+// representing milliseconds sinch Epoch or time.Time{} if the pointer is nil.
+func MillisecondsTimeValue(v *int64) time.Time {
+	if v != nil {
+		return time.Unix(0, (*v * 1000000))
+	}
+	return time.Time{}
+}
+
+// TimeUnixMilli returns a Unix timestamp in milliseconds from "January 1, 1970 UTC".
+// The result is undefined if the Unix time cannot be represented by an int64.
+// Which includes calling TimeUnixMilli on a zero Time is undefined.
+//
+// This utility is useful for service API's such as CloudWatch Logs which require
+// their unix time values to be in milliseconds.
+//
+// See Go stdlib https://golang.org/pkg/time/#Time.UnixNano for more information.
+func TimeUnixMilli(t time.Time) int64 {
+	return t.UnixNano() / int64(time.Millisecond/time.Nanosecond)
+}
+
+// TimeSlice converts a slice of time.Time values into a slice of
+// time.Time pointers
+func TimeSlice(src []time.Time) []*time.Time {
+	dst := make([]*time.Time, len(src))
+	for i := 0; i < len(src); i++ {
+		dst[i] = &(src[i])
+	}
+	return dst
+}
+
+// TimeValueSlice converts a slice of time.Time pointers into a slice of
+// time.Time values
+func TimeValueSlice(src []*time.Time) []time.Time {
+	dst := make([]time.Time, len(src))
+	for i := 0; i < len(src); i++ {
+		if src[i] != nil {
+			dst[i] = *(src[i])
+		}
+	}
+	return dst
+}
+
+// TimeMap converts a string map of time.Time values into a string
+// map of time.Time pointers
+func TimeMap(src map[string]time.Time) map[string]*time.Time {
+	dst := make(map[string]*time.Time)
+	for k, val := range src {
+		v := val
+		dst[k] = &v
+	}
+	return dst
+}
+
+// TimeValueMap converts a string map of time.Time pointers into a string
+// map of time.Time values
+func TimeValueMap(src map[string]*time.Time) map[string]time.Time {
+	dst := make(map[string]time.Time)
+	for k, val := range src {
+		if val != nil {
+			dst[k] = *val
+		}
+	}
+	return dst
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go
new file mode 100644
index 000000000..cfcddf3dc
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go
@@ -0,0 +1,228 @@
+package corehandlers
+
+import (
+	"bytes"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+	"regexp"
+	"strconv"
+	"time"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/credentials"
+	"github.com/aws/aws-sdk-go/aws/request"
+)
+
+// Interface for matching types which also have a Len method.
+type lener interface {
+	Len() int
+}
+
+// BuildContentLengthHandler builds the content length of a request based on the body,
+// or will use the HTTPRequest.Header's "Content-Length" if defined. If unable
+// to determine request body length and no "Content-Length" was specified it will panic.
+//
+// The Content-Length will only be added to the request if the length of the body
+// is greater than 0. If the body is empty or the current `Content-Length`
+// header is <= 0, the header will also be stripped.
+var BuildContentLengthHandler = request.NamedHandler{Name: "core.BuildContentLengthHandler", Fn: func(r *request.Request) {
+	var length int64
+
+	if slength := r.HTTPRequest.Header.Get("Content-Length"); slength != "" {
+		length, _ = strconv.ParseInt(slength, 10, 64)
+	} else {
+		if r.Body != nil {
+			var err error
+			length, err = aws.SeekerLen(r.Body)
+			if err != nil {
+				r.Error = awserr.New(request.ErrCodeSerialization, "failed to get request body's length", err)
+				return
+			}
+		}
+	}
+
+	if length > 0 {
+		r.HTTPRequest.ContentLength = length
+		r.HTTPRequest.Header.Set("Content-Length", fmt.Sprintf("%d", length))
+	} else {
+		r.HTTPRequest.ContentLength = 0
+		r.HTTPRequest.Header.Del("Content-Length")
+	}
+}}
+
+var reStatusCode = regexp.MustCompile(`^(\d{3})`)
+
+// ValidateReqSigHandler is a request handler to ensure that the request's
+// signature doesn't expire before it is sent. This can happen when a request
+// is built and signed significantly before it is sent. Or significant delays
+// occur when retrying requests that would cause the signature to expire.
+var ValidateReqSigHandler = request.NamedHandler{
+	Name: "core.ValidateReqSigHandler",
+	Fn: func(r *request.Request) {
+		// Unsigned requests are not signed
+		if r.Config.Credentials == credentials.AnonymousCredentials {
+			return
+		}
+
+		signedTime := r.Time
+		if !r.LastSignedAt.IsZero() {
+			signedTime = r.LastSignedAt
+		}
+
+		// 10 minutes to allow for some clock skew/delays in transmission.
+		// Would be improved with aws/aws-sdk-go#423
+		if signedTime.Add(10 * time.Minute).After(time.Now()) {
+			return
+		}
+
+		fmt.Println("request expired, resigning")
+		r.Sign()
+	},
+}
+
+// SendHandler is a request handler to send service request using HTTP client.
+var SendHandler = request.NamedHandler{
+	Name: "core.SendHandler",
+	Fn: func(r *request.Request) {
+		sender := sendFollowRedirects
+		if r.DisableFollowRedirects {
+			sender = sendWithoutFollowRedirects
+		}
+
+		if request.NoBody == r.HTTPRequest.Body {
+			// Strip off the request body if the NoBody reader was used as a
+			// place holder for a request body. This prevents the SDK from
+			// making requests with a request body when it would be invalid
+			// to do so.
+			//
+			// Use a shallow copy of the http.Request to ensure the race condition
+			// of transport on Body will not trigger
+			reqOrig, reqCopy := r.HTTPRequest, *r.HTTPRequest
+			reqCopy.Body = nil
+			r.HTTPRequest = &reqCopy
+			defer func() {
+				r.HTTPRequest = reqOrig
+			}()
+		}
+
+		var err error
+		r.HTTPResponse, err = sender(r)
+		if err != nil {
+			handleSendError(r, err)
+		}
+	},
+}
+
+func sendFollowRedirects(r *request.Request) (*http.Response, error) {
+	return r.Config.HTTPClient.Do(r.HTTPRequest)
+}
+
+func sendWithoutFollowRedirects(r *request.Request) (*http.Response, error) {
+	transport := r.Config.HTTPClient.Transport
+	if transport == nil {
+		transport = http.DefaultTransport
+	}
+
+	return transport.RoundTrip(r.HTTPRequest)
+}
+
+func handleSendError(r *request.Request, err error) {
+	// Prevent leaking if an HTTPResponse was returned. Clean up
+	// the body.
+	if r.HTTPResponse != nil {
+		r.HTTPResponse.Body.Close()
+	}
+	// Capture the case where url.Error is returned for error processing
+	// response. e.g. 301 without location header comes back as string
+	// error and r.HTTPResponse is nil. Other URL redirect errors will
+	// comeback in a similar method.
+	if e, ok := err.(*url.Error); ok && e.Err != nil {
+		if s := reStatusCode.FindStringSubmatch(e.Err.Error()); s != nil {
+			code, _ := strconv.ParseInt(s[1], 10, 64)
+			r.HTTPResponse = &http.Response{
+				StatusCode: int(code),
+				Status:     http.StatusText(int(code)),
+				Body:       ioutil.NopCloser(bytes.NewReader([]byte{})),
+			}
+			return
+		}
+	}
+	if r.HTTPResponse == nil {
+		// Add a dummy request response object to ensure the HTTPResponse
+		// value is consistent.
+		r.HTTPResponse = &http.Response{
+			StatusCode: int(0),
+			Status:     http.StatusText(int(0)),
+			Body:       ioutil.NopCloser(bytes.NewReader([]byte{})),
+		}
+	}
+	// Catch all other request errors.
+	r.Error = awserr.New("RequestError", "send request failed", err)
+	r.Retryable = aws.Bool(true) // network errors are retryable
+
+	// Override the error with a context canceled error, if that was canceled.
+	ctx := r.Context()
+	select {
+	case <-ctx.Done():
+		r.Error = awserr.New(request.CanceledErrorCode,
+			"request context canceled", ctx.Err())
+		r.Retryable = aws.Bool(false)
+	default:
+	}
+}
+
+// ValidateResponseHandler is a request handler to validate service response.
+var ValidateResponseHandler = request.NamedHandler{Name: "core.ValidateResponseHandler", Fn: func(r *request.Request) {
+	if r.HTTPResponse.StatusCode == 0 || r.HTTPResponse.StatusCode >= 300 {
+		// this may be replaced by an UnmarshalError handler
+		r.Error = awserr.New("UnknownError", "unknown error", nil)
+	}
+}}
+
+// AfterRetryHandler performs final checks to determine if the request should
+// be retried and how long to delay.
+var AfterRetryHandler = request.NamedHandler{Name: "core.AfterRetryHandler", Fn: func(r *request.Request) {
+	// If one of the other handlers already set the retry state
+	// we don't want to override it based on the service's state
+	if r.Retryable == nil || aws.BoolValue(r.Config.EnforceShouldRetryCheck) {
+		r.Retryable = aws.Bool(r.ShouldRetry(r))
+	}
+
+	if r.WillRetry() {
+		r.RetryDelay = r.RetryRules(r)
+
+		if sleepFn := r.Config.SleepDelay; sleepFn != nil {
+			// Support SleepDelay for backwards compatibility and testing
+			sleepFn(r.RetryDelay)
+		} else if err := aws.SleepWithContext(r.Context(), r.RetryDelay); err != nil {
+			r.Error = awserr.New(request.CanceledErrorCode,
+				"request context canceled", err)
+			r.Retryable = aws.Bool(false)
+			return
+		}
+
+		// when the expired token exception occurs the credentials
+		// need to be expired locally so that the next request to
+		// get credentials will trigger a credentials refresh.
+		if r.IsErrorExpired() {
+			r.Config.Credentials.Expire()
+		}
+
+		r.RetryCount++
+		r.Error = nil
+	}
+}}
+
+// ValidateEndpointHandler is a request handler to validate a request had the
+// appropriate Region and Endpoint set. Will set r.Error if the endpoint or
+// region is not valid.
+var ValidateEndpointHandler = request.NamedHandler{Name: "core.ValidateEndpointHandler", Fn: func(r *request.Request) {
+	if r.ClientInfo.SigningRegion == "" && aws.StringValue(r.Config.Region) == "" {
+		r.Error = aws.ErrMissingRegion
+	} else if r.ClientInfo.Endpoint == "" {
+		r.Error = aws.ErrMissingEndpoint
+	}
+}}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go
new file mode 100644
index 000000000..7d50b1557
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go
@@ -0,0 +1,17 @@
+package corehandlers
+
+import "github.com/aws/aws-sdk-go/aws/request"
+
+// ValidateParametersHandler is a request handler to validate the input parameters.
+// Validating parameters only has meaning if done prior to the request being sent.
+var ValidateParametersHandler = request.NamedHandler{Name: "core.ValidateParametersHandler", Fn: func(r *request.Request) {
+	if !r.ParamsFilled() {
+		return
+	}
+
+	if v, ok := r.Params.(request.Validator); ok {
+		if err := v.Validate(); err != nil {
+			r.Error = err
+		}
+	}
+}}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/user_agent.go b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/user_agent.go
new file mode 100644
index 000000000..a15f496bc
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/user_agent.go
@@ -0,0 +1,37 @@
+package corehandlers
+
+import (
+	"os"
+	"runtime"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/request"
+)
+
+// SDKVersionUserAgentHandler is a request handler for adding the SDK Version
+// to the user agent.
+var SDKVersionUserAgentHandler = request.NamedHandler{
+	Name: "core.SDKVersionUserAgentHandler",
+	Fn: request.MakeAddToUserAgentHandler(aws.SDKName, aws.SDKVersion,
+		runtime.Version(), runtime.GOOS, runtime.GOARCH),
+}
+
+const execEnvVar = `AWS_EXECUTION_ENV`
+const execEnvUAKey = `exec_env`
+
+// AddHostExecEnvUserAgentHander is a request handler appending the SDK's
+// execution environment to the user agent.
+//
+// If the environment variable AWS_EXECUTION_ENV is set, its value will be
+// appended to the user agent string.
+var AddHostExecEnvUserAgentHander = request.NamedHandler{
+	Name: "core.AddHostExecEnvUserAgentHander",
+	Fn: func(r *request.Request) {
+		v := os.Getenv(execEnvVar)
+		if len(v) == 0 {
+			return
+		}
+
+		request.AddToUserAgent(r, execEnvUAKey+"/"+v)
+	},
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go
new file mode 100644
index 000000000..f298d6596
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go
@@ -0,0 +1,102 @@
+package credentials
+
+import (
+	"github.com/aws/aws-sdk-go/aws/awserr"
+)
+
+var (
+	// ErrNoValidProvidersFoundInChain Is returned when there are no valid
+	// providers in the ChainProvider.
+	//
+	// This has been deprecated. For verbose error messaging set
+	// aws.Config.CredentialsChainVerboseErrors to true
+	//
+	// @readonly
+	ErrNoValidProvidersFoundInChain = awserr.New("NoCredentialProviders",
+		`no valid providers in chain. Deprecated.
+	For verbose messaging see aws.Config.CredentialsChainVerboseErrors`,
+		nil)
+)
+
+// A ChainProvider will search for a provider which returns credentials
+// and cache that provider until Retrieve is called again.
+//
+// The ChainProvider provides a way of chaining multiple providers together
+// which will pick the first available using priority order of the Providers
+// in the list.
+//
+// If none of the Providers retrieve valid credentials Value, ChainProvider's
+// Retrieve() will return the error ErrNoValidProvidersFoundInChain.
+//
+// If a Provider is found which returns valid credentials Value ChainProvider
+// will cache that Provider for all calls to IsExpired(), until Retrieve is
+// called again.
+//
+// Example of ChainProvider to be used with an EnvProvider and EC2RoleProvider.
+// In this example EnvProvider will first check if any credentials are available
+// via the environment variables. If there are none ChainProvider will check
+// the next Provider in the list, EC2RoleProvider in this case. If EC2RoleProvider
+// does not return any credentials ChainProvider will return the error
+// ErrNoValidProvidersFoundInChain
+//
+//     creds := credentials.NewChainCredentials(
+//         []credentials.Provider{
+//             &credentials.EnvProvider{},
+//             &ec2rolecreds.EC2RoleProvider{
+//                 Client: ec2metadata.New(sess),
+//             },
+//         })
+//
+//     // Usage of ChainCredentials with aws.Config
+//     svc := ec2.New(session.Must(session.NewSession(&aws.Config{
+//       Credentials: creds,
+//     })))
+//
+type ChainProvider struct {
+	Providers     []Provider
+	curr          Provider
+	VerboseErrors bool
+}
+
+// NewChainCredentials returns a pointer to a new Credentials object
+// wrapping a chain of providers.
+func NewChainCredentials(providers []Provider) *Credentials {
+	return NewCredentials(&ChainProvider{
+		Providers: append([]Provider{}, providers...),
+	})
+}
+
+// Retrieve returns the credentials value or error if no provider returned
+// without error.
+//
+// If a provider is found it will be cached and any calls to IsExpired()
+// will return the expired state of the cached provider.
+func (c *ChainProvider) Retrieve() (Value, error) {
+	var errs []error
+	for _, p := range c.Providers {
+		creds, err := p.Retrieve()
+		if err == nil {
+			c.curr = p
+			return creds, nil
+		}
+		errs = append(errs, err)
+	}
+	c.curr = nil
+
+	var err error
+	err = ErrNoValidProvidersFoundInChain
+	if c.VerboseErrors {
+		err = awserr.NewBatchError("NoCredentialProviders", "no valid providers in chain", errs)
+	}
+	return Value{}, err
+}
+
+// IsExpired will returned the expired state of the currently cached provider
+// if there is one.  If there is no current provider, true will be returned.
+func (c *ChainProvider) IsExpired() bool {
+	if c.curr != nil {
+		return c.curr.IsExpired()
+	}
+
+	return true
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go
new file mode 100644
index 000000000..a270844df
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go
@@ -0,0 +1,259 @@
+// Package credentials provides credential retrieval and management
+//
+// The Credentials is the primary method of getting access to and managing
+// credentials Values. Using dependency injection retrieval of the credential
+// values is handled by a object which satisfies the Provider interface.
+//
+// By default the Credentials.Get() will cache the successful result of a
+// Provider's Retrieve() until Provider.IsExpired() returns true. At which
+// point Credentials will call Provider's Retrieve() to get new credential Value.
+//
+// The Provider is responsible for determining when credentials Value have expired.
+// It is also important to note that Credentials will always call Retrieve the
+// first time Credentials.Get() is called.
+//
+// Example of using the environment variable credentials.
+//
+//     creds := credentials.NewEnvCredentials()
+//
+//     // Retrieve the credentials value
+//     credValue, err := creds.Get()
+//     if err != nil {
+//         // handle error
+//     }
+//
+// Example of forcing credentials to expire and be refreshed on the next Get().
+// This may be helpful to proactively expire credentials and refresh them sooner
+// than they would naturally expire on their own.
+//
+//     creds := credentials.NewCredentials(&ec2rolecreds.EC2RoleProvider{})
+//     creds.Expire()
+//     credsValue, err := creds.Get()
+//     // New credentials will be retrieved instead of from cache.
+//
+//
+// Custom Provider
+//
+// Each Provider built into this package also provides a helper method to generate
+// a Credentials pointer setup with the provider. To use a custom Provider just
+// create a type which satisfies the Provider interface and pass it to the
+// NewCredentials method.
+//
+//     type MyProvider struct{}
+//     func (m *MyProvider) Retrieve() (Value, error) {...}
+//     func (m *MyProvider) IsExpired() bool {...}
+//
+//     creds := credentials.NewCredentials(&MyProvider{})
+//     credValue, err := creds.Get()
+//
+package credentials
+
+import (
+	"sync"
+	"time"
+)
+
+// AnonymousCredentials is an empty Credential object that can be used as
+// dummy placeholder credentials for requests that do not need signed.
+//
+// This Credentials can be used to configure a service to not sign requests
+// when making service API calls. For example, when accessing public
+// s3 buckets.
+//
+//     svc := s3.New(session.Must(session.NewSession(&aws.Config{
+//       Credentials: credentials.AnonymousCredentials,
+//     })))
+//     // Access public S3 buckets.
+//
+// @readonly
+var AnonymousCredentials = NewStaticCredentials("", "", "")
+
+// A Value is the AWS credentials value for individual credential fields.
+type Value struct {
+	// AWS Access key ID
+	AccessKeyID string
+
+	// AWS Secret Access Key
+	SecretAccessKey string
+
+	// AWS Session Token
+	SessionToken string
+
+	// Provider used to get credentials
+	ProviderName string
+}
+
+// A Provider is the interface for any component which will provide credentials
+// Value. A provider is required to manage its own Expired state, and what to
+// be expired means.
+//
+// The Provider should not need to implement its own mutexes, because
+// that will be managed by Credentials.
+type Provider interface {
+	// Retrieve returns nil if it successfully retrieved the value.
+	// Error is returned if the value were not obtainable, or empty.
+	Retrieve() (Value, error)
+
+	// IsExpired returns if the credentials are no longer valid, and need
+	// to be retrieved.
+	IsExpired() bool
+}
+
+// An ErrorProvider is a stub credentials provider that always returns an error
+// this is used by the SDK when construction a known provider is not possible
+// due to an error.
+type ErrorProvider struct {
+	// The error to be returned from Retrieve
+	Err error
+
+	// The provider name to set on the Retrieved returned Value
+	ProviderName string
+}
+
+// Retrieve will always return the error that the ErrorProvider was created with.
+func (p ErrorProvider) Retrieve() (Value, error) {
+	return Value{ProviderName: p.ProviderName}, p.Err
+}
+
+// IsExpired will always return not expired.
+func (p ErrorProvider) IsExpired() bool {
+	return false
+}
+
+// A Expiry provides shared expiration logic to be used by credentials
+// providers to implement expiry functionality.
+//
+// The best method to use this struct is as an anonymous field within the
+// provider's struct.
+//
+// Example:
+//     type EC2RoleProvider struct {
+//         Expiry
+//         ...
+//     }
+type Expiry struct {
+	// The date/time when to expire on
+	expiration time.Time
+
+	// If set will be used by IsExpired to determine the current time.
+	// Defaults to time.Now if CurrentTime is not set.  Available for testing
+	// to be able to mock out the current time.
+	CurrentTime func() time.Time
+}
+
+// SetExpiration sets the expiration IsExpired will check when called.
+//
+// If window is greater than 0 the expiration time will be reduced by the
+// window value.
+//
+// Using a window is helpful to trigger credentials to expire sooner than
+// the expiration time given to ensure no requests are made with expired
+// tokens.
+func (e *Expiry) SetExpiration(expiration time.Time, window time.Duration) {
+	e.expiration = expiration
+	if window > 0 {
+		e.expiration = e.expiration.Add(-window)
+	}
+}
+
+// IsExpired returns if the credentials are expired.
+func (e *Expiry) IsExpired() bool {
+	curTime := e.CurrentTime
+	if curTime == nil {
+		curTime = time.Now
+	}
+	return e.expiration.Before(curTime())
+}
+
+// A Credentials provides concurrency safe retrieval of AWS credentials Value.
+// Credentials will cache the credentials value until they expire. Once the value
+// expires the next Get will attempt to retrieve valid credentials.
+//
+// Credentials is safe to use across multiple goroutines and will manage the
+// synchronous state so the Providers do not need to implement their own
+// synchronization.
+//
+// The first Credentials.Get() will always call Provider.Retrieve() to get the
+// first instance of the credentials Value. All calls to Get() after that
+// will return the cached credentials Value until IsExpired() returns true.
+type Credentials struct {
+	creds        Value
+	forceRefresh bool
+
+	m sync.RWMutex
+
+	provider Provider
+}
+
+// NewCredentials returns a pointer to a new Credentials with the provider set.
+func NewCredentials(provider Provider) *Credentials {
+	return &Credentials{
+		provider:     provider,
+		forceRefresh: true,
+	}
+}
+
+// Get returns the credentials value, or error if the credentials Value failed
+// to be retrieved.
+//
+// Will return the cached credentials Value if it has not expired. If the
+// credentials Value has expired the Provider's Retrieve() will be called
+// to refresh the credentials.
+//
+// If Credentials.Expire() was called the credentials Value will be force
+// expired, and the next call to Get() will cause them to be refreshed.
+func (c *Credentials) Get() (Value, error) {
+	// Check the cached credentials first with just the read lock.
+	c.m.RLock()
+	if !c.isExpired() {
+		creds := c.creds
+		c.m.RUnlock()
+		return creds, nil
+	}
+	c.m.RUnlock()
+
+	// Credentials are expired need to retrieve the credentials taking the full
+	// lock.
+	c.m.Lock()
+	defer c.m.Unlock()
+
+	if c.isExpired() {
+		creds, err := c.provider.Retrieve()
+		if err != nil {
+			return Value{}, err
+		}
+		c.creds = creds
+		c.forceRefresh = false
+	}
+
+	return c.creds, nil
+}
+
+// Expire expires the credentials and forces them to be retrieved on the
+// next call to Get().
+//
+// This will override the Provider's expired state, and force Credentials
+// to call the Provider's Retrieve().
+func (c *Credentials) Expire() {
+	c.m.Lock()
+	defer c.m.Unlock()
+
+	c.forceRefresh = true
+}
+
+// IsExpired returns if the credentials are no longer valid, and need
+// to be retrieved.
+//
+// If the Credentials were forced to be expired with Expire() this will
+// reflect that override.
+func (c *Credentials) IsExpired() bool {
+	c.m.RLock()
+	defer c.m.RUnlock()
+
+	return c.isExpired()
+}
+
+// isExpired helper method wrapping the definition of expired credentials.
+func (c *Credentials) isExpired() bool {
+	return c.forceRefresh || c.provider.IsExpired()
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go
new file mode 100644
index 000000000..0ed791be6
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go
@@ -0,0 +1,178 @@
+package ec2rolecreds
+
+import (
+	"bufio"
+	"encoding/json"
+	"fmt"
+	"strings"
+	"time"
+
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/client"
+	"github.com/aws/aws-sdk-go/aws/credentials"
+	"github.com/aws/aws-sdk-go/aws/ec2metadata"
+	"github.com/aws/aws-sdk-go/internal/sdkuri"
+)
+
+// ProviderName provides a name of EC2Role provider
+const ProviderName = "EC2RoleProvider"
+
+// A EC2RoleProvider retrieves credentials from the EC2 service, and keeps track if
+// those credentials are expired.
+//
+// Example how to configure the EC2RoleProvider with custom http Client, Endpoint
+// or ExpiryWindow
+//
+//     p := &ec2rolecreds.EC2RoleProvider{
+//         // Pass in a custom timeout to be used when requesting
+//         // IAM EC2 Role credentials.
+//         Client: ec2metadata.New(sess, aws.Config{
+//             HTTPClient: &http.Client{Timeout: 10 * time.Second},
+//         }),
+//
+//         // Do not use early expiry of credentials. If a non zero value is
+//         // specified the credentials will be expired early
+//         ExpiryWindow: 0,
+//     }
+type EC2RoleProvider struct {
+	credentials.Expiry
+
+	// Required EC2Metadata client to use when connecting to EC2 metadata service.
+	Client *ec2metadata.EC2Metadata
+
+	// ExpiryWindow will allow the credentials to trigger refreshing prior to
+	// the credentials actually expiring. This is beneficial so race conditions
+	// with expiring credentials do not cause request to fail unexpectedly
+	// due to ExpiredTokenException exceptions.
+	//
+	// So a ExpiryWindow of 10s would cause calls to IsExpired() to return true
+	// 10 seconds before the credentials are actually expired.
+	//
+	// If ExpiryWindow is 0 or less it will be ignored.
+	ExpiryWindow time.Duration
+}
+
+// NewCredentials returns a pointer to a new Credentials object wrapping
+// the EC2RoleProvider. Takes a ConfigProvider to create a EC2Metadata client.
+// The ConfigProvider is satisfied by the session.Session type.
+func NewCredentials(c client.ConfigProvider, options ...func(*EC2RoleProvider)) *credentials.Credentials {
+	p := &EC2RoleProvider{
+		Client: ec2metadata.New(c),
+	}
+
+	for _, option := range options {
+		option(p)
+	}
+
+	return credentials.NewCredentials(p)
+}
+
+// NewCredentialsWithClient returns a pointer to a new Credentials object wrapping
+// the EC2RoleProvider. Takes a EC2Metadata client to use when connecting to EC2
+// metadata service.
+func NewCredentialsWithClient(client *ec2metadata.EC2Metadata, options ...func(*EC2RoleProvider)) *credentials.Credentials {
+	p := &EC2RoleProvider{
+		Client: client,
+	}
+
+	for _, option := range options {
+		option(p)
+	}
+
+	return credentials.NewCredentials(p)
+}
+
+// Retrieve retrieves credentials from the EC2 service.
+// Error will be returned if the request fails, or unable to extract
+// the desired credentials.
+func (m *EC2RoleProvider) Retrieve() (credentials.Value, error) {
+	credsList, err := requestCredList(m.Client)
+	if err != nil {
+		return credentials.Value{ProviderName: ProviderName}, err
+	}
+
+	if len(credsList) == 0 {
+		return credentials.Value{ProviderName: ProviderName}, awserr.New("EmptyEC2RoleList", "empty EC2 Role list", nil)
+	}
+	credsName := credsList[0]
+
+	roleCreds, err := requestCred(m.Client, credsName)
+	if err != nil {
+		return credentials.Value{ProviderName: ProviderName}, err
+	}
+
+	m.SetExpiration(roleCreds.Expiration, m.ExpiryWindow)
+
+	return credentials.Value{
+		AccessKeyID:     roleCreds.AccessKeyID,
+		SecretAccessKey: roleCreds.SecretAccessKey,
+		SessionToken:    roleCreds.Token,
+		ProviderName:    ProviderName,
+	}, nil
+}
+
+// A ec2RoleCredRespBody provides the shape for unmarshaling credential
+// request responses.
+type ec2RoleCredRespBody struct {
+	// Success State
+	Expiration      time.Time
+	AccessKeyID     string
+	SecretAccessKey string
+	Token           string
+
+	// Error state
+	Code    string
+	Message string
+}
+
+const iamSecurityCredsPath = "iam/security-credentials/"
+
+// requestCredList requests a list of credentials from the EC2 service.
+// If there are no credentials, or there is an error making or receiving the request
+func requestCredList(client *ec2metadata.EC2Metadata) ([]string, error) {
+	resp, err := client.GetMetadata(iamSecurityCredsPath)
+	if err != nil {
+		return nil, awserr.New("EC2RoleRequestError", "no EC2 instance role found", err)
+	}
+
+	credsList := []string{}
+	s := bufio.NewScanner(strings.NewReader(resp))
+	for s.Scan() {
+		credsList = append(credsList, s.Text())
+	}
+
+	if err := s.Err(); err != nil {
+		return nil, awserr.New("SerializationError", "failed to read EC2 instance role from metadata service", err)
+	}
+
+	return credsList, nil
+}
+
+// requestCred requests the credentials for a specific credentials from the EC2 service.
+//
+// If the credentials cannot be found, or there is an error reading the response
+// and error will be returned.
+func requestCred(client *ec2metadata.EC2Metadata, credsName string) (ec2RoleCredRespBody, error) {
+	resp, err := client.GetMetadata(sdkuri.PathJoin(iamSecurityCredsPath, credsName))
+	if err != nil {
+		return ec2RoleCredRespBody{},
+			awserr.New("EC2RoleRequestError",
+				fmt.Sprintf("failed to get %s EC2 instance role credentials", credsName),
+				err)
+	}
+
+	respCreds := ec2RoleCredRespBody{}
+	if err := json.NewDecoder(strings.NewReader(resp)).Decode(&respCreds); err != nil {
+		return ec2RoleCredRespBody{},
+			awserr.New("SerializationError",
+				fmt.Sprintf("failed to decode %s EC2 instance role credentials", credsName),
+				err)
+	}
+
+	if respCreds.Code != "Success" {
+		// If an error code was returned something failed requesting the role.
+		return ec2RoleCredRespBody{}, awserr.New(respCreds.Code, respCreds.Message, nil)
+	}
+
+	return respCreds, nil
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go
new file mode 100644
index 000000000..a4cec5c55
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go
@@ -0,0 +1,191 @@
+// Package endpointcreds provides support for retrieving credentials from an
+// arbitrary HTTP endpoint.
+//
+// The credentials endpoint Provider can receive both static and refreshable
+// credentials that will expire. Credentials are static when an "Expiration"
+// value is not provided in the endpoint's response.
+//
+// Static credentials will never expire once they have been retrieved. The format
+// of the static credentials response:
+//    {
+//        "AccessKeyId" : "MUA...",
+//        "SecretAccessKey" : "/7PC5om....",
+//    }
+//
+// Refreshable credentials will expire within the "ExpiryWindow" of the Expiration
+// value in the response. The format of the refreshable credentials response:
+//    {
+//        "AccessKeyId" : "MUA...",
+//        "SecretAccessKey" : "/7PC5om....",
+//        "Token" : "AQoDY....=",
+//        "Expiration" : "2016-02-25T06:03:31Z"
+//    }
+//
+// Errors should be returned in the following format and only returned with 400
+// or 500 HTTP status codes.
+//    {
+//        "code": "ErrorCode",
+//        "message": "Helpful error message."
+//    }
+package endpointcreds
+
+import (
+	"encoding/json"
+	"time"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/client"
+	"github.com/aws/aws-sdk-go/aws/client/metadata"
+	"github.com/aws/aws-sdk-go/aws/credentials"
+	"github.com/aws/aws-sdk-go/aws/request"
+)
+
+// ProviderName is the name of the credentials provider.
+const ProviderName = `CredentialsEndpointProvider`
+
+// Provider satisfies the credentials.Provider interface, and is a client to
+// retrieve credentials from an arbitrary endpoint.
+type Provider struct {
+	staticCreds bool
+	credentials.Expiry
+
+	// Requires a AWS Client to make HTTP requests to the endpoint with.
+	// the Endpoint the request will be made to is provided by the aws.Config's
+	// Endpoint value.
+	Client *client.Client
+
+	// ExpiryWindow will allow the credentials to trigger refreshing prior to
+	// the credentials actually expiring. This is beneficial so race conditions
+	// with expiring credentials do not cause request to fail unexpectedly
+	// due to ExpiredTokenException exceptions.
+	//
+	// So a ExpiryWindow of 10s would cause calls to IsExpired() to return true
+	// 10 seconds before the credentials are actually expired.
+	//
+	// If ExpiryWindow is 0 or less it will be ignored.
+	ExpiryWindow time.Duration
+}
+
+// NewProviderClient returns a credentials Provider for retrieving AWS credentials
+// from arbitrary endpoint.
+func NewProviderClient(cfg aws.Config, handlers request.Handlers, endpoint string, options ...func(*Provider)) credentials.Provider {
+	p := &Provider{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName: "CredentialsEndpoint",
+				Endpoint:    endpoint,
+			},
+			handlers,
+		),
+	}
+
+	p.Client.Handlers.Unmarshal.PushBack(unmarshalHandler)
+	p.Client.Handlers.UnmarshalError.PushBack(unmarshalError)
+	p.Client.Handlers.Validate.Clear()
+	p.Client.Handlers.Validate.PushBack(validateEndpointHandler)
+
+	for _, option := range options {
+		option(p)
+	}
+
+	return p
+}
+
+// NewCredentialsClient returns a Credentials wrapper for retrieving credentials
+// from an arbitrary endpoint concurrently. The client will request the
+func NewCredentialsClient(cfg aws.Config, handlers request.Handlers, endpoint string, options ...func(*Provider)) *credentials.Credentials {
+	return credentials.NewCredentials(NewProviderClient(cfg, handlers, endpoint, options...))
+}
+
+// IsExpired returns true if the credentials retrieved are expired, or not yet
+// retrieved.
+func (p *Provider) IsExpired() bool {
+	if p.staticCreds {
+		return false
+	}
+	return p.Expiry.IsExpired()
+}
+
+// Retrieve will attempt to request the credentials from the endpoint the Provider
+// was configured for. And error will be returned if the retrieval fails.
+func (p *Provider) Retrieve() (credentials.Value, error) {
+	resp, err := p.getCredentials()
+	if err != nil {
+		return credentials.Value{ProviderName: ProviderName},
+			awserr.New("CredentialsEndpointError", "failed to load credentials", err)
+	}
+
+	if resp.Expiration != nil {
+		p.SetExpiration(*resp.Expiration, p.ExpiryWindow)
+	} else {
+		p.staticCreds = true
+	}
+
+	return credentials.Value{
+		AccessKeyID:     resp.AccessKeyID,
+		SecretAccessKey: resp.SecretAccessKey,
+		SessionToken:    resp.Token,
+		ProviderName:    ProviderName,
+	}, nil
+}
+
+type getCredentialsOutput struct {
+	Expiration      *time.Time
+	AccessKeyID     string
+	SecretAccessKey string
+	Token           string
+}
+
+type errorOutput struct {
+	Code    string `json:"code"`
+	Message string `json:"message"`
+}
+
+func (p *Provider) getCredentials() (*getCredentialsOutput, error) {
+	op := &request.Operation{
+		Name:       "GetCredentials",
+		HTTPMethod: "GET",
+	}
+
+	out := &getCredentialsOutput{}
+	req := p.Client.NewRequest(op, nil, out)
+	req.HTTPRequest.Header.Set("Accept", "application/json")
+
+	return out, req.Send()
+}
+
+func validateEndpointHandler(r *request.Request) {
+	if len(r.ClientInfo.Endpoint) == 0 {
+		r.Error = aws.ErrMissingEndpoint
+	}
+}
+
+func unmarshalHandler(r *request.Request) {
+	defer r.HTTPResponse.Body.Close()
+
+	out := r.Data.(*getCredentialsOutput)
+	if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&out); err != nil {
+		r.Error = awserr.New("SerializationError",
+			"failed to decode endpoint credentials",
+			err,
+		)
+	}
+}
+
+func unmarshalError(r *request.Request) {
+	defer r.HTTPResponse.Body.Close()
+
+	var errOut errorOutput
+	if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&errOut); err != nil {
+		r.Error = awserr.New("SerializationError",
+			"failed to decode endpoint credentials",
+			err,
+		)
+	}
+
+	// Response body format is not consistent between metadata endpoints.
+	// Grab the error message as a string and include that as the source error
+	r.Error = awserr.New(errOut.Code, errOut.Message, nil)
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go
new file mode 100644
index 000000000..c14231a16
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go
@@ -0,0 +1,78 @@
+package credentials
+
+import (
+	"os"
+
+	"github.com/aws/aws-sdk-go/aws/awserr"
+)
+
+// EnvProviderName provides a name of Env provider
+const EnvProviderName = "EnvProvider"
+
+var (
+	// ErrAccessKeyIDNotFound is returned when the AWS Access Key ID can't be
+	// found in the process's environment.
+	//
+	// @readonly
+	ErrAccessKeyIDNotFound = awserr.New("EnvAccessKeyNotFound", "AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY not found in environment", nil)
+
+	// ErrSecretAccessKeyNotFound is returned when the AWS Secret Access Key
+	// can't be found in the process's environment.
+	//
+	// @readonly
+	ErrSecretAccessKeyNotFound = awserr.New("EnvSecretNotFound", "AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY not found in environment", nil)
+)
+
+// A EnvProvider retrieves credentials from the environment variables of the
+// running process. Environment credentials never expire.
+//
+// Environment variables used:
+//
+// * Access Key ID:     AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY
+//
+// * Secret Access Key: AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY
+type EnvProvider struct {
+	retrieved bool
+}
+
+// NewEnvCredentials returns a pointer to a new Credentials object
+// wrapping the environment variable provider.
+func NewEnvCredentials() *Credentials {
+	return NewCredentials(&EnvProvider{})
+}
+
+// Retrieve retrieves the keys from the environment.
+func (e *EnvProvider) Retrieve() (Value, error) {
+	e.retrieved = false
+
+	id := os.Getenv("AWS_ACCESS_KEY_ID")
+	if id == "" {
+		id = os.Getenv("AWS_ACCESS_KEY")
+	}
+
+	secret := os.Getenv("AWS_SECRET_ACCESS_KEY")
+	if secret == "" {
+		secret = os.Getenv("AWS_SECRET_KEY")
+	}
+
+	if id == "" {
+		return Value{ProviderName: EnvProviderName}, ErrAccessKeyIDNotFound
+	}
+
+	if secret == "" {
+		return Value{ProviderName: EnvProviderName}, ErrSecretAccessKeyNotFound
+	}
+
+	e.retrieved = true
+	return Value{
+		AccessKeyID:     id,
+		SecretAccessKey: secret,
+		SessionToken:    os.Getenv("AWS_SESSION_TOKEN"),
+		ProviderName:    EnvProviderName,
+	}, nil
+}
+
+// IsExpired returns if the credentials have been retrieved.
+func (e *EnvProvider) IsExpired() bool {
+	return !e.retrieved
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go
new file mode 100644
index 000000000..51e21e0f3
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go
@@ -0,0 +1,150 @@
+package credentials
+
+import (
+	"fmt"
+	"os"
+
+	"github.com/go-ini/ini"
+
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/internal/shareddefaults"
+)
+
+// SharedCredsProviderName provides a name of SharedCreds provider
+const SharedCredsProviderName = "SharedCredentialsProvider"
+
+var (
+	// ErrSharedCredentialsHomeNotFound is emitted when the user directory cannot be found.
+	ErrSharedCredentialsHomeNotFound = awserr.New("UserHomeNotFound", "user home directory not found.", nil)
+)
+
+// A SharedCredentialsProvider retrieves credentials from the current user's home
+// directory, and keeps track if those credentials are expired.
+//
+// Profile ini file example: $HOME/.aws/credentials
+type SharedCredentialsProvider struct {
+	// Path to the shared credentials file.
+	//
+	// If empty will look for "AWS_SHARED_CREDENTIALS_FILE" env variable. If the
+	// env value is empty will default to current user's home directory.
+	// Linux/OSX: "$HOME/.aws/credentials"
+	// Windows:   "%USERPROFILE%\.aws\credentials"
+	Filename string
+
+	// AWS Profile to extract credentials from the shared credentials file. If empty
+	// will default to environment variable "AWS_PROFILE" or "default" if
+	// environment variable is also not set.
+	Profile string
+
+	// retrieved states if the credentials have been successfully retrieved.
+	retrieved bool
+}
+
+// NewSharedCredentials returns a pointer to a new Credentials object
+// wrapping the Profile file provider.
+func NewSharedCredentials(filename, profile string) *Credentials {
+	return NewCredentials(&SharedCredentialsProvider{
+		Filename: filename,
+		Profile:  profile,
+	})
+}
+
+// Retrieve reads and extracts the shared credentials from the current
+// users home directory.
+func (p *SharedCredentialsProvider) Retrieve() (Value, error) {
+	p.retrieved = false
+
+	filename, err := p.filename()
+	if err != nil {
+		return Value{ProviderName: SharedCredsProviderName}, err
+	}
+
+	creds, err := loadProfile(filename, p.profile())
+	if err != nil {
+		return Value{ProviderName: SharedCredsProviderName}, err
+	}
+
+	p.retrieved = true
+	return creds, nil
+}
+
+// IsExpired returns if the shared credentials have expired.
+func (p *SharedCredentialsProvider) IsExpired() bool {
+	return !p.retrieved
+}
+
+// loadProfiles loads from the file pointed to by shared credentials filename for profile.
+// The credentials retrieved from the profile will be returned or error. Error will be
+// returned if it fails to read from the file, or the data is invalid.
+func loadProfile(filename, profile string) (Value, error) {
+	config, err := ini.Load(filename)
+	if err != nil {
+		return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to load shared credentials file", err)
+	}
+	iniProfile, err := config.GetSection(profile)
+	if err != nil {
+		return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to get profile", err)
+	}
+
+	id, err := iniProfile.GetKey("aws_access_key_id")
+	if err != nil {
+		return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsAccessKey",
+			fmt.Sprintf("shared credentials %s in %s did not contain aws_access_key_id", profile, filename),
+			err)
+	}
+
+	secret, err := iniProfile.GetKey("aws_secret_access_key")
+	if err != nil {
+		return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsSecret",
+			fmt.Sprintf("shared credentials %s in %s did not contain aws_secret_access_key", profile, filename),
+			nil)
+	}
+
+	// Default to empty string if not found
+	token := iniProfile.Key("aws_session_token")
+
+	return Value{
+		AccessKeyID:     id.String(),
+		SecretAccessKey: secret.String(),
+		SessionToken:    token.String(),
+		ProviderName:    SharedCredsProviderName,
+	}, nil
+}
+
+// filename returns the filename to use to read AWS shared credentials.
+//
+// Will return an error if the user's home directory path cannot be found.
+func (p *SharedCredentialsProvider) filename() (string, error) {
+	if len(p.Filename) != 0 {
+		return p.Filename, nil
+	}
+
+	if p.Filename = os.Getenv("AWS_SHARED_CREDENTIALS_FILE"); len(p.Filename) != 0 {
+		return p.Filename, nil
+	}
+
+	if home := shareddefaults.UserHomeDir(); len(home) == 0 {
+		// Backwards compatibility of home directly not found error being returned.
+		// This error is too verbose, failure when opening the file would of been
+		// a better error to return.
+		return "", ErrSharedCredentialsHomeNotFound
+	}
+
+	p.Filename = shareddefaults.SharedCredentialsFilename()
+
+	return p.Filename, nil
+}
+
+// profile returns the AWS shared credentials profile.  If empty will read
+// environment variable "AWS_PROFILE". If that is not set profile will
+// return "default".
+func (p *SharedCredentialsProvider) profile() string {
+	if p.Profile == "" {
+		p.Profile = os.Getenv("AWS_PROFILE")
+	}
+	if p.Profile == "" {
+		p.Profile = "default"
+	}
+
+	return p.Profile
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go
new file mode 100644
index 000000000..4f5dab3fc
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go
@@ -0,0 +1,57 @@
+package credentials
+
+import (
+	"github.com/aws/aws-sdk-go/aws/awserr"
+)
+
+// StaticProviderName provides a name of Static provider
+const StaticProviderName = "StaticProvider"
+
+var (
+	// ErrStaticCredentialsEmpty is emitted when static credentials are empty.
+	//
+	// @readonly
+	ErrStaticCredentialsEmpty = awserr.New("EmptyStaticCreds", "static credentials are empty", nil)
+)
+
+// A StaticProvider is a set of credentials which are set programmatically,
+// and will never expire.
+type StaticProvider struct {
+	Value
+}
+
+// NewStaticCredentials returns a pointer to a new Credentials object
+// wrapping a static credentials value provider.
+func NewStaticCredentials(id, secret, token string) *Credentials {
+	return NewCredentials(&StaticProvider{Value: Value{
+		AccessKeyID:     id,
+		SecretAccessKey: secret,
+		SessionToken:    token,
+	}})
+}
+
+// NewStaticCredentialsFromCreds returns a pointer to a new Credentials object
+// wrapping the static credentials value provide. Same as NewStaticCredentials
+// but takes the creds Value instead of individual fields
+func NewStaticCredentialsFromCreds(creds Value) *Credentials {
+	return NewCredentials(&StaticProvider{Value: creds})
+}
+
+// Retrieve returns the credentials or error if the credentials are invalid.
+func (s *StaticProvider) Retrieve() (Value, error) {
+	if s.AccessKeyID == "" || s.SecretAccessKey == "" {
+		return Value{ProviderName: StaticProviderName}, ErrStaticCredentialsEmpty
+	}
+
+	if len(s.Value.ProviderName) == 0 {
+		s.Value.ProviderName = StaticProviderName
+	}
+	return s.Value, nil
+}
+
+// IsExpired returns if the credentials are expired.
+//
+// For StaticProvider, the credentials never expired.
+func (s *StaticProvider) IsExpired() bool {
+	return false
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go
new file mode 100644
index 000000000..4108e433e
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go
@@ -0,0 +1,298 @@
+/*
+Package stscreds are credential Providers to retrieve STS AWS credentials.
+
+STS provides multiple ways to retrieve credentials which can be used when making
+future AWS service API operation calls.
+
+The SDK will ensure that per instance of credentials.Credentials all requests
+to refresh the credentials will be synchronized. But, the SDK is unable to
+ensure synchronous usage of the AssumeRoleProvider if the value is shared
+between multiple Credentials, Sessions or service clients.
+
+Assume Role
+
+To assume an IAM role using STS with the SDK you can create a new Credentials
+with the SDKs's stscreds package.
+
+	// Initial credentials loaded from SDK's default credential chain. Such as
+	// the environment, shared credentials (~/.aws/credentials), or EC2 Instance
+	// Role. These credentials will be used to to make the STS Assume Role API.
+	sess := session.Must(session.NewSession())
+
+	// Create the credentials from AssumeRoleProvider to assume the role
+	// referenced by the "myRoleARN" ARN.
+	creds := stscreds.NewCredentials(sess, "myRoleArn")
+
+	// Create service client value configured for credentials
+	// from assumed role.
+	svc := s3.New(sess, &aws.Config{Credentials: creds})
+
+Assume Role with static MFA Token
+
+To assume an IAM role with a MFA token you can either specify a MFA token code
+directly or provide a function to prompt the user each time the credentials
+need to refresh the role's credentials. Specifying the TokenCode should be used
+for short lived operations that will not need to be refreshed, and when you do
+not want to have direct control over the user provides their MFA token.
+
+With TokenCode the AssumeRoleProvider will be not be able to refresh the role's
+credentials.
+
+	// Create the credentials from AssumeRoleProvider to assume the role
+	// referenced by the "myRoleARN" ARN using the MFA token code provided.
+	creds := stscreds.NewCredentials(sess, "myRoleArn", func(p *stscreds.AssumeRoleProvider) {
+		p.SerialNumber = aws.String("myTokenSerialNumber")
+		p.TokenCode = aws.String("00000000")
+	})
+
+	// Create service client value configured for credentials
+	// from assumed role.
+	svc := s3.New(sess, &aws.Config{Credentials: creds})
+
+Assume Role with MFA Token Provider
+
+To assume an IAM role with MFA for longer running tasks where the credentials
+may need to be refreshed setting the TokenProvider field of AssumeRoleProvider
+will allow the credential provider to prompt for new MFA token code when the
+role's credentials need to be refreshed.
+
+The StdinTokenProvider function is available to prompt on stdin to retrieve
+the MFA token code from the user. You can also implement custom prompts by
+satisfing the TokenProvider function signature.
+
+Using StdinTokenProvider with multiple AssumeRoleProviders, or Credentials will
+have undesirable results as the StdinTokenProvider will not be synchronized. A
+single Credentials with an AssumeRoleProvider can be shared safely.
+
+	// Create the credentials from AssumeRoleProvider to assume the role
+	// referenced by the "myRoleARN" ARN. Prompting for MFA token from stdin.
+	creds := stscreds.NewCredentials(sess, "myRoleArn", func(p *stscreds.AssumeRoleProvider) {
+		p.SerialNumber = aws.String("myTokenSerialNumber")
+		p.TokenProvider = stscreds.StdinTokenProvider
+	})
+
+	// Create service client value configured for credentials
+	// from assumed role.
+	svc := s3.New(sess, &aws.Config{Credentials: creds})
+
+*/
+package stscreds
+
+import (
+	"fmt"
+	"time"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/client"
+	"github.com/aws/aws-sdk-go/aws/credentials"
+	"github.com/aws/aws-sdk-go/service/sts"
+)
+
+// StdinTokenProvider will prompt on stdout and read from stdin for a string value.
+// An error is returned if reading from stdin fails.
+//
+// Use this function go read MFA tokens from stdin. The function makes no attempt
+// to make atomic prompts from stdin across multiple gorouties.
+//
+// Using StdinTokenProvider with multiple AssumeRoleProviders, or Credentials will
+// have undesirable results as the StdinTokenProvider will not be synchronized. A
+// single Credentials with an AssumeRoleProvider can be shared safely
+//
+// Will wait forever until something is provided on the stdin.
+func StdinTokenProvider() (string, error) {
+	var v string
+	fmt.Printf("Assume Role MFA token code: ")
+	_, err := fmt.Scanln(&v)
+
+	return v, err
+}
+
+// ProviderName provides a name of AssumeRole provider
+const ProviderName = "AssumeRoleProvider"
+
+// AssumeRoler represents the minimal subset of the STS client API used by this provider.
+type AssumeRoler interface {
+	AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error)
+}
+
+// DefaultDuration is the default amount of time in minutes that the credentials
+// will be valid for.
+var DefaultDuration = time.Duration(15) * time.Minute
+
+// AssumeRoleProvider retrieves temporary credentials from the STS service, and
+// keeps track of their expiration time.
+//
+// This credential provider will be used by the SDKs default credential change
+// when shared configuration is enabled, and the shared config or shared credentials
+// file configure assume role. See Session docs for how to do this.
+//
+// AssumeRoleProvider does not provide any synchronization and it is not safe
+// to share this value across multiple Credentials, Sessions, or service clients
+// without also sharing the same Credentials instance.
+type AssumeRoleProvider struct {
+	credentials.Expiry
+
+	// STS client to make assume role request with.
+	Client AssumeRoler
+
+	// Role to be assumed.
+	RoleARN string
+
+	// Session name, if you wish to reuse the credentials elsewhere.
+	RoleSessionName string
+
+	// Expiry duration of the STS credentials. Defaults to 15 minutes if not set.
+	Duration time.Duration
+
+	// Optional ExternalID to pass along, defaults to nil if not set.
+	ExternalID *string
+
+	// The policy plain text must be 2048 bytes or shorter. However, an internal
+	// conversion compresses it into a packed binary format with a separate limit.
+	// The PackedPolicySize response element indicates by percentage how close to
+	// the upper size limit the policy is, with 100% equaling the maximum allowed
+	// size.
+	Policy *string
+
+	// The identification number of the MFA device that is associated with the user
+	// who is making the AssumeRole call. Specify this value if the trust policy
+	// of the role being assumed includes a condition that requires MFA authentication.
+	// The value is either the serial number for a hardware device (such as GAHT12345678)
+	// or an Amazon Resource Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user).
+	SerialNumber *string
+
+	// The value provided by the MFA device, if the trust policy of the role being
+	// assumed requires MFA (that is, if the policy includes a condition that tests
+	// for MFA). If the role being assumed requires MFA and if the TokenCode value
+	// is missing or expired, the AssumeRole call returns an "access denied" error.
+	//
+	// If SerialNumber is set and neither TokenCode nor TokenProvider are also
+	// set an error will be returned.
+	TokenCode *string
+
+	// Async method of providing MFA token code for assuming an IAM role with MFA.
+	// The value returned by the function will be used as the TokenCode in the Retrieve
+	// call. See StdinTokenProvider for a provider that prompts and reads from stdin.
+	//
+	// This token provider will be called when ever the assumed role's
+	// credentials need to be refreshed when SerialNumber is also set and
+	// TokenCode is not set.
+	//
+	// If both TokenCode and TokenProvider is set, TokenProvider will be used and
+	// TokenCode is ignored.
+	TokenProvider func() (string, error)
+
+	// ExpiryWindow will allow the credentials to trigger refreshing prior to
+	// the credentials actually expiring. This is beneficial so race conditions
+	// with expiring credentials do not cause request to fail unexpectedly
+	// due to ExpiredTokenException exceptions.
+	//
+	// So a ExpiryWindow of 10s would cause calls to IsExpired() to return true
+	// 10 seconds before the credentials are actually expired.
+	//
+	// If ExpiryWindow is 0 or less it will be ignored.
+	ExpiryWindow time.Duration
+}
+
+// NewCredentials returns a pointer to a new Credentials object wrapping the
+// AssumeRoleProvider. The credentials will expire every 15 minutes and the
+// role will be named after a nanosecond timestamp of this operation.
+//
+// Takes a Config provider to create the STS client. The ConfigProvider is
+// satisfied by the session.Session type.
+//
+// It is safe to share the returned Credentials with multiple Sessions and
+// service clients. All access to the credentials and refreshing them
+// will be synchronized.
+func NewCredentials(c client.ConfigProvider, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials {
+	p := &AssumeRoleProvider{
+		Client:   sts.New(c),
+		RoleARN:  roleARN,
+		Duration: DefaultDuration,
+	}
+
+	for _, option := range options {
+		option(p)
+	}
+
+	return credentials.NewCredentials(p)
+}
+
+// NewCredentialsWithClient returns a pointer to a new Credentials object wrapping the
+// AssumeRoleProvider. The credentials will expire every 15 minutes and the
+// role will be named after a nanosecond timestamp of this operation.
+//
+// Takes an AssumeRoler which can be satisfied by the STS client.
+//
+// It is safe to share the returned Credentials with multiple Sessions and
+// service clients. All access to the credentials and refreshing them
+// will be synchronized.
+func NewCredentialsWithClient(svc AssumeRoler, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials {
+	p := &AssumeRoleProvider{
+		Client:   svc,
+		RoleARN:  roleARN,
+		Duration: DefaultDuration,
+	}
+
+	for _, option := range options {
+		option(p)
+	}
+
+	return credentials.NewCredentials(p)
+}
+
+// Retrieve generates a new set of temporary credentials using STS.
+func (p *AssumeRoleProvider) Retrieve() (credentials.Value, error) {
+
+	// Apply defaults where parameters are not set.
+	if p.RoleSessionName == "" {
+		// Try to work out a role name that will hopefully end up unique.
+		p.RoleSessionName = fmt.Sprintf("%d", time.Now().UTC().UnixNano())
+	}
+	if p.Duration == 0 {
+		// Expire as often as AWS permits.
+		p.Duration = DefaultDuration
+	}
+	input := &sts.AssumeRoleInput{
+		DurationSeconds: aws.Int64(int64(p.Duration / time.Second)),
+		RoleArn:         aws.String(p.RoleARN),
+		RoleSessionName: aws.String(p.RoleSessionName),
+		ExternalId:      p.ExternalID,
+	}
+	if p.Policy != nil {
+		input.Policy = p.Policy
+	}
+	if p.SerialNumber != nil {
+		if p.TokenCode != nil {
+			input.SerialNumber = p.SerialNumber
+			input.TokenCode = p.TokenCode
+		} else if p.TokenProvider != nil {
+			input.SerialNumber = p.SerialNumber
+			code, err := p.TokenProvider()
+			if err != nil {
+				return credentials.Value{ProviderName: ProviderName}, err
+			}
+			input.TokenCode = aws.String(code)
+		} else {
+			return credentials.Value{ProviderName: ProviderName},
+				awserr.New("AssumeRoleTokenNotAvailable",
+					"assume role with MFA enabled, but neither TokenCode nor TokenProvider are set", nil)
+		}
+	}
+
+	roleOutput, err := p.Client.AssumeRole(input)
+	if err != nil {
+		return credentials.Value{ProviderName: ProviderName}, err
+	}
+
+	// We will proactively generate new credentials before they expire.
+	p.SetExpiration(*roleOutput.Credentials.Expiration, p.ExpiryWindow)
+
+	return credentials.Value{
+		AccessKeyID:     *roleOutput.Credentials.AccessKeyId,
+		SecretAccessKey: *roleOutput.Credentials.SecretAccessKey,
+		SessionToken:    *roleOutput.Credentials.SessionToken,
+		ProviderName:    ProviderName,
+	}, nil
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/csm/doc.go b/vendor/github.com/aws/aws-sdk-go/aws/csm/doc.go
new file mode 100644
index 000000000..152d785b3
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/csm/doc.go
@@ -0,0 +1,46 @@
+// Package csm provides Client Side Monitoring (CSM) which enables sending metrics
+// via UDP connection. Using the Start function will enable the reporting of
+// metrics on a given port. If Start is called, with different parameters, again,
+// a panic will occur.
+//
+// Pause can be called to pause any metrics publishing on a given port. Sessions
+// that have had their handlers modified via InjectHandlers may still be used.
+// However, the handlers will act as a no-op meaning no metrics will be published.
+//
+//	Example:
+//		r, err := csm.Start("clientID", ":31000")
+//		if err != nil {
+//			panic(fmt.Errorf("failed starting CSM:  %v", err))
+//		}
+//
+//		sess, err := session.NewSession(&aws.Config{})
+//		if err != nil {
+//			panic(fmt.Errorf("failed loading session: %v", err))
+//		}
+//
+//		r.InjectHandlers(&sess.Handlers)
+//
+//		client := s3.New(sess)
+//		resp, err := client.GetObject(&s3.GetObjectInput{
+//			Bucket: aws.String("bucket"),
+//			Key: aws.String("key"),
+//		})
+//
+//		// Will pause monitoring
+//		r.Pause()
+//		resp, err = client.GetObject(&s3.GetObjectInput{
+//			Bucket: aws.String("bucket"),
+//			Key: aws.String("key"),
+//		})
+//
+//		// Resume monitoring
+//		r.Continue()
+//
+// Start returns a Reporter that is used to enable or disable monitoring. If
+// access to the Reporter is required later, calling Get will return the Reporter
+// singleton.
+//
+//	Example:
+//		r := csm.Get()
+//		r.Continue()
+package csm
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/csm/enable.go b/vendor/github.com/aws/aws-sdk-go/aws/csm/enable.go
new file mode 100644
index 000000000..2f0c6eac9
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/csm/enable.go
@@ -0,0 +1,67 @@
+package csm
+
+import (
+	"fmt"
+	"sync"
+)
+
+var (
+	lock sync.Mutex
+)
+
+// Client side metric handler names
+const (
+	APICallMetricHandlerName        = "awscsm.SendAPICallMetric"
+	APICallAttemptMetricHandlerName = "awscsm.SendAPICallAttemptMetric"
+)
+
+// Start will start the a long running go routine to capture
+// client side metrics. Calling start multiple time will only
+// start the metric listener once and will panic if a different
+// client ID or port is passed in.
+//
+//	Example:
+//		r, err := csm.Start("clientID", "127.0.0.1:8094")
+//		if err != nil {
+//			panic(fmt.Errorf("expected no error, but received %v", err))
+//		}
+//		sess := session.NewSession()
+//		r.InjectHandlers(sess.Handlers)
+//
+//		svc := s3.New(sess)
+//		out, err := svc.GetObject(&s3.GetObjectInput{
+//			Bucket: aws.String("bucket"),
+//			Key: aws.String("key"),
+//		})
+func Start(clientID string, url string) (*Reporter, error) {
+	lock.Lock()
+	defer lock.Unlock()
+
+	if sender == nil {
+		sender = newReporter(clientID, url)
+	} else {
+		if sender.clientID != clientID {
+			panic(fmt.Errorf("inconsistent client IDs. %q was expected, but received %q", sender.clientID, clientID))
+		}
+
+		if sender.url != url {
+			panic(fmt.Errorf("inconsistent URLs. %q was expected, but received %q", sender.url, url))
+		}
+	}
+
+	if err := connect(url); err != nil {
+		sender = nil
+		return nil, err
+	}
+
+	return sender, nil
+}
+
+// Get will return a reporter if one exists, if one does not exist, nil will
+// be returned.
+func Get() *Reporter {
+	lock.Lock()
+	defer lock.Unlock()
+
+	return sender
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/csm/metric.go b/vendor/github.com/aws/aws-sdk-go/aws/csm/metric.go
new file mode 100644
index 000000000..4b0d630e4
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/csm/metric.go
@@ -0,0 +1,51 @@
+package csm
+
+import (
+	"strconv"
+	"time"
+)
+
+type metricTime time.Time
+
+func (t metricTime) MarshalJSON() ([]byte, error) {
+	ns := time.Duration(time.Time(t).UnixNano())
+	return []byte(strconv.FormatInt(int64(ns/time.Millisecond), 10)), nil
+}
+
+type metric struct {
+	ClientID  *string     `json:"ClientId,omitempty"`
+	API       *string     `json:"Api,omitempty"`
+	Service   *string     `json:"Service,omitempty"`
+	Timestamp *metricTime `json:"Timestamp,omitempty"`
+	Type      *string     `json:"Type,omitempty"`
+	Version   *int        `json:"Version,omitempty"`
+
+	AttemptCount *int `json:"AttemptCount,omitempty"`
+	Latency      *int `json:"Latency,omitempty"`
+
+	Fqdn           *string `json:"Fqdn,omitempty"`
+	UserAgent      *string `json:"UserAgent,omitempty"`
+	AttemptLatency *int    `json:"AttemptLatency,omitempty"`
+
+	SessionToken   *string `json:"SessionToken,omitempty"`
+	Region         *string `json:"Region,omitempty"`
+	AccessKey      *string `json:"AccessKey,omitempty"`
+	HTTPStatusCode *int    `json:"HttpStatusCode,omitempty"`
+	XAmzID2        *string `json:"XAmzId2,omitempty"`
+	XAmzRequestID  *string `json:"XAmznRequestId,omitempty"`
+
+	AWSException        *string `json:"AwsException,omitempty"`
+	AWSExceptionMessage *string `json:"AwsExceptionMessage,omitempty"`
+	SDKException        *string `json:"SdkException,omitempty"`
+	SDKExceptionMessage *string `json:"SdkExceptionMessage,omitempty"`
+
+	DestinationIP    *string `json:"DestinationIp,omitempty"`
+	ConnectionReused *int    `json:"ConnectionReused,omitempty"`
+
+	AcquireConnectionLatency *int `json:"AcquireConnectionLatency,omitempty"`
+	ConnectLatency           *int `json:"ConnectLatency,omitempty"`
+	RequestLatency           *int `json:"RequestLatency,omitempty"`
+	DNSLatency               *int `json:"DnsLatency,omitempty"`
+	TCPLatency               *int `json:"TcpLatency,omitempty"`
+	SSLLatency               *int `json:"SslLatency,omitempty"`
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/csm/metric_chan.go b/vendor/github.com/aws/aws-sdk-go/aws/csm/metric_chan.go
new file mode 100644
index 000000000..514fc3739
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/csm/metric_chan.go
@@ -0,0 +1,54 @@
+package csm
+
+import (
+	"sync/atomic"
+)
+
+const (
+	runningEnum = iota
+	pausedEnum
+)
+
+var (
+	// MetricsChannelSize of metrics to hold in the channel
+	MetricsChannelSize = 100
+)
+
+type metricChan struct {
+	ch     chan metric
+	paused int64
+}
+
+func newMetricChan(size int) metricChan {
+	return metricChan{
+		ch: make(chan metric, size),
+	}
+}
+
+func (ch *metricChan) Pause() {
+	atomic.StoreInt64(&ch.paused, pausedEnum)
+}
+
+func (ch *metricChan) Continue() {
+	atomic.StoreInt64(&ch.paused, runningEnum)
+}
+
+func (ch *metricChan) IsPaused() bool {
+	v := atomic.LoadInt64(&ch.paused)
+	return v == pausedEnum
+}
+
+// Push will push metrics to the metric channel if the channel
+// is not paused
+func (ch *metricChan) Push(m metric) bool {
+	if ch.IsPaused() {
+		return false
+	}
+
+	select {
+	case ch.ch <- m:
+		return true
+	default:
+		return false
+	}
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/csm/reporter.go b/vendor/github.com/aws/aws-sdk-go/aws/csm/reporter.go
new file mode 100644
index 000000000..11082e5ed
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/csm/reporter.go
@@ -0,0 +1,231 @@
+package csm
+
+import (
+	"encoding/json"
+	"net"
+	"time"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/request"
+)
+
+const (
+	// DefaultPort is used when no port is specified
+	DefaultPort = "31000"
+)
+
+// Reporter will gather metrics of API requests made and
+// send those metrics to the CSM endpoint.
+type Reporter struct {
+	clientID  string
+	url       string
+	conn      net.Conn
+	metricsCh metricChan
+	done      chan struct{}
+}
+
+var (
+	sender *Reporter
+)
+
+func connect(url string) error {
+	const network = "udp"
+	if err := sender.connect(network, url); err != nil {
+		return err
+	}
+
+	if sender.done == nil {
+		sender.done = make(chan struct{})
+		go sender.start()
+	}
+
+	return nil
+}
+
+func newReporter(clientID, url string) *Reporter {
+	return &Reporter{
+		clientID:  clientID,
+		url:       url,
+		metricsCh: newMetricChan(MetricsChannelSize),
+	}
+}
+
+func (rep *Reporter) sendAPICallAttemptMetric(r *request.Request) {
+	if rep == nil {
+		return
+	}
+
+	now := time.Now()
+	creds, _ := r.Config.Credentials.Get()
+
+	m := metric{
+		ClientID:  aws.String(rep.clientID),
+		API:       aws.String(r.Operation.Name),
+		Service:   aws.String(r.ClientInfo.ServiceID),
+		Timestamp: (*metricTime)(&now),
+		UserAgent: aws.String(r.HTTPRequest.Header.Get("User-Agent")),
+		Region:    r.Config.Region,
+		Type:      aws.String("ApiCallAttempt"),
+		Version:   aws.Int(1),
+
+		XAmzRequestID: aws.String(r.RequestID),
+
+		AttemptCount:   aws.Int(r.RetryCount + 1),
+		AttemptLatency: aws.Int(int(now.Sub(r.AttemptTime).Nanoseconds() / int64(time.Millisecond))),
+		AccessKey:      aws.String(creds.AccessKeyID),
+	}
+
+	if r.HTTPResponse != nil {
+		m.HTTPStatusCode = aws.Int(r.HTTPResponse.StatusCode)
+	}
+
+	if r.Error != nil {
+		if awserr, ok := r.Error.(awserr.Error); ok {
+			setError(&m, awserr)
+		}
+	}
+
+	rep.metricsCh.Push(m)
+}
+
+func setError(m *metric, err awserr.Error) {
+	msg := err.Error()
+	code := err.Code()
+
+	switch code {
+	case "RequestError",
+		"SerializationError",
+		request.CanceledErrorCode:
+		m.SDKException = &code
+		m.SDKExceptionMessage = &msg
+	default:
+		m.AWSException = &code
+		m.AWSExceptionMessage = &msg
+	}
+}
+
+func (rep *Reporter) sendAPICallMetric(r *request.Request) {
+	if rep == nil {
+		return
+	}
+
+	now := time.Now()
+	m := metric{
+		ClientID:      aws.String(rep.clientID),
+		API:           aws.String(r.Operation.Name),
+		Service:       aws.String(r.ClientInfo.ServiceID),
+		Timestamp:     (*metricTime)(&now),
+		Type:          aws.String("ApiCall"),
+		AttemptCount:  aws.Int(r.RetryCount + 1),
+		Latency:       aws.Int(int(time.Now().Sub(r.Time) / time.Millisecond)),
+		XAmzRequestID: aws.String(r.RequestID),
+	}
+
+	// TODO: Probably want to figure something out for logging dropped
+	// metrics
+	rep.metricsCh.Push(m)
+}
+
+func (rep *Reporter) connect(network, url string) error {
+	if rep.conn != nil {
+		rep.conn.Close()
+	}
+
+	conn, err := net.Dial(network, url)
+	if err != nil {
+		return awserr.New("UDPError", "Could not connect", err)
+	}
+
+	rep.conn = conn
+
+	return nil
+}
+
+func (rep *Reporter) close() {
+	if rep.done != nil {
+		close(rep.done)
+	}
+
+	rep.metricsCh.Pause()
+}
+
+func (rep *Reporter) start() {
+	defer func() {
+		rep.metricsCh.Pause()
+	}()
+
+	for {
+		select {
+		case <-rep.done:
+			rep.done = nil
+			return
+		case m := <-rep.metricsCh.ch:
+			// TODO: What to do with this error? Probably should just log
+			b, err := json.Marshal(m)
+			if err != nil {
+				continue
+			}
+
+			rep.conn.Write(b)
+		}
+	}
+}
+
+// Pause will pause the metric channel preventing any new metrics from
+// being added.
+func (rep *Reporter) Pause() {
+	lock.Lock()
+	defer lock.Unlock()
+
+	if rep == nil {
+		return
+	}
+
+	rep.close()
+}
+
+// Continue will reopen the metric channel and allow for monitoring
+// to be resumed.
+func (rep *Reporter) Continue() {
+	lock.Lock()
+	defer lock.Unlock()
+	if rep == nil {
+		return
+	}
+
+	if !rep.metricsCh.IsPaused() {
+		return
+	}
+
+	rep.metricsCh.Continue()
+}
+
+// InjectHandlers will will enable client side metrics and inject the proper
+// handlers to handle how metrics are sent.
+//
+//	Example:
+//		// Start must be called in order to inject the correct handlers
+//		r, err := csm.Start("clientID", "127.0.0.1:8094")
+//		if err != nil {
+//			panic(fmt.Errorf("expected no error, but received %v", err))
+//		}
+//
+//		sess := session.NewSession()
+//		r.InjectHandlers(&sess.Handlers)
+//
+//		// create a new service client with our client side metric session
+//		svc := s3.New(sess)
+func (rep *Reporter) InjectHandlers(handlers *request.Handlers) {
+	if rep == nil {
+		return
+	}
+
+	apiCallHandler := request.NamedHandler{Name: APICallMetricHandlerName, Fn: rep.sendAPICallMetric}
+	apiCallAttemptHandler := request.NamedHandler{Name: APICallAttemptMetricHandlerName, Fn: rep.sendAPICallAttemptMetric}
+
+	handlers.Complete.PushFrontNamed(apiCallHandler)
+	handlers.Complete.PushFrontNamed(apiCallAttemptHandler)
+
+	handlers.AfterRetry.PushFrontNamed(apiCallAttemptHandler)
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go
new file mode 100644
index 000000000..5040a2f64
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go
@@ -0,0 +1,205 @@
+// Package defaults is a collection of helpers to retrieve the SDK's default
+// configuration and handlers.
+//
+// Generally this package shouldn't be used directly, but session.Session
+// instead. This package is useful when you need to reset the defaults
+// of a session or service client to the SDK defaults before setting
+// additional parameters.
+package defaults
+
+import (
+	"fmt"
+	"net"
+	"net/http"
+	"net/url"
+	"os"
+	"time"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/corehandlers"
+	"github.com/aws/aws-sdk-go/aws/credentials"
+	"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
+	"github.com/aws/aws-sdk-go/aws/credentials/endpointcreds"
+	"github.com/aws/aws-sdk-go/aws/ec2metadata"
+	"github.com/aws/aws-sdk-go/aws/endpoints"
+	"github.com/aws/aws-sdk-go/aws/request"
+)
+
+// A Defaults provides a collection of default values for SDK clients.
+type Defaults struct {
+	Config   *aws.Config
+	Handlers request.Handlers
+}
+
+// Get returns the SDK's default values with Config and handlers pre-configured.
+func Get() Defaults {
+	cfg := Config()
+	handlers := Handlers()
+	cfg.Credentials = CredChain(cfg, handlers)
+
+	return Defaults{
+		Config:   cfg,
+		Handlers: handlers,
+	}
+}
+
+// Config returns the default configuration without credentials.
+// To retrieve a config with credentials also included use
+// `defaults.Get().Config` instead.
+//
+// Generally you shouldn't need to use this method directly, but
+// is available if you need to reset the configuration of an
+// existing service client or session.
+func Config() *aws.Config {
+	return aws.NewConfig().
+		WithCredentials(credentials.AnonymousCredentials).
+		WithRegion(os.Getenv("AWS_REGION")).
+		WithHTTPClient(http.DefaultClient).
+		WithMaxRetries(aws.UseServiceDefaultRetries).
+		WithLogger(aws.NewDefaultLogger()).
+		WithLogLevel(aws.LogOff).
+		WithEndpointResolver(endpoints.DefaultResolver())
+}
+
+// Handlers returns the default request handlers.
+//
+// Generally you shouldn't need to use this method directly, but
+// is available if you need to reset the request handlers of an
+// existing service client or session.
+func Handlers() request.Handlers {
+	var handlers request.Handlers
+
+	handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
+	handlers.Validate.AfterEachFn = request.HandlerListStopOnError
+	handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler)
+	handlers.Build.PushBackNamed(corehandlers.AddHostExecEnvUserAgentHander)
+	handlers.Build.AfterEachFn = request.HandlerListStopOnError
+	handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler)
+	handlers.Send.PushBackNamed(corehandlers.ValidateReqSigHandler)
+	handlers.Send.PushBackNamed(corehandlers.SendHandler)
+	handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler)
+	handlers.ValidateResponse.PushBackNamed(corehandlers.ValidateResponseHandler)
+
+	return handlers
+}
+
+// CredChain returns the default credential chain.
+//
+// Generally you shouldn't need to use this method directly, but
+// is available if you need to reset the credentials of an
+// existing service client or session's Config.
+func CredChain(cfg *aws.Config, handlers request.Handlers) *credentials.Credentials {
+	return credentials.NewCredentials(&credentials.ChainProvider{
+		VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors),
+		Providers:     CredProviders(cfg, handlers),
+	})
+}
+
+// CredProviders returns the slice of providers used in
+// the default credential chain.
+//
+// For applications that need to use some other provider (for example use
+// different  environment variables for legacy reasons) but still fall back
+// on the default chain of providers. This allows that default chaint to be
+// automatically updated
+func CredProviders(cfg *aws.Config, handlers request.Handlers) []credentials.Provider {
+	return []credentials.Provider{
+		&credentials.EnvProvider{},
+		&credentials.SharedCredentialsProvider{Filename: "", Profile: ""},
+		RemoteCredProvider(*cfg, handlers),
+	}
+}
+
+const (
+	httpProviderEnvVar     = "AWS_CONTAINER_CREDENTIALS_FULL_URI"
+	ecsCredsProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
+)
+
+// RemoteCredProvider returns a credentials provider for the default remote
+// endpoints such as EC2 or ECS Roles.
+func RemoteCredProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider {
+	if u := os.Getenv(httpProviderEnvVar); len(u) > 0 {
+		return localHTTPCredProvider(cfg, handlers, u)
+	}
+
+	if uri := os.Getenv(ecsCredsProviderEnvVar); len(uri) > 0 {
+		u := fmt.Sprintf("http://169.254.170.2%s", uri)
+		return httpCredProvider(cfg, handlers, u)
+	}
+
+	return ec2RoleProvider(cfg, handlers)
+}
+
+var lookupHostFn = net.LookupHost
+
+func isLoopbackHost(host string) (bool, error) {
+	ip := net.ParseIP(host)
+	if ip != nil {
+		return ip.IsLoopback(), nil
+	}
+
+	// Host is not an ip, perform lookup
+	addrs, err := lookupHostFn(host)
+	if err != nil {
+		return false, err
+	}
+	for _, addr := range addrs {
+		if !net.ParseIP(addr).IsLoopback() {
+			return false, nil
+		}
+	}
+
+	return true, nil
+}
+
+func localHTTPCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider {
+	var errMsg string
+
+	parsed, err := url.Parse(u)
+	if err != nil {
+		errMsg = fmt.Sprintf("invalid URL, %v", err)
+	} else {
+		host := aws.URLHostname(parsed)
+		if len(host) == 0 {
+			errMsg = "unable to parse host from local HTTP cred provider URL"
+		} else if isLoopback, loopbackErr := isLoopbackHost(host); loopbackErr != nil {
+			errMsg = fmt.Sprintf("failed to resolve host %q, %v", host, loopbackErr)
+		} else if !isLoopback {
+			errMsg = fmt.Sprintf("invalid endpoint host, %q, only loopback hosts are allowed.", host)
+		}
+	}
+
+	if len(errMsg) > 0 {
+		if cfg.Logger != nil {
+			cfg.Logger.Log("Ignoring, HTTP credential provider", errMsg, err)
+		}
+		return credentials.ErrorProvider{
+			Err:          awserr.New("CredentialsEndpointError", errMsg, err),
+			ProviderName: endpointcreds.ProviderName,
+		}
+	}
+
+	return httpCredProvider(cfg, handlers, u)
+}
+
+func httpCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider {
+	return endpointcreds.NewProviderClient(cfg, handlers, u,
+		func(p *endpointcreds.Provider) {
+			p.ExpiryWindow = 5 * time.Minute
+		},
+	)
+}
+
+func ec2RoleProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider {
+	resolver := cfg.EndpointResolver
+	if resolver == nil {
+		resolver = endpoints.DefaultResolver()
+	}
+
+	e, _ := resolver.EndpointFor(endpoints.Ec2metadataServiceID, "")
+	return &ec2rolecreds.EC2RoleProvider{
+		Client:       ec2metadata.NewClient(cfg, handlers, e.URL, e.SigningRegion),
+		ExpiryWindow: 5 * time.Minute,
+	}
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/defaults/shared_config.go b/vendor/github.com/aws/aws-sdk-go/aws/defaults/shared_config.go
new file mode 100644
index 000000000..ca0ee1dcc
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/defaults/shared_config.go
@@ -0,0 +1,27 @@
+package defaults
+
+import (
+	"github.com/aws/aws-sdk-go/internal/shareddefaults"
+)
+
+// SharedCredentialsFilename returns the SDK's default file path
+// for the shared credentials file.
+//
+// Builds the shared config file path based on the OS's platform.
+//
+//   - Linux/Unix: $HOME/.aws/credentials
+//   - Windows: %USERPROFILE%\.aws\credentials
+func SharedCredentialsFilename() string {
+	return shareddefaults.SharedCredentialsFilename()
+}
+
+// SharedConfigFilename returns the SDK's default file path for
+// the shared config file.
+//
+// Builds the shared config file path based on the OS's platform.
+//
+//   - Linux/Unix: $HOME/.aws/config
+//   - Windows: %USERPROFILE%\.aws\config
+func SharedConfigFilename() string {
+	return shareddefaults.SharedConfigFilename()
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/doc.go b/vendor/github.com/aws/aws-sdk-go/aws/doc.go
new file mode 100644
index 000000000..4fcb61618
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/doc.go
@@ -0,0 +1,56 @@
+// Package aws provides the core SDK's utilities and shared types. Use this package's
+// utilities to simplify setting and reading API operations parameters.
+//
+// Value and Pointer Conversion Utilities
+//
+// This package includes a helper conversion utility for each scalar type the SDK's
+// API use. These utilities make getting a pointer of the scalar, and dereferencing
+// a pointer easier.
+//
+// Each conversion utility comes in two forms. Value to Pointer and Pointer to Value.
+// The Pointer to value will safely dereference the pointer and return its value.
+// If the pointer was nil, the scalar's zero value will be returned.
+//
+// The value to pointer functions will be named after the scalar type. So get a
+// *string from a string value use the "String" function. This makes it easy to
+// to get pointer of a literal string value, because getting the address of a
+// literal requires assigning the value to a variable first.
+//
+//    var strPtr *string
+//
+//    // Without the SDK's conversion functions
+//    str := "my string"
+//    strPtr = &str
+//
+//    // With the SDK's conversion functions
+//    strPtr = aws.String("my string")
+//
+//    // Convert *string to string value
+//    str = aws.StringValue(strPtr)
+//
+// In addition to scalars the aws package also includes conversion utilities for
+// map and slice for commonly types used in API parameters. The map and slice
+// conversion functions use similar naming pattern as the scalar conversion
+// functions.
+//
+//    var strPtrs []*string
+//    var strs []string = []string{"Go", "Gophers", "Go"}
+//
+//    // Convert []string to []*string
+//    strPtrs = aws.StringSlice(strs)
+//
+//    // Convert []*string to []string
+//    strs = aws.StringValueSlice(strPtrs)
+//
+// SDK Default HTTP Client
+//
+// The SDK will use the http.DefaultClient if a HTTP client is not provided to
+// the SDK's Session, or service client constructor. This means that if the
+// http.DefaultClient is modified by other components of your application the
+// modifications will be picked up by the SDK as well.
+//
+// In some cases this might be intended, but it is a better practice to create
+// a custom HTTP Client to share explicitly through your application. You can
+// configure the SDK to use the custom HTTP Client by setting the HTTPClient
+// value of the SDK's Config type when creating a Session or service client.
+package aws
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go b/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go
new file mode 100644
index 000000000..c215cd3f5
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go
@@ -0,0 +1,162 @@
+package ec2metadata
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+	"strings"
+	"time"
+
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/request"
+	"github.com/aws/aws-sdk-go/internal/sdkuri"
+)
+
+// GetMetadata uses the path provided to request information from the EC2
+// instance metdata service. The content will be returned as a string, or
+// error if the request failed.
+func (c *EC2Metadata) GetMetadata(p string) (string, error) {
+	op := &request.Operation{
+		Name:       "GetMetadata",
+		HTTPMethod: "GET",
+		HTTPPath:   sdkuri.PathJoin("/meta-data", p),
+	}
+
+	output := &metadataOutput{}
+	req := c.NewRequest(op, nil, output)
+
+	return output.Content, req.Send()
+}
+
+// GetUserData returns the userdata that was configured for the service. If
+// there is no user-data setup for the EC2 instance a "NotFoundError" error
+// code will be returned.
+func (c *EC2Metadata) GetUserData() (string, error) {
+	op := &request.Operation{
+		Name:       "GetUserData",
+		HTTPMethod: "GET",
+		HTTPPath:   "/user-data",
+	}
+
+	output := &metadataOutput{}
+	req := c.NewRequest(op, nil, output)
+	req.Handlers.UnmarshalError.PushBack(func(r *request.Request) {
+		if r.HTTPResponse.StatusCode == http.StatusNotFound {
+			r.Error = awserr.New("NotFoundError", "user-data not found", r.Error)
+		}
+	})
+
+	return output.Content, req.Send()
+}
+
+// GetDynamicData uses the path provided to request information from the EC2
+// instance metadata service for dynamic data. The content will be returned
+// as a string, or error if the request failed.
+func (c *EC2Metadata) GetDynamicData(p string) (string, error) {
+	op := &request.Operation{
+		Name:       "GetDynamicData",
+		HTTPMethod: "GET",
+		HTTPPath:   sdkuri.PathJoin("/dynamic", p),
+	}
+
+	output := &metadataOutput{}
+	req := c.NewRequest(op, nil, output)
+
+	return output.Content, req.Send()
+}
+
+// GetInstanceIdentityDocument retrieves an identity document describing an
+// instance. Error is returned if the request fails or is unable to parse
+// the response.
+func (c *EC2Metadata) GetInstanceIdentityDocument() (EC2InstanceIdentityDocument, error) {
+	resp, err := c.GetDynamicData("instance-identity/document")
+	if err != nil {
+		return EC2InstanceIdentityDocument{},
+			awserr.New("EC2MetadataRequestError",
+				"failed to get EC2 instance identity document", err)
+	}
+
+	doc := EC2InstanceIdentityDocument{}
+	if err := json.NewDecoder(strings.NewReader(resp)).Decode(&doc); err != nil {
+		return EC2InstanceIdentityDocument{},
+			awserr.New("SerializationError",
+				"failed to decode EC2 instance identity document", err)
+	}
+
+	return doc, nil
+}
+
+// IAMInfo retrieves IAM info from the metadata API
+func (c *EC2Metadata) IAMInfo() (EC2IAMInfo, error) {
+	resp, err := c.GetMetadata("iam/info")
+	if err != nil {
+		return EC2IAMInfo{},
+			awserr.New("EC2MetadataRequestError",
+				"failed to get EC2 IAM info", err)
+	}
+
+	info := EC2IAMInfo{}
+	if err := json.NewDecoder(strings.NewReader(resp)).Decode(&info); err != nil {
+		return EC2IAMInfo{},
+			awserr.New("SerializationError",
+				"failed to decode EC2 IAM info", err)
+	}
+
+	if info.Code != "Success" {
+		errMsg := fmt.Sprintf("failed to get EC2 IAM Info (%s)", info.Code)
+		return EC2IAMInfo{},
+			awserr.New("EC2MetadataError", errMsg, nil)
+	}
+
+	return info, nil
+}
+
+// Region returns the region the instance is running in.
+func (c *EC2Metadata) Region() (string, error) {
+	resp, err := c.GetMetadata("placement/availability-zone")
+	if err != nil {
+		return "", err
+	}
+
+	// returns region without the suffix. Eg: us-west-2a becomes us-west-2
+	return resp[:len(resp)-1], nil
+}
+
+// Available returns if the application has access to the EC2 Metadata service.
+// Can be used to determine if application is running within an EC2 Instance and
+// the metadata service is available.
+func (c *EC2Metadata) Available() bool {
+	if _, err := c.GetMetadata("instance-id"); err != nil {
+		return false
+	}
+
+	return true
+}
+
+// An EC2IAMInfo provides the shape for unmarshaling
+// an IAM info from the metadata API
+type EC2IAMInfo struct {
+	Code               string
+	LastUpdated        time.Time
+	InstanceProfileArn string
+	InstanceProfileID  string
+}
+
+// An EC2InstanceIdentityDocument provides the shape for unmarshaling
+// an instance identity document
+type EC2InstanceIdentityDocument struct {
+	DevpayProductCodes []string  `json:"devpayProductCodes"`
+	AvailabilityZone   string    `json:"availabilityZone"`
+	PrivateIP          string    `json:"privateIp"`
+	Version            string    `json:"version"`
+	Region             string    `json:"region"`
+	InstanceID         string    `json:"instanceId"`
+	BillingProducts    []string  `json:"billingProducts"`
+	InstanceType       string    `json:"instanceType"`
+	AccountID          string    `json:"accountId"`
+	PendingTime        time.Time `json:"pendingTime"`
+	ImageID            string    `json:"imageId"`
+	KernelID           string    `json:"kernelId"`
+	RamdiskID          string    `json:"ramdiskId"`
+	Architecture       string    `json:"architecture"`
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go b/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go
new file mode 100644
index 000000000..ef5f73292
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go
@@ -0,0 +1,148 @@
+// Package ec2metadata provides the client for making API calls to the
+// EC2 Metadata service.
+//
+// This package's client can be disabled completely by setting the environment
+// variable "AWS_EC2_METADATA_DISABLED=true". This environment variable set to
+// true instructs the SDK to disable the EC2 Metadata client. The client cannot
+// be used while the environemnt variable is set to true, (case insensitive).
+package ec2metadata
+
+import (
+	"bytes"
+	"errors"
+	"io"
+	"net/http"
+	"os"
+	"strings"
+	"time"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/client"
+	"github.com/aws/aws-sdk-go/aws/client/metadata"
+	"github.com/aws/aws-sdk-go/aws/corehandlers"
+	"github.com/aws/aws-sdk-go/aws/request"
+)
+
+// ServiceName is the name of the service.
+const ServiceName = "ec2metadata"
+const disableServiceEnvVar = "AWS_EC2_METADATA_DISABLED"
+
+// A EC2Metadata is an EC2 Metadata service Client.
+type EC2Metadata struct {
+	*client.Client
+}
+
+// New creates a new instance of the EC2Metadata client with a session.
+// This client is safe to use across multiple goroutines.
+//
+//
+// Example:
+//     // Create a EC2Metadata client from just a session.
+//     svc := ec2metadata.New(mySession)
+//
+//     // Create a EC2Metadata client with additional configuration
+//     svc := ec2metadata.New(mySession, aws.NewConfig().WithLogLevel(aws.LogDebugHTTPBody))
+func New(p client.ConfigProvider, cfgs ...*aws.Config) *EC2Metadata {
+	c := p.ClientConfig(ServiceName, cfgs...)
+	return NewClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
+}
+
+// NewClient returns a new EC2Metadata client. Should be used to create
+// a client when not using a session. Generally using just New with a session
+// is preferred.
+//
+// If an unmodified HTTP client is provided from the stdlib default, or no client
+// the EC2RoleProvider's EC2Metadata HTTP client's timeout will be shortened.
+// To disable this set Config.EC2MetadataDisableTimeoutOverride to false. Enabled by default.
+func NewClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string, opts ...func(*client.Client)) *EC2Metadata {
+	if !aws.BoolValue(cfg.EC2MetadataDisableTimeoutOverride) && httpClientZero(cfg.HTTPClient) {
+		// If the http client is unmodified and this feature is not disabled
+		// set custom timeouts for EC2Metadata requests.
+		cfg.HTTPClient = &http.Client{
+			// use a shorter timeout than default because the metadata
+			// service is local if it is running, and to fail faster
+			// if not running on an ec2 instance.
+			Timeout: 5 * time.Second,
+		}
+	}
+
+	svc := &EC2Metadata{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName: ServiceName,
+				Endpoint:    endpoint,
+				APIVersion:  "latest",
+			},
+			handlers,
+		),
+	}
+
+	svc.Handlers.Unmarshal.PushBack(unmarshalHandler)
+	svc.Handlers.UnmarshalError.PushBack(unmarshalError)
+	svc.Handlers.Validate.Clear()
+	svc.Handlers.Validate.PushBack(validateEndpointHandler)
+
+	// Disable the EC2 Metadata service if the environment variable is set.
+	// This shortcirctes the service's functionality to always fail to send
+	// requests.
+	if strings.ToLower(os.Getenv(disableServiceEnvVar)) == "true" {
+		svc.Handlers.Send.SwapNamed(request.NamedHandler{
+			Name: corehandlers.SendHandler.Name,
+			Fn: func(r *request.Request) {
+				r.Error = awserr.New(
+					request.CanceledErrorCode,
+					"EC2 IMDS access disabled via "+disableServiceEnvVar+" env var",
+					nil)
+			},
+		})
+	}
+
+	// Add additional options to the service config
+	for _, option := range opts {
+		option(svc.Client)
+	}
+
+	return svc
+}
+
+func httpClientZero(c *http.Client) bool {
+	return c == nil || (c.Transport == nil && c.CheckRedirect == nil && c.Jar == nil && c.Timeout == 0)
+}
+
+type metadataOutput struct {
+	Content string
+}
+
+func unmarshalHandler(r *request.Request) {
+	defer r.HTTPResponse.Body.Close()
+	b := &bytes.Buffer{}
+	if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil {
+		r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata respose", err)
+		return
+	}
+
+	if data, ok := r.Data.(*metadataOutput); ok {
+		data.Content = b.String()
+	}
+}
+
+func unmarshalError(r *request.Request) {
+	defer r.HTTPResponse.Body.Close()
+	b := &bytes.Buffer{}
+	if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil {
+		r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata error respose", err)
+		return
+	}
+
+	// Response body format is not consistent between metadata endpoints.
+	// Grab the error message as a string and include that as the source error
+	r.Error = awserr.New("EC2MetadataError", "failed to make EC2Metadata request", errors.New(b.String()))
+}
+
+func validateEndpointHandler(r *request.Request) {
+	if r.ClientInfo.Endpoint == "" {
+		r.Error = aws.ErrMissingEndpoint
+	}
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go
new file mode 100644
index 000000000..c04ba06c5
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go
@@ -0,0 +1,155 @@
+package endpoints
+
+import (
+	"encoding/json"
+	"fmt"
+	"io"
+
+	"github.com/aws/aws-sdk-go/aws/awserr"
+)
+
+type modelDefinition map[string]json.RawMessage
+
+// A DecodeModelOptions are the options for how the endpoints model definition
+// are decoded.
+type DecodeModelOptions struct {
+	SkipCustomizations bool
+}
+
+// Set combines all of the option functions together.
+func (d *DecodeModelOptions) Set(optFns ...func(*DecodeModelOptions)) {
+	for _, fn := range optFns {
+		fn(d)
+	}
+}
+
+// DecodeModel unmarshals a Regions and Endpoint model definition file into
+// a endpoint Resolver. If the file format is not supported, or an error occurs
+// when unmarshaling the model an error will be returned.
+//
+// Casting the return value of this func to a EnumPartitions will
+// allow you to get a list of the partitions in the order the endpoints
+// will be resolved in.
+//
+//    resolver, err := endpoints.DecodeModel(reader)
+//
+//    partitions := resolver.(endpoints.EnumPartitions).Partitions()
+//    for _, p := range partitions {
+//        // ... inspect partitions
+//    }
+func DecodeModel(r io.Reader, optFns ...func(*DecodeModelOptions)) (Resolver, error) {
+	var opts DecodeModelOptions
+	opts.Set(optFns...)
+
+	// Get the version of the partition file to determine what
+	// unmarshaling model to use.
+	modelDef := modelDefinition{}
+	if err := json.NewDecoder(r).Decode(&modelDef); err != nil {
+		return nil, newDecodeModelError("failed to decode endpoints model", err)
+	}
+
+	var version string
+	if b, ok := modelDef["version"]; ok {
+		version = string(b)
+	} else {
+		return nil, newDecodeModelError("endpoints version not found in model", nil)
+	}
+
+	if version == "3" {
+		return decodeV3Endpoints(modelDef, opts)
+	}
+
+	return nil, newDecodeModelError(
+		fmt.Sprintf("endpoints version %s, not supported", version), nil)
+}
+
+func decodeV3Endpoints(modelDef modelDefinition, opts DecodeModelOptions) (Resolver, error) {
+	b, ok := modelDef["partitions"]
+	if !ok {
+		return nil, newDecodeModelError("endpoints model missing partitions", nil)
+	}
+
+	ps := partitions{}
+	if err := json.Unmarshal(b, &ps); err != nil {
+		return nil, newDecodeModelError("failed to decode endpoints model", err)
+	}
+
+	if opts.SkipCustomizations {
+		return ps, nil
+	}
+
+	// Customization
+	for i := 0; i < len(ps); i++ {
+		p := &ps[i]
+		custAddEC2Metadata(p)
+		custAddS3DualStack(p)
+		custRmIotDataService(p)
+		custFixAppAutoscalingChina(p)
+	}
+
+	return ps, nil
+}
+
+func custAddS3DualStack(p *partition) {
+	if p.ID != "aws" {
+		return
+	}
+
+	s, ok := p.Services["s3"]
+	if !ok {
+		return
+	}
+
+	s.Defaults.HasDualStack = boxedTrue
+	s.Defaults.DualStackHostname = "{service}.dualstack.{region}.{dnsSuffix}"
+
+	p.Services["s3"] = s
+}
+
+func custAddEC2Metadata(p *partition) {
+	p.Services["ec2metadata"] = service{
+		IsRegionalized:    boxedFalse,
+		PartitionEndpoint: "aws-global",
+		Endpoints: endpoints{
+			"aws-global": endpoint{
+				Hostname:  "169.254.169.254/latest",
+				Protocols: []string{"http"},
+			},
+		},
+	}
+}
+
+func custRmIotDataService(p *partition) {
+	delete(p.Services, "data.iot")
+}
+
+func custFixAppAutoscalingChina(p *partition) {
+	if p.ID != "aws-cn" {
+		return
+	}
+
+	const serviceName = "application-autoscaling"
+	s, ok := p.Services[serviceName]
+	if !ok {
+		return
+	}
+
+	const expectHostname = `autoscaling.{region}.amazonaws.com`
+	if e, a := s.Defaults.Hostname, expectHostname; e != a {
+		fmt.Printf("custFixAppAutoscalingChina: ignoring customization, expected %s, got %s\n", e, a)
+		return
+	}
+
+	s.Defaults.Hostname = expectHostname + ".cn"
+	p.Services[serviceName] = s
+}
+
+type decodeModelError struct {
+	awsError
+}
+
+func newDecodeModelError(msg string, err error) decodeModelError {
+	return decodeModelError{
+		awsError: awserr.New("DecodeEndpointsModelError", msg, err),
+	}
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
new file mode 100644
index 000000000..ebce035cf
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
@@ -0,0 +1,3243 @@
+// Code generated by aws/endpoints/v3model_codegen.go. DO NOT EDIT.
+
+package endpoints
+
+import (
+	"regexp"
+)
+
+// Partition identifiers
+const (
+	AwsPartitionID      = "aws"        // AWS Standard partition.
+	AwsCnPartitionID    = "aws-cn"     // AWS China partition.
+	AwsUsGovPartitionID = "aws-us-gov" // AWS GovCloud (US) partition.
+)
+
+// AWS Standard partition's regions.
+const (
+	ApNortheast1RegionID = "ap-northeast-1" // Asia Pacific (Tokyo).
+	ApNortheast2RegionID = "ap-northeast-2" // Asia Pacific (Seoul).
+	ApSouth1RegionID     = "ap-south-1"     // Asia Pacific (Mumbai).
+	ApSoutheast1RegionID = "ap-southeast-1" // Asia Pacific (Singapore).
+	ApSoutheast2RegionID = "ap-southeast-2" // Asia Pacific (Sydney).
+	CaCentral1RegionID   = "ca-central-1"   // Canada (Central).
+	EuCentral1RegionID   = "eu-central-1"   // EU (Frankfurt).
+	EuWest1RegionID      = "eu-west-1"      // EU (Ireland).
+	EuWest2RegionID      = "eu-west-2"      // EU (London).
+	EuWest3RegionID      = "eu-west-3"      // EU (Paris).
+	SaEast1RegionID      = "sa-east-1"      // South America (Sao Paulo).
+	UsEast1RegionID      = "us-east-1"      // US East (N. Virginia).
+	UsEast2RegionID      = "us-east-2"      // US East (Ohio).
+	UsWest1RegionID      = "us-west-1"      // US West (N. California).
+	UsWest2RegionID      = "us-west-2"      // US West (Oregon).
+)
+
+// AWS China partition's regions.
+const (
+	CnNorth1RegionID     = "cn-north-1"     // China (Beijing).
+	CnNorthwest1RegionID = "cn-northwest-1" // China (Ningxia).
+)
+
+// AWS GovCloud (US) partition's regions.
+const (
+	UsGovWest1RegionID = "us-gov-west-1" // AWS GovCloud (US).
+)
+
+// Service identifiers
+const (
+	A4bServiceID                          = "a4b"                          // A4b.
+	AcmServiceID                          = "acm"                          // Acm.
+	AcmPcaServiceID                       = "acm-pca"                      // AcmPca.
+	ApiMediatailorServiceID               = "api.mediatailor"              // ApiMediatailor.
+	ApiPricingServiceID                   = "api.pricing"                  // ApiPricing.
+	ApiSagemakerServiceID                 = "api.sagemaker"                // ApiSagemaker.
+	ApigatewayServiceID                   = "apigateway"                   // Apigateway.
+	ApplicationAutoscalingServiceID       = "application-autoscaling"      // ApplicationAutoscaling.
+	Appstream2ServiceID                   = "appstream2"                   // Appstream2.
+	AthenaServiceID                       = "athena"                       // Athena.
+	AutoscalingServiceID                  = "autoscaling"                  // Autoscaling.
+	AutoscalingPlansServiceID             = "autoscaling-plans"            // AutoscalingPlans.
+	BatchServiceID                        = "batch"                        // Batch.
+	BudgetsServiceID                      = "budgets"                      // Budgets.
+	CeServiceID                           = "ce"                           // Ce.
+	Cloud9ServiceID                       = "cloud9"                       // Cloud9.
+	ClouddirectoryServiceID               = "clouddirectory"               // Clouddirectory.
+	CloudformationServiceID               = "cloudformation"               // Cloudformation.
+	CloudfrontServiceID                   = "cloudfront"                   // Cloudfront.
+	CloudhsmServiceID                     = "cloudhsm"                     // Cloudhsm.
+	Cloudhsmv2ServiceID                   = "cloudhsmv2"                   // Cloudhsmv2.
+	CloudsearchServiceID                  = "cloudsearch"                  // Cloudsearch.
+	CloudtrailServiceID                   = "cloudtrail"                   // Cloudtrail.
+	CodebuildServiceID                    = "codebuild"                    // Codebuild.
+	CodecommitServiceID                   = "codecommit"                   // Codecommit.
+	CodedeployServiceID                   = "codedeploy"                   // Codedeploy.
+	CodepipelineServiceID                 = "codepipeline"                 // Codepipeline.
+	CodestarServiceID                     = "codestar"                     // Codestar.
+	CognitoIdentityServiceID              = "cognito-identity"             // CognitoIdentity.
+	CognitoIdpServiceID                   = "cognito-idp"                  // CognitoIdp.
+	CognitoSyncServiceID                  = "cognito-sync"                 // CognitoSync.
+	ComprehendServiceID                   = "comprehend"                   // Comprehend.
+	ConfigServiceID                       = "config"                       // Config.
+	CurServiceID                          = "cur"                          // Cur.
+	DatapipelineServiceID                 = "datapipeline"                 // Datapipeline.
+	DaxServiceID                          = "dax"                          // Dax.
+	DevicefarmServiceID                   = "devicefarm"                   // Devicefarm.
+	DirectconnectServiceID                = "directconnect"                // Directconnect.
+	DiscoveryServiceID                    = "discovery"                    // Discovery.
+	DmsServiceID                          = "dms"                          // Dms.
+	DsServiceID                           = "ds"                           // Ds.
+	DynamodbServiceID                     = "dynamodb"                     // Dynamodb.
+	Ec2ServiceID                          = "ec2"                          // Ec2.
+	Ec2metadataServiceID                  = "ec2metadata"                  // Ec2metadata.
+	EcrServiceID                          = "ecr"                          // Ecr.
+	EcsServiceID                          = "ecs"                          // Ecs.
+	ElasticacheServiceID                  = "elasticache"                  // Elasticache.
+	ElasticbeanstalkServiceID             = "elasticbeanstalk"             // Elasticbeanstalk.
+	ElasticfilesystemServiceID            = "elasticfilesystem"            // Elasticfilesystem.
+	ElasticloadbalancingServiceID         = "elasticloadbalancing"         // Elasticloadbalancing.
+	ElasticmapreduceServiceID             = "elasticmapreduce"             // Elasticmapreduce.
+	ElastictranscoderServiceID            = "elastictranscoder"            // Elastictranscoder.
+	EmailServiceID                        = "email"                        // Email.
+	EntitlementMarketplaceServiceID       = "entitlement.marketplace"      // EntitlementMarketplace.
+	EsServiceID                           = "es"                           // Es.
+	EventsServiceID                       = "events"                       // Events.
+	FirehoseServiceID                     = "firehose"                     // Firehose.
+	FmsServiceID                          = "fms"                          // Fms.
+	GameliftServiceID                     = "gamelift"                     // Gamelift.
+	GlacierServiceID                      = "glacier"                      // Glacier.
+	GlueServiceID                         = "glue"                         // Glue.
+	GreengrassServiceID                   = "greengrass"                   // Greengrass.
+	GuarddutyServiceID                    = "guardduty"                    // Guardduty.
+	HealthServiceID                       = "health"                       // Health.
+	IamServiceID                          = "iam"                          // Iam.
+	ImportexportServiceID                 = "importexport"                 // Importexport.
+	InspectorServiceID                    = "inspector"                    // Inspector.
+	IotServiceID                          = "iot"                          // Iot.
+	KinesisServiceID                      = "kinesis"                      // Kinesis.
+	KinesisanalyticsServiceID             = "kinesisanalytics"             // Kinesisanalytics.
+	KinesisvideoServiceID                 = "kinesisvideo"                 // Kinesisvideo.
+	KmsServiceID                          = "kms"                          // Kms.
+	LambdaServiceID                       = "lambda"                       // Lambda.
+	LightsailServiceID                    = "lightsail"                    // Lightsail.
+	LogsServiceID                         = "logs"                         // Logs.
+	MachinelearningServiceID              = "machinelearning"              // Machinelearning.
+	MarketplacecommerceanalyticsServiceID = "marketplacecommerceanalytics" // Marketplacecommerceanalytics.
+	MediaconvertServiceID                 = "mediaconvert"                 // Mediaconvert.
+	MedialiveServiceID                    = "medialive"                    // Medialive.
+	MediapackageServiceID                 = "mediapackage"                 // Mediapackage.
+	MediastoreServiceID                   = "mediastore"                   // Mediastore.
+	MeteringMarketplaceServiceID          = "metering.marketplace"         // MeteringMarketplace.
+	MghServiceID                          = "mgh"                          // Mgh.
+	MobileanalyticsServiceID              = "mobileanalytics"              // Mobileanalytics.
+	ModelsLexServiceID                    = "models.lex"                   // ModelsLex.
+	MonitoringServiceID                   = "monitoring"                   // Monitoring.
+	MturkRequesterServiceID               = "mturk-requester"              // MturkRequester.
+	NeptuneServiceID                      = "neptune"                      // Neptune.
+	OpsworksServiceID                     = "opsworks"                     // Opsworks.
+	OpsworksCmServiceID                   = "opsworks-cm"                  // OpsworksCm.
+	OrganizationsServiceID                = "organizations"                // Organizations.
+	PinpointServiceID                     = "pinpoint"                     // Pinpoint.
+	PollyServiceID                        = "polly"                        // Polly.
+	RdsServiceID                          = "rds"                          // Rds.
+	RedshiftServiceID                     = "redshift"                     // Redshift.
+	RekognitionServiceID                  = "rekognition"                  // Rekognition.
+	ResourceGroupsServiceID               = "resource-groups"              // ResourceGroups.
+	Route53ServiceID                      = "route53"                      // Route53.
+	Route53domainsServiceID               = "route53domains"               // Route53domains.
+	RuntimeLexServiceID                   = "runtime.lex"                  // RuntimeLex.
+	RuntimeSagemakerServiceID             = "runtime.sagemaker"            // RuntimeSagemaker.
+	S3ServiceID                           = "s3"                           // S3.
+	SdbServiceID                          = "sdb"                          // Sdb.
+	SecretsmanagerServiceID               = "secretsmanager"               // Secretsmanager.
+	ServerlessrepoServiceID               = "serverlessrepo"               // Serverlessrepo.
+	ServicecatalogServiceID               = "servicecatalog"               // Servicecatalog.
+	ServicediscoveryServiceID             = "servicediscovery"             // Servicediscovery.
+	ShieldServiceID                       = "shield"                       // Shield.
+	SmsServiceID                          = "sms"                          // Sms.
+	SnowballServiceID                     = "snowball"                     // Snowball.
+	SnsServiceID                          = "sns"                          // Sns.
+	SqsServiceID                          = "sqs"                          // Sqs.
+	SsmServiceID                          = "ssm"                          // Ssm.
+	StatesServiceID                       = "states"                       // States.
+	StoragegatewayServiceID               = "storagegateway"               // Storagegateway.
+	StreamsDynamodbServiceID              = "streams.dynamodb"             // StreamsDynamodb.
+	StsServiceID                          = "sts"                          // Sts.
+	SupportServiceID                      = "support"                      // Support.
+	SwfServiceID                          = "swf"                          // Swf.
+	TaggingServiceID                      = "tagging"                      // Tagging.
+	TranslateServiceID                    = "translate"                    // Translate.
+	WafServiceID                          = "waf"                          // Waf.
+	WafRegionalServiceID                  = "waf-regional"                 // WafRegional.
+	WorkdocsServiceID                     = "workdocs"                     // Workdocs.
+	WorkmailServiceID                     = "workmail"                     // Workmail.
+	WorkspacesServiceID                   = "workspaces"                   // Workspaces.
+	XrayServiceID                         = "xray"                         // Xray.
+)
+
+// DefaultResolver returns an Endpoint resolver that will be able
+// to resolve endpoints for: AWS Standard, AWS China, and AWS GovCloud (US).
+//
+// Use DefaultPartitions() to get the list of the default partitions.
+func DefaultResolver() Resolver {
+	return defaultPartitions
+}
+
+// DefaultPartitions returns a list of the partitions the SDK is bundled
+// with. The available partitions are: AWS Standard, AWS China, and AWS GovCloud (US).
+//
+//    partitions := endpoints.DefaultPartitions
+//    for _, p := range partitions {
+//        // ... inspect partitions
+//    }
+func DefaultPartitions() []Partition {
+	return defaultPartitions.Partitions()
+}
+
+var defaultPartitions = partitions{
+	awsPartition,
+	awscnPartition,
+	awsusgovPartition,
+}
+
+// AwsPartition returns the Resolver for AWS Standard.
+func AwsPartition() Partition {
+	return awsPartition.Partition()
+}
+
+var awsPartition = partition{
+	ID:        "aws",
+	Name:      "AWS Standard",
+	DNSSuffix: "amazonaws.com",
+	RegionRegex: regionRegex{
+		Regexp: func() *regexp.Regexp {
+			reg, _ := regexp.Compile("^(us|eu|ap|sa|ca)\\-\\w+\\-\\d+$")
+			return reg
+		}(),
+	},
+	Defaults: endpoint{
+		Hostname:          "{service}.{region}.{dnsSuffix}",
+		Protocols:         []string{"https"},
+		SignatureVersions: []string{"v4"},
+	},
+	Regions: regions{
+		"ap-northeast-1": region{
+			Description: "Asia Pacific (Tokyo)",
+		},
+		"ap-northeast-2": region{
+			Description: "Asia Pacific (Seoul)",
+		},
+		"ap-south-1": region{
+			Description: "Asia Pacific (Mumbai)",
+		},
+		"ap-southeast-1": region{
+			Description: "Asia Pacific (Singapore)",
+		},
+		"ap-southeast-2": region{
+			Description: "Asia Pacific (Sydney)",
+		},
+		"ca-central-1": region{
+			Description: "Canada (Central)",
+		},
+		"eu-central-1": region{
+			Description: "EU (Frankfurt)",
+		},
+		"eu-west-1": region{
+			Description: "EU (Ireland)",
+		},
+		"eu-west-2": region{
+			Description: "EU (London)",
+		},
+		"eu-west-3": region{
+			Description: "EU (Paris)",
+		},
+		"sa-east-1": region{
+			Description: "South America (Sao Paulo)",
+		},
+		"us-east-1": region{
+			Description: "US East (N. Virginia)",
+		},
+		"us-east-2": region{
+			Description: "US East (Ohio)",
+		},
+		"us-west-1": region{
+			Description: "US West (N. California)",
+		},
+		"us-west-2": region{
+			Description: "US West (Oregon)",
+		},
+	},
+	Services: services{
+		"a4b": service{
+
+			Endpoints: endpoints{
+				"us-east-1": endpoint{},
+			},
+		},
+		"acm": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"acm-pca": service{
+			Defaults: endpoint{
+				Protocols: []string{"https"},
+			},
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"api.mediatailor": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-west-1":      endpoint{},
+				"us-east-1":      endpoint{},
+			},
+		},
+		"api.pricing": service{
+			Defaults: endpoint{
+				CredentialScope: credentialScope{
+					Service: "pricing",
+				},
+			},
+			Endpoints: endpoints{
+				"ap-south-1": endpoint{},
+				"us-east-1":  endpoint{},
+			},
+		},
+		"api.sagemaker": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"apigateway": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"application-autoscaling": service{
+			Defaults: endpoint{
+				Hostname:  "autoscaling.{region}.amazonaws.com",
+				Protocols: []string{"http", "https"},
+				CredentialScope: credentialScope{
+					Service: "application-autoscaling",
+				},
+			},
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"appstream2": service{
+			Defaults: endpoint{
+				Protocols: []string{"https"},
+				CredentialScope: credentialScope{
+					Service: "appstream",
+				},
+			},
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"eu-west-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"athena": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"autoscaling": service{
+			Defaults: endpoint{
+				Protocols: []string{"http", "https"},
+			},
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"autoscaling-plans": service{
+			Defaults: endpoint{
+				Hostname:  "autoscaling.{region}.amazonaws.com",
+				Protocols: []string{"http", "https"},
+				CredentialScope: credentialScope{
+					Service: "autoscaling-plans",
+				},
+			},
+			Endpoints: endpoints{
+				"ap-southeast-1": endpoint{},
+				"eu-west-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"batch": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"budgets": service{
+			PartitionEndpoint: "aws-global",
+			IsRegionalized:    boxedFalse,
+
+			Endpoints: endpoints{
+				"aws-global": endpoint{
+					Hostname: "budgets.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-east-1",
+					},
+				},
+			},
+		},
+		"ce": service{
+			PartitionEndpoint: "aws-global",
+			IsRegionalized:    boxedFalse,
+
+			Endpoints: endpoints{
+				"aws-global": endpoint{
+					Hostname: "ce.us-east-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-east-1",
+					},
+				},
+			},
+		},
+		"cloud9": service{
+
+			Endpoints: endpoints{
+				"ap-southeast-1": endpoint{},
+				"eu-west-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"clouddirectory": service{
+
+			Endpoints: endpoints{
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"cloudformation": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"cloudfront": service{
+			PartitionEndpoint: "aws-global",
+			IsRegionalized:    boxedFalse,
+
+			Endpoints: endpoints{
+				"aws-global": endpoint{
+					Hostname:  "cloudfront.amazonaws.com",
+					Protocols: []string{"http", "https"},
+					CredentialScope: credentialScope{
+						Region: "us-east-1",
+					},
+				},
+			},
+		},
+		"cloudhsm": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"cloudhsmv2": service{
+			Defaults: endpoint{
+				CredentialScope: credentialScope{
+					Service: "cloudhsm",
+				},
+			},
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"cloudsearch": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"cloudtrail": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"codebuild": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-1-fips": endpoint{
+					Hostname: "codebuild-fips.us-east-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-east-1",
+					},
+				},
+				"us-east-2": endpoint{},
+				"us-east-2-fips": endpoint{
+					Hostname: "codebuild-fips.us-east-2.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-east-2",
+					},
+				},
+				"us-west-1": endpoint{},
+				"us-west-1-fips": endpoint{
+					Hostname: "codebuild-fips.us-west-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-west-1",
+					},
+				},
+				"us-west-2": endpoint{},
+				"us-west-2-fips": endpoint{
+					Hostname: "codebuild-fips.us-west-2.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-west-2",
+					},
+				},
+			},
+		},
+		"codecommit": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"codedeploy": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"codepipeline": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"codestar": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"cognito-identity": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"cognito-idp": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"cognito-sync": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"comprehend": service{
+			Defaults: endpoint{
+				Protocols: []string{"https"},
+			},
+			Endpoints: endpoints{
+				"ap-southeast-2": endpoint{},
+				"eu-west-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"config": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"cur": service{
+
+			Endpoints: endpoints{
+				"us-east-1": endpoint{},
+			},
+		},
+		"datapipeline": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-west-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"dax": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-west-1":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"devicefarm": service{
+
+			Endpoints: endpoints{
+				"us-west-2": endpoint{},
+			},
+		},
+		"directconnect": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"discovery": service{
+
+			Endpoints: endpoints{
+				"us-west-2": endpoint{},
+			},
+		},
+		"dms": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"ds": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"dynamodb": service{
+			Defaults: endpoint{
+				Protocols: []string{"http", "https"},
+			},
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"local": endpoint{
+					Hostname:  "localhost:8000",
+					Protocols: []string{"http"},
+					CredentialScope: credentialScope{
+						Region: "us-east-1",
+					},
+				},
+				"sa-east-1": endpoint{},
+				"us-east-1": endpoint{},
+				"us-east-2": endpoint{},
+				"us-west-1": endpoint{},
+				"us-west-2": endpoint{},
+			},
+		},
+		"ec2": service{
+			Defaults: endpoint{
+				Protocols: []string{"http", "https"},
+			},
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"ec2metadata": service{
+			PartitionEndpoint: "aws-global",
+			IsRegionalized:    boxedFalse,
+
+			Endpoints: endpoints{
+				"aws-global": endpoint{
+					Hostname:  "169.254.169.254/latest",
+					Protocols: []string{"http"},
+				},
+			},
+		},
+		"ecr": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"ecs": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"elasticache": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"fips": endpoint{
+					Hostname: "elasticache-fips.us-west-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-west-1",
+					},
+				},
+				"sa-east-1": endpoint{},
+				"us-east-1": endpoint{},
+				"us-east-2": endpoint{},
+				"us-west-1": endpoint{},
+				"us-west-2": endpoint{},
+			},
+		},
+		"elasticbeanstalk": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"elasticfilesystem": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"elasticloadbalancing": service{
+			Defaults: endpoint{
+				Protocols: []string{"https"},
+			},
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"elasticmapreduce": service{
+			Defaults: endpoint{
+				SSLCommonName: "{region}.{service}.{dnsSuffix}",
+				Protocols:     []string{"https"},
+			},
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1": endpoint{
+					SSLCommonName: "{service}.{region}.{dnsSuffix}",
+				},
+				"eu-west-1": endpoint{},
+				"eu-west-2": endpoint{},
+				"eu-west-3": endpoint{},
+				"sa-east-1": endpoint{},
+				"us-east-1": endpoint{
+					SSLCommonName: "{service}.{region}.{dnsSuffix}",
+				},
+				"us-east-2": endpoint{},
+				"us-west-1": endpoint{},
+				"us-west-2": endpoint{},
+			},
+		},
+		"elastictranscoder": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-west-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"email": service{
+
+			Endpoints: endpoints{
+				"eu-west-1": endpoint{},
+				"us-east-1": endpoint{},
+				"us-west-2": endpoint{},
+			},
+		},
+		"entitlement.marketplace": service{
+			Defaults: endpoint{
+				CredentialScope: credentialScope{
+					Service: "aws-marketplace",
+				},
+			},
+			Endpoints: endpoints{
+				"us-east-1": endpoint{},
+			},
+		},
+		"es": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"events": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"firehose": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"fms": service{
+			Defaults: endpoint{
+				Protocols: []string{"https"},
+			},
+			Endpoints: endpoints{
+				"eu-west-1": endpoint{},
+				"us-east-1": endpoint{},
+				"us-west-2": endpoint{},
+			},
+		},
+		"gamelift": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"glacier": service{
+			Defaults: endpoint{
+				Protocols: []string{"http", "https"},
+			},
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"glue": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"greengrass": service{
+			IsRegionalized: boxedTrue,
+			Defaults: endpoint{
+				Protocols: []string{"https"},
+			},
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"guardduty": service{
+			IsRegionalized: boxedTrue,
+			Defaults: endpoint{
+				Protocols: []string{"https"},
+			},
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"health": service{
+
+			Endpoints: endpoints{
+				"us-east-1": endpoint{},
+			},
+		},
+		"iam": service{
+			PartitionEndpoint: "aws-global",
+			IsRegionalized:    boxedFalse,
+
+			Endpoints: endpoints{
+				"aws-global": endpoint{
+					Hostname: "iam.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-east-1",
+					},
+				},
+			},
+		},
+		"importexport": service{
+			PartitionEndpoint: "aws-global",
+			IsRegionalized:    boxedFalse,
+
+			Endpoints: endpoints{
+				"aws-global": endpoint{
+					Hostname:          "importexport.amazonaws.com",
+					SignatureVersions: []string{"v2", "v4"},
+					CredentialScope: credentialScope{
+						Region:  "us-east-1",
+						Service: "IngestionService",
+					},
+				},
+			},
+		},
+		"inspector": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"iot": service{
+			Defaults: endpoint{
+				CredentialScope: credentialScope{
+					Service: "execute-api",
+				},
+			},
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"kinesis": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"kinesisanalytics": service{
+
+			Endpoints: endpoints{
+				"eu-central-1": endpoint{},
+				"eu-west-1":    endpoint{},
+				"us-east-1":    endpoint{},
+				"us-west-2":    endpoint{},
+			},
+		},
+		"kinesisvideo": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"kms": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"lambda": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"lightsail": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"logs": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"machinelearning": service{
+
+			Endpoints: endpoints{
+				"eu-west-1": endpoint{},
+				"us-east-1": endpoint{},
+			},
+		},
+		"marketplacecommerceanalytics": service{
+
+			Endpoints: endpoints{
+				"us-east-1": endpoint{},
+			},
+		},
+		"mediaconvert": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"medialive": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"mediapackage": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"mediastore": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"metering.marketplace": service{
+			Defaults: endpoint{
+				CredentialScope: credentialScope{
+					Service: "aws-marketplace",
+				},
+			},
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"mgh": service{
+
+			Endpoints: endpoints{
+				"us-west-2": endpoint{},
+			},
+		},
+		"mobileanalytics": service{
+
+			Endpoints: endpoints{
+				"us-east-1": endpoint{},
+			},
+		},
+		"models.lex": service{
+			Defaults: endpoint{
+				CredentialScope: credentialScope{
+					Service: "lex",
+				},
+			},
+			Endpoints: endpoints{
+				"eu-west-1": endpoint{},
+				"us-east-1": endpoint{},
+				"us-west-2": endpoint{},
+			},
+		},
+		"monitoring": service{
+			Defaults: endpoint{
+				Protocols: []string{"http", "https"},
+			},
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"mturk-requester": service{
+			IsRegionalized: boxedFalse,
+
+			Endpoints: endpoints{
+				"sandbox": endpoint{
+					Hostname: "mturk-requester-sandbox.us-east-1.amazonaws.com",
+				},
+				"us-east-1": endpoint{},
+			},
+		},
+		"neptune": service{
+
+			Endpoints: endpoints{
+				"eu-west-1": endpoint{
+					Hostname: "rds.eu-west-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "eu-west-1",
+					},
+				},
+				"us-east-1": endpoint{
+					Hostname: "rds.us-east-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-east-1",
+					},
+				},
+				"us-east-2": endpoint{
+					Hostname: "rds.us-east-2.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-east-2",
+					},
+				},
+				"us-west-2": endpoint{
+					Hostname: "rds.us-west-2.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-west-2",
+					},
+				},
+			},
+		},
+		"opsworks": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"opsworks-cm": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"organizations": service{
+			PartitionEndpoint: "aws-global",
+			IsRegionalized:    boxedFalse,
+
+			Endpoints: endpoints{
+				"aws-global": endpoint{
+					Hostname: "organizations.us-east-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-east-1",
+					},
+				},
+			},
+		},
+		"pinpoint": service{
+			Defaults: endpoint{
+				CredentialScope: credentialScope{
+					Service: "mobiletargeting",
+				},
+			},
+			Endpoints: endpoints{
+				"us-east-1": endpoint{},
+			},
+		},
+		"polly": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"rds": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1": endpoint{
+					SSLCommonName: "{service}.{dnsSuffix}",
+				},
+				"us-east-2": endpoint{},
+				"us-west-1": endpoint{},
+				"us-west-2": endpoint{},
+			},
+		},
+		"redshift": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"rekognition": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-west-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"resource-groups": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"route53": service{
+			PartitionEndpoint: "aws-global",
+			IsRegionalized:    boxedFalse,
+
+			Endpoints: endpoints{
+				"aws-global": endpoint{
+					Hostname: "route53.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-east-1",
+					},
+				},
+			},
+		},
+		"route53domains": service{
+
+			Endpoints: endpoints{
+				"us-east-1": endpoint{},
+			},
+		},
+		"runtime.lex": service{
+			Defaults: endpoint{
+				CredentialScope: credentialScope{
+					Service: "lex",
+				},
+			},
+			Endpoints: endpoints{
+				"eu-west-1": endpoint{},
+				"us-east-1": endpoint{},
+				"us-west-2": endpoint{},
+			},
+		},
+		"runtime.sagemaker": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"s3": service{
+			PartitionEndpoint: "us-east-1",
+			IsRegionalized:    boxedTrue,
+			Defaults: endpoint{
+				Protocols:         []string{"http", "https"},
+				SignatureVersions: []string{"s3v4"},
+
+				HasDualStack:      boxedTrue,
+				DualStackHostname: "{service}.dualstack.{region}.{dnsSuffix}",
+			},
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{
+					Hostname:          "s3.ap-northeast-1.amazonaws.com",
+					SignatureVersions: []string{"s3", "s3v4"},
+				},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{
+					Hostname:          "s3.ap-southeast-1.amazonaws.com",
+					SignatureVersions: []string{"s3", "s3v4"},
+				},
+				"ap-southeast-2": endpoint{
+					Hostname:          "s3.ap-southeast-2.amazonaws.com",
+					SignatureVersions: []string{"s3", "s3v4"},
+				},
+				"ca-central-1": endpoint{},
+				"eu-central-1": endpoint{},
+				"eu-west-1": endpoint{
+					Hostname:          "s3.eu-west-1.amazonaws.com",
+					SignatureVersions: []string{"s3", "s3v4"},
+				},
+				"eu-west-2": endpoint{},
+				"eu-west-3": endpoint{},
+				"s3-external-1": endpoint{
+					Hostname:          "s3-external-1.amazonaws.com",
+					SignatureVersions: []string{"s3", "s3v4"},
+					CredentialScope: credentialScope{
+						Region: "us-east-1",
+					},
+				},
+				"sa-east-1": endpoint{
+					Hostname:          "s3.sa-east-1.amazonaws.com",
+					SignatureVersions: []string{"s3", "s3v4"},
+				},
+				"us-east-1": endpoint{
+					Hostname:          "s3.amazonaws.com",
+					SignatureVersions: []string{"s3", "s3v4"},
+				},
+				"us-east-2": endpoint{},
+				"us-west-1": endpoint{
+					Hostname:          "s3.us-west-1.amazonaws.com",
+					SignatureVersions: []string{"s3", "s3v4"},
+				},
+				"us-west-2": endpoint{
+					Hostname:          "s3.us-west-2.amazonaws.com",
+					SignatureVersions: []string{"s3", "s3v4"},
+				},
+			},
+		},
+		"sdb": service{
+			Defaults: endpoint{
+				Protocols:         []string{"http", "https"},
+				SignatureVersions: []string{"v2"},
+			},
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-west-1":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1": endpoint{
+					Hostname: "sdb.amazonaws.com",
+				},
+				"us-west-1": endpoint{},
+				"us-west-2": endpoint{},
+			},
+		},
+		"secretsmanager": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"serverlessrepo": service{
+			Defaults: endpoint{
+				Protocols: []string{"https"},
+			},
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{
+					Protocols: []string{"https"},
+				},
+				"ap-northeast-2": endpoint{
+					Protocols: []string{"https"},
+				},
+				"ap-south-1": endpoint{
+					Protocols: []string{"https"},
+				},
+				"ap-southeast-1": endpoint{
+					Protocols: []string{"https"},
+				},
+				"ap-southeast-2": endpoint{
+					Protocols: []string{"https"},
+				},
+				"ca-central-1": endpoint{
+					Protocols: []string{"https"},
+				},
+				"eu-central-1": endpoint{
+					Protocols: []string{"https"},
+				},
+				"eu-west-1": endpoint{
+					Protocols: []string{"https"},
+				},
+				"eu-west-2": endpoint{
+					Protocols: []string{"https"},
+				},
+				"sa-east-1": endpoint{
+					Protocols: []string{"https"},
+				},
+				"us-east-1": endpoint{
+					Protocols: []string{"https"},
+				},
+				"us-east-2": endpoint{
+					Protocols: []string{"https"},
+				},
+				"us-west-1": endpoint{
+					Protocols: []string{"https"},
+				},
+				"us-west-2": endpoint{
+					Protocols: []string{"https"},
+				},
+			},
+		},
+		"servicecatalog": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"servicediscovery": service{
+
+			Endpoints: endpoints{
+				"eu-west-1": endpoint{},
+				"us-east-1": endpoint{},
+				"us-east-2": endpoint{},
+				"us-west-1": endpoint{},
+				"us-west-2": endpoint{},
+			},
+		},
+		"shield": service{
+			IsRegionalized: boxedFalse,
+			Defaults: endpoint{
+				SSLCommonName: "Shield.us-east-1.amazonaws.com",
+				Protocols:     []string{"https"},
+			},
+			Endpoints: endpoints{
+				"us-east-1": endpoint{},
+			},
+		},
+		"sms": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"snowball": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"sns": service{
+			Defaults: endpoint{
+				Protocols: []string{"http", "https"},
+			},
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"sqs": service{
+			Defaults: endpoint{
+				SSLCommonName: "{region}.queue.{dnsSuffix}",
+				Protocols:     []string{"http", "https"},
+			},
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"fips-us-east-1": endpoint{
+					Hostname: "sqs-fips.us-east-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-east-1",
+					},
+				},
+				"fips-us-east-2": endpoint{
+					Hostname: "sqs-fips.us-east-2.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-east-2",
+					},
+				},
+				"fips-us-west-1": endpoint{
+					Hostname: "sqs-fips.us-west-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-west-1",
+					},
+				},
+				"fips-us-west-2": endpoint{
+					Hostname: "sqs-fips.us-west-2.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-west-2",
+					},
+				},
+				"sa-east-1": endpoint{},
+				"us-east-1": endpoint{
+					SSLCommonName: "queue.{dnsSuffix}",
+				},
+				"us-east-2": endpoint{},
+				"us-west-1": endpoint{},
+				"us-west-2": endpoint{},
+			},
+		},
+		"ssm": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"states": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"storagegateway": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"streams.dynamodb": service{
+			Defaults: endpoint{
+				Protocols: []string{"http", "https"},
+				CredentialScope: credentialScope{
+					Service: "dynamodb",
+				},
+			},
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"local": endpoint{
+					Hostname:  "localhost:8000",
+					Protocols: []string{"http"},
+					CredentialScope: credentialScope{
+						Region: "us-east-1",
+					},
+				},
+				"sa-east-1": endpoint{},
+				"us-east-1": endpoint{},
+				"us-east-2": endpoint{},
+				"us-west-1": endpoint{},
+				"us-west-2": endpoint{},
+			},
+		},
+		"sts": service{
+			PartitionEndpoint: "aws-global",
+			Defaults: endpoint{
+				Hostname: "sts.amazonaws.com",
+				CredentialScope: credentialScope{
+					Region: "us-east-1",
+				},
+			},
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{
+					Hostname: "sts.ap-northeast-2.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "ap-northeast-2",
+					},
+				},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"aws-global":     endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-1-fips": endpoint{
+					Hostname: "sts-fips.us-east-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-east-1",
+					},
+				},
+				"us-east-2": endpoint{},
+				"us-east-2-fips": endpoint{
+					Hostname: "sts-fips.us-east-2.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-east-2",
+					},
+				},
+				"us-west-1": endpoint{},
+				"us-west-1-fips": endpoint{
+					Hostname: "sts-fips.us-west-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-west-1",
+					},
+				},
+				"us-west-2": endpoint{},
+				"us-west-2-fips": endpoint{
+					Hostname: "sts-fips.us-west-2.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-west-2",
+					},
+				},
+			},
+		},
+		"support": service{
+
+			Endpoints: endpoints{
+				"us-east-1": endpoint{},
+			},
+		},
+		"swf": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"tagging": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"eu-west-3":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"translate": service{
+			Defaults: endpoint{
+				Protocols: []string{"https"},
+			},
+			Endpoints: endpoints{
+				"eu-west-1": endpoint{},
+				"us-east-1": endpoint{},
+				"us-east-2": endpoint{},
+				"us-west-2": endpoint{},
+			},
+		},
+		"waf": service{
+			PartitionEndpoint: "aws-global",
+			IsRegionalized:    boxedFalse,
+
+			Endpoints: endpoints{
+				"aws-global": endpoint{
+					Hostname: "waf.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-east-1",
+					},
+				},
+			},
+		},
+		"waf-regional": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"workdocs": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"eu-west-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"workmail": service{
+			Defaults: endpoint{
+				Protocols: []string{"https"},
+			},
+			Endpoints: endpoints{
+				"eu-west-1": endpoint{},
+				"us-east-1": endpoint{},
+				"us-west-2": endpoint{},
+			},
+		},
+		"workspaces": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+		"xray": service{
+
+			Endpoints: endpoints{
+				"ap-northeast-1": endpoint{},
+				"ap-northeast-2": endpoint{},
+				"ap-south-1":     endpoint{},
+				"ap-southeast-1": endpoint{},
+				"ap-southeast-2": endpoint{},
+				"ca-central-1":   endpoint{},
+				"eu-central-1":   endpoint{},
+				"eu-west-1":      endpoint{},
+				"eu-west-2":      endpoint{},
+				"sa-east-1":      endpoint{},
+				"us-east-1":      endpoint{},
+				"us-east-2":      endpoint{},
+				"us-west-1":      endpoint{},
+				"us-west-2":      endpoint{},
+			},
+		},
+	},
+}
+
+// AwsCnPartition returns the Resolver for AWS China.
+func AwsCnPartition() Partition {
+	return awscnPartition.Partition()
+}
+
+var awscnPartition = partition{
+	ID:        "aws-cn",
+	Name:      "AWS China",
+	DNSSuffix: "amazonaws.com.cn",
+	RegionRegex: regionRegex{
+		Regexp: func() *regexp.Regexp {
+			reg, _ := regexp.Compile("^cn\\-\\w+\\-\\d+$")
+			return reg
+		}(),
+	},
+	Defaults: endpoint{
+		Hostname:          "{service}.{region}.{dnsSuffix}",
+		Protocols:         []string{"https"},
+		SignatureVersions: []string{"v4"},
+	},
+	Regions: regions{
+		"cn-north-1": region{
+			Description: "China (Beijing)",
+		},
+		"cn-northwest-1": region{
+			Description: "China (Ningxia)",
+		},
+	},
+	Services: services{
+		"apigateway": service{
+
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"application-autoscaling": service{
+			Defaults: endpoint{
+				Hostname:  "autoscaling.{region}.amazonaws.com.cn",
+				Protocols: []string{"http", "https"},
+				CredentialScope: credentialScope{
+					Service: "application-autoscaling",
+				},
+			},
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"autoscaling": service{
+			Defaults: endpoint{
+				Protocols: []string{"http", "https"},
+			},
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"cloudformation": service{
+
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"cloudtrail": service{
+
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"codedeploy": service{
+
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"cognito-identity": service{
+
+			Endpoints: endpoints{
+				"cn-north-1": endpoint{},
+			},
+		},
+		"config": service{
+
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"directconnect": service{
+
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"ds": service{
+
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"dynamodb": service{
+			Defaults: endpoint{
+				Protocols: []string{"http", "https"},
+			},
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"ec2": service{
+			Defaults: endpoint{
+				Protocols: []string{"http", "https"},
+			},
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"ec2metadata": service{
+			PartitionEndpoint: "aws-global",
+			IsRegionalized:    boxedFalse,
+
+			Endpoints: endpoints{
+				"aws-global": endpoint{
+					Hostname:  "169.254.169.254/latest",
+					Protocols: []string{"http"},
+				},
+			},
+		},
+		"ecr": service{
+
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"ecs": service{
+
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"elasticache": service{
+
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"elasticbeanstalk": service{
+
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"elasticloadbalancing": service{
+			Defaults: endpoint{
+				Protocols: []string{"https"},
+			},
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"elasticmapreduce": service{
+			Defaults: endpoint{
+				Protocols: []string{"https"},
+			},
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"es": service{
+
+			Endpoints: endpoints{
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"events": service{
+
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"glacier": service{
+			Defaults: endpoint{
+				Protocols: []string{"http", "https"},
+			},
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"iam": service{
+			PartitionEndpoint: "aws-cn-global",
+			IsRegionalized:    boxedFalse,
+
+			Endpoints: endpoints{
+				"aws-cn-global": endpoint{
+					Hostname: "iam.cn-north-1.amazonaws.com.cn",
+					CredentialScope: credentialScope{
+						Region: "cn-north-1",
+					},
+				},
+			},
+		},
+		"iot": service{
+			Defaults: endpoint{
+				CredentialScope: credentialScope{
+					Service: "execute-api",
+				},
+			},
+			Endpoints: endpoints{
+				"cn-north-1": endpoint{},
+			},
+		},
+		"kinesis": service{
+
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"lambda": service{
+
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"logs": service{
+
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"monitoring": service{
+			Defaults: endpoint{
+				Protocols: []string{"http", "https"},
+			},
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"rds": service{
+
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"redshift": service{
+
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"s3": service{
+			Defaults: endpoint{
+				Protocols:         []string{"http", "https"},
+				SignatureVersions: []string{"s3v4"},
+			},
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"sms": service{
+
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"snowball": service{
+
+			Endpoints: endpoints{
+				"cn-north-1": endpoint{},
+			},
+		},
+		"sns": service{
+			Defaults: endpoint{
+				Protocols: []string{"http", "https"},
+			},
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"sqs": service{
+			Defaults: endpoint{
+				SSLCommonName: "{region}.queue.{dnsSuffix}",
+				Protocols:     []string{"http", "https"},
+			},
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"ssm": service{
+
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"storagegateway": service{
+
+			Endpoints: endpoints{
+				"cn-north-1": endpoint{},
+			},
+		},
+		"streams.dynamodb": service{
+			Defaults: endpoint{
+				Protocols: []string{"http", "https"},
+				CredentialScope: credentialScope{
+					Service: "dynamodb",
+				},
+			},
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"sts": service{
+
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"swf": service{
+
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+		"tagging": service{
+
+			Endpoints: endpoints{
+				"cn-north-1":     endpoint{},
+				"cn-northwest-1": endpoint{},
+			},
+		},
+	},
+}
+
+// AwsUsGovPartition returns the Resolver for AWS GovCloud (US).
+func AwsUsGovPartition() Partition {
+	return awsusgovPartition.Partition()
+}
+
+var awsusgovPartition = partition{
+	ID:        "aws-us-gov",
+	Name:      "AWS GovCloud (US)",
+	DNSSuffix: "amazonaws.com",
+	RegionRegex: regionRegex{
+		Regexp: func() *regexp.Regexp {
+			reg, _ := regexp.Compile("^us\\-gov\\-\\w+\\-\\d+$")
+			return reg
+		}(),
+	},
+	Defaults: endpoint{
+		Hostname:          "{service}.{region}.{dnsSuffix}",
+		Protocols:         []string{"https"},
+		SignatureVersions: []string{"v4"},
+	},
+	Regions: regions{
+		"us-gov-west-1": region{
+			Description: "AWS GovCloud (US)",
+		},
+	},
+	Services: services{
+		"acm": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"apigateway": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"autoscaling": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{
+					Protocols: []string{"http", "https"},
+				},
+			},
+		},
+		"cloudformation": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"cloudhsm": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"cloudhsmv2": service{
+			Defaults: endpoint{
+				CredentialScope: credentialScope{
+					Service: "cloudhsm",
+				},
+			},
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"cloudtrail": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"codedeploy": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"config": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"directconnect": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"dms": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"dynamodb": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+				"us-gov-west-1-fips": endpoint{
+					Hostname: "dynamodb.us-gov-west-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-gov-west-1",
+					},
+				},
+			},
+		},
+		"ec2": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"ec2metadata": service{
+			PartitionEndpoint: "aws-global",
+			IsRegionalized:    boxedFalse,
+
+			Endpoints: endpoints{
+				"aws-global": endpoint{
+					Hostname:  "169.254.169.254/latest",
+					Protocols: []string{"http"},
+				},
+			},
+		},
+		"ecr": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"ecs": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"elasticache": service{
+
+			Endpoints: endpoints{
+				"fips": endpoint{
+					Hostname: "elasticache-fips.us-gov-west-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-gov-west-1",
+					},
+				},
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"elasticbeanstalk": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"elasticloadbalancing": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{
+					Protocols: []string{"http", "https"},
+				},
+			},
+		},
+		"elasticmapreduce": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{
+					Protocols: []string{"https"},
+				},
+			},
+		},
+		"es": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"events": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"glacier": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{
+					Protocols: []string{"http", "https"},
+				},
+			},
+		},
+		"iam": service{
+			PartitionEndpoint: "aws-us-gov-global",
+			IsRegionalized:    boxedFalse,
+
+			Endpoints: endpoints{
+				"aws-us-gov-global": endpoint{
+					Hostname: "iam.us-gov.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-gov-west-1",
+					},
+				},
+			},
+		},
+		"inspector": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"iot": service{
+			Defaults: endpoint{
+				CredentialScope: credentialScope{
+					Service: "execute-api",
+				},
+			},
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"kinesis": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"kms": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"lambda": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"logs": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"metering.marketplace": service{
+			Defaults: endpoint{
+				CredentialScope: credentialScope{
+					Service: "aws-marketplace",
+				},
+			},
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"monitoring": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"polly": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"rds": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"redshift": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"rekognition": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"s3": service{
+			Defaults: endpoint{
+				SignatureVersions: []string{"s3", "s3v4"},
+			},
+			Endpoints: endpoints{
+				"fips-us-gov-west-1": endpoint{
+					Hostname: "s3-fips-us-gov-west-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-gov-west-1",
+					},
+				},
+				"us-gov-west-1": endpoint{
+					Hostname:  "s3.us-gov-west-1.amazonaws.com",
+					Protocols: []string{"http", "https"},
+				},
+			},
+		},
+		"sms": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"snowball": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"sns": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{
+					Protocols: []string{"http", "https"},
+				},
+			},
+		},
+		"sqs": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{
+					SSLCommonName: "{region}.queue.{dnsSuffix}",
+					Protocols:     []string{"http", "https"},
+				},
+			},
+		},
+		"ssm": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"states": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"storagegateway": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"streams.dynamodb": service{
+			Defaults: endpoint{
+				CredentialScope: credentialScope{
+					Service: "dynamodb",
+				},
+			},
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+				"us-gov-west-1-fips": endpoint{
+					Hostname: "dynamodb.us-gov-west-1.amazonaws.com",
+					CredentialScope: credentialScope{
+						Region: "us-gov-west-1",
+					},
+				},
+			},
+		},
+		"sts": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"swf": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"tagging": service{
+
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+		"translate": service{
+			Defaults: endpoint{
+				Protocols: []string{"https"},
+			},
+			Endpoints: endpoints{
+				"us-gov-west-1": endpoint{},
+			},
+		},
+	},
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/doc.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/doc.go
new file mode 100644
index 000000000..84316b92c
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/doc.go
@@ -0,0 +1,66 @@
+// Package endpoints provides the types and functionality for defining regions
+// and endpoints, as well as querying those definitions.
+//
+// The SDK's Regions and Endpoints metadata is code generated into the endpoints
+// package, and is accessible via the DefaultResolver function. This function
+// returns a endpoint Resolver will search the metadata and build an associated
+// endpoint if one is found. The default resolver will search all partitions
+// known by the SDK. e.g AWS Standard (aws), AWS China (aws-cn), and
+// AWS GovCloud (US) (aws-us-gov).
+// .
+//
+// Enumerating Regions and Endpoint Metadata
+//
+// Casting the Resolver returned by DefaultResolver to a EnumPartitions interface
+// will allow you to get access to the list of underlying Partitions with the
+// Partitions method. This is helpful if you want to limit the SDK's endpoint
+// resolving to a single partition, or enumerate regions, services, and endpoints
+// in the partition.
+//
+//     resolver := endpoints.DefaultResolver()
+//     partitions := resolver.(endpoints.EnumPartitions).Partitions()
+//
+//     for _, p := range partitions {
+//         fmt.Println("Regions for", p.ID())
+//         for id, _ := range p.Regions() {
+//             fmt.Println("*", id)
+//         }
+//
+//         fmt.Println("Services for", p.ID())
+//         for id, _ := range p.Services() {
+//             fmt.Println("*", id)
+//         }
+//     }
+//
+// Using Custom Endpoints
+//
+// The endpoints package also gives you the ability to use your own logic how
+// endpoints are resolved. This is a great way to define a custom endpoint
+// for select services, without passing that logic down through your code.
+//
+// If a type implements the Resolver interface it can be used to resolve
+// endpoints. To use this with the SDK's Session and Config set the value
+// of the type to the EndpointsResolver field of aws.Config when initializing
+// the session, or service client.
+//
+// In addition the ResolverFunc is a wrapper for a func matching the signature
+// of Resolver.EndpointFor, converting it to a type that satisfies the
+// Resolver interface.
+//
+//
+//     myCustomResolver := func(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) {
+//         if service == endpoints.S3ServiceID {
+//             return endpoints.ResolvedEndpoint{
+//                 URL:           "s3.custom.endpoint.com",
+//                 SigningRegion: "custom-signing-region",
+//             }, nil
+//         }
+//
+//         return endpoints.DefaultResolver().EndpointFor(service, region, optFns...)
+//     }
+//
+//     sess := session.Must(session.NewSession(&aws.Config{
+//         Region:           aws.String("us-west-2"),
+//         EndpointResolver: endpoints.ResolverFunc(myCustomResolver),
+//     }))
+package endpoints
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go
new file mode 100644
index 000000000..e29c09512
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go
@@ -0,0 +1,449 @@
+package endpoints
+
+import (
+	"fmt"
+	"regexp"
+
+	"github.com/aws/aws-sdk-go/aws/awserr"
+)
+
+// Options provide the configuration needed to direct how the
+// endpoints will be resolved.
+type Options struct {
+	// DisableSSL forces the endpoint to be resolved as HTTP.
+	// instead of HTTPS if the service supports it.
+	DisableSSL bool
+
+	// Sets the resolver to resolve the endpoint as a dualstack endpoint
+	// for the service. If dualstack support for a service is not known and
+	// StrictMatching is not enabled a dualstack endpoint for the service will
+	// be returned. This endpoint may not be valid. If StrictMatching is
+	// enabled only services that are known to support dualstack will return
+	// dualstack endpoints.
+	UseDualStack bool
+
+	// Enables strict matching of services and regions resolved endpoints.
+	// If the partition doesn't enumerate the exact service and region an
+	// error will be returned. This option will prevent returning endpoints
+	// that look valid, but may not resolve to any real endpoint.
+	StrictMatching bool
+
+	// Enables resolving a service endpoint based on the region provided if the
+	// service does not exist. The service endpoint ID will be used as the service
+	// domain name prefix. By default the endpoint resolver requires the service
+	// to be known when resolving endpoints.
+	//
+	// If resolving an endpoint on the partition list the provided region will
+	// be used to determine which partition's domain name pattern to the service
+	// endpoint ID with. If both the service and region are unkonwn and resolving
+	// the endpoint on partition list an UnknownEndpointError error will be returned.
+	//
+	// If resolving and endpoint on a partition specific resolver that partition's
+	// domain name pattern will be used with the service endpoint ID. If both
+	// region and service do not exist when resolving an endpoint on a specific
+	// partition the partition's domain pattern will be used to combine the
+	// endpoint and region together.
+	//
+	// This option is ignored if StrictMatching is enabled.
+	ResolveUnknownService bool
+}
+
+// Set combines all of the option functions together.
+func (o *Options) Set(optFns ...func(*Options)) {
+	for _, fn := range optFns {
+		fn(o)
+	}
+}
+
+// DisableSSLOption sets the DisableSSL options. Can be used as a functional
+// option when resolving endpoints.
+func DisableSSLOption(o *Options) {
+	o.DisableSSL = true
+}
+
+// UseDualStackOption sets the UseDualStack option. Can be used as a functional
+// option when resolving endpoints.
+func UseDualStackOption(o *Options) {
+	o.UseDualStack = true
+}
+
+// StrictMatchingOption sets the StrictMatching option. Can be used as a functional
+// option when resolving endpoints.
+func StrictMatchingOption(o *Options) {
+	o.StrictMatching = true
+}
+
+// ResolveUnknownServiceOption sets the ResolveUnknownService option. Can be used
+// as a functional option when resolving endpoints.
+func ResolveUnknownServiceOption(o *Options) {
+	o.ResolveUnknownService = true
+}
+
+// A Resolver provides the interface for functionality to resolve endpoints.
+// The build in Partition and DefaultResolver return value satisfy this interface.
+type Resolver interface {
+	EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error)
+}
+
+// ResolverFunc is a helper utility that wraps a function so it satisfies the
+// Resolver interface. This is useful when you want to add additional endpoint
+// resolving logic, or stub out specific endpoints with custom values.
+type ResolverFunc func(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error)
+
+// EndpointFor wraps the ResolverFunc function to satisfy the Resolver interface.
+func (fn ResolverFunc) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
+	return fn(service, region, opts...)
+}
+
+var schemeRE = regexp.MustCompile("^([^:]+)://")
+
+// AddScheme adds the HTTP or HTTPS schemes to a endpoint URL if there is no
+// scheme. If disableSSL is true HTTP will set HTTP instead of the default HTTPS.
+//
+// If disableSSL is set, it will only set the URL's scheme if the URL does not
+// contain a scheme.
+func AddScheme(endpoint string, disableSSL bool) string {
+	if !schemeRE.MatchString(endpoint) {
+		scheme := "https"
+		if disableSSL {
+			scheme = "http"
+		}
+		endpoint = fmt.Sprintf("%s://%s", scheme, endpoint)
+	}
+
+	return endpoint
+}
+
+// EnumPartitions a provides a way to retrieve the underlying partitions that
+// make up the SDK's default Resolver, or any resolver decoded from a model
+// file.
+//
+// Use this interface with DefaultResolver and DecodeModels to get the list of
+// Partitions.
+type EnumPartitions interface {
+	Partitions() []Partition
+}
+
+// RegionsForService returns a map of regions for the partition and service.
+// If either the partition or service does not exist false will be returned
+// as the second parameter.
+//
+// This example shows how  to get the regions for DynamoDB in the AWS partition.
+//    rs, exists := endpoints.RegionsForService(endpoints.DefaultPartitions(), endpoints.AwsPartitionID, endpoints.DynamodbServiceID)
+//
+// This is equivalent to using the partition directly.
+//    rs := endpoints.AwsPartition().Services()[endpoints.DynamodbServiceID].Regions()
+func RegionsForService(ps []Partition, partitionID, serviceID string) (map[string]Region, bool) {
+	for _, p := range ps {
+		if p.ID() != partitionID {
+			continue
+		}
+		if _, ok := p.p.Services[serviceID]; !ok {
+			break
+		}
+
+		s := Service{
+			id: serviceID,
+			p:  p.p,
+		}
+		return s.Regions(), true
+	}
+
+	return map[string]Region{}, false
+}
+
+// PartitionForRegion returns the first partition which includes the region
+// passed in. This includes both known regions and regions which match
+// a pattern supported by the partition which may include regions that are
+// not explicitly known by the partition. Use the Regions method of the
+// returned Partition if explicit support is needed.
+func PartitionForRegion(ps []Partition, regionID string) (Partition, bool) {
+	for _, p := range ps {
+		if _, ok := p.p.Regions[regionID]; ok || p.p.RegionRegex.MatchString(regionID) {
+			return p, true
+		}
+	}
+
+	return Partition{}, false
+}
+
+// A Partition provides the ability to enumerate the partition's regions
+// and services.
+type Partition struct {
+	id string
+	p  *partition
+}
+
+// ID returns the identifier of the partition.
+func (p Partition) ID() string { return p.id }
+
+// EndpointFor attempts to resolve the endpoint based on service and region.
+// See Options for information on configuring how the endpoint is resolved.
+//
+// If the service cannot be found in the metadata the UnknownServiceError
+// error will be returned. This validation will occur regardless if
+// StrictMatching is enabled. To enable resolving unknown services set the
+// "ResolveUnknownService" option to true. When StrictMatching is disabled
+// this option allows the partition resolver to resolve a endpoint based on
+// the service endpoint ID provided.
+//
+// When resolving endpoints you can choose to enable StrictMatching. This will
+// require the provided service and region to be known by the partition.
+// If the endpoint cannot be strictly resolved an error will be returned. This
+// mode is useful to ensure the endpoint resolved is valid. Without
+// StrictMatching enabled the endpoint returned my look valid but may not work.
+// StrictMatching requires the SDK to be updated if you want to take advantage
+// of new regions and services expansions.
+//
+// Errors that can be returned.
+//   * UnknownServiceError
+//   * UnknownEndpointError
+func (p Partition) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
+	return p.p.EndpointFor(service, region, opts...)
+}
+
+// Regions returns a map of Regions indexed by their ID. This is useful for
+// enumerating over the regions in a partition.
+func (p Partition) Regions() map[string]Region {
+	rs := map[string]Region{}
+	for id, r := range p.p.Regions {
+		rs[id] = Region{
+			id:   id,
+			desc: r.Description,
+			p:    p.p,
+		}
+	}
+
+	return rs
+}
+
+// Services returns a map of Service indexed by their ID. This is useful for
+// enumerating over the services in a partition.
+func (p Partition) Services() map[string]Service {
+	ss := map[string]Service{}
+	for id := range p.p.Services {
+		ss[id] = Service{
+			id: id,
+			p:  p.p,
+		}
+	}
+
+	return ss
+}
+
+// A Region provides information about a region, and ability to resolve an
+// endpoint from the context of a region, given a service.
+type Region struct {
+	id, desc string
+	p        *partition
+}
+
+// ID returns the region's identifier.
+func (r Region) ID() string { return r.id }
+
+// Description returns the region's description. The region description
+// is free text, it can be empty, and it may change between SDK releases.
+func (r Region) Description() string { return r.desc }
+
+// ResolveEndpoint resolves an endpoint from the context of the region given
+// a service. See Partition.EndpointFor for usage and errors that can be returned.
+func (r Region) ResolveEndpoint(service string, opts ...func(*Options)) (ResolvedEndpoint, error) {
+	return r.p.EndpointFor(service, r.id, opts...)
+}
+
+// Services returns a list of all services that are known to be in this region.
+func (r Region) Services() map[string]Service {
+	ss := map[string]Service{}
+	for id, s := range r.p.Services {
+		if _, ok := s.Endpoints[r.id]; ok {
+			ss[id] = Service{
+				id: id,
+				p:  r.p,
+			}
+		}
+	}
+
+	return ss
+}
+
+// A Service provides information about a service, and ability to resolve an
+// endpoint from the context of a service, given a region.
+type Service struct {
+	id string
+	p  *partition
+}
+
+// ID returns the identifier for the service.
+func (s Service) ID() string { return s.id }
+
+// ResolveEndpoint resolves an endpoint from the context of a service given
+// a region. See Partition.EndpointFor for usage and errors that can be returned.
+func (s Service) ResolveEndpoint(region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
+	return s.p.EndpointFor(s.id, region, opts...)
+}
+
+// Regions returns a map of Regions that the service is present in.
+//
+// A region is the AWS region the service exists in. Whereas a Endpoint is
+// an URL that can be resolved to a instance of a service.
+func (s Service) Regions() map[string]Region {
+	rs := map[string]Region{}
+	for id := range s.p.Services[s.id].Endpoints {
+		if r, ok := s.p.Regions[id]; ok {
+			rs[id] = Region{
+				id:   id,
+				desc: r.Description,
+				p:    s.p,
+			}
+		}
+	}
+
+	return rs
+}
+
+// Endpoints returns a map of Endpoints indexed by their ID for all known
+// endpoints for a service.
+//
+// A region is the AWS region the service exists in. Whereas a Endpoint is
+// an URL that can be resolved to a instance of a service.
+func (s Service) Endpoints() map[string]Endpoint {
+	es := map[string]Endpoint{}
+	for id := range s.p.Services[s.id].Endpoints {
+		es[id] = Endpoint{
+			id:        id,
+			serviceID: s.id,
+			p:         s.p,
+		}
+	}
+
+	return es
+}
+
+// A Endpoint provides information about endpoints, and provides the ability
+// to resolve that endpoint for the service, and the region the endpoint
+// represents.
+type Endpoint struct {
+	id        string
+	serviceID string
+	p         *partition
+}
+
+// ID returns the identifier for an endpoint.
+func (e Endpoint) ID() string { return e.id }
+
+// ServiceID returns the identifier the endpoint belongs to.
+func (e Endpoint) ServiceID() string { return e.serviceID }
+
+// ResolveEndpoint resolves an endpoint from the context of a service and
+// region the endpoint represents. See Partition.EndpointFor for usage and
+// errors that can be returned.
+func (e Endpoint) ResolveEndpoint(opts ...func(*Options)) (ResolvedEndpoint, error) {
+	return e.p.EndpointFor(e.serviceID, e.id, opts...)
+}
+
+// A ResolvedEndpoint is an endpoint that has been resolved based on a partition
+// service, and region.
+type ResolvedEndpoint struct {
+	// The endpoint URL
+	URL string
+
+	// The region that should be used for signing requests.
+	SigningRegion string
+
+	// The service name that should be used for signing requests.
+	SigningName string
+
+	// States that the signing name for this endpoint was derived from metadata
+	// passed in, but was not explicitly modeled.
+	SigningNameDerived bool
+
+	// The signing method that should be used for signing requests.
+	SigningMethod string
+}
+
+// So that the Error interface type can be included as an anonymous field
+// in the requestError struct and not conflict with the error.Error() method.
+type awsError awserr.Error
+
+// A EndpointNotFoundError is returned when in StrictMatching mode, and the
+// endpoint for the service and region cannot be found in any of the partitions.
+type EndpointNotFoundError struct {
+	awsError
+	Partition string
+	Service   string
+	Region    string
+}
+
+// A UnknownServiceError is returned when the service does not resolve to an
+// endpoint. Includes a list of all known services for the partition. Returned
+// when a partition does not support the service.
+type UnknownServiceError struct {
+	awsError
+	Partition string
+	Service   string
+	Known     []string
+}
+
+// NewUnknownServiceError builds and returns UnknownServiceError.
+func NewUnknownServiceError(p, s string, known []string) UnknownServiceError {
+	return UnknownServiceError{
+		awsError: awserr.New("UnknownServiceError",
+			"could not resolve endpoint for unknown service", nil),
+		Partition: p,
+		Service:   s,
+		Known:     known,
+	}
+}
+
+// String returns the string representation of the error.
+func (e UnknownServiceError) Error() string {
+	extra := fmt.Sprintf("partition: %q, service: %q",
+		e.Partition, e.Service)
+	if len(e.Known) > 0 {
+		extra += fmt.Sprintf(", known: %v", e.Known)
+	}
+	return awserr.SprintError(e.Code(), e.Message(), extra, e.OrigErr())
+}
+
+// String returns the string representation of the error.
+func (e UnknownServiceError) String() string {
+	return e.Error()
+}
+
+// A UnknownEndpointError is returned when in StrictMatching mode and the
+// service is valid, but the region does not resolve to an endpoint. Includes
+// a list of all known endpoints for the service.
+type UnknownEndpointError struct {
+	awsError
+	Partition string
+	Service   string
+	Region    string
+	Known     []string
+}
+
+// NewUnknownEndpointError builds and returns UnknownEndpointError.
+func NewUnknownEndpointError(p, s, r string, known []string) UnknownEndpointError {
+	return UnknownEndpointError{
+		awsError: awserr.New("UnknownEndpointError",
+			"could not resolve endpoint", nil),
+		Partition: p,
+		Service:   s,
+		Region:    r,
+		Known:     known,
+	}
+}
+
+// String returns the string representation of the error.
+func (e UnknownEndpointError) Error() string {
+	extra := fmt.Sprintf("partition: %q, service: %q, region: %q",
+		e.Partition, e.Service, e.Region)
+	if len(e.Known) > 0 {
+		extra += fmt.Sprintf(", known: %v", e.Known)
+	}
+	return awserr.SprintError(e.Code(), e.Message(), extra, e.OrigErr())
+}
+
+// String returns the string representation of the error.
+func (e UnknownEndpointError) String() string {
+	return e.Error()
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model.go
new file mode 100644
index 000000000..ff6f76db6
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model.go
@@ -0,0 +1,307 @@
+package endpoints
+
+import (
+	"fmt"
+	"regexp"
+	"strconv"
+	"strings"
+)
+
+type partitions []partition
+
+func (ps partitions) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
+	var opt Options
+	opt.Set(opts...)
+
+	for i := 0; i < len(ps); i++ {
+		if !ps[i].canResolveEndpoint(service, region, opt.StrictMatching) {
+			continue
+		}
+
+		return ps[i].EndpointFor(service, region, opts...)
+	}
+
+	// If loose matching fallback to first partition format to use
+	// when resolving the endpoint.
+	if !opt.StrictMatching && len(ps) > 0 {
+		return ps[0].EndpointFor(service, region, opts...)
+	}
+
+	return ResolvedEndpoint{}, NewUnknownEndpointError("all partitions", service, region, []string{})
+}
+
+// Partitions satisfies the EnumPartitions interface and returns a list
+// of Partitions representing each partition represented in the SDK's
+// endpoints model.
+func (ps partitions) Partitions() []Partition {
+	parts := make([]Partition, 0, len(ps))
+	for i := 0; i < len(ps); i++ {
+		parts = append(parts, ps[i].Partition())
+	}
+
+	return parts
+}
+
+type partition struct {
+	ID          string      `json:"partition"`
+	Name        string      `json:"partitionName"`
+	DNSSuffix   string      `json:"dnsSuffix"`
+	RegionRegex regionRegex `json:"regionRegex"`
+	Defaults    endpoint    `json:"defaults"`
+	Regions     regions     `json:"regions"`
+	Services    services    `json:"services"`
+}
+
+func (p partition) Partition() Partition {
+	return Partition{
+		id: p.ID,
+		p:  &p,
+	}
+}
+
+func (p partition) canResolveEndpoint(service, region string, strictMatch bool) bool {
+	s, hasService := p.Services[service]
+	_, hasEndpoint := s.Endpoints[region]
+
+	if hasEndpoint && hasService {
+		return true
+	}
+
+	if strictMatch {
+		return false
+	}
+
+	return p.RegionRegex.MatchString(region)
+}
+
+func (p partition) EndpointFor(service, region string, opts ...func(*Options)) (resolved ResolvedEndpoint, err error) {
+	var opt Options
+	opt.Set(opts...)
+
+	s, hasService := p.Services[service]
+	if !(hasService || opt.ResolveUnknownService) {
+		// Only return error if the resolver will not fallback to creating
+		// endpoint based on service endpoint ID passed in.
+		return resolved, NewUnknownServiceError(p.ID, service, serviceList(p.Services))
+	}
+
+	e, hasEndpoint := s.endpointForRegion(region)
+	if !hasEndpoint && opt.StrictMatching {
+		return resolved, NewUnknownEndpointError(p.ID, service, region, endpointList(s.Endpoints))
+	}
+
+	defs := []endpoint{p.Defaults, s.Defaults}
+	return e.resolve(service, region, p.DNSSuffix, defs, opt), nil
+}
+
+func serviceList(ss services) []string {
+	list := make([]string, 0, len(ss))
+	for k := range ss {
+		list = append(list, k)
+	}
+	return list
+}
+func endpointList(es endpoints) []string {
+	list := make([]string, 0, len(es))
+	for k := range es {
+		list = append(list, k)
+	}
+	return list
+}
+
+type regionRegex struct {
+	*regexp.Regexp
+}
+
+func (rr *regionRegex) UnmarshalJSON(b []byte) (err error) {
+	// Strip leading and trailing quotes
+	regex, err := strconv.Unquote(string(b))
+	if err != nil {
+		return fmt.Errorf("unable to strip quotes from regex, %v", err)
+	}
+
+	rr.Regexp, err = regexp.Compile(regex)
+	if err != nil {
+		return fmt.Errorf("unable to unmarshal region regex, %v", err)
+	}
+	return nil
+}
+
+type regions map[string]region
+
+type region struct {
+	Description string `json:"description"`
+}
+
+type services map[string]service
+
+type service struct {
+	PartitionEndpoint string    `json:"partitionEndpoint"`
+	IsRegionalized    boxedBool `json:"isRegionalized,omitempty"`
+	Defaults          endpoint  `json:"defaults"`
+	Endpoints         endpoints `json:"endpoints"`
+}
+
+func (s *service) endpointForRegion(region string) (endpoint, bool) {
+	if s.IsRegionalized == boxedFalse {
+		return s.Endpoints[s.PartitionEndpoint], region == s.PartitionEndpoint
+	}
+
+	if e, ok := s.Endpoints[region]; ok {
+		return e, true
+	}
+
+	// Unable to find any matching endpoint, return
+	// blank that will be used for generic endpoint creation.
+	return endpoint{}, false
+}
+
+type endpoints map[string]endpoint
+
+type endpoint struct {
+	Hostname        string          `json:"hostname"`
+	Protocols       []string        `json:"protocols"`
+	CredentialScope credentialScope `json:"credentialScope"`
+
+	// Custom fields not modeled
+	HasDualStack      boxedBool `json:"-"`
+	DualStackHostname string    `json:"-"`
+
+	// Signature Version not used
+	SignatureVersions []string `json:"signatureVersions"`
+
+	// SSLCommonName not used.
+	SSLCommonName string `json:"sslCommonName"`
+}
+
+const (
+	defaultProtocol = "https"
+	defaultSigner   = "v4"
+)
+
+var (
+	protocolPriority = []string{"https", "http"}
+	signerPriority   = []string{"v4", "v2"}
+)
+
+func getByPriority(s []string, p []string, def string) string {
+	if len(s) == 0 {
+		return def
+	}
+
+	for i := 0; i < len(p); i++ {
+		for j := 0; j < len(s); j++ {
+			if s[j] == p[i] {
+				return s[j]
+			}
+		}
+	}
+
+	return s[0]
+}
+
+func (e endpoint) resolve(service, region, dnsSuffix string, defs []endpoint, opts Options) ResolvedEndpoint {
+	var merged endpoint
+	for _, def := range defs {
+		merged.mergeIn(def)
+	}
+	merged.mergeIn(e)
+	e = merged
+
+	hostname := e.Hostname
+
+	// Offset the hostname for dualstack if enabled
+	if opts.UseDualStack && e.HasDualStack == boxedTrue {
+		hostname = e.DualStackHostname
+	}
+
+	u := strings.Replace(hostname, "{service}", service, 1)
+	u = strings.Replace(u, "{region}", region, 1)
+	u = strings.Replace(u, "{dnsSuffix}", dnsSuffix, 1)
+
+	scheme := getEndpointScheme(e.Protocols, opts.DisableSSL)
+	u = fmt.Sprintf("%s://%s", scheme, u)
+
+	signingRegion := e.CredentialScope.Region
+	if len(signingRegion) == 0 {
+		signingRegion = region
+	}
+
+	signingName := e.CredentialScope.Service
+	var signingNameDerived bool
+	if len(signingName) == 0 {
+		signingName = service
+		signingNameDerived = true
+	}
+
+	return ResolvedEndpoint{
+		URL:                u,
+		SigningRegion:      signingRegion,
+		SigningName:        signingName,
+		SigningNameDerived: signingNameDerived,
+		SigningMethod:      getByPriority(e.SignatureVersions, signerPriority, defaultSigner),
+	}
+}
+
+func getEndpointScheme(protocols []string, disableSSL bool) string {
+	if disableSSL {
+		return "http"
+	}
+
+	return getByPriority(protocols, protocolPriority, defaultProtocol)
+}
+
+func (e *endpoint) mergeIn(other endpoint) {
+	if len(other.Hostname) > 0 {
+		e.Hostname = other.Hostname
+	}
+	if len(other.Protocols) > 0 {
+		e.Protocols = other.Protocols
+	}
+	if len(other.SignatureVersions) > 0 {
+		e.SignatureVersions = other.SignatureVersions
+	}
+	if len(other.CredentialScope.Region) > 0 {
+		e.CredentialScope.Region = other.CredentialScope.Region
+	}
+	if len(other.CredentialScope.Service) > 0 {
+		e.CredentialScope.Service = other.CredentialScope.Service
+	}
+	if len(other.SSLCommonName) > 0 {
+		e.SSLCommonName = other.SSLCommonName
+	}
+	if other.HasDualStack != boxedBoolUnset {
+		e.HasDualStack = other.HasDualStack
+	}
+	if len(other.DualStackHostname) > 0 {
+		e.DualStackHostname = other.DualStackHostname
+	}
+}
+
+type credentialScope struct {
+	Region  string `json:"region"`
+	Service string `json:"service"`
+}
+
+type boxedBool int
+
+func (b *boxedBool) UnmarshalJSON(buf []byte) error {
+	v, err := strconv.ParseBool(string(buf))
+	if err != nil {
+		return err
+	}
+
+	if v {
+		*b = boxedTrue
+	} else {
+		*b = boxedFalse
+	}
+
+	return nil
+}
+
+const (
+	boxedBoolUnset boxedBool = iota
+	boxedFalse
+	boxedTrue
+)
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go
new file mode 100644
index 000000000..05e92df22
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go
@@ -0,0 +1,337 @@
+// +build codegen
+
+package endpoints
+
+import (
+	"fmt"
+	"io"
+	"reflect"
+	"strings"
+	"text/template"
+	"unicode"
+)
+
+// A CodeGenOptions are the options for code generating the endpoints into
+// Go code from the endpoints model definition.
+type CodeGenOptions struct {
+	// Options for how the model will be decoded.
+	DecodeModelOptions DecodeModelOptions
+}
+
+// Set combines all of the option functions together
+func (d *CodeGenOptions) Set(optFns ...func(*CodeGenOptions)) {
+	for _, fn := range optFns {
+		fn(d)
+	}
+}
+
+// CodeGenModel given a endpoints model file will decode it and attempt to
+// generate Go code from the model definition. Error will be returned if
+// the code is unable to be generated, or decoded.
+func CodeGenModel(modelFile io.Reader, outFile io.Writer, optFns ...func(*CodeGenOptions)) error {
+	var opts CodeGenOptions
+	opts.Set(optFns...)
+
+	resolver, err := DecodeModel(modelFile, func(d *DecodeModelOptions) {
+		*d = opts.DecodeModelOptions
+	})
+	if err != nil {
+		return err
+	}
+
+	tmpl := template.Must(template.New("tmpl").Funcs(funcMap).Parse(v3Tmpl))
+	if err := tmpl.ExecuteTemplate(outFile, "defaults", resolver); err != nil {
+		return fmt.Errorf("failed to execute template, %v", err)
+	}
+
+	return nil
+}
+
+func toSymbol(v string) string {
+	out := []rune{}
+	for _, c := range strings.Title(v) {
+		if !(unicode.IsNumber(c) || unicode.IsLetter(c)) {
+			continue
+		}
+
+		out = append(out, c)
+	}
+
+	return string(out)
+}
+
+func quoteString(v string) string {
+	return fmt.Sprintf("%q", v)
+}
+
+func regionConstName(p, r string) string {
+	return toSymbol(p) + toSymbol(r)
+}
+
+func partitionGetter(id string) string {
+	return fmt.Sprintf("%sPartition", toSymbol(id))
+}
+
+func partitionVarName(id string) string {
+	return fmt.Sprintf("%sPartition", strings.ToLower(toSymbol(id)))
+}
+
+func listPartitionNames(ps partitions) string {
+	names := []string{}
+	switch len(ps) {
+	case 1:
+		return ps[0].Name
+	case 2:
+		return fmt.Sprintf("%s and %s", ps[0].Name, ps[1].Name)
+	default:
+		for i, p := range ps {
+			if i == len(ps)-1 {
+				names = append(names, "and "+p.Name)
+			} else {
+				names = append(names, p.Name)
+			}
+		}
+		return strings.Join(names, ", ")
+	}
+}
+
+func boxedBoolIfSet(msg string, v boxedBool) string {
+	switch v {
+	case boxedTrue:
+		return fmt.Sprintf(msg, "boxedTrue")
+	case boxedFalse:
+		return fmt.Sprintf(msg, "boxedFalse")
+	default:
+		return ""
+	}
+}
+
+func stringIfSet(msg, v string) string {
+	if len(v) == 0 {
+		return ""
+	}
+
+	return fmt.Sprintf(msg, v)
+}
+
+func stringSliceIfSet(msg string, vs []string) string {
+	if len(vs) == 0 {
+		return ""
+	}
+
+	names := []string{}
+	for _, v := range vs {
+		names = append(names, `"`+v+`"`)
+	}
+
+	return fmt.Sprintf(msg, strings.Join(names, ","))
+}
+
+func endpointIsSet(v endpoint) bool {
+	return !reflect.DeepEqual(v, endpoint{})
+}
+
+func serviceSet(ps partitions) map[string]struct{} {
+	set := map[string]struct{}{}
+	for _, p := range ps {
+		for id := range p.Services {
+			set[id] = struct{}{}
+		}
+	}
+
+	return set
+}
+
+var funcMap = template.FuncMap{
+	"ToSymbol":           toSymbol,
+	"QuoteString":        quoteString,
+	"RegionConst":        regionConstName,
+	"PartitionGetter":    partitionGetter,
+	"PartitionVarName":   partitionVarName,
+	"ListPartitionNames": listPartitionNames,
+	"BoxedBoolIfSet":     boxedBoolIfSet,
+	"StringIfSet":        stringIfSet,
+	"StringSliceIfSet":   stringSliceIfSet,
+	"EndpointIsSet":      endpointIsSet,
+	"ServicesSet":        serviceSet,
+}
+
+const v3Tmpl = `
+{{ define "defaults" -}}
+// Code generated by aws/endpoints/v3model_codegen.go. DO NOT EDIT.
+
+package endpoints
+
+import (
+	"regexp"
+)
+
+	{{ template "partition consts" . }}
+
+	{{ range $_, $partition := . }}
+		{{ template "partition region consts" $partition }}
+	{{ end }}
+
+	{{ template "service consts" . }}
+	
+	{{ template "endpoint resolvers" . }}
+{{- end }}
+
+{{ define "partition consts" }}
+	// Partition identifiers
+	const (
+		{{ range $_, $p := . -}}
+			{{ ToSymbol $p.ID }}PartitionID = {{ QuoteString $p.ID }} // {{ $p.Name }} partition.
+		{{ end -}}
+	)
+{{- end }}
+
+{{ define "partition region consts" }}
+	// {{ .Name }} partition's regions.
+	const (
+		{{ range $id, $region := .Regions -}}
+			{{ ToSymbol $id }}RegionID = {{ QuoteString $id }} // {{ $region.Description }}.
+		{{ end -}}
+	)
+{{- end }}
+
+{{ define "service consts" }}
+	// Service identifiers
+	const (
+		{{ $serviceSet := ServicesSet . -}}
+		{{ range $id, $_ := $serviceSet -}}
+			{{ ToSymbol $id }}ServiceID = {{ QuoteString $id }} // {{ ToSymbol $id }}.
+		{{ end -}}
+	)
+{{- end }}
+
+{{ define "endpoint resolvers" }}
+	// DefaultResolver returns an Endpoint resolver that will be able
+	// to resolve endpoints for: {{ ListPartitionNames . }}.
+	//
+	// Use DefaultPartitions() to get the list of the default partitions.
+	func DefaultResolver() Resolver {
+		return defaultPartitions
+	}
+
+	// DefaultPartitions returns a list of the partitions the SDK is bundled
+	// with. The available partitions are: {{ ListPartitionNames . }}.
+	//
+	//    partitions := endpoints.DefaultPartitions
+	//    for _, p := range partitions {
+	//        // ... inspect partitions
+	//    }
+	func DefaultPartitions() []Partition {
+		return defaultPartitions.Partitions()
+	}
+
+	var defaultPartitions = partitions{
+		{{ range $_, $partition := . -}}
+			{{ PartitionVarName $partition.ID }},
+		{{ end }}
+	}
+	
+	{{ range $_, $partition := . -}}
+		{{ $name := PartitionGetter $partition.ID -}}
+		// {{ $name }} returns the Resolver for {{ $partition.Name }}.
+		func {{ $name }}() Partition {
+			return  {{ PartitionVarName $partition.ID }}.Partition()
+		}
+		var {{ PartitionVarName $partition.ID }} = {{ template "gocode Partition" $partition }}
+	{{ end }}
+{{ end }}
+
+{{ define "default partitions" }}
+	func DefaultPartitions() []Partition {
+		return []partition{
+			{{ range $_, $partition := . -}}
+			// {{ ToSymbol $partition.ID}}Partition(),
+			{{ end }}
+		}
+	}
+{{ end }}
+
+{{ define "gocode Partition" -}}
+partition{
+	{{ StringIfSet "ID: %q,\n" .ID -}}
+	{{ StringIfSet "Name: %q,\n" .Name -}}
+	{{ StringIfSet "DNSSuffix: %q,\n" .DNSSuffix -}}
+	RegionRegex: {{ template "gocode RegionRegex" .RegionRegex }},
+	{{ if EndpointIsSet .Defaults -}}
+		Defaults: {{ template "gocode Endpoint" .Defaults }},
+	{{- end }}
+	Regions:  {{ template "gocode Regions" .Regions }},
+	Services: {{ template "gocode Services" .Services }},
+}
+{{- end }}
+
+{{ define "gocode RegionRegex" -}}
+regionRegex{
+	Regexp: func() *regexp.Regexp{
+		reg, _ := regexp.Compile({{ QuoteString .Regexp.String }})
+		return reg
+	}(),
+}
+{{- end }}
+
+{{ define "gocode Regions" -}}
+regions{
+	{{ range $id, $region := . -}}
+		"{{ $id }}": {{ template "gocode Region" $region }},
+	{{ end -}}
+}
+{{- end }}
+
+{{ define "gocode Region" -}}
+region{
+	{{ StringIfSet "Description: %q,\n" .Description -}}
+}
+{{- end }}
+
+{{ define "gocode Services" -}}
+services{
+	{{ range $id, $service := . -}}
+	"{{ $id }}": {{ template "gocode Service" $service }},
+	{{ end }}
+}
+{{- end }}
+
+{{ define "gocode Service" -}}
+service{
+	{{ StringIfSet "PartitionEndpoint: %q,\n" .PartitionEndpoint -}}
+	{{ BoxedBoolIfSet "IsRegionalized: %s,\n" .IsRegionalized -}}
+	{{ if EndpointIsSet .Defaults -}}
+		Defaults: {{ template "gocode Endpoint" .Defaults -}},
+	{{- end }}
+	{{ if .Endpoints -}}
+		Endpoints: {{ template "gocode Endpoints" .Endpoints }},
+	{{- end }}
+}
+{{- end }}
+
+{{ define "gocode Endpoints" -}}
+endpoints{
+	{{ range $id, $endpoint := . -}}
+	"{{ $id }}": {{ template "gocode Endpoint" $endpoint }},
+	{{ end }}
+}
+{{- end }}
+
+{{ define "gocode Endpoint" -}}
+endpoint{
+	{{ StringIfSet "Hostname: %q,\n" .Hostname -}}
+	{{ StringIfSet "SSLCommonName: %q,\n" .SSLCommonName -}}
+	{{ StringSliceIfSet "Protocols: []string{%s},\n" .Protocols -}}
+	{{ StringSliceIfSet "SignatureVersions: []string{%s},\n" .SignatureVersions -}}
+	{{ if or .CredentialScope.Region .CredentialScope.Service -}}
+	CredentialScope: credentialScope{
+		{{ StringIfSet "Region: %q,\n" .CredentialScope.Region -}}
+		{{ StringIfSet "Service: %q,\n" .CredentialScope.Service -}}
+	},
+	{{- end }}
+	{{ BoxedBoolIfSet "HasDualStack: %s,\n" .HasDualStack -}}
+	{{ StringIfSet "DualStackHostname: %q,\n" .DualStackHostname -}}
+
+}
+{{- end }}
+`
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/errors.go b/vendor/github.com/aws/aws-sdk-go/aws/errors.go
new file mode 100644
index 000000000..576636168
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/errors.go
@@ -0,0 +1,17 @@
+package aws
+
+import "github.com/aws/aws-sdk-go/aws/awserr"
+
+var (
+	// ErrMissingRegion is an error that is returned if region configuration is
+	// not found.
+	//
+	// @readonly
+	ErrMissingRegion = awserr.New("MissingRegion", "could not find region configuration", nil)
+
+	// ErrMissingEndpoint is an error that is returned if an endpoint cannot be
+	// resolved for a service.
+	//
+	// @readonly
+	ErrMissingEndpoint = awserr.New("MissingEndpoint", "'Endpoint' configuration is required for this service", nil)
+)
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/jsonvalue.go b/vendor/github.com/aws/aws-sdk-go/aws/jsonvalue.go
new file mode 100644
index 000000000..91a6f277a
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/jsonvalue.go
@@ -0,0 +1,12 @@
+package aws
+
+// JSONValue is a representation of a grab bag type that will be marshaled
+// into a json string. This type can be used just like any other map.
+//
+//	Example:
+//
+//	values := aws.JSONValue{
+//		"Foo": "Bar",
+//	}
+//	values["Baz"] = "Qux"
+type JSONValue map[string]interface{}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/logger.go b/vendor/github.com/aws/aws-sdk-go/aws/logger.go
new file mode 100644
index 000000000..6ed15b2ec
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/logger.go
@@ -0,0 +1,118 @@
+package aws
+
+import (
+	"log"
+	"os"
+)
+
+// A LogLevelType defines the level logging should be performed at. Used to instruct
+// the SDK which statements should be logged.
+type LogLevelType uint
+
+// LogLevel returns the pointer to a LogLevel. Should be used to workaround
+// not being able to take the address of a non-composite literal.
+func LogLevel(l LogLevelType) *LogLevelType {
+	return &l
+}
+
+// Value returns the LogLevel value or the default value LogOff if the LogLevel
+// is nil. Safe to use on nil value LogLevelTypes.
+func (l *LogLevelType) Value() LogLevelType {
+	if l != nil {
+		return *l
+	}
+	return LogOff
+}
+
+// Matches returns true if the v LogLevel is enabled by this LogLevel. Should be
+// used with logging sub levels. Is safe to use on nil value LogLevelTypes. If
+// LogLevel is nil, will default to LogOff comparison.
+func (l *LogLevelType) Matches(v LogLevelType) bool {
+	c := l.Value()
+	return c&v == v
+}
+
+// AtLeast returns true if this LogLevel is at least high enough to satisfies v.
+// Is safe to use on nil value LogLevelTypes. If LogLevel is nil, will default
+// to LogOff comparison.
+func (l *LogLevelType) AtLeast(v LogLevelType) bool {
+	c := l.Value()
+	return c >= v
+}
+
+const (
+	// LogOff states that no logging should be performed by the SDK. This is the
+	// default state of the SDK, and should be use to disable all logging.
+	LogOff LogLevelType = iota * 0x1000
+
+	// LogDebug state that debug output should be logged by the SDK. This should
+	// be used to inspect request made and responses received.
+	LogDebug
+)
+
+// Debug Logging Sub Levels
+const (
+	// LogDebugWithSigning states that the SDK should log request signing and
+	// presigning events. This should be used to log the signing details of
+	// requests for debugging. Will also enable LogDebug.
+	LogDebugWithSigning LogLevelType = LogDebug | (1 << iota)
+
+	// LogDebugWithHTTPBody states the SDK should log HTTP request and response
+	// HTTP bodys in addition to the headers and path. This should be used to
+	// see the body content of requests and responses made while using the SDK
+	// Will also enable LogDebug.
+	LogDebugWithHTTPBody
+
+	// LogDebugWithRequestRetries states the SDK should log when service requests will
+	// be retried. This should be used to log when you want to log when service
+	// requests are being retried. Will also enable LogDebug.
+	LogDebugWithRequestRetries
+
+	// LogDebugWithRequestErrors states the SDK should log when service requests fail
+	// to build, send, validate, or unmarshal.
+	LogDebugWithRequestErrors
+
+	// LogDebugWithEventStreamBody states the SDK should log EventStream
+	// request and response bodys. This should be used to log the EventStream
+	// wire unmarshaled message content of requests and responses made while
+	// using the SDK Will also enable LogDebug.
+	LogDebugWithEventStreamBody
+)
+
+// A Logger is a minimalistic interface for the SDK to log messages to. Should
+// be used to provide custom logging writers for the SDK to use.
+type Logger interface {
+	Log(...interface{})
+}
+
+// A LoggerFunc is a convenience type to convert a function taking a variadic
+// list of arguments and wrap it so the Logger interface can be used.
+//
+// Example:
+//     s3.New(sess, &aws.Config{Logger: aws.LoggerFunc(func(args ...interface{}) {
+//         fmt.Fprintln(os.Stdout, args...)
+//     })})
+type LoggerFunc func(...interface{})
+
+// Log calls the wrapped function with the arguments provided
+func (f LoggerFunc) Log(args ...interface{}) {
+	f(args...)
+}
+
+// NewDefaultLogger returns a Logger which will write log messages to stdout, and
+// use same formatting runes as the stdlib log.Logger
+func NewDefaultLogger() Logger {
+	return &defaultLogger{
+		logger: log.New(os.Stdout, "", log.LstdFlags),
+	}
+}
+
+// A defaultLogger provides a minimalistic logger satisfying the Logger interface.
+type defaultLogger struct {
+	logger *log.Logger
+}
+
+// Log logs the parameters to the stdlib logger. See log.Println.
+func (l defaultLogger) Log(args ...interface{}) {
+	l.logger.Println(args...)
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go b/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go
new file mode 100644
index 000000000..271da432c
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go
@@ -0,0 +1,19 @@
+// +build !appengine,!plan9
+
+package request
+
+import (
+	"net"
+	"os"
+	"syscall"
+)
+
+func isErrConnectionReset(err error) bool {
+	if opErr, ok := err.(*net.OpError); ok {
+		if sysErr, ok := opErr.Err.(*os.SyscallError); ok {
+			return sysErr.Err == syscall.ECONNRESET
+		}
+	}
+
+	return false
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_other.go b/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_other.go
new file mode 100644
index 000000000..daf9eca43
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_other.go
@@ -0,0 +1,11 @@
+// +build appengine plan9
+
+package request
+
+import (
+	"strings"
+)
+
+func isErrConnectionReset(err error) bool {
+	return strings.Contains(err.Error(), "connection reset")
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go b/vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go
new file mode 100644
index 000000000..605a72d3c
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go
@@ -0,0 +1,274 @@
+package request
+
+import (
+	"fmt"
+	"strings"
+)
+
+// A Handlers provides a collection of request handlers for various
+// stages of handling requests.
+type Handlers struct {
+	Validate         HandlerList
+	Build            HandlerList
+	Sign             HandlerList
+	Send             HandlerList
+	ValidateResponse HandlerList
+	Unmarshal        HandlerList
+	UnmarshalStream  HandlerList
+	UnmarshalMeta    HandlerList
+	UnmarshalError   HandlerList
+	Retry            HandlerList
+	AfterRetry       HandlerList
+	Complete         HandlerList
+}
+
+// Copy returns of this handler's lists.
+func (h *Handlers) Copy() Handlers {
+	return Handlers{
+		Validate:         h.Validate.copy(),
+		Build:            h.Build.copy(),
+		Sign:             h.Sign.copy(),
+		Send:             h.Send.copy(),
+		ValidateResponse: h.ValidateResponse.copy(),
+		Unmarshal:        h.Unmarshal.copy(),
+		UnmarshalStream:  h.UnmarshalStream.copy(),
+		UnmarshalError:   h.UnmarshalError.copy(),
+		UnmarshalMeta:    h.UnmarshalMeta.copy(),
+		Retry:            h.Retry.copy(),
+		AfterRetry:       h.AfterRetry.copy(),
+		Complete:         h.Complete.copy(),
+	}
+}
+
+// Clear removes callback functions for all handlers
+func (h *Handlers) Clear() {
+	h.Validate.Clear()
+	h.Build.Clear()
+	h.Send.Clear()
+	h.Sign.Clear()
+	h.Unmarshal.Clear()
+	h.UnmarshalStream.Clear()
+	h.UnmarshalMeta.Clear()
+	h.UnmarshalError.Clear()
+	h.ValidateResponse.Clear()
+	h.Retry.Clear()
+	h.AfterRetry.Clear()
+	h.Complete.Clear()
+}
+
+// A HandlerListRunItem represents an entry in the HandlerList which
+// is being run.
+type HandlerListRunItem struct {
+	Index   int
+	Handler NamedHandler
+	Request *Request
+}
+
+// A HandlerList manages zero or more handlers in a list.
+type HandlerList struct {
+	list []NamedHandler
+
+	// Called after each request handler in the list is called. If set
+	// and the func returns true the HandlerList will continue to iterate
+	// over the request handlers. If false is returned the HandlerList
+	// will stop iterating.
+	//
+	// Should be used if extra logic to be performed between each handler
+	// in the list. This can be used to terminate a list's iteration
+	// based on a condition such as error like, HandlerListStopOnError.
+	// Or for logging like HandlerListLogItem.
+	AfterEachFn func(item HandlerListRunItem) bool
+}
+
+// A NamedHandler is a struct that contains a name and function callback.
+type NamedHandler struct {
+	Name string
+	Fn   func(*Request)
+}
+
+// copy creates a copy of the handler list.
+func (l *HandlerList) copy() HandlerList {
+	n := HandlerList{
+		AfterEachFn: l.AfterEachFn,
+	}
+	if len(l.list) == 0 {
+		return n
+	}
+
+	n.list = append(make([]NamedHandler, 0, len(l.list)), l.list...)
+	return n
+}
+
+// Clear clears the handler list.
+func (l *HandlerList) Clear() {
+	l.list = l.list[0:0]
+}
+
+// Len returns the number of handlers in the list.
+func (l *HandlerList) Len() int {
+	return len(l.list)
+}
+
+// PushBack pushes handler f to the back of the handler list.
+func (l *HandlerList) PushBack(f func(*Request)) {
+	l.PushBackNamed(NamedHandler{"__anonymous", f})
+}
+
+// PushBackNamed pushes named handler f to the back of the handler list.
+func (l *HandlerList) PushBackNamed(n NamedHandler) {
+	if cap(l.list) == 0 {
+		l.list = make([]NamedHandler, 0, 5)
+	}
+	l.list = append(l.list, n)
+}
+
+// PushFront pushes handler f to the front of the handler list.
+func (l *HandlerList) PushFront(f func(*Request)) {
+	l.PushFrontNamed(NamedHandler{"__anonymous", f})
+}
+
+// PushFrontNamed pushes named handler f to the front of the handler list.
+func (l *HandlerList) PushFrontNamed(n NamedHandler) {
+	if cap(l.list) == len(l.list) {
+		// Allocating new list required
+		l.list = append([]NamedHandler{n}, l.list...)
+	} else {
+		// Enough room to prepend into list.
+		l.list = append(l.list, NamedHandler{})
+		copy(l.list[1:], l.list)
+		l.list[0] = n
+	}
+}
+
+// Remove removes a NamedHandler n
+func (l *HandlerList) Remove(n NamedHandler) {
+	l.RemoveByName(n.Name)
+}
+
+// RemoveByName removes a NamedHandler by name.
+func (l *HandlerList) RemoveByName(name string) {
+	for i := 0; i < len(l.list); i++ {
+		m := l.list[i]
+		if m.Name == name {
+			// Shift array preventing creating new arrays
+			copy(l.list[i:], l.list[i+1:])
+			l.list[len(l.list)-1] = NamedHandler{}
+			l.list = l.list[:len(l.list)-1]
+
+			// decrement list so next check to length is correct
+			i--
+		}
+	}
+}
+
+// SwapNamed will swap out any existing handlers with the same name as the
+// passed in NamedHandler returning true if handlers were swapped. False is
+// returned otherwise.
+func (l *HandlerList) SwapNamed(n NamedHandler) (swapped bool) {
+	for i := 0; i < len(l.list); i++ {
+		if l.list[i].Name == n.Name {
+			l.list[i].Fn = n.Fn
+			swapped = true
+		}
+	}
+
+	return swapped
+}
+
+// Swap will swap out all handlers matching the name passed in. The matched
+// handlers will be swapped in. True is returned if the handlers were swapped.
+func (l *HandlerList) Swap(name string, replace NamedHandler) bool {
+	var swapped bool
+
+	for i := 0; i < len(l.list); i++ {
+		if l.list[i].Name == name {
+			l.list[i] = replace
+			swapped = true
+		}
+	}
+
+	return swapped
+}
+
+// SetBackNamed will replace the named handler if it exists in the handler list.
+// If the handler does not exist the handler will be added to the end of the list.
+func (l *HandlerList) SetBackNamed(n NamedHandler) {
+	if !l.SwapNamed(n) {
+		l.PushBackNamed(n)
+	}
+}
+
+// SetFrontNamed will replace the named handler if it exists in the handler list.
+// If the handler does not exist the handler will be added to the beginning of
+// the list.
+func (l *HandlerList) SetFrontNamed(n NamedHandler) {
+	if !l.SwapNamed(n) {
+		l.PushFrontNamed(n)
+	}
+}
+
+// Run executes all handlers in the list with a given request object.
+func (l *HandlerList) Run(r *Request) {
+	for i, h := range l.list {
+		h.Fn(r)
+		item := HandlerListRunItem{
+			Index: i, Handler: h, Request: r,
+		}
+		if l.AfterEachFn != nil && !l.AfterEachFn(item) {
+			return
+		}
+	}
+}
+
+// HandlerListLogItem logs the request handler and the state of the
+// request's Error value. Always returns true to continue iterating
+// request handlers in a HandlerList.
+func HandlerListLogItem(item HandlerListRunItem) bool {
+	if item.Request.Config.Logger == nil {
+		return true
+	}
+	item.Request.Config.Logger.Log("DEBUG: RequestHandler",
+		item.Index, item.Handler.Name, item.Request.Error)
+
+	return true
+}
+
+// HandlerListStopOnError returns false to stop the HandlerList iterating
+// over request handlers if Request.Error is not nil. True otherwise
+// to continue iterating.
+func HandlerListStopOnError(item HandlerListRunItem) bool {
+	return item.Request.Error == nil
+}
+
+// WithAppendUserAgent will add a string to the user agent prefixed with a
+// single white space.
+func WithAppendUserAgent(s string) Option {
+	return func(r *Request) {
+		r.Handlers.Build.PushBack(func(r2 *Request) {
+			AddToUserAgent(r, s)
+		})
+	}
+}
+
+// MakeAddToUserAgentHandler will add the name/version pair to the User-Agent request
+// header. If the extra parameters are provided they will be added as metadata to the
+// name/version pair resulting in the following format.
+// "name/version (extra0; extra1; ...)"
+// The user agent part will be concatenated with this current request's user agent string.
+func MakeAddToUserAgentHandler(name, version string, extra ...string) func(*Request) {
+	ua := fmt.Sprintf("%s/%s", name, version)
+	if len(extra) > 0 {
+		ua += fmt.Sprintf(" (%s)", strings.Join(extra, "; "))
+	}
+	return func(r *Request) {
+		AddToUserAgent(r, ua)
+	}
+}
+
+// MakeAddToUserAgentFreeFormHandler adds the input to the User-Agent request header.
+// The input string will be concatenated with the current request's user agent string.
+func MakeAddToUserAgentFreeFormHandler(s string) func(*Request) {
+	return func(r *Request) {
+		AddToUserAgent(r, s)
+	}
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go b/vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go
new file mode 100644
index 000000000..79f79602b
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go
@@ -0,0 +1,24 @@
+package request
+
+import (
+	"io"
+	"net/http"
+	"net/url"
+)
+
+func copyHTTPRequest(r *http.Request, body io.ReadCloser) *http.Request {
+	req := new(http.Request)
+	*req = *r
+	req.URL = &url.URL{}
+	*req.URL = *r.URL
+	req.Body = body
+
+	req.Header = http.Header{}
+	for k, v := range r.Header {
+		for _, vv := range v {
+			req.Header.Add(k, vv)
+		}
+	}
+
+	return req
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go b/vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go
new file mode 100644
index 000000000..b0c2ef4fe
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go
@@ -0,0 +1,60 @@
+package request
+
+import (
+	"io"
+	"sync"
+
+	"github.com/aws/aws-sdk-go/internal/sdkio"
+)
+
+// offsetReader is a thread-safe io.ReadCloser to prevent racing
+// with retrying requests
+type offsetReader struct {
+	buf    io.ReadSeeker
+	lock   sync.Mutex
+	closed bool
+}
+
+func newOffsetReader(buf io.ReadSeeker, offset int64) *offsetReader {
+	reader := &offsetReader{}
+	buf.Seek(offset, sdkio.SeekStart)
+
+	reader.buf = buf
+	return reader
+}
+
+// Close will close the instance of the offset reader's access to
+// the underlying io.ReadSeeker.
+func (o *offsetReader) Close() error {
+	o.lock.Lock()
+	defer o.lock.Unlock()
+	o.closed = true
+	return nil
+}
+
+// Read is a thread-safe read of the underlying io.ReadSeeker
+func (o *offsetReader) Read(p []byte) (int, error) {
+	o.lock.Lock()
+	defer o.lock.Unlock()
+
+	if o.closed {
+		return 0, io.EOF
+	}
+
+	return o.buf.Read(p)
+}
+
+// Seek is a thread-safe seeking operation.
+func (o *offsetReader) Seek(offset int64, whence int) (int64, error) {
+	o.lock.Lock()
+	defer o.lock.Unlock()
+
+	return o.buf.Seek(offset, whence)
+}
+
+// CloseAndCopy will return a new offsetReader with a copy of the old buffer
+// and close the old buffer.
+func (o *offsetReader) CloseAndCopy(offset int64) *offsetReader {
+	o.Close()
+	return newOffsetReader(o.buf, offset)
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request.go
new file mode 100644
index 000000000..75f0fe077
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request.go
@@ -0,0 +1,657 @@
+package request
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"net"
+	"net/http"
+	"net/url"
+	"reflect"
+	"strings"
+	"time"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/client/metadata"
+	"github.com/aws/aws-sdk-go/internal/sdkio"
+)
+
+const (
+	// ErrCodeSerialization is the serialization error code that is received
+	// during protocol unmarshaling.
+	ErrCodeSerialization = "SerializationError"
+
+	// ErrCodeRead is an error that is returned during HTTP reads.
+	ErrCodeRead = "ReadError"
+
+	// ErrCodeResponseTimeout is the connection timeout error that is received
+	// during body reads.
+	ErrCodeResponseTimeout = "ResponseTimeout"
+
+	// ErrCodeInvalidPresignExpire is returned when the expire time provided to
+	// presign is invalid
+	ErrCodeInvalidPresignExpire = "InvalidPresignExpireError"
+
+	// CanceledErrorCode is the error code that will be returned by an
+	// API request that was canceled. Requests given a aws.Context may
+	// return this error when canceled.
+	CanceledErrorCode = "RequestCanceled"
+)
+
+// A Request is the service request to be made.
+type Request struct {
+	Config     aws.Config
+	ClientInfo metadata.ClientInfo
+	Handlers   Handlers
+
+	Retryer
+	AttemptTime            time.Time
+	Time                   time.Time
+	Operation              *Operation
+	HTTPRequest            *http.Request
+	HTTPResponse           *http.Response
+	Body                   io.ReadSeeker
+	BodyStart              int64 // offset from beginning of Body that the request body starts
+	Params                 interface{}
+	Error                  error
+	Data                   interface{}
+	RequestID              string
+	RetryCount             int
+	Retryable              *bool
+	RetryDelay             time.Duration
+	NotHoist               bool
+	SignedHeaderVals       http.Header
+	LastSignedAt           time.Time
+	DisableFollowRedirects bool
+
+	// A value greater than 0 instructs the request to be signed as Presigned URL
+	// You should not set this field directly. Instead use Request's
+	// Presign or PresignRequest methods.
+	ExpireTime time.Duration
+
+	context aws.Context
+
+	built bool
+
+	// Need to persist an intermediate body between the input Body and HTTP
+	// request body because the HTTP Client's transport can maintain a reference
+	// to the HTTP request's body after the client has returned. This value is
+	// safe to use concurrently and wrap the input Body for each HTTP request.
+	safeBody *offsetReader
+}
+
+// An Operation is the service API operation to be made.
+type Operation struct {
+	Name       string
+	HTTPMethod string
+	HTTPPath   string
+	*Paginator
+
+	BeforePresignFn func(r *Request) error
+}
+
+// New returns a new Request pointer for the service API
+// operation and parameters.
+//
+// Params is any value of input parameters to be the request payload.
+// Data is pointer value to an object which the request's response
+// payload will be deserialized to.
+func New(cfg aws.Config, clientInfo metadata.ClientInfo, handlers Handlers,
+	retryer Retryer, operation *Operation, params interface{}, data interface{}) *Request {
+
+	method := operation.HTTPMethod
+	if method == "" {
+		method = "POST"
+	}
+
+	httpReq, _ := http.NewRequest(method, "", nil)
+
+	var err error
+	httpReq.URL, err = url.Parse(clientInfo.Endpoint + operation.HTTPPath)
+	if err != nil {
+		httpReq.URL = &url.URL{}
+		err = awserr.New("InvalidEndpointURL", "invalid endpoint uri", err)
+	}
+
+	SanitizeHostForHeader(httpReq)
+
+	r := &Request{
+		Config:     cfg,
+		ClientInfo: clientInfo,
+		Handlers:   handlers.Copy(),
+
+		Retryer:     retryer,
+		AttemptTime: time.Now(),
+		Time:        time.Now(),
+		ExpireTime:  0,
+		Operation:   operation,
+		HTTPRequest: httpReq,
+		Body:        nil,
+		Params:      params,
+		Error:       err,
+		Data:        data,
+	}
+	r.SetBufferBody([]byte{})
+
+	return r
+}
+
+// A Option is a functional option that can augment or modify a request when
+// using a WithContext API operation method.
+type Option func(*Request)
+
+// WithGetResponseHeader builds a request Option which will retrieve a single
+// header value from the HTTP Response. If there are multiple values for the
+// header key use WithGetResponseHeaders instead to access the http.Header
+// map directly. The passed in val pointer must be non-nil.
+//
+// This Option can be used multiple times with a single API operation.
+//
+//    var id2, versionID string
+//    svc.PutObjectWithContext(ctx, params,
+//        request.WithGetResponseHeader("x-amz-id-2", &id2),
+//        request.WithGetResponseHeader("x-amz-version-id", &versionID),
+//    )
+func WithGetResponseHeader(key string, val *string) Option {
+	return func(r *Request) {
+		r.Handlers.Complete.PushBack(func(req *Request) {
+			*val = req.HTTPResponse.Header.Get(key)
+		})
+	}
+}
+
+// WithGetResponseHeaders builds a request Option which will retrieve the
+// headers from the HTTP response and assign them to the passed in headers
+// variable. The passed in headers pointer must be non-nil.
+//
+//    var headers http.Header
+//    svc.PutObjectWithContext(ctx, params, request.WithGetResponseHeaders(&headers))
+func WithGetResponseHeaders(headers *http.Header) Option {
+	return func(r *Request) {
+		r.Handlers.Complete.PushBack(func(req *Request) {
+			*headers = req.HTTPResponse.Header
+		})
+	}
+}
+
+// WithLogLevel is a request option that will set the request to use a specific
+// log level when the request is made.
+//
+//     svc.PutObjectWithContext(ctx, params, request.WithLogLevel(aws.LogDebugWithHTTPBody)
+func WithLogLevel(l aws.LogLevelType) Option {
+	return func(r *Request) {
+		r.Config.LogLevel = aws.LogLevel(l)
+	}
+}
+
+// ApplyOptions will apply each option to the request calling them in the order
+// the were provided.
+func (r *Request) ApplyOptions(opts ...Option) {
+	for _, opt := range opts {
+		opt(r)
+	}
+}
+
+// Context will always returns a non-nil context. If Request does not have a
+// context aws.BackgroundContext will be returned.
+func (r *Request) Context() aws.Context {
+	if r.context != nil {
+		return r.context
+	}
+	return aws.BackgroundContext()
+}
+
+// SetContext adds a Context to the current request that can be used to cancel
+// a in-flight request. The Context value must not be nil, or this method will
+// panic.
+//
+// Unlike http.Request.WithContext, SetContext does not return a copy of the
+// Request. It is not safe to use use a single Request value for multiple
+// requests. A new Request should be created for each API operation request.
+//
+// Go 1.6 and below:
+// The http.Request's Cancel field will be set to the Done() value of
+// the context. This will overwrite the Cancel field's value.
+//
+// Go 1.7 and above:
+// The http.Request.WithContext will be used to set the context on the underlying
+// http.Request. This will create a shallow copy of the http.Request. The SDK
+// may create sub contexts in the future for nested requests such as retries.
+func (r *Request) SetContext(ctx aws.Context) {
+	if ctx == nil {
+		panic("context cannot be nil")
+	}
+	setRequestContext(r, ctx)
+}
+
+// WillRetry returns if the request's can be retried.
+func (r *Request) WillRetry() bool {
+	if !aws.IsReaderSeekable(r.Body) && r.HTTPRequest.Body != NoBody {
+		return false
+	}
+	return r.Error != nil && aws.BoolValue(r.Retryable) && r.RetryCount < r.MaxRetries()
+}
+
+// ParamsFilled returns if the request's parameters have been populated
+// and the parameters are valid. False is returned if no parameters are
+// provided or invalid.
+func (r *Request) ParamsFilled() bool {
+	return r.Params != nil && reflect.ValueOf(r.Params).Elem().IsValid()
+}
+
+// DataFilled returns true if the request's data for response deserialization
+// target has been set and is a valid. False is returned if data is not
+// set, or is invalid.
+func (r *Request) DataFilled() bool {
+	return r.Data != nil && reflect.ValueOf(r.Data).Elem().IsValid()
+}
+
+// SetBufferBody will set the request's body bytes that will be sent to
+// the service API.
+func (r *Request) SetBufferBody(buf []byte) {
+	r.SetReaderBody(bytes.NewReader(buf))
+}
+
+// SetStringBody sets the body of the request to be backed by a string.
+func (r *Request) SetStringBody(s string) {
+	r.SetReaderBody(strings.NewReader(s))
+}
+
+// SetReaderBody will set the request's body reader.
+func (r *Request) SetReaderBody(reader io.ReadSeeker) {
+	r.Body = reader
+	r.BodyStart, _ = reader.Seek(0, sdkio.SeekCurrent) // Get the Bodies current offset.
+	r.ResetBody()
+}
+
+// Presign returns the request's signed URL. Error will be returned
+// if the signing fails.
+//
+// It is invalid to create a presigned URL with a expire duration 0 or less. An
+// error is returned if expire duration is 0 or less.
+func (r *Request) Presign(expire time.Duration) (string, error) {
+	r = r.copy()
+
+	// Presign requires all headers be hoisted. There is no way to retrieve
+	// the signed headers not hoisted without this. Making the presigned URL
+	// useless.
+	r.NotHoist = false
+
+	u, _, err := getPresignedURL(r, expire)
+	return u, err
+}
+
+// PresignRequest behaves just like presign, with the addition of returning a
+// set of headers that were signed.
+//
+// It is invalid to create a presigned URL with a expire duration 0 or less. An
+// error is returned if expire duration is 0 or less.
+//
+// Returns the URL string for the API operation with signature in the query string,
+// and the HTTP headers that were included in the signature. These headers must
+// be included in any HTTP request made with the presigned URL.
+//
+// To prevent hoisting any headers to the query string set NotHoist to true on
+// this Request value prior to calling PresignRequest.
+func (r *Request) PresignRequest(expire time.Duration) (string, http.Header, error) {
+	r = r.copy()
+	return getPresignedURL(r, expire)
+}
+
+// IsPresigned returns true if the request represents a presigned API url.
+func (r *Request) IsPresigned() bool {
+	return r.ExpireTime != 0
+}
+
+func getPresignedURL(r *Request, expire time.Duration) (string, http.Header, error) {
+	if expire <= 0 {
+		return "", nil, awserr.New(
+			ErrCodeInvalidPresignExpire,
+			"presigned URL requires an expire duration greater than 0",
+			nil,
+		)
+	}
+
+	r.ExpireTime = expire
+
+	if r.Operation.BeforePresignFn != nil {
+		if err := r.Operation.BeforePresignFn(r); err != nil {
+			return "", nil, err
+		}
+	}
+
+	if err := r.Sign(); err != nil {
+		return "", nil, err
+	}
+
+	return r.HTTPRequest.URL.String(), r.SignedHeaderVals, nil
+}
+
+func debugLogReqError(r *Request, stage string, retrying bool, err error) {
+	if !r.Config.LogLevel.Matches(aws.LogDebugWithRequestErrors) {
+		return
+	}
+
+	retryStr := "not retrying"
+	if retrying {
+		retryStr = "will retry"
+	}
+
+	r.Config.Logger.Log(fmt.Sprintf("DEBUG: %s %s/%s failed, %s, error %v",
+		stage, r.ClientInfo.ServiceName, r.Operation.Name, retryStr, err))
+}
+
+// Build will build the request's object so it can be signed and sent
+// to the service. Build will also validate all the request's parameters.
+// Any additional build Handlers set on this request will be run
+// in the order they were set.
+//
+// The request will only be built once. Multiple calls to build will have
+// no effect.
+//
+// If any Validate or Build errors occur the build will stop and the error
+// which occurred will be returned.
+func (r *Request) Build() error {
+	if !r.built {
+		r.Handlers.Validate.Run(r)
+		if r.Error != nil {
+			debugLogReqError(r, "Validate Request", false, r.Error)
+			return r.Error
+		}
+		r.Handlers.Build.Run(r)
+		if r.Error != nil {
+			debugLogReqError(r, "Build Request", false, r.Error)
+			return r.Error
+		}
+		r.built = true
+	}
+
+	return r.Error
+}
+
+// Sign will sign the request, returning error if errors are encountered.
+//
+// Sign will build the request prior to signing. All Sign Handlers will
+// be executed in the order they were set.
+func (r *Request) Sign() error {
+	r.Build()
+	if r.Error != nil {
+		debugLogReqError(r, "Build Request", false, r.Error)
+		return r.Error
+	}
+
+	r.Handlers.Sign.Run(r)
+	return r.Error
+}
+
+func (r *Request) getNextRequestBody() (io.ReadCloser, error) {
+	if r.safeBody != nil {
+		r.safeBody.Close()
+	}
+
+	r.safeBody = newOffsetReader(r.Body, r.BodyStart)
+
+	// Go 1.8 tightened and clarified the rules code needs to use when building
+	// requests with the http package. Go 1.8 removed the automatic detection
+	// of if the Request.Body was empty, or actually had bytes in it. The SDK
+	// always sets the Request.Body even if it is empty and should not actually
+	// be sent. This is incorrect.
+	//
+	// Go 1.8 did add a http.NoBody value that the SDK can use to tell the http
+	// client that the request really should be sent without a body. The
+	// Request.Body cannot be set to nil, which is preferable, because the
+	// field is exported and could introduce nil pointer dereferences for users
+	// of the SDK if they used that field.
+	//
+	// Related golang/go#18257
+	l, err := aws.SeekerLen(r.Body)
+	if err != nil {
+		return nil, awserr.New(ErrCodeSerialization, "failed to compute request body size", err)
+	}
+
+	var body io.ReadCloser
+	if l == 0 {
+		body = NoBody
+	} else if l > 0 {
+		body = r.safeBody
+	} else {
+		// Hack to prevent sending bodies for methods where the body
+		// should be ignored by the server. Sending bodies on these
+		// methods without an associated ContentLength will cause the
+		// request to socket timeout because the server does not handle
+		// Transfer-Encoding: chunked bodies for these methods.
+		//
+		// This would only happen if a aws.ReaderSeekerCloser was used with
+		// a io.Reader that was not also an io.Seeker, or did not implement
+		// Len() method.
+		switch r.Operation.HTTPMethod {
+		case "GET", "HEAD", "DELETE":
+			body = NoBody
+		default:
+			body = r.safeBody
+		}
+	}
+
+	return body, nil
+}
+
+// GetBody will return an io.ReadSeeker of the Request's underlying
+// input body with a concurrency safe wrapper.
+func (r *Request) GetBody() io.ReadSeeker {
+	return r.safeBody
+}
+
+// Send will send the request, returning error if errors are encountered.
+//
+// Send will sign the request prior to sending. All Send Handlers will
+// be executed in the order they were set.
+//
+// Canceling a request is non-deterministic. If a request has been canceled,
+// then the transport will choose, randomly, one of the state channels during
+// reads or getting the connection.
+//
+// readLoop() and getConn(req *Request, cm connectMethod)
+// https://github.com/golang/go/blob/master/src/net/http/transport.go
+//
+// Send will not close the request.Request's body.
+func (r *Request) Send() error {
+	defer func() {
+		// Regardless of success or failure of the request trigger the Complete
+		// request handlers.
+		r.Handlers.Complete.Run(r)
+	}()
+
+	for {
+		r.AttemptTime = time.Now()
+		if aws.BoolValue(r.Retryable) {
+			if r.Config.LogLevel.Matches(aws.LogDebugWithRequestRetries) {
+				r.Config.Logger.Log(fmt.Sprintf("DEBUG: Retrying Request %s/%s, attempt %d",
+					r.ClientInfo.ServiceName, r.Operation.Name, r.RetryCount))
+			}
+
+			// The previous http.Request will have a reference to the r.Body
+			// and the HTTP Client's Transport may still be reading from
+			// the request's body even though the Client's Do returned.
+			r.HTTPRequest = copyHTTPRequest(r.HTTPRequest, nil)
+			r.ResetBody()
+
+			// Closing response body to ensure that no response body is leaked
+			// between retry attempts.
+			if r.HTTPResponse != nil && r.HTTPResponse.Body != nil {
+				r.HTTPResponse.Body.Close()
+			}
+		}
+
+		r.Sign()
+		if r.Error != nil {
+			return r.Error
+		}
+
+		r.Retryable = nil
+
+		r.Handlers.Send.Run(r)
+		if r.Error != nil {
+			if !shouldRetryCancel(r) {
+				return r.Error
+			}
+
+			err := r.Error
+			r.Handlers.Retry.Run(r)
+			r.Handlers.AfterRetry.Run(r)
+			if r.Error != nil {
+				debugLogReqError(r, "Send Request", false, err)
+				return r.Error
+			}
+			debugLogReqError(r, "Send Request", true, err)
+			continue
+		}
+		r.Handlers.UnmarshalMeta.Run(r)
+		r.Handlers.ValidateResponse.Run(r)
+		if r.Error != nil {
+			r.Handlers.UnmarshalError.Run(r)
+			err := r.Error
+
+			r.Handlers.Retry.Run(r)
+			r.Handlers.AfterRetry.Run(r)
+			if r.Error != nil {
+				debugLogReqError(r, "Validate Response", false, err)
+				return r.Error
+			}
+			debugLogReqError(r, "Validate Response", true, err)
+			continue
+		}
+
+		r.Handlers.Unmarshal.Run(r)
+		if r.Error != nil {
+			err := r.Error
+			r.Handlers.Retry.Run(r)
+			r.Handlers.AfterRetry.Run(r)
+			if r.Error != nil {
+				debugLogReqError(r, "Unmarshal Response", false, err)
+				return r.Error
+			}
+			debugLogReqError(r, "Unmarshal Response", true, err)
+			continue
+		}
+
+		break
+	}
+
+	return nil
+}
+
+// copy will copy a request which will allow for local manipulation of the
+// request.
+func (r *Request) copy() *Request {
+	req := &Request{}
+	*req = *r
+	req.Handlers = r.Handlers.Copy()
+	op := *r.Operation
+	req.Operation = &op
+	return req
+}
+
+// AddToUserAgent adds the string to the end of the request's current user agent.
+func AddToUserAgent(r *Request, s string) {
+	curUA := r.HTTPRequest.Header.Get("User-Agent")
+	if len(curUA) > 0 {
+		s = curUA + " " + s
+	}
+	r.HTTPRequest.Header.Set("User-Agent", s)
+}
+
+func shouldRetryCancel(r *Request) bool {
+	awsErr, ok := r.Error.(awserr.Error)
+	timeoutErr := false
+	errStr := r.Error.Error()
+	if ok {
+		if awsErr.Code() == CanceledErrorCode {
+			return false
+		}
+		err := awsErr.OrigErr()
+		netErr, netOK := err.(net.Error)
+		timeoutErr = netOK && netErr.Temporary()
+		if urlErr, ok := err.(*url.Error); !timeoutErr && ok {
+			errStr = urlErr.Err.Error()
+		}
+	}
+
+	// There can be two types of canceled errors here.
+	// The first being a net.Error and the other being an error.
+	// If the request was timed out, we want to continue the retry
+	// process. Otherwise, return the canceled error.
+	return timeoutErr ||
+		(errStr != "net/http: request canceled" &&
+			errStr != "net/http: request canceled while waiting for connection")
+
+}
+
+// SanitizeHostForHeader removes default port from host and updates request.Host
+func SanitizeHostForHeader(r *http.Request) {
+	host := getHost(r)
+	port := portOnly(host)
+	if port != "" && isDefaultPort(r.URL.Scheme, port) {
+		r.Host = stripPort(host)
+	}
+}
+
+// Returns host from request
+func getHost(r *http.Request) string {
+	if r.Host != "" {
+		return r.Host
+	}
+
+	return r.URL.Host
+}
+
+// Hostname returns u.Host, without any port number.
+//
+// If Host is an IPv6 literal with a port number, Hostname returns the
+// IPv6 literal without the square brackets. IPv6 literals may include
+// a zone identifier.
+//
+// Copied from the Go 1.8 standard library (net/url)
+func stripPort(hostport string) string {
+	colon := strings.IndexByte(hostport, ':')
+	if colon == -1 {
+		return hostport
+	}
+	if i := strings.IndexByte(hostport, ']'); i != -1 {
+		return strings.TrimPrefix(hostport[:i], "[")
+	}
+	return hostport[:colon]
+}
+
+// Port returns the port part of u.Host, without the leading colon.
+// If u.Host doesn't contain a port, Port returns an empty string.
+//
+// Copied from the Go 1.8 standard library (net/url)
+func portOnly(hostport string) string {
+	colon := strings.IndexByte(hostport, ':')
+	if colon == -1 {
+		return ""
+	}
+	if i := strings.Index(hostport, "]:"); i != -1 {
+		return hostport[i+len("]:"):]
+	}
+	if strings.Contains(hostport, "]") {
+		return ""
+	}
+	return hostport[colon+len(":"):]
+}
+
+// Returns true if the specified URI is using the standard port
+// (i.e. port 80 for HTTP URIs or 443 for HTTPS URIs)
+func isDefaultPort(scheme, port string) bool {
+	if port == "" {
+		return true
+	}
+
+	lowerCaseScheme := strings.ToLower(scheme)
+	if (lowerCaseScheme == "http" && port == "80") || (lowerCaseScheme == "https" && port == "443") {
+		return true
+	}
+
+	return false
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_1_7.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_1_7.go
new file mode 100644
index 000000000..e36e468b7
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_1_7.go
@@ -0,0 +1,39 @@
+// +build !go1.8
+
+package request
+
+import "io"
+
+// NoBody is an io.ReadCloser with no bytes. Read always returns EOF
+// and Close always returns nil. It can be used in an outgoing client
+// request to explicitly signal that a request has zero bytes.
+// An alternative, however, is to simply set Request.Body to nil.
+//
+// Copy of Go 1.8 NoBody type from net/http/http.go
+type noBody struct{}
+
+func (noBody) Read([]byte) (int, error)         { return 0, io.EOF }
+func (noBody) Close() error                     { return nil }
+func (noBody) WriteTo(io.Writer) (int64, error) { return 0, nil }
+
+// NoBody is an empty reader that will trigger the Go HTTP client to not include
+// and body in the HTTP request.
+var NoBody = noBody{}
+
+// ResetBody rewinds the request body back to its starting position, and
+// sets the HTTP Request body reference. When the body is read prior
+// to being sent in the HTTP request it will need to be rewound.
+//
+// ResetBody will automatically be called by the SDK's build handler, but if
+// the request is being used directly ResetBody must be called before the request
+// is Sent.  SetStringBody, SetBufferBody, and SetReaderBody will automatically
+// call ResetBody.
+func (r *Request) ResetBody() {
+	body, err := r.getNextRequestBody()
+	if err != nil {
+		r.Error = err
+		return
+	}
+
+	r.HTTPRequest.Body = body
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_1_8.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_1_8.go
new file mode 100644
index 000000000..7c6a8000f
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_1_8.go
@@ -0,0 +1,33 @@
+// +build go1.8
+
+package request
+
+import (
+	"net/http"
+)
+
+// NoBody is a http.NoBody reader instructing Go HTTP client to not include
+// and body in the HTTP request.
+var NoBody = http.NoBody
+
+// ResetBody rewinds the request body back to its starting position, and
+// sets the HTTP Request body reference. When the body is read prior
+// to being sent in the HTTP request it will need to be rewound.
+//
+// ResetBody will automatically be called by the SDK's build handler, but if
+// the request is being used directly ResetBody must be called before the request
+// is Sent.  SetStringBody, SetBufferBody, and SetReaderBody will automatically
+// call ResetBody.
+//
+// Will also set the Go 1.8's http.Request.GetBody member to allow retrying
+// PUT/POST redirects.
+func (r *Request) ResetBody() {
+	body, err := r.getNextRequestBody()
+	if err != nil {
+		r.Error = err
+		return
+	}
+
+	r.HTTPRequest.Body = body
+	r.HTTPRequest.GetBody = r.getNextRequestBody
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_context.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_context.go
new file mode 100644
index 000000000..a7365cd1e
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_context.go
@@ -0,0 +1,14 @@
+// +build go1.7
+
+package request
+
+import "github.com/aws/aws-sdk-go/aws"
+
+// setContext updates the Request to use the passed in context for cancellation.
+// Context will also be used for request retry delay.
+//
+// Creates shallow copy of the http.Request with the WithContext method.
+func setRequestContext(r *Request, ctx aws.Context) {
+	r.context = ctx
+	r.HTTPRequest = r.HTTPRequest.WithContext(ctx)
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_context_1_6.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_context_1_6.go
new file mode 100644
index 000000000..307fa0705
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_context_1_6.go
@@ -0,0 +1,14 @@
+// +build !go1.7
+
+package request
+
+import "github.com/aws/aws-sdk-go/aws"
+
+// setContext updates the Request to use the passed in context for cancellation.
+// Context will also be used for request retry delay.
+//
+// Creates shallow copy of the http.Request with the WithContext method.
+func setRequestContext(r *Request, ctx aws.Context) {
+	r.context = ctx
+	r.HTTPRequest.Cancel = ctx.Done()
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go
new file mode 100644
index 000000000..a633ed5ac
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go
@@ -0,0 +1,264 @@
+package request
+
+import (
+	"reflect"
+	"sync/atomic"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awsutil"
+)
+
+// A Pagination provides paginating of SDK API operations which are paginatable.
+// Generally you should not use this type directly, but use the "Pages" API
+// operations method to automatically perform pagination for you. Such as,
+// "S3.ListObjectsPages", and "S3.ListObjectsPagesWithContext" methods.
+//
+// Pagination differs from a Paginator type in that pagination is the type that
+// does the pagination between API operations, and Paginator defines the
+// configuration that will be used per page request.
+//
+//     cont := true
+//     for p.Next() && cont {
+//         data := p.Page().(*s3.ListObjectsOutput)
+//         // process the page's data
+//     }
+//     return p.Err()
+//
+// See service client API operation Pages methods for examples how the SDK will
+// use the Pagination type.
+type Pagination struct {
+	// Function to return a Request value for each pagination request.
+	// Any configuration or handlers that need to be applied to the request
+	// prior to getting the next page should be done here before the request
+	// returned.
+	//
+	// NewRequest should always be built from the same API operations. It is
+	// undefined if different API operations are returned on subsequent calls.
+	NewRequest func() (*Request, error)
+	// EndPageOnSameToken, when enabled, will allow the paginator to stop on
+	// token that are the same as its previous tokens.
+	EndPageOnSameToken bool
+
+	started    bool
+	prevTokens []interface{}
+	nextTokens []interface{}
+
+	err     error
+	curPage interface{}
+}
+
+// HasNextPage will return true if Pagination is able to determine that the API
+// operation has additional pages. False will be returned if there are no more
+// pages remaining.
+//
+// Will always return true if Next has not been called yet.
+func (p *Pagination) HasNextPage() bool {
+	if !p.started {
+		return true
+	}
+
+	hasNextPage := len(p.nextTokens) != 0
+	if p.EndPageOnSameToken {
+		return hasNextPage && !awsutil.DeepEqual(p.nextTokens, p.prevTokens)
+	}
+	return hasNextPage
+}
+
+// Err returns the error Pagination encountered when retrieving the next page.
+func (p *Pagination) Err() error {
+	return p.err
+}
+
+// Page returns the current page. Page should only be called after a successful
+// call to Next. It is undefined what Page will return if Page is called after
+// Next returns false.
+func (p *Pagination) Page() interface{} {
+	return p.curPage
+}
+
+// Next will attempt to retrieve the next page for the API operation. When a page
+// is retrieved true will be returned. If the page cannot be retrieved, or there
+// are no more pages false will be returned.
+//
+// Use the Page method to retrieve the current page data. The data will need
+// to be cast to the API operation's output type.
+//
+// Use the Err method to determine if an error occurred if Page returns false.
+func (p *Pagination) Next() bool {
+	if !p.HasNextPage() {
+		return false
+	}
+
+	req, err := p.NewRequest()
+	if err != nil {
+		p.err = err
+		return false
+	}
+
+	if p.started {
+		for i, intok := range req.Operation.InputTokens {
+			awsutil.SetValueAtPath(req.Params, intok, p.nextTokens[i])
+		}
+	}
+	p.started = true
+
+	err = req.Send()
+	if err != nil {
+		p.err = err
+		return false
+	}
+
+	p.prevTokens = p.nextTokens
+	p.nextTokens = req.nextPageTokens()
+	p.curPage = req.Data
+
+	return true
+}
+
+// A Paginator is the configuration data that defines how an API operation
+// should be paginated. This type is used by the API service models to define
+// the generated pagination config for service APIs.
+//
+// The Pagination type is what provides iterating between pages of an API. It
+// is only used to store the token metadata the SDK should use for performing
+// pagination.
+type Paginator struct {
+	InputTokens     []string
+	OutputTokens    []string
+	LimitToken      string
+	TruncationToken string
+}
+
+// nextPageTokens returns the tokens to use when asking for the next page of data.
+func (r *Request) nextPageTokens() []interface{} {
+	if r.Operation.Paginator == nil {
+		return nil
+	}
+	if r.Operation.TruncationToken != "" {
+		tr, _ := awsutil.ValuesAtPath(r.Data, r.Operation.TruncationToken)
+		if len(tr) == 0 {
+			return nil
+		}
+
+		switch v := tr[0].(type) {
+		case *bool:
+			if !aws.BoolValue(v) {
+				return nil
+			}
+		case bool:
+			if v == false {
+				return nil
+			}
+		}
+	}
+
+	tokens := []interface{}{}
+	tokenAdded := false
+	for _, outToken := range r.Operation.OutputTokens {
+		vs, _ := awsutil.ValuesAtPath(r.Data, outToken)
+		if len(vs) == 0 {
+			tokens = append(tokens, nil)
+			continue
+		}
+		v := vs[0]
+
+		switch tv := v.(type) {
+		case *string:
+			if len(aws.StringValue(tv)) == 0 {
+				tokens = append(tokens, nil)
+				continue
+			}
+		case string:
+			if len(tv) == 0 {
+				tokens = append(tokens, nil)
+				continue
+			}
+		}
+
+		tokenAdded = true
+		tokens = append(tokens, v)
+	}
+	if !tokenAdded {
+		return nil
+	}
+
+	return tokens
+}
+
+// Ensure a deprecated item is only logged once instead of each time its used.
+func logDeprecatedf(logger aws.Logger, flag *int32, msg string) {
+	if logger == nil {
+		return
+	}
+	if atomic.CompareAndSwapInt32(flag, 0, 1) {
+		logger.Log(msg)
+	}
+}
+
+var (
+	logDeprecatedHasNextPage int32
+	logDeprecatedNextPage    int32
+	logDeprecatedEachPage    int32
+)
+
+// HasNextPage returns true if this request has more pages of data available.
+//
+// Deprecated Use Pagination type for configurable pagination of API operations
+func (r *Request) HasNextPage() bool {
+	logDeprecatedf(r.Config.Logger, &logDeprecatedHasNextPage,
+		"Request.HasNextPage deprecated. Use Pagination type for configurable pagination of API operations")
+
+	return len(r.nextPageTokens()) > 0
+}
+
+// NextPage returns a new Request that can be executed to return the next
+// page of result data. Call .Send() on this request to execute it.
+//
+// Deprecated Use Pagination type for configurable pagination of API operations
+func (r *Request) NextPage() *Request {
+	logDeprecatedf(r.Config.Logger, &logDeprecatedNextPage,
+		"Request.NextPage deprecated. Use Pagination type for configurable pagination of API operations")
+
+	tokens := r.nextPageTokens()
+	if len(tokens) == 0 {
+		return nil
+	}
+
+	data := reflect.New(reflect.TypeOf(r.Data).Elem()).Interface()
+	nr := New(r.Config, r.ClientInfo, r.Handlers, r.Retryer, r.Operation, awsutil.CopyOf(r.Params), data)
+	for i, intok := range nr.Operation.InputTokens {
+		awsutil.SetValueAtPath(nr.Params, intok, tokens[i])
+	}
+	return nr
+}
+
+// EachPage iterates over each page of a paginated request object. The fn
+// parameter should be a function with the following sample signature:
+//
+//   func(page *T, lastPage bool) bool {
+//       return true // return false to stop iterating
+//   }
+//
+// Where "T" is the structure type matching the output structure of the given
+// operation. For example, a request object generated by
+// DynamoDB.ListTablesRequest() would expect to see dynamodb.ListTablesOutput
+// as the structure "T". The lastPage value represents whether the page is
+// the last page of data or not. The return value of this function should
+// return true to keep iterating or false to stop.
+//
+// Deprecated Use Pagination type for configurable pagination of API operations
+func (r *Request) EachPage(fn func(data interface{}, isLastPage bool) (shouldContinue bool)) error {
+	logDeprecatedf(r.Config.Logger, &logDeprecatedEachPage,
+		"Request.EachPage deprecated. Use Pagination type for configurable pagination of API operations")
+
+	for page := r; page != nil; page = page.NextPage() {
+		if err := page.Send(); err != nil {
+			return err
+		}
+		if getNextPage := fn(page.Data, !page.HasNextPage()); !getNextPage {
+			return page.Error
+		}
+	}
+
+	return nil
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go b/vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go
new file mode 100644
index 000000000..7d5270298
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go
@@ -0,0 +1,161 @@
+package request
+
+import (
+	"time"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awserr"
+)
+
+// Retryer is an interface to control retry logic for a given service.
+// The default implementation used by most services is the client.DefaultRetryer
+// structure, which contains basic retry logic using exponential backoff.
+type Retryer interface {
+	RetryRules(*Request) time.Duration
+	ShouldRetry(*Request) bool
+	MaxRetries() int
+}
+
+// WithRetryer sets a config Retryer value to the given Config returning it
+// for chaining.
+func WithRetryer(cfg *aws.Config, retryer Retryer) *aws.Config {
+	cfg.Retryer = retryer
+	return cfg
+}
+
+// retryableCodes is a collection of service response codes which are retry-able
+// without any further action.
+var retryableCodes = map[string]struct{}{
+	"RequestError":            {},
+	"RequestTimeout":          {},
+	ErrCodeResponseTimeout:    {},
+	"RequestTimeoutException": {}, // Glacier's flavor of RequestTimeout
+}
+
+var throttleCodes = map[string]struct{}{
+	"ProvisionedThroughputExceededException": {},
+	"Throttling":                             {},
+	"ThrottlingException":                    {},
+	"RequestLimitExceeded":                   {},
+	"RequestThrottled":                       {},
+	"TooManyRequestsException":               {}, // Lambda functions
+	"PriorRequestNotComplete":                {}, // Route53
+}
+
+// credsExpiredCodes is a collection of error codes which signify the credentials
+// need to be refreshed. Expired tokens require refreshing of credentials, and
+// resigning before the request can be retried.
+var credsExpiredCodes = map[string]struct{}{
+	"ExpiredToken":          {},
+	"ExpiredTokenException": {},
+	"RequestExpired":        {}, // EC2 Only
+}
+
+func isCodeThrottle(code string) bool {
+	_, ok := throttleCodes[code]
+	return ok
+}
+
+func isCodeRetryable(code string) bool {
+	if _, ok := retryableCodes[code]; ok {
+		return true
+	}
+
+	return isCodeExpiredCreds(code)
+}
+
+func isCodeExpiredCreds(code string) bool {
+	_, ok := credsExpiredCodes[code]
+	return ok
+}
+
+var validParentCodes = map[string]struct{}{
+	ErrCodeSerialization: {},
+	ErrCodeRead:          {},
+}
+
+type temporaryError interface {
+	Temporary() bool
+}
+
+func isNestedErrorRetryable(parentErr awserr.Error) bool {
+	if parentErr == nil {
+		return false
+	}
+
+	if _, ok := validParentCodes[parentErr.Code()]; !ok {
+		return false
+	}
+
+	err := parentErr.OrigErr()
+	if err == nil {
+		return false
+	}
+
+	if aerr, ok := err.(awserr.Error); ok {
+		return isCodeRetryable(aerr.Code())
+	}
+
+	if t, ok := err.(temporaryError); ok {
+		return t.Temporary() || isErrConnectionReset(err)
+	}
+
+	return isErrConnectionReset(err)
+}
+
+// IsErrorRetryable returns whether the error is retryable, based on its Code.
+// Returns false if error is nil.
+func IsErrorRetryable(err error) bool {
+	if err != nil {
+		if aerr, ok := err.(awserr.Error); ok {
+			return isCodeRetryable(aerr.Code()) || isNestedErrorRetryable(aerr)
+		}
+	}
+	return false
+}
+
+// IsErrorThrottle returns whether the error is to be throttled based on its code.
+// Returns false if error is nil.
+func IsErrorThrottle(err error) bool {
+	if err != nil {
+		if aerr, ok := err.(awserr.Error); ok {
+			return isCodeThrottle(aerr.Code())
+		}
+	}
+	return false
+}
+
+// IsErrorExpiredCreds returns whether the error code is a credential expiry error.
+// Returns false if error is nil.
+func IsErrorExpiredCreds(err error) bool {
+	if err != nil {
+		if aerr, ok := err.(awserr.Error); ok {
+			return isCodeExpiredCreds(aerr.Code())
+		}
+	}
+	return false
+}
+
+// IsErrorRetryable returns whether the error is retryable, based on its Code.
+// Returns false if the request has no Error set.
+//
+// Alias for the utility function IsErrorRetryable
+func (r *Request) IsErrorRetryable() bool {
+	return IsErrorRetryable(r.Error)
+}
+
+// IsErrorThrottle returns whether the error is to be throttled based on its code.
+// Returns false if the request has no Error set
+//
+// Alias for the utility function IsErrorThrottle
+func (r *Request) IsErrorThrottle() bool {
+	return IsErrorThrottle(r.Error)
+}
+
+// IsErrorExpired returns whether the error code is a credential expiry error.
+// Returns false if the request has no Error set.
+//
+// Alias for the utility function IsErrorExpiredCreds
+func (r *Request) IsErrorExpired() bool {
+	return IsErrorExpiredCreds(r.Error)
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer.go b/vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer.go
new file mode 100644
index 000000000..09a44eb98
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer.go
@@ -0,0 +1,94 @@
+package request
+
+import (
+	"io"
+	"time"
+
+	"github.com/aws/aws-sdk-go/aws/awserr"
+)
+
+var timeoutErr = awserr.New(
+	ErrCodeResponseTimeout,
+	"read on body has reached the timeout limit",
+	nil,
+)
+
+type readResult struct {
+	n   int
+	err error
+}
+
+// timeoutReadCloser will handle body reads that take too long.
+// We will return a ErrReadTimeout error if a timeout occurs.
+type timeoutReadCloser struct {
+	reader   io.ReadCloser
+	duration time.Duration
+}
+
+// Read will spin off a goroutine to call the reader's Read method. We will
+// select on the timer's channel or the read's channel. Whoever completes first
+// will be returned.
+func (r *timeoutReadCloser) Read(b []byte) (int, error) {
+	timer := time.NewTimer(r.duration)
+	c := make(chan readResult, 1)
+
+	go func() {
+		n, err := r.reader.Read(b)
+		timer.Stop()
+		c <- readResult{n: n, err: err}
+	}()
+
+	select {
+	case data := <-c:
+		return data.n, data.err
+	case <-timer.C:
+		return 0, timeoutErr
+	}
+}
+
+func (r *timeoutReadCloser) Close() error {
+	return r.reader.Close()
+}
+
+const (
+	// HandlerResponseTimeout is what we use to signify the name of the
+	// response timeout handler.
+	HandlerResponseTimeout = "ResponseTimeoutHandler"
+)
+
+// adaptToResponseTimeoutError is a handler that will replace any top level error
+// to a ErrCodeResponseTimeout, if its child is that.
+func adaptToResponseTimeoutError(req *Request) {
+	if err, ok := req.Error.(awserr.Error); ok {
+		aerr, ok := err.OrigErr().(awserr.Error)
+		if ok && aerr.Code() == ErrCodeResponseTimeout {
+			req.Error = aerr
+		}
+	}
+}
+
+// WithResponseReadTimeout is a request option that will wrap the body in a timeout read closer.
+// This will allow for per read timeouts. If a timeout occurred, we will return the
+// ErrCodeResponseTimeout.
+//
+//     svc.PutObjectWithContext(ctx, params, request.WithTimeoutReadCloser(30 * time.Second)
+func WithResponseReadTimeout(duration time.Duration) Option {
+	return func(r *Request) {
+
+		var timeoutHandler = NamedHandler{
+			HandlerResponseTimeout,
+			func(req *Request) {
+				req.HTTPResponse.Body = &timeoutReadCloser{
+					reader:   req.HTTPResponse.Body,
+					duration: duration,
+				}
+			}}
+
+		// remove the handler so we are not stomping over any new durations.
+		r.Handlers.Send.RemoveByName(HandlerResponseTimeout)
+		r.Handlers.Send.PushBackNamed(timeoutHandler)
+
+		r.Handlers.Unmarshal.PushBack(adaptToResponseTimeoutError)
+		r.Handlers.UnmarshalError.PushBack(adaptToResponseTimeoutError)
+	}
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/validation.go b/vendor/github.com/aws/aws-sdk-go/aws/request/validation.go
new file mode 100644
index 000000000..401246228
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/request/validation.go
@@ -0,0 +1,234 @@
+package request
+
+import (
+	"bytes"
+	"fmt"
+
+	"github.com/aws/aws-sdk-go/aws/awserr"
+)
+
+const (
+	// InvalidParameterErrCode is the error code for invalid parameters errors
+	InvalidParameterErrCode = "InvalidParameter"
+	// ParamRequiredErrCode is the error code for required parameter errors
+	ParamRequiredErrCode = "ParamRequiredError"
+	// ParamMinValueErrCode is the error code for fields with too low of a
+	// number value.
+	ParamMinValueErrCode = "ParamMinValueError"
+	// ParamMinLenErrCode is the error code for fields without enough elements.
+	ParamMinLenErrCode = "ParamMinLenError"
+)
+
+// Validator provides a way for types to perform validation logic on their
+// input values that external code can use to determine if a type's values
+// are valid.
+type Validator interface {
+	Validate() error
+}
+
+// An ErrInvalidParams provides wrapping of invalid parameter errors found when
+// validating API operation input parameters.
+type ErrInvalidParams struct {
+	// Context is the base context of the invalid parameter group.
+	Context string
+	errs    []ErrInvalidParam
+}
+
+// Add adds a new invalid parameter error to the collection of invalid
+// parameters. The context of the invalid parameter will be updated to reflect
+// this collection.
+func (e *ErrInvalidParams) Add(err ErrInvalidParam) {
+	err.SetContext(e.Context)
+	e.errs = append(e.errs, err)
+}
+
+// AddNested adds the invalid parameter errors from another ErrInvalidParams
+// value into this collection. The nested errors will have their nested context
+// updated and base context to reflect the merging.
+//
+// Use for nested validations errors.
+func (e *ErrInvalidParams) AddNested(nestedCtx string, nested ErrInvalidParams) {
+	for _, err := range nested.errs {
+		err.SetContext(e.Context)
+		err.AddNestedContext(nestedCtx)
+		e.errs = append(e.errs, err)
+	}
+}
+
+// Len returns the number of invalid parameter errors
+func (e ErrInvalidParams) Len() int {
+	return len(e.errs)
+}
+
+// Code returns the code of the error
+func (e ErrInvalidParams) Code() string {
+	return InvalidParameterErrCode
+}
+
+// Message returns the message of the error
+func (e ErrInvalidParams) Message() string {
+	return fmt.Sprintf("%d validation error(s) found.", len(e.errs))
+}
+
+// Error returns the string formatted form of the invalid parameters.
+func (e ErrInvalidParams) Error() string {
+	w := &bytes.Buffer{}
+	fmt.Fprintf(w, "%s: %s\n", e.Code(), e.Message())
+
+	for _, err := range e.errs {
+		fmt.Fprintf(w, "- %s\n", err.Message())
+	}
+
+	return w.String()
+}
+
+// OrigErr returns the invalid parameters as a awserr.BatchedErrors value
+func (e ErrInvalidParams) OrigErr() error {
+	return awserr.NewBatchError(
+		InvalidParameterErrCode, e.Message(), e.OrigErrs())
+}
+
+// OrigErrs returns a slice of the invalid parameters
+func (e ErrInvalidParams) OrigErrs() []error {
+	errs := make([]error, len(e.errs))
+	for i := 0; i < len(errs); i++ {
+		errs[i] = e.errs[i]
+	}
+
+	return errs
+}
+
+// An ErrInvalidParam represents an invalid parameter error type.
+type ErrInvalidParam interface {
+	awserr.Error
+
+	// Field name the error occurred on.
+	Field() string
+
+	// SetContext updates the context of the error.
+	SetContext(string)
+
+	// AddNestedContext updates the error's context to include a nested level.
+	AddNestedContext(string)
+}
+
+type errInvalidParam struct {
+	context       string
+	nestedContext string
+	field         string
+	code          string
+	msg           string
+}
+
+// Code returns the error code for the type of invalid parameter.
+func (e *errInvalidParam) Code() string {
+	return e.code
+}
+
+// Message returns the reason the parameter was invalid, and its context.
+func (e *errInvalidParam) Message() string {
+	return fmt.Sprintf("%s, %s.", e.msg, e.Field())
+}
+
+// Error returns the string version of the invalid parameter error.
+func (e *errInvalidParam) Error() string {
+	return fmt.Sprintf("%s: %s", e.code, e.Message())
+}
+
+// OrigErr returns nil, Implemented for awserr.Error interface.
+func (e *errInvalidParam) OrigErr() error {
+	return nil
+}
+
+// Field Returns the field and context the error occurred.
+func (e *errInvalidParam) Field() string {
+	field := e.context
+	if len(field) > 0 {
+		field += "."
+	}
+	if len(e.nestedContext) > 0 {
+		field += fmt.Sprintf("%s.", e.nestedContext)
+	}
+	field += e.field
+
+	return field
+}
+
+// SetContext updates the base context of the error.
+func (e *errInvalidParam) SetContext(ctx string) {
+	e.context = ctx
+}
+
+// AddNestedContext prepends a context to the field's path.
+func (e *errInvalidParam) AddNestedContext(ctx string) {
+	if len(e.nestedContext) == 0 {
+		e.nestedContext = ctx
+	} else {
+		e.nestedContext = fmt.Sprintf("%s.%s", ctx, e.nestedContext)
+	}
+
+}
+
+// An ErrParamRequired represents an required parameter error.
+type ErrParamRequired struct {
+	errInvalidParam
+}
+
+// NewErrParamRequired creates a new required parameter error.
+func NewErrParamRequired(field string) *ErrParamRequired {
+	return &ErrParamRequired{
+		errInvalidParam{
+			code:  ParamRequiredErrCode,
+			field: field,
+			msg:   fmt.Sprintf("missing required field"),
+		},
+	}
+}
+
+// An ErrParamMinValue represents a minimum value parameter error.
+type ErrParamMinValue struct {
+	errInvalidParam
+	min float64
+}
+
+// NewErrParamMinValue creates a new minimum value parameter error.
+func NewErrParamMinValue(field string, min float64) *ErrParamMinValue {
+	return &ErrParamMinValue{
+		errInvalidParam: errInvalidParam{
+			code:  ParamMinValueErrCode,
+			field: field,
+			msg:   fmt.Sprintf("minimum field value of %v", min),
+		},
+		min: min,
+	}
+}
+
+// MinValue returns the field's require minimum value.
+//
+// float64 is returned for both int and float min values.
+func (e *ErrParamMinValue) MinValue() float64 {
+	return e.min
+}
+
+// An ErrParamMinLen represents a minimum length parameter error.
+type ErrParamMinLen struct {
+	errInvalidParam
+	min int
+}
+
+// NewErrParamMinLen creates a new minimum length parameter error.
+func NewErrParamMinLen(field string, min int) *ErrParamMinLen {
+	return &ErrParamMinLen{
+		errInvalidParam: errInvalidParam{
+			code:  ParamMinLenErrCode,
+			field: field,
+			msg:   fmt.Sprintf("minimum field size of %v", min),
+		},
+		min: min,
+	}
+}
+
+// MinLen returns the field's required minimum length.
+func (e *ErrParamMinLen) MinLen() int {
+	return e.min
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/waiter.go b/vendor/github.com/aws/aws-sdk-go/aws/request/waiter.go
new file mode 100644
index 000000000..4601f883c
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/request/waiter.go
@@ -0,0 +1,295 @@
+package request
+
+import (
+	"fmt"
+	"time"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/awsutil"
+)
+
+// WaiterResourceNotReadyErrorCode is the error code returned by a waiter when
+// the waiter's max attempts have been exhausted.
+const WaiterResourceNotReadyErrorCode = "ResourceNotReady"
+
+// A WaiterOption is a function that will update the Waiter value's fields to
+// configure the waiter.
+type WaiterOption func(*Waiter)
+
+// WithWaiterMaxAttempts returns the maximum number of times the waiter should
+// attempt to check the resource for the target state.
+func WithWaiterMaxAttempts(max int) WaiterOption {
+	return func(w *Waiter) {
+		w.MaxAttempts = max
+	}
+}
+
+// WaiterDelay will return a delay the waiter should pause between attempts to
+// check the resource state. The passed in attempt is the number of times the
+// Waiter has checked the resource state.
+//
+// Attempt is the number of attempts the Waiter has made checking the resource
+// state.
+type WaiterDelay func(attempt int) time.Duration
+
+// ConstantWaiterDelay returns a WaiterDelay that will always return a constant
+// delay the waiter should use between attempts. It ignores the number of
+// attempts made.
+func ConstantWaiterDelay(delay time.Duration) WaiterDelay {
+	return func(attempt int) time.Duration {
+		return delay
+	}
+}
+
+// WithWaiterDelay will set the Waiter to use the WaiterDelay passed in.
+func WithWaiterDelay(delayer WaiterDelay) WaiterOption {
+	return func(w *Waiter) {
+		w.Delay = delayer
+	}
+}
+
+// WithWaiterLogger returns a waiter option to set the logger a waiter
+// should use to log warnings and errors to.
+func WithWaiterLogger(logger aws.Logger) WaiterOption {
+	return func(w *Waiter) {
+		w.Logger = logger
+	}
+}
+
+// WithWaiterRequestOptions returns a waiter option setting the request
+// options for each request the waiter makes. Appends to waiter's request
+// options already set.
+func WithWaiterRequestOptions(opts ...Option) WaiterOption {
+	return func(w *Waiter) {
+		w.RequestOptions = append(w.RequestOptions, opts...)
+	}
+}
+
+// A Waiter provides the functionality to perform a blocking call which will
+// wait for a resource state to be satisfied by a service.
+//
+// This type should not be used directly. The API operations provided in the
+// service packages prefixed with "WaitUntil" should be used instead.
+type Waiter struct {
+	Name      string
+	Acceptors []WaiterAcceptor
+	Logger    aws.Logger
+
+	MaxAttempts int
+	Delay       WaiterDelay
+
+	RequestOptions   []Option
+	NewRequest       func([]Option) (*Request, error)
+	SleepWithContext func(aws.Context, time.Duration) error
+}
+
+// ApplyOptions updates the waiter with the list of waiter options provided.
+func (w *Waiter) ApplyOptions(opts ...WaiterOption) {
+	for _, fn := range opts {
+		fn(w)
+	}
+}
+
+// WaiterState are states the waiter uses based on WaiterAcceptor definitions
+// to identify if the resource state the waiter is waiting on has occurred.
+type WaiterState int
+
+// String returns the string representation of the waiter state.
+func (s WaiterState) String() string {
+	switch s {
+	case SuccessWaiterState:
+		return "success"
+	case FailureWaiterState:
+		return "failure"
+	case RetryWaiterState:
+		return "retry"
+	default:
+		return "unknown waiter state"
+	}
+}
+
+// States the waiter acceptors will use to identify target resource states.
+const (
+	SuccessWaiterState WaiterState = iota // waiter successful
+	FailureWaiterState                    // waiter failed
+	RetryWaiterState                      // waiter needs to be retried
+)
+
+// WaiterMatchMode is the mode that the waiter will use to match the WaiterAcceptor
+// definition's Expected attribute.
+type WaiterMatchMode int
+
+// Modes the waiter will use when inspecting API response to identify target
+// resource states.
+const (
+	PathAllWaiterMatch  WaiterMatchMode = iota // match on all paths
+	PathWaiterMatch                            // match on specific path
+	PathAnyWaiterMatch                         // match on any path
+	PathListWaiterMatch                        // match on list of paths
+	StatusWaiterMatch                          // match on status code
+	ErrorWaiterMatch                           // match on error
+)
+
+// String returns the string representation of the waiter match mode.
+func (m WaiterMatchMode) String() string {
+	switch m {
+	case PathAllWaiterMatch:
+		return "pathAll"
+	case PathWaiterMatch:
+		return "path"
+	case PathAnyWaiterMatch:
+		return "pathAny"
+	case PathListWaiterMatch:
+		return "pathList"
+	case StatusWaiterMatch:
+		return "status"
+	case ErrorWaiterMatch:
+		return "error"
+	default:
+		return "unknown waiter match mode"
+	}
+}
+
+// WaitWithContext will make requests for the API operation using NewRequest to
+// build API requests. The request's response will be compared against the
+// Waiter's Acceptors to determine the successful state of the resource the
+// waiter is inspecting.
+//
+// The passed in context must not be nil. If it is nil a panic will occur. The
+// Context will be used to cancel the waiter's pending requests and retry delays.
+// Use aws.BackgroundContext if no context is available.
+//
+// The waiter will continue until the target state defined by the Acceptors,
+// or the max attempts expires.
+//
+// Will return the WaiterResourceNotReadyErrorCode error code if the waiter's
+// retryer ShouldRetry returns false. This normally will happen when the max
+// wait attempts expires.
+func (w Waiter) WaitWithContext(ctx aws.Context) error {
+
+	for attempt := 1; ; attempt++ {
+		req, err := w.NewRequest(w.RequestOptions)
+		if err != nil {
+			waiterLogf(w.Logger, "unable to create request %v", err)
+			return err
+		}
+		req.Handlers.Build.PushBack(MakeAddToUserAgentFreeFormHandler("Waiter"))
+		err = req.Send()
+
+		// See if any of the acceptors match the request's response, or error
+		for _, a := range w.Acceptors {
+			if matched, matchErr := a.match(w.Name, w.Logger, req, err); matched {
+				return matchErr
+			}
+		}
+
+		// The Waiter should only check the resource state MaxAttempts times
+		// This is here instead of in the for loop above to prevent delaying
+		// unnecessary when the waiter will not retry.
+		if attempt == w.MaxAttempts {
+			break
+		}
+
+		// Delay to wait before inspecting the resource again
+		delay := w.Delay(attempt)
+		if sleepFn := req.Config.SleepDelay; sleepFn != nil {
+			// Support SleepDelay for backwards compatibility and testing
+			sleepFn(delay)
+		} else {
+			sleepCtxFn := w.SleepWithContext
+			if sleepCtxFn == nil {
+				sleepCtxFn = aws.SleepWithContext
+			}
+
+			if err := sleepCtxFn(ctx, delay); err != nil {
+				return awserr.New(CanceledErrorCode, "waiter context canceled", err)
+			}
+		}
+	}
+
+	return awserr.New(WaiterResourceNotReadyErrorCode, "exceeded wait attempts", nil)
+}
+
+// A WaiterAcceptor provides the information needed to wait for an API operation
+// to complete.
+type WaiterAcceptor struct {
+	State    WaiterState
+	Matcher  WaiterMatchMode
+	Argument string
+	Expected interface{}
+}
+
+// match returns if the acceptor found a match with the passed in request
+// or error. True is returned if the acceptor made a match, error is returned
+// if there was an error attempting to perform the match.
+func (a *WaiterAcceptor) match(name string, l aws.Logger, req *Request, err error) (bool, error) {
+	result := false
+	var vals []interface{}
+
+	switch a.Matcher {
+	case PathAllWaiterMatch, PathWaiterMatch:
+		// Require all matches to be equal for result to match
+		vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument)
+		if len(vals) == 0 {
+			break
+		}
+		result = true
+		for _, val := range vals {
+			if !awsutil.DeepEqual(val, a.Expected) {
+				result = false
+				break
+			}
+		}
+	case PathAnyWaiterMatch:
+		// Only a single match needs to equal for the result to match
+		vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument)
+		for _, val := range vals {
+			if awsutil.DeepEqual(val, a.Expected) {
+				result = true
+				break
+			}
+		}
+	case PathListWaiterMatch:
+		// ignored matcher
+	case StatusWaiterMatch:
+		s := a.Expected.(int)
+		result = s == req.HTTPResponse.StatusCode
+	case ErrorWaiterMatch:
+		if aerr, ok := err.(awserr.Error); ok {
+			result = aerr.Code() == a.Expected.(string)
+		}
+	default:
+		waiterLogf(l, "WARNING: Waiter %s encountered unexpected matcher: %s",
+			name, a.Matcher)
+	}
+
+	if !result {
+		// If there was no matching result found there is nothing more to do
+		// for this response, retry the request.
+		return false, nil
+	}
+
+	switch a.State {
+	case SuccessWaiterState:
+		// waiter completed
+		return true, nil
+	case FailureWaiterState:
+		// Waiter failure state triggered
+		return true, awserr.New(WaiterResourceNotReadyErrorCode,
+			"failed waiting for successful resource state", err)
+	case RetryWaiterState:
+		// clear the error and retry the operation
+		return false, nil
+	default:
+		waiterLogf(l, "WARNING: Waiter %s encountered unexpected state: %s",
+			name, a.State)
+		return false, nil
+	}
+}
+
+func waiterLogf(logger aws.Logger, msg string, args ...interface{}) {
+	if logger != nil {
+		logger.Log(fmt.Sprintf(msg, args...))
+	}
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/doc.go b/vendor/github.com/aws/aws-sdk-go/aws/session/doc.go
new file mode 100644
index 000000000..98d420fd6
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/session/doc.go
@@ -0,0 +1,273 @@
+/*
+Package session provides configuration for the SDK's service clients.
+
+Sessions can be shared across all service clients that share the same base
+configuration.  The Session is built from the SDK's default configuration and
+request handlers.
+
+Sessions should be cached when possible, because creating a new Session will
+load all configuration values from the environment, and config files each time
+the Session is created. Sharing the Session value across all of your service
+clients will ensure the configuration is loaded the fewest number of times possible.
+
+Concurrency
+
+Sessions are safe to use concurrently as long as the Session is not being
+modified. The SDK will not modify the Session once the Session has been created.
+Creating service clients concurrently from a shared Session is safe.
+
+Sessions from Shared Config
+
+Sessions can be created using the method above that will only load the
+additional config if the AWS_SDK_LOAD_CONFIG environment variable is set.
+Alternatively you can explicitly create a Session with shared config enabled.
+To do this you can use NewSessionWithOptions to configure how the Session will
+be created. Using the NewSessionWithOptions with SharedConfigState set to
+SharedConfigEnable will create the session as if the AWS_SDK_LOAD_CONFIG
+environment variable was set.
+
+Creating Sessions
+
+When creating Sessions optional aws.Config values can be passed in that will
+override the default, or loaded config values the Session is being created
+with. This allows you to provide additional, or case based, configuration
+as needed.
+
+By default NewSession will only load credentials from the shared credentials
+file (~/.aws/credentials). If the AWS_SDK_LOAD_CONFIG environment variable is
+set to a truthy value the Session will be created from the configuration
+values from the shared config (~/.aws/config) and shared credentials
+(~/.aws/credentials) files. See the section Sessions from Shared Config for
+more information.
+
+Create a Session with the default config and request handlers. With credentials
+region, and profile loaded from the environment and shared config automatically.
+Requires the AWS_PROFILE to be set, or "default" is used.
+
+	// Create Session
+	sess := session.Must(session.NewSession())
+
+	// Create a Session with a custom region
+	sess := session.Must(session.NewSession(&aws.Config{
+		Region: aws.String("us-east-1"),
+	}))
+
+	// Create a S3 client instance from a session
+	sess := session.Must(session.NewSession())
+
+	svc := s3.New(sess)
+
+Create Session With Option Overrides
+
+In addition to NewSession, Sessions can be created using NewSessionWithOptions.
+This func allows you to control and override how the Session will be created
+through code instead of being driven by environment variables only.
+
+Use NewSessionWithOptions when you want to provide the config profile, or
+override the shared config state (AWS_SDK_LOAD_CONFIG).
+
+	// Equivalent to session.NewSession()
+	sess := session.Must(session.NewSessionWithOptions(session.Options{
+		// Options
+	}))
+
+	// Specify profile to load for the session's config
+	sess := session.Must(session.NewSessionWithOptions(session.Options{
+		 Profile: "profile_name",
+	}))
+
+	// Specify profile for config and region for requests
+	sess := session.Must(session.NewSessionWithOptions(session.Options{
+		 Config: aws.Config{Region: aws.String("us-east-1")},
+		 Profile: "profile_name",
+	}))
+
+	// Force enable Shared Config support
+	sess := session.Must(session.NewSessionWithOptions(session.Options{
+		SharedConfigState: session.SharedConfigEnable,
+	}))
+
+Adding Handlers
+
+You can add handlers to a session for processing HTTP requests. All service
+clients that use the session inherit the handlers. For example, the following
+handler logs every request and its payload made by a service client:
+
+	// Create a session, and add additional handlers for all service
+	// clients created with the Session to inherit. Adds logging handler.
+	sess := session.Must(session.NewSession())
+
+	sess.Handlers.Send.PushFront(func(r *request.Request) {
+		// Log every request made and its payload
+		logger.Println("Request: %s/%s, Payload: %s",
+			r.ClientInfo.ServiceName, r.Operation, r.Params)
+	})
+
+Deprecated "New" function
+
+The New session function has been deprecated because it does not provide good
+way to return errors that occur when loading the configuration files and values.
+Because of this, NewSession was created so errors can be retrieved when
+creating a session fails.
+
+Shared Config Fields
+
+By default the SDK will only load the shared credentials file's (~/.aws/credentials)
+credentials values, and all other config is provided by the environment variables,
+SDK defaults, and user provided aws.Config values.
+
+If the AWS_SDK_LOAD_CONFIG environment variable is set, or SharedConfigEnable
+option is used to create the Session the full shared config values will be
+loaded. This includes credentials, region, and support for assume role. In
+addition the Session will load its configuration from both the shared config
+file (~/.aws/config) and shared credentials file (~/.aws/credentials). Both
+files have the same format.
+
+If both config files are present the configuration from both files will be
+read. The Session will be created from configuration values from the shared
+credentials file (~/.aws/credentials) over those in the shared config file (~/.aws/config).
+
+Credentials are the values the SDK should use for authenticating requests with
+AWS Services. They are from a configuration file will need to include both
+aws_access_key_id and aws_secret_access_key must be provided together in the
+same file to be considered valid. The values will be ignored if not a complete
+group. aws_session_token is an optional field that can be provided if both of
+the other two fields are also provided.
+
+	aws_access_key_id = AKID
+	aws_secret_access_key = SECRET
+	aws_session_token = TOKEN
+
+Assume Role values allow you to configure the SDK to assume an IAM role using
+a set of credentials provided in a config file via the source_profile field.
+Both "role_arn" and "source_profile" are required. The SDK supports assuming
+a role with MFA token if the session option AssumeRoleTokenProvider
+is set.
+
+	role_arn = arn:aws:iam:::role/
+	source_profile = profile_with_creds
+	external_id = 1234
+	mfa_serial = 
+	role_session_name = session_name
+
+Region is the region the SDK should use for looking up AWS service endpoints
+and signing requests.
+
+	region = us-east-1
+
+Assume Role with MFA token
+
+To create a session with support for assuming an IAM role with MFA set the
+session option AssumeRoleTokenProvider to a function that will prompt for the
+MFA token code when the SDK assumes the role and refreshes the role's credentials.
+This allows you to configure the SDK via the shared config to assumea role
+with MFA tokens.
+
+In order for the SDK to assume a role with MFA the SharedConfigState
+session option must be set to SharedConfigEnable, or AWS_SDK_LOAD_CONFIG
+environment variable set.
+
+The shared configuration instructs the SDK to assume an IAM role with MFA
+when the mfa_serial configuration field is set in the shared config
+(~/.aws/config) or shared credentials (~/.aws/credentials) file.
+
+If mfa_serial is set in the configuration, the SDK will assume the role, and
+the AssumeRoleTokenProvider session option is not set an an error will
+be returned when creating the session.
+
+    sess := session.Must(session.NewSessionWithOptions(session.Options{
+        AssumeRoleTokenProvider: stscreds.StdinTokenProvider,
+    }))
+
+    // Create service client value configured for credentials
+    // from assumed role.
+    svc := s3.New(sess)
+
+To setup assume role outside of a session see the stscrds.AssumeRoleProvider
+documentation.
+
+Environment Variables
+
+When a Session is created several environment variables can be set to adjust
+how the SDK functions, and what configuration data it loads when creating
+Sessions. All environment values are optional, but some values like credentials
+require multiple of the values to set or the partial values will be ignored.
+All environment variable values are strings unless otherwise noted.
+
+Environment configuration values. If set both Access Key ID and Secret Access
+Key must be provided. Session Token and optionally also be provided, but is
+not required.
+
+	# Access Key ID
+	AWS_ACCESS_KEY_ID=AKID
+	AWS_ACCESS_KEY=AKID # only read if AWS_ACCESS_KEY_ID is not set.
+
+	# Secret Access Key
+	AWS_SECRET_ACCESS_KEY=SECRET
+	AWS_SECRET_KEY=SECRET=SECRET # only read if AWS_SECRET_ACCESS_KEY is not set.
+
+	# Session Token
+	AWS_SESSION_TOKEN=TOKEN
+
+Region value will instruct the SDK where to make service API requests to. If is
+not provided in the environment the region must be provided before a service
+client request is made.
+
+	AWS_REGION=us-east-1
+
+	# AWS_DEFAULT_REGION is only read if AWS_SDK_LOAD_CONFIG is also set,
+	# and AWS_REGION is not also set.
+	AWS_DEFAULT_REGION=us-east-1
+
+Profile name the SDK should load use when loading shared config from the
+configuration files. If not provided "default" will be used as the profile name.
+
+	AWS_PROFILE=my_profile
+
+	# AWS_DEFAULT_PROFILE is only read if AWS_SDK_LOAD_CONFIG is also set,
+	# and AWS_PROFILE is not also set.
+	AWS_DEFAULT_PROFILE=my_profile
+
+SDK load config instructs the SDK to load the shared config in addition to
+shared credentials. This also expands the configuration loaded so the shared
+credentials will have parity with the shared config file. This also enables
+Region and Profile support for the AWS_DEFAULT_REGION and AWS_DEFAULT_PROFILE
+env values as well.
+
+	AWS_SDK_LOAD_CONFIG=1
+
+Shared credentials file path can be set to instruct the SDK to use an alternative
+file for the shared credentials. If not set the file will be loaded from
+$HOME/.aws/credentials on Linux/Unix based systems, and
+%USERPROFILE%\.aws\credentials on Windows.
+
+	AWS_SHARED_CREDENTIALS_FILE=$HOME/my_shared_credentials
+
+Shared config file path can be set to instruct the SDK to use an alternative
+file for the shared config. If not set the file will be loaded from
+$HOME/.aws/config on Linux/Unix based systems, and
+%USERPROFILE%\.aws\config on Windows.
+
+	AWS_CONFIG_FILE=$HOME/my_shared_config
+
+Path to a custom Credentials Authority (CA) bundle PEM file that the SDK
+will use instead of the default system's root CA bundle. Use this only
+if you want to replace the CA bundle the SDK uses for TLS requests.
+
+	AWS_CA_BUNDLE=$HOME/my_custom_ca_bundle
+
+Enabling this option will attempt to merge the Transport into the SDK's HTTP
+client. If the client's Transport is not a http.Transport an error will be
+returned. If the Transport's TLS config is set this option will cause the SDK
+to overwrite the Transport's TLS config's  RootCAs value. If the CA bundle file
+contains multiple certificates all of them will be loaded.
+
+The Session option CustomCABundle is also available when creating sessions
+to also enable this feature. CustomCABundle session option field has priority
+over the AWS_CA_BUNDLE environment variable, and will be used if both are set.
+
+Setting a custom HTTPClient in the aws.Config options will override this setting.
+To use this option and custom HTTP client, the HTTP client needs to be provided
+when creating the session. Not the service client.
+*/
+package session
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go b/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go
new file mode 100644
index 000000000..82e04d76c
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go
@@ -0,0 +1,219 @@
+package session
+
+import (
+	"os"
+	"strconv"
+
+	"github.com/aws/aws-sdk-go/aws/credentials"
+	"github.com/aws/aws-sdk-go/aws/defaults"
+)
+
+// EnvProviderName provides a name of the provider when config is loaded from environment.
+const EnvProviderName = "EnvConfigCredentials"
+
+// envConfig is a collection of environment values the SDK will read
+// setup config from. All environment values are optional. But some values
+// such as credentials require multiple values to be complete or the values
+// will be ignored.
+type envConfig struct {
+	// Environment configuration values. If set both Access Key ID and Secret Access
+	// Key must be provided. Session Token and optionally also be provided, but is
+	// not required.
+	//
+	//	# Access Key ID
+	//	AWS_ACCESS_KEY_ID=AKID
+	//	AWS_ACCESS_KEY=AKID # only read if AWS_ACCESS_KEY_ID is not set.
+	//
+	//	# Secret Access Key
+	//	AWS_SECRET_ACCESS_KEY=SECRET
+	//	AWS_SECRET_KEY=SECRET=SECRET # only read if AWS_SECRET_ACCESS_KEY is not set.
+	//
+	//	# Session Token
+	//	AWS_SESSION_TOKEN=TOKEN
+	Creds credentials.Value
+
+	// Region value will instruct the SDK where to make service API requests to. If is
+	// not provided in the environment the region must be provided before a service
+	// client request is made.
+	//
+	//	AWS_REGION=us-east-1
+	//
+	//	# AWS_DEFAULT_REGION is only read if AWS_SDK_LOAD_CONFIG is also set,
+	//	# and AWS_REGION is not also set.
+	//	AWS_DEFAULT_REGION=us-east-1
+	Region string
+
+	// Profile name the SDK should load use when loading shared configuration from the
+	// shared configuration files. If not provided "default" will be used as the
+	// profile name.
+	//
+	//	AWS_PROFILE=my_profile
+	//
+	//	# AWS_DEFAULT_PROFILE is only read if AWS_SDK_LOAD_CONFIG is also set,
+	//	# and AWS_PROFILE is not also set.
+	//	AWS_DEFAULT_PROFILE=my_profile
+	Profile string
+
+	// SDK load config instructs the SDK to load the shared config in addition to
+	// shared credentials. This also expands the configuration loaded from the shared
+	// credentials to have parity with the shared config file. This also enables
+	// Region and Profile support for the AWS_DEFAULT_REGION and AWS_DEFAULT_PROFILE
+	// env values as well.
+	//
+	//	AWS_SDK_LOAD_CONFIG=1
+	EnableSharedConfig bool
+
+	// Shared credentials file path can be set to instruct the SDK to use an alternate
+	// file for the shared credentials. If not set the file will be loaded from
+	// $HOME/.aws/credentials on Linux/Unix based systems, and
+	// %USERPROFILE%\.aws\credentials on Windows.
+	//
+	//	AWS_SHARED_CREDENTIALS_FILE=$HOME/my_shared_credentials
+	SharedCredentialsFile string
+
+	// Shared config file path can be set to instruct the SDK to use an alternate
+	// file for the shared config. If not set the file will be loaded from
+	// $HOME/.aws/config on Linux/Unix based systems, and
+	// %USERPROFILE%\.aws\config on Windows.
+	//
+	//	AWS_CONFIG_FILE=$HOME/my_shared_config
+	SharedConfigFile string
+
+	// Sets the path to a custom Credentials Authroity (CA) Bundle PEM file
+	// that the SDK will use instead of the system's root CA bundle.
+	// Only use this if you want to configure the SDK to use a custom set
+	// of CAs.
+	//
+	// Enabling this option will attempt to merge the Transport
+	// into the SDK's HTTP client. If the client's Transport is
+	// not a http.Transport an error will be returned. If the
+	// Transport's TLS config is set this option will cause the
+	// SDK to overwrite the Transport's TLS config's  RootCAs value.
+	//
+	// Setting a custom HTTPClient in the aws.Config options will override this setting.
+	// To use this option and custom HTTP client, the HTTP client needs to be provided
+	// when creating the session. Not the service client.
+	//
+	//  AWS_CA_BUNDLE=$HOME/my_custom_ca_bundle
+	CustomCABundle string
+
+	csmEnabled  string
+	CSMEnabled  bool
+	CSMPort     string
+	CSMClientID string
+}
+
+var (
+	csmEnabledEnvKey = []string{
+		"AWS_CSM_ENABLED",
+	}
+	csmPortEnvKey = []string{
+		"AWS_CSM_PORT",
+	}
+	csmClientIDEnvKey = []string{
+		"AWS_CSM_CLIENT_ID",
+	}
+	credAccessEnvKey = []string{
+		"AWS_ACCESS_KEY_ID",
+		"AWS_ACCESS_KEY",
+	}
+	credSecretEnvKey = []string{
+		"AWS_SECRET_ACCESS_KEY",
+		"AWS_SECRET_KEY",
+	}
+	credSessionEnvKey = []string{
+		"AWS_SESSION_TOKEN",
+	}
+
+	regionEnvKeys = []string{
+		"AWS_REGION",
+		"AWS_DEFAULT_REGION", // Only read if AWS_SDK_LOAD_CONFIG is also set
+	}
+	profileEnvKeys = []string{
+		"AWS_PROFILE",
+		"AWS_DEFAULT_PROFILE", // Only read if AWS_SDK_LOAD_CONFIG is also set
+	}
+	sharedCredsFileEnvKey = []string{
+		"AWS_SHARED_CREDENTIALS_FILE",
+	}
+	sharedConfigFileEnvKey = []string{
+		"AWS_CONFIG_FILE",
+	}
+)
+
+// loadEnvConfig retrieves the SDK's environment configuration.
+// See `envConfig` for the values that will be retrieved.
+//
+// If the environment variable `AWS_SDK_LOAD_CONFIG` is set to a truthy value
+// the shared SDK config will be loaded in addition to the SDK's specific
+// configuration values.
+func loadEnvConfig() envConfig {
+	enableSharedConfig, _ := strconv.ParseBool(os.Getenv("AWS_SDK_LOAD_CONFIG"))
+	return envConfigLoad(enableSharedConfig)
+}
+
+// loadEnvSharedConfig retrieves the SDK's environment configuration, and the
+// SDK shared config. See `envConfig` for the values that will be retrieved.
+//
+// Loads the shared configuration in addition to the SDK's specific configuration.
+// This will load the same values as `loadEnvConfig` if the `AWS_SDK_LOAD_CONFIG`
+// environment variable is set.
+func loadSharedEnvConfig() envConfig {
+	return envConfigLoad(true)
+}
+
+func envConfigLoad(enableSharedConfig bool) envConfig {
+	cfg := envConfig{}
+
+	cfg.EnableSharedConfig = enableSharedConfig
+
+	setFromEnvVal(&cfg.Creds.AccessKeyID, credAccessEnvKey)
+	setFromEnvVal(&cfg.Creds.SecretAccessKey, credSecretEnvKey)
+	setFromEnvVal(&cfg.Creds.SessionToken, credSessionEnvKey)
+
+	// CSM environment variables
+	setFromEnvVal(&cfg.csmEnabled, csmEnabledEnvKey)
+	setFromEnvVal(&cfg.CSMPort, csmPortEnvKey)
+	setFromEnvVal(&cfg.CSMClientID, csmClientIDEnvKey)
+	cfg.CSMEnabled = len(cfg.csmEnabled) > 0
+
+	// Require logical grouping of credentials
+	if len(cfg.Creds.AccessKeyID) == 0 || len(cfg.Creds.SecretAccessKey) == 0 {
+		cfg.Creds = credentials.Value{}
+	} else {
+		cfg.Creds.ProviderName = EnvProviderName
+	}
+
+	regionKeys := regionEnvKeys
+	profileKeys := profileEnvKeys
+	if !cfg.EnableSharedConfig {
+		regionKeys = regionKeys[:1]
+		profileKeys = profileKeys[:1]
+	}
+
+	setFromEnvVal(&cfg.Region, regionKeys)
+	setFromEnvVal(&cfg.Profile, profileKeys)
+
+	setFromEnvVal(&cfg.SharedCredentialsFile, sharedCredsFileEnvKey)
+	setFromEnvVal(&cfg.SharedConfigFile, sharedConfigFileEnvKey)
+
+	if len(cfg.SharedCredentialsFile) == 0 {
+		cfg.SharedCredentialsFile = defaults.SharedCredentialsFilename()
+	}
+	if len(cfg.SharedConfigFile) == 0 {
+		cfg.SharedConfigFile = defaults.SharedConfigFilename()
+	}
+
+	cfg.CustomCABundle = os.Getenv("AWS_CA_BUNDLE")
+
+	return cfg
+}
+
+func setFromEnvVal(dst *string, keys []string) {
+	for _, k := range keys {
+		if v := os.Getenv(k); len(v) > 0 {
+			*dst = v
+			break
+		}
+	}
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/session.go b/vendor/github.com/aws/aws-sdk-go/aws/session/session.go
new file mode 100644
index 000000000..51f305563
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/session/session.go
@@ -0,0 +1,628 @@
+package session
+
+import (
+	"crypto/tls"
+	"crypto/x509"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net/http"
+	"os"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/client"
+	"github.com/aws/aws-sdk-go/aws/corehandlers"
+	"github.com/aws/aws-sdk-go/aws/credentials"
+	"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
+	"github.com/aws/aws-sdk-go/aws/csm"
+	"github.com/aws/aws-sdk-go/aws/defaults"
+	"github.com/aws/aws-sdk-go/aws/endpoints"
+	"github.com/aws/aws-sdk-go/aws/request"
+)
+
+// A Session provides a central location to create service clients from and
+// store configurations and request handlers for those services.
+//
+// Sessions are safe to create service clients concurrently, but it is not safe
+// to mutate the Session concurrently.
+//
+// The Session satisfies the service client's client.ConfigProvider.
+type Session struct {
+	Config   *aws.Config
+	Handlers request.Handlers
+}
+
+// New creates a new instance of the handlers merging in the provided configs
+// on top of the SDK's default configurations. Once the Session is created it
+// can be mutated to modify the Config or Handlers. The Session is safe to be
+// read concurrently, but it should not be written to concurrently.
+//
+// If the AWS_SDK_LOAD_CONFIG environment is set to a truthy value, the New
+// method could now encounter an error when loading the configuration. When
+// The environment variable is set, and an error occurs, New will return a
+// session that will fail all requests reporting the error that occurred while
+// loading the session. Use NewSession to get the error when creating the
+// session.
+//
+// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value
+// the shared config file (~/.aws/config) will also be loaded, in addition to
+// the shared credentials file (~/.aws/credentials). Values set in both the
+// shared config, and shared credentials will be taken from the shared
+// credentials file.
+//
+// Deprecated: Use NewSession functions to create sessions instead. NewSession
+// has the same functionality as New except an error can be returned when the
+// func is called instead of waiting to receive an error until a request is made.
+func New(cfgs ...*aws.Config) *Session {
+	// load initial config from environment
+	envCfg := loadEnvConfig()
+
+	if envCfg.EnableSharedConfig {
+		var cfg aws.Config
+		cfg.MergeIn(cfgs...)
+		s, err := NewSessionWithOptions(Options{
+			Config:            cfg,
+			SharedConfigState: SharedConfigEnable,
+		})
+		if err != nil {
+			// Old session.New expected all errors to be discovered when
+			// a request is made, and would report the errors then. This
+			// needs to be replicated if an error occurs while creating
+			// the session.
+			msg := "failed to create session with AWS_SDK_LOAD_CONFIG enabled. " +
+				"Use session.NewSession to handle errors occurring during session creation."
+
+			// Session creation failed, need to report the error and prevent
+			// any requests from succeeding.
+			s = &Session{Config: defaults.Config()}
+			s.Config.MergeIn(cfgs...)
+			s.Config.Logger.Log("ERROR:", msg, "Error:", err)
+			s.Handlers.Validate.PushBack(func(r *request.Request) {
+				r.Error = err
+			})
+		}
+
+		return s
+	}
+
+	s := deprecatedNewSession(cfgs...)
+	if envCfg.CSMEnabled {
+		enableCSM(&s.Handlers, envCfg.CSMClientID, envCfg.CSMPort, s.Config.Logger)
+	}
+
+	return s
+}
+
+// NewSession returns a new Session created from SDK defaults, config files,
+// environment, and user provided config files. Once the Session is created
+// it can be mutated to modify the Config or Handlers. The Session is safe to
+// be read concurrently, but it should not be written to concurrently.
+//
+// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value
+// the shared config file (~/.aws/config) will also be loaded in addition to
+// the shared credentials file (~/.aws/credentials). Values set in both the
+// shared config, and shared credentials will be taken from the shared
+// credentials file. Enabling the Shared Config will also allow the Session
+// to be built with retrieving credentials with AssumeRole set in the config.
+//
+// See the NewSessionWithOptions func for information on how to override or
+// control through code how the Session will be created. Such as specifying the
+// config profile, and controlling if shared config is enabled or not.
+func NewSession(cfgs ...*aws.Config) (*Session, error) {
+	opts := Options{}
+	opts.Config.MergeIn(cfgs...)
+
+	return NewSessionWithOptions(opts)
+}
+
+// SharedConfigState provides the ability to optionally override the state
+// of the session's creation based on the shared config being enabled or
+// disabled.
+type SharedConfigState int
+
+const (
+	// SharedConfigStateFromEnv does not override any state of the
+	// AWS_SDK_LOAD_CONFIG env var. It is the default value of the
+	// SharedConfigState type.
+	SharedConfigStateFromEnv SharedConfigState = iota
+
+	// SharedConfigDisable overrides the AWS_SDK_LOAD_CONFIG env var value
+	// and disables the shared config functionality.
+	SharedConfigDisable
+
+	// SharedConfigEnable overrides the AWS_SDK_LOAD_CONFIG env var value
+	// and enables the shared config functionality.
+	SharedConfigEnable
+)
+
+// Options provides the means to control how a Session is created and what
+// configuration values will be loaded.
+//
+type Options struct {
+	// Provides config values for the SDK to use when creating service clients
+	// and making API requests to services. Any value set in with this field
+	// will override the associated value provided by the SDK defaults,
+	// environment or config files where relevant.
+	//
+	// If not set, configuration values from from SDK defaults, environment,
+	// config will be used.
+	Config aws.Config
+
+	// Overrides the config profile the Session should be created from. If not
+	// set the value of the environment variable will be loaded (AWS_PROFILE,
+	// or AWS_DEFAULT_PROFILE if the Shared Config is enabled).
+	//
+	// If not set and environment variables are not set the "default"
+	// (DefaultSharedConfigProfile) will be used as the profile to load the
+	// session config from.
+	Profile string
+
+	// Instructs how the Session will be created based on the AWS_SDK_LOAD_CONFIG
+	// environment variable. By default a Session will be created using the
+	// value provided by the AWS_SDK_LOAD_CONFIG environment variable.
+	//
+	// Setting this value to SharedConfigEnable or SharedConfigDisable
+	// will allow you to override the AWS_SDK_LOAD_CONFIG environment variable
+	// and enable or disable the shared config functionality.
+	SharedConfigState SharedConfigState
+
+	// Ordered list of files the session will load configuration from.
+	// It will override environment variable AWS_SHARED_CREDENTIALS_FILE, AWS_CONFIG_FILE.
+	SharedConfigFiles []string
+
+	// When the SDK's shared config is configured to assume a role with MFA
+	// this option is required in order to provide the mechanism that will
+	// retrieve the MFA token. There is no default value for this field. If
+	// it is not set an error will be returned when creating the session.
+	//
+	// This token provider will be called when ever the assumed role's
+	// credentials need to be refreshed. Within the context of service clients
+	// all sharing the same session the SDK will ensure calls to the token
+	// provider are atomic. When sharing a token provider across multiple
+	// sessions additional synchronization logic is needed to ensure the
+	// token providers do not introduce race conditions. It is recommend to
+	// share the session where possible.
+	//
+	// stscreds.StdinTokenProvider is a basic implementation that will prompt
+	// from stdin for the MFA token code.
+	//
+	// This field is only used if the shared configuration is enabled, and
+	// the config enables assume role wit MFA via the mfa_serial field.
+	AssumeRoleTokenProvider func() (string, error)
+
+	// Reader for a custom Credentials Authority (CA) bundle in PEM format that
+	// the SDK will use instead of the default system's root CA bundle. Use this
+	// only if you want to replace the CA bundle the SDK uses for TLS requests.
+	//
+	// Enabling this option will attempt to merge the Transport into the SDK's HTTP
+	// client. If the client's Transport is not a http.Transport an error will be
+	// returned. If the Transport's TLS config is set this option will cause the SDK
+	// to overwrite the Transport's TLS config's  RootCAs value. If the CA
+	// bundle reader contains multiple certificates all of them will be loaded.
+	//
+	// The Session option CustomCABundle is also available when creating sessions
+	// to also enable this feature. CustomCABundle session option field has priority
+	// over the AWS_CA_BUNDLE environment variable, and will be used if both are set.
+	CustomCABundle io.Reader
+}
+
+// NewSessionWithOptions returns a new Session created from SDK defaults, config files,
+// environment, and user provided config files. This func uses the Options
+// values to configure how the Session is created.
+//
+// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value
+// the shared config file (~/.aws/config) will also be loaded in addition to
+// the shared credentials file (~/.aws/credentials). Values set in both the
+// shared config, and shared credentials will be taken from the shared
+// credentials file. Enabling the Shared Config will also allow the Session
+// to be built with retrieving credentials with AssumeRole set in the config.
+//
+//     // Equivalent to session.New
+//     sess := session.Must(session.NewSessionWithOptions(session.Options{}))
+//
+//     // Specify profile to load for the session's config
+//     sess := session.Must(session.NewSessionWithOptions(session.Options{
+//          Profile: "profile_name",
+//     }))
+//
+//     // Specify profile for config and region for requests
+//     sess := session.Must(session.NewSessionWithOptions(session.Options{
+//          Config: aws.Config{Region: aws.String("us-east-1")},
+//          Profile: "profile_name",
+//     }))
+//
+//     // Force enable Shared Config support
+//     sess := session.Must(session.NewSessionWithOptions(session.Options{
+//         SharedConfigState: session.SharedConfigEnable,
+//     }))
+func NewSessionWithOptions(opts Options) (*Session, error) {
+	var envCfg envConfig
+	if opts.SharedConfigState == SharedConfigEnable {
+		envCfg = loadSharedEnvConfig()
+	} else {
+		envCfg = loadEnvConfig()
+	}
+
+	if len(opts.Profile) > 0 {
+		envCfg.Profile = opts.Profile
+	}
+
+	switch opts.SharedConfigState {
+	case SharedConfigDisable:
+		envCfg.EnableSharedConfig = false
+	case SharedConfigEnable:
+		envCfg.EnableSharedConfig = true
+	}
+
+	// Only use AWS_CA_BUNDLE if session option is not provided.
+	if len(envCfg.CustomCABundle) != 0 && opts.CustomCABundle == nil {
+		f, err := os.Open(envCfg.CustomCABundle)
+		if err != nil {
+			return nil, awserr.New("LoadCustomCABundleError",
+				"failed to open custom CA bundle PEM file", err)
+		}
+		defer f.Close()
+		opts.CustomCABundle = f
+	}
+
+	return newSession(opts, envCfg, &opts.Config)
+}
+
+// Must is a helper function to ensure the Session is valid and there was no
+// error when calling a NewSession function.
+//
+// This helper is intended to be used in variable initialization to load the
+// Session and configuration at startup. Such as:
+//
+//     var sess = session.Must(session.NewSession())
+func Must(sess *Session, err error) *Session {
+	if err != nil {
+		panic(err)
+	}
+
+	return sess
+}
+
+func deprecatedNewSession(cfgs ...*aws.Config) *Session {
+	cfg := defaults.Config()
+	handlers := defaults.Handlers()
+
+	// Apply the passed in configs so the configuration can be applied to the
+	// default credential chain
+	cfg.MergeIn(cfgs...)
+	if cfg.EndpointResolver == nil {
+		// An endpoint resolver is required for a session to be able to provide
+		// endpoints for service client configurations.
+		cfg.EndpointResolver = endpoints.DefaultResolver()
+	}
+	cfg.Credentials = defaults.CredChain(cfg, handlers)
+
+	// Reapply any passed in configs to override credentials if set
+	cfg.MergeIn(cfgs...)
+
+	s := &Session{
+		Config:   cfg,
+		Handlers: handlers,
+	}
+
+	initHandlers(s)
+	return s
+}
+
+func enableCSM(handlers *request.Handlers, clientID string, port string, logger aws.Logger) {
+	logger.Log("Enabling CSM")
+	if len(port) == 0 {
+		port = csm.DefaultPort
+	}
+
+	r, err := csm.Start(clientID, "127.0.0.1:"+port)
+	if err != nil {
+		return
+	}
+	r.InjectHandlers(handlers)
+}
+
+func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session, error) {
+	cfg := defaults.Config()
+	handlers := defaults.Handlers()
+
+	// Get a merged version of the user provided config to determine if
+	// credentials were.
+	userCfg := &aws.Config{}
+	userCfg.MergeIn(cfgs...)
+
+	// Ordered config files will be loaded in with later files overwriting
+	// previous config file values.
+	var cfgFiles []string
+	if opts.SharedConfigFiles != nil {
+		cfgFiles = opts.SharedConfigFiles
+	} else {
+		cfgFiles = []string{envCfg.SharedConfigFile, envCfg.SharedCredentialsFile}
+		if !envCfg.EnableSharedConfig {
+			// The shared config file (~/.aws/config) is only loaded if instructed
+			// to load via the envConfig.EnableSharedConfig (AWS_SDK_LOAD_CONFIG).
+			cfgFiles = cfgFiles[1:]
+		}
+	}
+
+	// Load additional config from file(s)
+	sharedCfg, err := loadSharedConfig(envCfg.Profile, cfgFiles)
+	if err != nil {
+		return nil, err
+	}
+
+	if err := mergeConfigSrcs(cfg, userCfg, envCfg, sharedCfg, handlers, opts); err != nil {
+		return nil, err
+	}
+
+	s := &Session{
+		Config:   cfg,
+		Handlers: handlers,
+	}
+
+	initHandlers(s)
+	if envCfg.CSMEnabled {
+		enableCSM(&s.Handlers, envCfg.CSMClientID, envCfg.CSMPort, s.Config.Logger)
+	}
+
+	// Setup HTTP client with custom cert bundle if enabled
+	if opts.CustomCABundle != nil {
+		if err := loadCustomCABundle(s, opts.CustomCABundle); err != nil {
+			return nil, err
+		}
+	}
+
+	return s, nil
+}
+
+func loadCustomCABundle(s *Session, bundle io.Reader) error {
+	var t *http.Transport
+	switch v := s.Config.HTTPClient.Transport.(type) {
+	case *http.Transport:
+		t = v
+	default:
+		if s.Config.HTTPClient.Transport != nil {
+			return awserr.New("LoadCustomCABundleError",
+				"unable to load custom CA bundle, HTTPClient's transport unsupported type", nil)
+		}
+	}
+	if t == nil {
+		t = &http.Transport{}
+	}
+
+	p, err := loadCertPool(bundle)
+	if err != nil {
+		return err
+	}
+	if t.TLSClientConfig == nil {
+		t.TLSClientConfig = &tls.Config{}
+	}
+	t.TLSClientConfig.RootCAs = p
+
+	s.Config.HTTPClient.Transport = t
+
+	return nil
+}
+
+func loadCertPool(r io.Reader) (*x509.CertPool, error) {
+	b, err := ioutil.ReadAll(r)
+	if err != nil {
+		return nil, awserr.New("LoadCustomCABundleError",
+			"failed to read custom CA bundle PEM file", err)
+	}
+
+	p := x509.NewCertPool()
+	if !p.AppendCertsFromPEM(b) {
+		return nil, awserr.New("LoadCustomCABundleError",
+			"failed to load custom CA bundle PEM file", err)
+	}
+
+	return p, nil
+}
+
+func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg sharedConfig, handlers request.Handlers, sessOpts Options) error {
+	// Merge in user provided configuration
+	cfg.MergeIn(userCfg)
+
+	// Region if not already set by user
+	if len(aws.StringValue(cfg.Region)) == 0 {
+		if len(envCfg.Region) > 0 {
+			cfg.WithRegion(envCfg.Region)
+		} else if envCfg.EnableSharedConfig && len(sharedCfg.Region) > 0 {
+			cfg.WithRegion(sharedCfg.Region)
+		}
+	}
+
+	// Configure credentials if not already set
+	if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil {
+		if len(envCfg.Creds.AccessKeyID) > 0 {
+			cfg.Credentials = credentials.NewStaticCredentialsFromCreds(
+				envCfg.Creds,
+			)
+		} else if envCfg.EnableSharedConfig && len(sharedCfg.AssumeRole.RoleARN) > 0 && sharedCfg.AssumeRoleSource != nil {
+			cfgCp := *cfg
+			cfgCp.Credentials = credentials.NewStaticCredentialsFromCreds(
+				sharedCfg.AssumeRoleSource.Creds,
+			)
+			if len(sharedCfg.AssumeRole.MFASerial) > 0 && sessOpts.AssumeRoleTokenProvider == nil {
+				// AssumeRole Token provider is required if doing Assume Role
+				// with MFA.
+				return AssumeRoleTokenProviderNotSetError{}
+			}
+			cfg.Credentials = stscreds.NewCredentials(
+				&Session{
+					Config:   &cfgCp,
+					Handlers: handlers.Copy(),
+				},
+				sharedCfg.AssumeRole.RoleARN,
+				func(opt *stscreds.AssumeRoleProvider) {
+					opt.RoleSessionName = sharedCfg.AssumeRole.RoleSessionName
+
+					// Assume role with external ID
+					if len(sharedCfg.AssumeRole.ExternalID) > 0 {
+						opt.ExternalID = aws.String(sharedCfg.AssumeRole.ExternalID)
+					}
+
+					// Assume role with MFA
+					if len(sharedCfg.AssumeRole.MFASerial) > 0 {
+						opt.SerialNumber = aws.String(sharedCfg.AssumeRole.MFASerial)
+						opt.TokenProvider = sessOpts.AssumeRoleTokenProvider
+					}
+				},
+			)
+		} else if len(sharedCfg.Creds.AccessKeyID) > 0 {
+			cfg.Credentials = credentials.NewStaticCredentialsFromCreds(
+				sharedCfg.Creds,
+			)
+		} else {
+			// Fallback to default credentials provider, include mock errors
+			// for the credential chain so user can identify why credentials
+			// failed to be retrieved.
+			cfg.Credentials = credentials.NewCredentials(&credentials.ChainProvider{
+				VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors),
+				Providers: []credentials.Provider{
+					&credProviderError{Err: awserr.New("EnvAccessKeyNotFound", "failed to find credentials in the environment.", nil)},
+					&credProviderError{Err: awserr.New("SharedCredsLoad", fmt.Sprintf("failed to load profile, %s.", envCfg.Profile), nil)},
+					defaults.RemoteCredProvider(*cfg, handlers),
+				},
+			})
+		}
+	}
+
+	return nil
+}
+
+// AssumeRoleTokenProviderNotSetError is an error returned when creating a session when the
+// MFAToken option is not set when shared config is configured load assume a
+// role with an MFA token.
+type AssumeRoleTokenProviderNotSetError struct{}
+
+// Code is the short id of the error.
+func (e AssumeRoleTokenProviderNotSetError) Code() string {
+	return "AssumeRoleTokenProviderNotSetError"
+}
+
+// Message is the description of the error
+func (e AssumeRoleTokenProviderNotSetError) Message() string {
+	return fmt.Sprintf("assume role with MFA enabled, but AssumeRoleTokenProvider session option not set.")
+}
+
+// OrigErr is the underlying error that caused the failure.
+func (e AssumeRoleTokenProviderNotSetError) OrigErr() error {
+	return nil
+}
+
+// Error satisfies the error interface.
+func (e AssumeRoleTokenProviderNotSetError) Error() string {
+	return awserr.SprintError(e.Code(), e.Message(), "", nil)
+}
+
+type credProviderError struct {
+	Err error
+}
+
+var emptyCreds = credentials.Value{}
+
+func (c credProviderError) Retrieve() (credentials.Value, error) {
+	return credentials.Value{}, c.Err
+}
+func (c credProviderError) IsExpired() bool {
+	return true
+}
+
+func initHandlers(s *Session) {
+	// Add the Validate parameter handler if it is not disabled.
+	s.Handlers.Validate.Remove(corehandlers.ValidateParametersHandler)
+	if !aws.BoolValue(s.Config.DisableParamValidation) {
+		s.Handlers.Validate.PushBackNamed(corehandlers.ValidateParametersHandler)
+	}
+}
+
+// Copy creates and returns a copy of the current Session, coping the config
+// and handlers. If any additional configs are provided they will be merged
+// on top of the Session's copied config.
+//
+//     // Create a copy of the current Session, configured for the us-west-2 region.
+//     sess.Copy(&aws.Config{Region: aws.String("us-west-2")})
+func (s *Session) Copy(cfgs ...*aws.Config) *Session {
+	newSession := &Session{
+		Config:   s.Config.Copy(cfgs...),
+		Handlers: s.Handlers.Copy(),
+	}
+
+	initHandlers(newSession)
+
+	return newSession
+}
+
+// ClientConfig satisfies the client.ConfigProvider interface and is used to
+// configure the service client instances. Passing the Session to the service
+// client's constructor (New) will use this method to configure the client.
+func (s *Session) ClientConfig(serviceName string, cfgs ...*aws.Config) client.Config {
+	// Backwards compatibility, the error will be eaten if user calls ClientConfig
+	// directly. All SDK services will use ClientconfigWithError.
+	cfg, _ := s.clientConfigWithErr(serviceName, cfgs...)
+
+	return cfg
+}
+
+func (s *Session) clientConfigWithErr(serviceName string, cfgs ...*aws.Config) (client.Config, error) {
+	s = s.Copy(cfgs...)
+
+	var resolved endpoints.ResolvedEndpoint
+	var err error
+
+	region := aws.StringValue(s.Config.Region)
+
+	if endpoint := aws.StringValue(s.Config.Endpoint); len(endpoint) != 0 {
+		resolved.URL = endpoints.AddScheme(endpoint, aws.BoolValue(s.Config.DisableSSL))
+		resolved.SigningRegion = region
+	} else {
+		resolved, err = s.Config.EndpointResolver.EndpointFor(
+			serviceName, region,
+			func(opt *endpoints.Options) {
+				opt.DisableSSL = aws.BoolValue(s.Config.DisableSSL)
+				opt.UseDualStack = aws.BoolValue(s.Config.UseDualStack)
+
+				// Support the condition where the service is modeled but its
+				// endpoint metadata is not available.
+				opt.ResolveUnknownService = true
+			},
+		)
+	}
+
+	return client.Config{
+		Config:             s.Config,
+		Handlers:           s.Handlers,
+		Endpoint:           resolved.URL,
+		SigningRegion:      resolved.SigningRegion,
+		SigningNameDerived: resolved.SigningNameDerived,
+		SigningName:        resolved.SigningName,
+	}, err
+}
+
+// ClientConfigNoResolveEndpoint is the same as ClientConfig with the exception
+// that the EndpointResolver will not be used to resolve the endpoint. The only
+// endpoint set must come from the aws.Config.Endpoint field.
+func (s *Session) ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) client.Config {
+	s = s.Copy(cfgs...)
+
+	var resolved endpoints.ResolvedEndpoint
+
+	region := aws.StringValue(s.Config.Region)
+
+	if ep := aws.StringValue(s.Config.Endpoint); len(ep) > 0 {
+		resolved.URL = endpoints.AddScheme(ep, aws.BoolValue(s.Config.DisableSSL))
+		resolved.SigningRegion = region
+	}
+
+	return client.Config{
+		Config:             s.Config,
+		Handlers:           s.Handlers,
+		Endpoint:           resolved.URL,
+		SigningRegion:      resolved.SigningRegion,
+		SigningNameDerived: resolved.SigningNameDerived,
+		SigningName:        resolved.SigningName,
+	}
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go b/vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go
new file mode 100644
index 000000000..09c8e5bc7
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go
@@ -0,0 +1,295 @@
+package session
+
+import (
+	"fmt"
+	"io/ioutil"
+
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/credentials"
+	"github.com/go-ini/ini"
+)
+
+const (
+	// Static Credentials group
+	accessKeyIDKey  = `aws_access_key_id`     // group required
+	secretAccessKey = `aws_secret_access_key` // group required
+	sessionTokenKey = `aws_session_token`     // optional
+
+	// Assume Role Credentials group
+	roleArnKey         = `role_arn`          // group required
+	sourceProfileKey   = `source_profile`    // group required
+	externalIDKey      = `external_id`       // optional
+	mfaSerialKey       = `mfa_serial`        // optional
+	roleSessionNameKey = `role_session_name` // optional
+
+	// Additional Config fields
+	regionKey = `region`
+
+	// DefaultSharedConfigProfile is the default profile to be used when
+	// loading configuration from the config files if another profile name
+	// is not provided.
+	DefaultSharedConfigProfile = `default`
+)
+
+type assumeRoleConfig struct {
+	RoleARN         string
+	SourceProfile   string
+	ExternalID      string
+	MFASerial       string
+	RoleSessionName string
+}
+
+// sharedConfig represents the configuration fields of the SDK config files.
+type sharedConfig struct {
+	// Credentials values from the config file. Both aws_access_key_id
+	// and aws_secret_access_key must be provided together in the same file
+	// to be considered valid. The values will be ignored if not a complete group.
+	// aws_session_token is an optional field that can be provided if both of the
+	// other two fields are also provided.
+	//
+	//	aws_access_key_id
+	//	aws_secret_access_key
+	//	aws_session_token
+	Creds credentials.Value
+
+	AssumeRole       assumeRoleConfig
+	AssumeRoleSource *sharedConfig
+
+	// Region is the region the SDK should use for looking up AWS service endpoints
+	// and signing requests.
+	//
+	//	region
+	Region string
+}
+
+type sharedConfigFile struct {
+	Filename string
+	IniData  *ini.File
+}
+
+// loadSharedConfig retrieves the configuration from the list of files
+// using the profile provided. The order the files are listed will determine
+// precedence. Values in subsequent files will overwrite values defined in
+// earlier files.
+//
+// For example, given two files A and B. Both define credentials. If the order
+// of the files are A then B, B's credential values will be used instead of A's.
+//
+// See sharedConfig.setFromFile for information how the config files
+// will be loaded.
+func loadSharedConfig(profile string, filenames []string) (sharedConfig, error) {
+	if len(profile) == 0 {
+		profile = DefaultSharedConfigProfile
+	}
+
+	files, err := loadSharedConfigIniFiles(filenames)
+	if err != nil {
+		return sharedConfig{}, err
+	}
+
+	cfg := sharedConfig{}
+	if err = cfg.setFromIniFiles(profile, files); err != nil {
+		return sharedConfig{}, err
+	}
+
+	if len(cfg.AssumeRole.SourceProfile) > 0 {
+		if err := cfg.setAssumeRoleSource(profile, files); err != nil {
+			return sharedConfig{}, err
+		}
+	}
+
+	return cfg, nil
+}
+
+func loadSharedConfigIniFiles(filenames []string) ([]sharedConfigFile, error) {
+	files := make([]sharedConfigFile, 0, len(filenames))
+
+	for _, filename := range filenames {
+		b, err := ioutil.ReadFile(filename)
+		if err != nil {
+			// Skip files which can't be opened and read for whatever reason
+			continue
+		}
+
+		f, err := ini.Load(b)
+		if err != nil {
+			return nil, SharedConfigLoadError{Filename: filename, Err: err}
+		}
+
+		files = append(files, sharedConfigFile{
+			Filename: filename, IniData: f,
+		})
+	}
+
+	return files, nil
+}
+
+func (cfg *sharedConfig) setAssumeRoleSource(origProfile string, files []sharedConfigFile) error {
+	var assumeRoleSrc sharedConfig
+
+	// Multiple level assume role chains are not support
+	if cfg.AssumeRole.SourceProfile == origProfile {
+		assumeRoleSrc = *cfg
+		assumeRoleSrc.AssumeRole = assumeRoleConfig{}
+	} else {
+		err := assumeRoleSrc.setFromIniFiles(cfg.AssumeRole.SourceProfile, files)
+		if err != nil {
+			return err
+		}
+	}
+
+	if len(assumeRoleSrc.Creds.AccessKeyID) == 0 {
+		return SharedConfigAssumeRoleError{RoleARN: cfg.AssumeRole.RoleARN}
+	}
+
+	cfg.AssumeRoleSource = &assumeRoleSrc
+
+	return nil
+}
+
+func (cfg *sharedConfig) setFromIniFiles(profile string, files []sharedConfigFile) error {
+	// Trim files from the list that don't exist.
+	for _, f := range files {
+		if err := cfg.setFromIniFile(profile, f); err != nil {
+			if _, ok := err.(SharedConfigProfileNotExistsError); ok {
+				// Ignore proviles missings
+				continue
+			}
+			return err
+		}
+	}
+
+	return nil
+}
+
+// setFromFile loads the configuration from the file using
+// the profile provided. A sharedConfig pointer type value is used so that
+// multiple config file loadings can be chained.
+//
+// Only loads complete logically grouped values, and will not set fields in cfg
+// for incomplete grouped values in the config. Such as credentials. For example
+// if a config file only includes aws_access_key_id but no aws_secret_access_key
+// the aws_access_key_id will be ignored.
+func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile) error {
+	section, err := file.IniData.GetSection(profile)
+	if err != nil {
+		// Fallback to to alternate profile name: profile 
+		section, err = file.IniData.GetSection(fmt.Sprintf("profile %s", profile))
+		if err != nil {
+			return SharedConfigProfileNotExistsError{Profile: profile, Err: err}
+		}
+	}
+
+	// Shared Credentials
+	akid := section.Key(accessKeyIDKey).String()
+	secret := section.Key(secretAccessKey).String()
+	if len(akid) > 0 && len(secret) > 0 {
+		cfg.Creds = credentials.Value{
+			AccessKeyID:     akid,
+			SecretAccessKey: secret,
+			SessionToken:    section.Key(sessionTokenKey).String(),
+			ProviderName:    fmt.Sprintf("SharedConfigCredentials: %s", file.Filename),
+		}
+	}
+
+	// Assume Role
+	roleArn := section.Key(roleArnKey).String()
+	srcProfile := section.Key(sourceProfileKey).String()
+	if len(roleArn) > 0 && len(srcProfile) > 0 {
+		cfg.AssumeRole = assumeRoleConfig{
+			RoleARN:         roleArn,
+			SourceProfile:   srcProfile,
+			ExternalID:      section.Key(externalIDKey).String(),
+			MFASerial:       section.Key(mfaSerialKey).String(),
+			RoleSessionName: section.Key(roleSessionNameKey).String(),
+		}
+	}
+
+	// Region
+	if v := section.Key(regionKey).String(); len(v) > 0 {
+		cfg.Region = v
+	}
+
+	return nil
+}
+
+// SharedConfigLoadError is an error for the shared config file failed to load.
+type SharedConfigLoadError struct {
+	Filename string
+	Err      error
+}
+
+// Code is the short id of the error.
+func (e SharedConfigLoadError) Code() string {
+	return "SharedConfigLoadError"
+}
+
+// Message is the description of the error
+func (e SharedConfigLoadError) Message() string {
+	return fmt.Sprintf("failed to load config file, %s", e.Filename)
+}
+
+// OrigErr is the underlying error that caused the failure.
+func (e SharedConfigLoadError) OrigErr() error {
+	return e.Err
+}
+
+// Error satisfies the error interface.
+func (e SharedConfigLoadError) Error() string {
+	return awserr.SprintError(e.Code(), e.Message(), "", e.Err)
+}
+
+// SharedConfigProfileNotExistsError is an error for the shared config when
+// the profile was not find in the config file.
+type SharedConfigProfileNotExistsError struct {
+	Profile string
+	Err     error
+}
+
+// Code is the short id of the error.
+func (e SharedConfigProfileNotExistsError) Code() string {
+	return "SharedConfigProfileNotExistsError"
+}
+
+// Message is the description of the error
+func (e SharedConfigProfileNotExistsError) Message() string {
+	return fmt.Sprintf("failed to get profile, %s", e.Profile)
+}
+
+// OrigErr is the underlying error that caused the failure.
+func (e SharedConfigProfileNotExistsError) OrigErr() error {
+	return e.Err
+}
+
+// Error satisfies the error interface.
+func (e SharedConfigProfileNotExistsError) Error() string {
+	return awserr.SprintError(e.Code(), e.Message(), "", e.Err)
+}
+
+// SharedConfigAssumeRoleError is an error for the shared config when the
+// profile contains assume role information, but that information is invalid
+// or not complete.
+type SharedConfigAssumeRoleError struct {
+	RoleARN string
+}
+
+// Code is the short id of the error.
+func (e SharedConfigAssumeRoleError) Code() string {
+	return "SharedConfigAssumeRoleError"
+}
+
+// Message is the description of the error
+func (e SharedConfigAssumeRoleError) Message() string {
+	return fmt.Sprintf("failed to load assume role for %s, source profile has no shared credentials",
+		e.RoleARN)
+}
+
+// OrigErr is the underlying error that caused the failure.
+func (e SharedConfigAssumeRoleError) OrigErr() error {
+	return nil
+}
+
+// Error satisfies the error interface.
+func (e SharedConfigAssumeRoleError) Error() string {
+	return awserr.SprintError(e.Code(), e.Message(), "", nil)
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go
new file mode 100644
index 000000000..244c86da0
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go
@@ -0,0 +1,82 @@
+package v4
+
+import (
+	"net/http"
+	"strings"
+)
+
+// validator houses a set of rule needed for validation of a
+// string value
+type rules []rule
+
+// rule interface allows for more flexible rules and just simply
+// checks whether or not a value adheres to that rule
+type rule interface {
+	IsValid(value string) bool
+}
+
+// IsValid will iterate through all rules and see if any rules
+// apply to the value and supports nested rules
+func (r rules) IsValid(value string) bool {
+	for _, rule := range r {
+		if rule.IsValid(value) {
+			return true
+		}
+	}
+	return false
+}
+
+// mapRule generic rule for maps
+type mapRule map[string]struct{}
+
+// IsValid for the map rule satisfies whether it exists in the map
+func (m mapRule) IsValid(value string) bool {
+	_, ok := m[value]
+	return ok
+}
+
+// whitelist is a generic rule for whitelisting
+type whitelist struct {
+	rule
+}
+
+// IsValid for whitelist checks if the value is within the whitelist
+func (w whitelist) IsValid(value string) bool {
+	return w.rule.IsValid(value)
+}
+
+// blacklist is a generic rule for blacklisting
+type blacklist struct {
+	rule
+}
+
+// IsValid for whitelist checks if the value is within the whitelist
+func (b blacklist) IsValid(value string) bool {
+	return !b.rule.IsValid(value)
+}
+
+type patterns []string
+
+// IsValid for patterns checks each pattern and returns if a match has
+// been found
+func (p patterns) IsValid(value string) bool {
+	for _, pattern := range p {
+		if strings.HasPrefix(http.CanonicalHeaderKey(value), pattern) {
+			return true
+		}
+	}
+	return false
+}
+
+// inclusiveRules rules allow for rules to depend on one another
+type inclusiveRules []rule
+
+// IsValid will return true if all rules are true
+func (r inclusiveRules) IsValid(value string) bool {
+	for _, rule := range r {
+		if !rule.IsValid(value) {
+			return false
+		}
+	}
+	return true
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go
new file mode 100644
index 000000000..6aa2ed241
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go
@@ -0,0 +1,7 @@
+package v4
+
+// WithUnsignedPayload will enable and set the UnsignedPayload field to
+// true of the signer.
+func WithUnsignedPayload(v4 *Signer) {
+	v4.UnsignedPayload = true
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/uri_path.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/uri_path.go
new file mode 100644
index 000000000..bd082e9d1
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/uri_path.go
@@ -0,0 +1,24 @@
+// +build go1.5
+
+package v4
+
+import (
+	"net/url"
+	"strings"
+)
+
+func getURIPath(u *url.URL) string {
+	var uri string
+
+	if len(u.Opaque) > 0 {
+		uri = "/" + strings.Join(strings.Split(u.Opaque, "/")[3:], "/")
+	} else {
+		uri = u.EscapedPath()
+	}
+
+	if len(uri) == 0 {
+		uri = "/"
+	}
+
+	return uri
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go
new file mode 100644
index 000000000..8aa0681d3
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go
@@ -0,0 +1,788 @@
+// Package v4 implements signing for AWS V4 signer
+//
+// Provides request signing for request that need to be signed with
+// AWS V4 Signatures.
+//
+// Standalone Signer
+//
+// Generally using the signer outside of the SDK should not require any additional
+// logic when using Go v1.5 or higher. The signer does this by taking advantage
+// of the URL.EscapedPath method. If your request URI requires additional escaping
+// you many need to use the URL.Opaque to define what the raw URI should be sent
+// to the service as.
+//
+// The signer will first check the URL.Opaque field, and use its value if set.
+// The signer does require the URL.Opaque field to be set in the form of:
+//
+//     "///"
+//
+//     // e.g.
+//     "//example.com/some/path"
+//
+// The leading "//" and hostname are required or the URL.Opaque escaping will
+// not work correctly.
+//
+// If URL.Opaque is not set the signer will fallback to the URL.EscapedPath()
+// method and using the returned value. If you're using Go v1.4 you must set
+// URL.Opaque if the URI path needs escaping. If URL.Opaque is not set with
+// Go v1.5 the signer will fallback to URL.Path.
+//
+// AWS v4 signature validation requires that the canonical string's URI path
+// element must be the URI escaped form of the HTTP request's path.
+// http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
+//
+// The Go HTTP client will perform escaping automatically on the request. Some
+// of these escaping may cause signature validation errors because the HTTP
+// request differs from the URI path or query that the signature was generated.
+// https://golang.org/pkg/net/url/#URL.EscapedPath
+//
+// Because of this, it is recommended that when using the signer outside of the
+// SDK that explicitly escaping the request prior to being signed is preferable,
+// and will help prevent signature validation errors. This can be done by setting
+// the URL.Opaque or URL.RawPath. The SDK will use URL.Opaque first and then
+// call URL.EscapedPath() if Opaque is not set.
+//
+// If signing a request intended for HTTP2 server, and you're using Go 1.6.2
+// through 1.7.4 you should use the URL.RawPath as the pre-escaped form of the
+// request URL. https://github.com/golang/go/issues/16847 points to a bug in
+// Go pre 1.8 that fails to make HTTP2 requests using absolute URL in the HTTP
+// message. URL.Opaque generally will force Go to make requests with absolute URL.
+// URL.RawPath does not do this, but RawPath must be a valid escaping of Path
+// or url.EscapedPath will ignore the RawPath escaping.
+//
+// Test `TestStandaloneSign` provides a complete example of using the signer
+// outside of the SDK and pre-escaping the URI path.
+package v4
+
+import (
+	"crypto/hmac"
+	"crypto/sha256"
+	"encoding/hex"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+	"sort"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/credentials"
+	"github.com/aws/aws-sdk-go/aws/request"
+	"github.com/aws/aws-sdk-go/internal/sdkio"
+	"github.com/aws/aws-sdk-go/private/protocol/rest"
+)
+
+const (
+	authHeaderPrefix = "AWS4-HMAC-SHA256"
+	timeFormat       = "20060102T150405Z"
+	shortTimeFormat  = "20060102"
+
+	// emptyStringSHA256 is a SHA256 of an empty string
+	emptyStringSHA256 = `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`
+)
+
+var ignoredHeaders = rules{
+	blacklist{
+		mapRule{
+			"Authorization":   struct{}{},
+			"User-Agent":      struct{}{},
+			"X-Amzn-Trace-Id": struct{}{},
+		},
+	},
+}
+
+// requiredSignedHeaders is a whitelist for build canonical headers.
+var requiredSignedHeaders = rules{
+	whitelist{
+		mapRule{
+			"Cache-Control":                         struct{}{},
+			"Content-Disposition":                   struct{}{},
+			"Content-Encoding":                      struct{}{},
+			"Content-Language":                      struct{}{},
+			"Content-Md5":                           struct{}{},
+			"Content-Type":                          struct{}{},
+			"Expires":                               struct{}{},
+			"If-Match":                              struct{}{},
+			"If-Modified-Since":                     struct{}{},
+			"If-None-Match":                         struct{}{},
+			"If-Unmodified-Since":                   struct{}{},
+			"Range":                                 struct{}{},
+			"X-Amz-Acl":                             struct{}{},
+			"X-Amz-Copy-Source":                     struct{}{},
+			"X-Amz-Copy-Source-If-Match":            struct{}{},
+			"X-Amz-Copy-Source-If-Modified-Since":   struct{}{},
+			"X-Amz-Copy-Source-If-None-Match":       struct{}{},
+			"X-Amz-Copy-Source-If-Unmodified-Since": struct{}{},
+			"X-Amz-Copy-Source-Range":               struct{}{},
+			"X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": struct{}{},
+			"X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key":       struct{}{},
+			"X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5":   struct{}{},
+			"X-Amz-Grant-Full-control":                                    struct{}{},
+			"X-Amz-Grant-Read":                                            struct{}{},
+			"X-Amz-Grant-Read-Acp":                                        struct{}{},
+			"X-Amz-Grant-Write":                                           struct{}{},
+			"X-Amz-Grant-Write-Acp":                                       struct{}{},
+			"X-Amz-Metadata-Directive":                                    struct{}{},
+			"X-Amz-Mfa":                                                   struct{}{},
+			"X-Amz-Request-Payer":                                         struct{}{},
+			"X-Amz-Server-Side-Encryption":                                struct{}{},
+			"X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id":                 struct{}{},
+			"X-Amz-Server-Side-Encryption-Customer-Algorithm":             struct{}{},
+			"X-Amz-Server-Side-Encryption-Customer-Key":                   struct{}{},
+			"X-Amz-Server-Side-Encryption-Customer-Key-Md5":               struct{}{},
+			"X-Amz-Storage-Class":                                         struct{}{},
+			"X-Amz-Website-Redirect-Location":                             struct{}{},
+			"X-Amz-Content-Sha256":                                        struct{}{},
+		},
+	},
+	patterns{"X-Amz-Meta-"},
+}
+
+// allowedHoisting is a whitelist for build query headers. The boolean value
+// represents whether or not it is a pattern.
+var allowedQueryHoisting = inclusiveRules{
+	blacklist{requiredSignedHeaders},
+	patterns{"X-Amz-"},
+}
+
+// Signer applies AWS v4 signing to given request. Use this to sign requests
+// that need to be signed with AWS V4 Signatures.
+type Signer struct {
+	// The authentication credentials the request will be signed against.
+	// This value must be set to sign requests.
+	Credentials *credentials.Credentials
+
+	// Sets the log level the signer should use when reporting information to
+	// the logger. If the logger is nil nothing will be logged. See
+	// aws.LogLevelType for more information on available logging levels
+	//
+	// By default nothing will be logged.
+	Debug aws.LogLevelType
+
+	// The logger loging information will be written to. If there the logger
+	// is nil, nothing will be logged.
+	Logger aws.Logger
+
+	// Disables the Signer's moving HTTP header key/value pairs from the HTTP
+	// request header to the request's query string. This is most commonly used
+	// with pre-signed requests preventing headers from being added to the
+	// request's query string.
+	DisableHeaderHoisting bool
+
+	// Disables the automatic escaping of the URI path of the request for the
+	// siganture's canonical string's path. For services that do not need additional
+	// escaping then use this to disable the signer escaping the path.
+	//
+	// S3 is an example of a service that does not need additional escaping.
+	//
+	// http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
+	DisableURIPathEscaping bool
+
+	// Disales the automatical setting of the HTTP request's Body field with the
+	// io.ReadSeeker passed in to the signer. This is useful if you're using a
+	// custom wrapper around the body for the io.ReadSeeker and want to preserve
+	// the Body value on the Request.Body.
+	//
+	// This does run the risk of signing a request with a body that will not be
+	// sent in the request. Need to ensure that the underlying data of the Body
+	// values are the same.
+	DisableRequestBodyOverwrite bool
+
+	// currentTimeFn returns the time value which represents the current time.
+	// This value should only be used for testing. If it is nil the default
+	// time.Now will be used.
+	currentTimeFn func() time.Time
+
+	// UnsignedPayload will prevent signing of the payload. This will only
+	// work for services that have support for this.
+	UnsignedPayload bool
+}
+
+// NewSigner returns a Signer pointer configured with the credentials and optional
+// option values provided. If not options are provided the Signer will use its
+// default configuration.
+func NewSigner(credentials *credentials.Credentials, options ...func(*Signer)) *Signer {
+	v4 := &Signer{
+		Credentials: credentials,
+	}
+
+	for _, option := range options {
+		option(v4)
+	}
+
+	return v4
+}
+
+type signingCtx struct {
+	ServiceName      string
+	Region           string
+	Request          *http.Request
+	Body             io.ReadSeeker
+	Query            url.Values
+	Time             time.Time
+	ExpireTime       time.Duration
+	SignedHeaderVals http.Header
+
+	DisableURIPathEscaping bool
+
+	credValues         credentials.Value
+	isPresign          bool
+	formattedTime      string
+	formattedShortTime string
+	unsignedPayload    bool
+
+	bodyDigest       string
+	signedHeaders    string
+	canonicalHeaders string
+	canonicalString  string
+	credentialString string
+	stringToSign     string
+	signature        string
+	authorization    string
+}
+
+// Sign signs AWS v4 requests with the provided body, service name, region the
+// request is made to, and time the request is signed at. The signTime allows
+// you to specify that a request is signed for the future, and cannot be
+// used until then.
+//
+// Returns a list of HTTP headers that were included in the signature or an
+// error if signing the request failed. Generally for signed requests this value
+// is not needed as the full request context will be captured by the http.Request
+// value. It is included for reference though.
+//
+// Sign will set the request's Body to be the `body` parameter passed in. If
+// the body is not already an io.ReadCloser, it will be wrapped within one. If
+// a `nil` body parameter passed to Sign, the request's Body field will be
+// also set to nil. Its important to note that this functionality will not
+// change the request's ContentLength of the request.
+//
+// Sign differs from Presign in that it will sign the request using HTTP
+// header values. This type of signing is intended for http.Request values that
+// will not be shared, or are shared in a way the header values on the request
+// will not be lost.
+//
+// The requests body is an io.ReadSeeker so the SHA256 of the body can be
+// generated. To bypass the signer computing the hash you can set the
+// "X-Amz-Content-Sha256" header with a precomputed value. The signer will
+// only compute the hash if the request header value is empty.
+func (v4 Signer) Sign(r *http.Request, body io.ReadSeeker, service, region string, signTime time.Time) (http.Header, error) {
+	return v4.signWithBody(r, body, service, region, 0, false, signTime)
+}
+
+// Presign signs AWS v4 requests with the provided body, service name, region
+// the request is made to, and time the request is signed at. The signTime
+// allows you to specify that a request is signed for the future, and cannot
+// be used until then.
+//
+// Returns a list of HTTP headers that were included in the signature or an
+// error if signing the request failed. For presigned requests these headers
+// and their values must be included on the HTTP request when it is made. This
+// is helpful to know what header values need to be shared with the party the
+// presigned request will be distributed to.
+//
+// Presign differs from Sign in that it will sign the request using query string
+// instead of header values. This allows you to share the Presigned Request's
+// URL with third parties, or distribute it throughout your system with minimal
+// dependencies.
+//
+// Presign also takes an exp value which is the duration the
+// signed request will be valid after the signing time. This is allows you to
+// set when the request will expire.
+//
+// The requests body is an io.ReadSeeker so the SHA256 of the body can be
+// generated. To bypass the signer computing the hash you can set the
+// "X-Amz-Content-Sha256" header with a precomputed value. The signer will
+// only compute the hash if the request header value is empty.
+//
+// Presigning a S3 request will not compute the body's SHA256 hash by default.
+// This is done due to the general use case for S3 presigned URLs is to share
+// PUT/GET capabilities. If you would like to include the body's SHA256 in the
+// presigned request's signature you can set the "X-Amz-Content-Sha256"
+// HTTP header and that will be included in the request's signature.
+func (v4 Signer) Presign(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, signTime time.Time) (http.Header, error) {
+	return v4.signWithBody(r, body, service, region, exp, true, signTime)
+}
+
+func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, isPresign bool, signTime time.Time) (http.Header, error) {
+	currentTimeFn := v4.currentTimeFn
+	if currentTimeFn == nil {
+		currentTimeFn = time.Now
+	}
+
+	ctx := &signingCtx{
+		Request:                r,
+		Body:                   body,
+		Query:                  r.URL.Query(),
+		Time:                   signTime,
+		ExpireTime:             exp,
+		isPresign:              isPresign,
+		ServiceName:            service,
+		Region:                 region,
+		DisableURIPathEscaping: v4.DisableURIPathEscaping,
+		unsignedPayload:        v4.UnsignedPayload,
+	}
+
+	for key := range ctx.Query {
+		sort.Strings(ctx.Query[key])
+	}
+
+	if ctx.isRequestSigned() {
+		ctx.Time = currentTimeFn()
+		ctx.handlePresignRemoval()
+	}
+
+	var err error
+	ctx.credValues, err = v4.Credentials.Get()
+	if err != nil {
+		return http.Header{}, err
+	}
+
+	ctx.sanitizeHostForHeader()
+	ctx.assignAmzQueryValues()
+	if err := ctx.build(v4.DisableHeaderHoisting); err != nil {
+		return nil, err
+	}
+
+	// If the request is not presigned the body should be attached to it. This
+	// prevents the confusion of wanting to send a signed request without
+	// the body the request was signed for attached.
+	if !(v4.DisableRequestBodyOverwrite || ctx.isPresign) {
+		var reader io.ReadCloser
+		if body != nil {
+			var ok bool
+			if reader, ok = body.(io.ReadCloser); !ok {
+				reader = ioutil.NopCloser(body)
+			}
+		}
+		r.Body = reader
+	}
+
+	if v4.Debug.Matches(aws.LogDebugWithSigning) {
+		v4.logSigningInfo(ctx)
+	}
+
+	return ctx.SignedHeaderVals, nil
+}
+
+func (ctx *signingCtx) sanitizeHostForHeader() {
+	request.SanitizeHostForHeader(ctx.Request)
+}
+
+func (ctx *signingCtx) handlePresignRemoval() {
+	if !ctx.isPresign {
+		return
+	}
+
+	// The credentials have expired for this request. The current signing
+	// is invalid, and needs to be request because the request will fail.
+	ctx.removePresign()
+
+	// Update the request's query string to ensure the values stays in
+	// sync in the case retrieving the new credentials fails.
+	ctx.Request.URL.RawQuery = ctx.Query.Encode()
+}
+
+func (ctx *signingCtx) assignAmzQueryValues() {
+	if ctx.isPresign {
+		ctx.Query.Set("X-Amz-Algorithm", authHeaderPrefix)
+		if ctx.credValues.SessionToken != "" {
+			ctx.Query.Set("X-Amz-Security-Token", ctx.credValues.SessionToken)
+		} else {
+			ctx.Query.Del("X-Amz-Security-Token")
+		}
+
+		return
+	}
+
+	if ctx.credValues.SessionToken != "" {
+		ctx.Request.Header.Set("X-Amz-Security-Token", ctx.credValues.SessionToken)
+	}
+}
+
+// SignRequestHandler is a named request handler the SDK will use to sign
+// service client request with using the V4 signature.
+var SignRequestHandler = request.NamedHandler{
+	Name: "v4.SignRequestHandler", Fn: SignSDKRequest,
+}
+
+// SignSDKRequest signs an AWS request with the V4 signature. This
+// request handler should only be used with the SDK's built in service client's
+// API operation requests.
+//
+// This function should not be used on its on its own, but in conjunction with
+// an AWS service client's API operation call. To sign a standalone request
+// not created by a service client's API operation method use the "Sign" or
+// "Presign" functions of the "Signer" type.
+//
+// If the credentials of the request's config are set to
+// credentials.AnonymousCredentials the request will not be signed.
+func SignSDKRequest(req *request.Request) {
+	signSDKRequestWithCurrTime(req, time.Now)
+}
+
+// BuildNamedHandler will build a generic handler for signing.
+func BuildNamedHandler(name string, opts ...func(*Signer)) request.NamedHandler {
+	return request.NamedHandler{
+		Name: name,
+		Fn: func(req *request.Request) {
+			signSDKRequestWithCurrTime(req, time.Now, opts...)
+		},
+	}
+}
+
+func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time, opts ...func(*Signer)) {
+	// If the request does not need to be signed ignore the signing of the
+	// request if the AnonymousCredentials object is used.
+	if req.Config.Credentials == credentials.AnonymousCredentials {
+		return
+	}
+
+	region := req.ClientInfo.SigningRegion
+	if region == "" {
+		region = aws.StringValue(req.Config.Region)
+	}
+
+	name := req.ClientInfo.SigningName
+	if name == "" {
+		name = req.ClientInfo.ServiceName
+	}
+
+	v4 := NewSigner(req.Config.Credentials, func(v4 *Signer) {
+		v4.Debug = req.Config.LogLevel.Value()
+		v4.Logger = req.Config.Logger
+		v4.DisableHeaderHoisting = req.NotHoist
+		v4.currentTimeFn = curTimeFn
+		if name == "s3" {
+			// S3 service should not have any escaping applied
+			v4.DisableURIPathEscaping = true
+		}
+		// Prevents setting the HTTPRequest's Body. Since the Body could be
+		// wrapped in a custom io.Closer that we do not want to be stompped
+		// on top of by the signer.
+		v4.DisableRequestBodyOverwrite = true
+	})
+
+	for _, opt := range opts {
+		opt(v4)
+	}
+
+	signingTime := req.Time
+	if !req.LastSignedAt.IsZero() {
+		signingTime = req.LastSignedAt
+	}
+
+	signedHeaders, err := v4.signWithBody(req.HTTPRequest, req.GetBody(),
+		name, region, req.ExpireTime, req.ExpireTime > 0, signingTime,
+	)
+	if err != nil {
+		req.Error = err
+		req.SignedHeaderVals = nil
+		return
+	}
+
+	req.SignedHeaderVals = signedHeaders
+	req.LastSignedAt = curTimeFn()
+}
+
+const logSignInfoMsg = `DEBUG: Request Signature:
+---[ CANONICAL STRING  ]-----------------------------
+%s
+---[ STRING TO SIGN ]--------------------------------
+%s%s
+-----------------------------------------------------`
+const logSignedURLMsg = `
+---[ SIGNED URL ]------------------------------------
+%s`
+
+func (v4 *Signer) logSigningInfo(ctx *signingCtx) {
+	signedURLMsg := ""
+	if ctx.isPresign {
+		signedURLMsg = fmt.Sprintf(logSignedURLMsg, ctx.Request.URL.String())
+	}
+	msg := fmt.Sprintf(logSignInfoMsg, ctx.canonicalString, ctx.stringToSign, signedURLMsg)
+	v4.Logger.Log(msg)
+}
+
+func (ctx *signingCtx) build(disableHeaderHoisting bool) error {
+	ctx.buildTime()             // no depends
+	ctx.buildCredentialString() // no depends
+
+	if err := ctx.buildBodyDigest(); err != nil {
+		return err
+	}
+
+	unsignedHeaders := ctx.Request.Header
+	if ctx.isPresign {
+		if !disableHeaderHoisting {
+			urlValues := url.Values{}
+			urlValues, unsignedHeaders = buildQuery(allowedQueryHoisting, unsignedHeaders) // no depends
+			for k := range urlValues {
+				ctx.Query[k] = urlValues[k]
+			}
+		}
+	}
+
+	ctx.buildCanonicalHeaders(ignoredHeaders, unsignedHeaders)
+	ctx.buildCanonicalString() // depends on canon headers / signed headers
+	ctx.buildStringToSign()    // depends on canon string
+	ctx.buildSignature()       // depends on string to sign
+
+	if ctx.isPresign {
+		ctx.Request.URL.RawQuery += "&X-Amz-Signature=" + ctx.signature
+	} else {
+		parts := []string{
+			authHeaderPrefix + " Credential=" + ctx.credValues.AccessKeyID + "/" + ctx.credentialString,
+			"SignedHeaders=" + ctx.signedHeaders,
+			"Signature=" + ctx.signature,
+		}
+		ctx.Request.Header.Set("Authorization", strings.Join(parts, ", "))
+	}
+
+	return nil
+}
+
+func (ctx *signingCtx) buildTime() {
+	ctx.formattedTime = ctx.Time.UTC().Format(timeFormat)
+	ctx.formattedShortTime = ctx.Time.UTC().Format(shortTimeFormat)
+
+	if ctx.isPresign {
+		duration := int64(ctx.ExpireTime / time.Second)
+		ctx.Query.Set("X-Amz-Date", ctx.formattedTime)
+		ctx.Query.Set("X-Amz-Expires", strconv.FormatInt(duration, 10))
+	} else {
+		ctx.Request.Header.Set("X-Amz-Date", ctx.formattedTime)
+	}
+}
+
+func (ctx *signingCtx) buildCredentialString() {
+	ctx.credentialString = strings.Join([]string{
+		ctx.formattedShortTime,
+		ctx.Region,
+		ctx.ServiceName,
+		"aws4_request",
+	}, "/")
+
+	if ctx.isPresign {
+		ctx.Query.Set("X-Amz-Credential", ctx.credValues.AccessKeyID+"/"+ctx.credentialString)
+	}
+}
+
+func buildQuery(r rule, header http.Header) (url.Values, http.Header) {
+	query := url.Values{}
+	unsignedHeaders := http.Header{}
+	for k, h := range header {
+		if r.IsValid(k) {
+			query[k] = h
+		} else {
+			unsignedHeaders[k] = h
+		}
+	}
+
+	return query, unsignedHeaders
+}
+func (ctx *signingCtx) buildCanonicalHeaders(r rule, header http.Header) {
+	var headers []string
+	headers = append(headers, "host")
+	for k, v := range header {
+		canonicalKey := http.CanonicalHeaderKey(k)
+		if !r.IsValid(canonicalKey) {
+			continue // ignored header
+		}
+		if ctx.SignedHeaderVals == nil {
+			ctx.SignedHeaderVals = make(http.Header)
+		}
+
+		lowerCaseKey := strings.ToLower(k)
+		if _, ok := ctx.SignedHeaderVals[lowerCaseKey]; ok {
+			// include additional values
+			ctx.SignedHeaderVals[lowerCaseKey] = append(ctx.SignedHeaderVals[lowerCaseKey], v...)
+			continue
+		}
+
+		headers = append(headers, lowerCaseKey)
+		ctx.SignedHeaderVals[lowerCaseKey] = v
+	}
+	sort.Strings(headers)
+
+	ctx.signedHeaders = strings.Join(headers, ";")
+
+	if ctx.isPresign {
+		ctx.Query.Set("X-Amz-SignedHeaders", ctx.signedHeaders)
+	}
+
+	headerValues := make([]string, len(headers))
+	for i, k := range headers {
+		if k == "host" {
+			if ctx.Request.Host != "" {
+				headerValues[i] = "host:" + ctx.Request.Host
+			} else {
+				headerValues[i] = "host:" + ctx.Request.URL.Host
+			}
+		} else {
+			headerValues[i] = k + ":" +
+				strings.Join(ctx.SignedHeaderVals[k], ",")
+		}
+	}
+	stripExcessSpaces(headerValues)
+	ctx.canonicalHeaders = strings.Join(headerValues, "\n")
+}
+
+func (ctx *signingCtx) buildCanonicalString() {
+	ctx.Request.URL.RawQuery = strings.Replace(ctx.Query.Encode(), "+", "%20", -1)
+
+	uri := getURIPath(ctx.Request.URL)
+
+	if !ctx.DisableURIPathEscaping {
+		uri = rest.EscapePath(uri, false)
+	}
+
+	ctx.canonicalString = strings.Join([]string{
+		ctx.Request.Method,
+		uri,
+		ctx.Request.URL.RawQuery,
+		ctx.canonicalHeaders + "\n",
+		ctx.signedHeaders,
+		ctx.bodyDigest,
+	}, "\n")
+}
+
+func (ctx *signingCtx) buildStringToSign() {
+	ctx.stringToSign = strings.Join([]string{
+		authHeaderPrefix,
+		ctx.formattedTime,
+		ctx.credentialString,
+		hex.EncodeToString(makeSha256([]byte(ctx.canonicalString))),
+	}, "\n")
+}
+
+func (ctx *signingCtx) buildSignature() {
+	secret := ctx.credValues.SecretAccessKey
+	date := makeHmac([]byte("AWS4"+secret), []byte(ctx.formattedShortTime))
+	region := makeHmac(date, []byte(ctx.Region))
+	service := makeHmac(region, []byte(ctx.ServiceName))
+	credentials := makeHmac(service, []byte("aws4_request"))
+	signature := makeHmac(credentials, []byte(ctx.stringToSign))
+	ctx.signature = hex.EncodeToString(signature)
+}
+
+func (ctx *signingCtx) buildBodyDigest() error {
+	hash := ctx.Request.Header.Get("X-Amz-Content-Sha256")
+	if hash == "" {
+		includeSHA256Header := ctx.unsignedPayload ||
+			ctx.ServiceName == "s3" ||
+			ctx.ServiceName == "glacier"
+
+		s3Presign := ctx.isPresign && ctx.ServiceName == "s3"
+
+		if ctx.unsignedPayload || s3Presign {
+			hash = "UNSIGNED-PAYLOAD"
+			includeSHA256Header = !s3Presign
+		} else if ctx.Body == nil {
+			hash = emptyStringSHA256
+		} else {
+			if !aws.IsReaderSeekable(ctx.Body) {
+				return fmt.Errorf("cannot use unseekable request body %T, for signed request with body", ctx.Body)
+			}
+			hash = hex.EncodeToString(makeSha256Reader(ctx.Body))
+		}
+
+		if includeSHA256Header {
+			ctx.Request.Header.Set("X-Amz-Content-Sha256", hash)
+		}
+	}
+	ctx.bodyDigest = hash
+
+	return nil
+}
+
+// isRequestSigned returns if the request is currently signed or presigned
+func (ctx *signingCtx) isRequestSigned() bool {
+	if ctx.isPresign && ctx.Query.Get("X-Amz-Signature") != "" {
+		return true
+	}
+	if ctx.Request.Header.Get("Authorization") != "" {
+		return true
+	}
+
+	return false
+}
+
+// unsign removes signing flags for both signed and presigned requests.
+func (ctx *signingCtx) removePresign() {
+	ctx.Query.Del("X-Amz-Algorithm")
+	ctx.Query.Del("X-Amz-Signature")
+	ctx.Query.Del("X-Amz-Security-Token")
+	ctx.Query.Del("X-Amz-Date")
+	ctx.Query.Del("X-Amz-Expires")
+	ctx.Query.Del("X-Amz-Credential")
+	ctx.Query.Del("X-Amz-SignedHeaders")
+}
+
+func makeHmac(key []byte, data []byte) []byte {
+	hash := hmac.New(sha256.New, key)
+	hash.Write(data)
+	return hash.Sum(nil)
+}
+
+func makeSha256(data []byte) []byte {
+	hash := sha256.New()
+	hash.Write(data)
+	return hash.Sum(nil)
+}
+
+func makeSha256Reader(reader io.ReadSeeker) []byte {
+	hash := sha256.New()
+	start, _ := reader.Seek(0, sdkio.SeekCurrent)
+	defer reader.Seek(start, sdkio.SeekStart)
+
+	io.Copy(hash, reader)
+	return hash.Sum(nil)
+}
+
+const doubleSpace = "  "
+
+// stripExcessSpaces will rewrite the passed in slice's string values to not
+// contain muliple side-by-side spaces.
+func stripExcessSpaces(vals []string) {
+	var j, k, l, m, spaces int
+	for i, str := range vals {
+		// Trim trailing spaces
+		for j = len(str) - 1; j >= 0 && str[j] == ' '; j-- {
+		}
+
+		// Trim leading spaces
+		for k = 0; k < j && str[k] == ' '; k++ {
+		}
+		str = str[k : j+1]
+
+		// Strip multiple spaces.
+		j = strings.Index(str, doubleSpace)
+		if j < 0 {
+			vals[i] = str
+			continue
+		}
+
+		buf := []byte(str)
+		for k, m, l = j, j, len(buf); k < l; k++ {
+			if buf[k] == ' ' {
+				if spaces == 0 {
+					// First space.
+					buf[m] = buf[k]
+					m++
+				}
+				spaces++
+			} else {
+				// End of multiple spaces.
+				spaces = 0
+				buf[m] = buf[k]
+				m++
+			}
+		}
+
+		vals[i] = string(buf[:m])
+	}
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/types.go b/vendor/github.com/aws/aws-sdk-go/aws/types.go
new file mode 100644
index 000000000..8b6f23425
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/types.go
@@ -0,0 +1,201 @@
+package aws
+
+import (
+	"io"
+	"sync"
+
+	"github.com/aws/aws-sdk-go/internal/sdkio"
+)
+
+// ReadSeekCloser wraps a io.Reader returning a ReaderSeekerCloser. Should
+// only be used with an io.Reader that is also an io.Seeker. Doing so may
+// cause request signature errors, or request body's not sent for GET, HEAD
+// and DELETE HTTP methods.
+//
+// Deprecated: Should only be used with io.ReadSeeker. If using for
+// S3 PutObject to stream content use s3manager.Uploader instead.
+func ReadSeekCloser(r io.Reader) ReaderSeekerCloser {
+	return ReaderSeekerCloser{r}
+}
+
+// ReaderSeekerCloser represents a reader that can also delegate io.Seeker and
+// io.Closer interfaces to the underlying object if they are available.
+type ReaderSeekerCloser struct {
+	r io.Reader
+}
+
+// IsReaderSeekable returns if the underlying reader type can be seeked. A
+// io.Reader might not actually be seekable if it is the ReaderSeekerCloser
+// type.
+func IsReaderSeekable(r io.Reader) bool {
+	switch v := r.(type) {
+	case ReaderSeekerCloser:
+		return v.IsSeeker()
+	case *ReaderSeekerCloser:
+		return v.IsSeeker()
+	case io.ReadSeeker:
+		return true
+	default:
+		return false
+	}
+}
+
+// Read reads from the reader up to size of p. The number of bytes read, and
+// error if it occurred will be returned.
+//
+// If the reader is not an io.Reader zero bytes read, and nil error will be returned.
+//
+// Performs the same functionality as io.Reader Read
+func (r ReaderSeekerCloser) Read(p []byte) (int, error) {
+	switch t := r.r.(type) {
+	case io.Reader:
+		return t.Read(p)
+	}
+	return 0, nil
+}
+
+// Seek sets the offset for the next Read to offset, interpreted according to
+// whence: 0 means relative to the origin of the file, 1 means relative to the
+// current offset, and 2 means relative to the end. Seek returns the new offset
+// and an error, if any.
+//
+// If the ReaderSeekerCloser is not an io.Seeker nothing will be done.
+func (r ReaderSeekerCloser) Seek(offset int64, whence int) (int64, error) {
+	switch t := r.r.(type) {
+	case io.Seeker:
+		return t.Seek(offset, whence)
+	}
+	return int64(0), nil
+}
+
+// IsSeeker returns if the underlying reader is also a seeker.
+func (r ReaderSeekerCloser) IsSeeker() bool {
+	_, ok := r.r.(io.Seeker)
+	return ok
+}
+
+// HasLen returns the length of the underlying reader if the value implements
+// the Len() int method.
+func (r ReaderSeekerCloser) HasLen() (int, bool) {
+	type lenner interface {
+		Len() int
+	}
+
+	if lr, ok := r.r.(lenner); ok {
+		return lr.Len(), true
+	}
+
+	return 0, false
+}
+
+// GetLen returns the length of the bytes remaining in the underlying reader.
+// Checks first for Len(), then io.Seeker to determine the size of the
+// underlying reader.
+//
+// Will return -1 if the length cannot be determined.
+func (r ReaderSeekerCloser) GetLen() (int64, error) {
+	if l, ok := r.HasLen(); ok {
+		return int64(l), nil
+	}
+
+	if s, ok := r.r.(io.Seeker); ok {
+		return seekerLen(s)
+	}
+
+	return -1, nil
+}
+
+// SeekerLen attempts to get the number of bytes remaining at the seeker's
+// current position.  Returns the number of bytes remaining or error.
+func SeekerLen(s io.Seeker) (int64, error) {
+	// Determine if the seeker is actually seekable. ReaderSeekerCloser
+	// hides the fact that a io.Readers might not actually be seekable.
+	switch v := s.(type) {
+	case ReaderSeekerCloser:
+		return v.GetLen()
+	case *ReaderSeekerCloser:
+		return v.GetLen()
+	}
+
+	return seekerLen(s)
+}
+
+func seekerLen(s io.Seeker) (int64, error) {
+	curOffset, err := s.Seek(0, sdkio.SeekCurrent)
+	if err != nil {
+		return 0, err
+	}
+
+	endOffset, err := s.Seek(0, sdkio.SeekEnd)
+	if err != nil {
+		return 0, err
+	}
+
+	_, err = s.Seek(curOffset, sdkio.SeekStart)
+	if err != nil {
+		return 0, err
+	}
+
+	return endOffset - curOffset, nil
+}
+
+// Close closes the ReaderSeekerCloser.
+//
+// If the ReaderSeekerCloser is not an io.Closer nothing will be done.
+func (r ReaderSeekerCloser) Close() error {
+	switch t := r.r.(type) {
+	case io.Closer:
+		return t.Close()
+	}
+	return nil
+}
+
+// A WriteAtBuffer provides a in memory buffer supporting the io.WriterAt interface
+// Can be used with the s3manager.Downloader to download content to a buffer
+// in memory. Safe to use concurrently.
+type WriteAtBuffer struct {
+	buf []byte
+	m   sync.Mutex
+
+	// GrowthCoeff defines the growth rate of the internal buffer. By
+	// default, the growth rate is 1, where expanding the internal
+	// buffer will allocate only enough capacity to fit the new expected
+	// length.
+	GrowthCoeff float64
+}
+
+// NewWriteAtBuffer creates a WriteAtBuffer with an internal buffer
+// provided by buf.
+func NewWriteAtBuffer(buf []byte) *WriteAtBuffer {
+	return &WriteAtBuffer{buf: buf}
+}
+
+// WriteAt writes a slice of bytes to a buffer starting at the position provided
+// The number of bytes written will be returned, or error. Can overwrite previous
+// written slices if the write ats overlap.
+func (b *WriteAtBuffer) WriteAt(p []byte, pos int64) (n int, err error) {
+	pLen := len(p)
+	expLen := pos + int64(pLen)
+	b.m.Lock()
+	defer b.m.Unlock()
+	if int64(len(b.buf)) < expLen {
+		if int64(cap(b.buf)) < expLen {
+			if b.GrowthCoeff < 1 {
+				b.GrowthCoeff = 1
+			}
+			newBuf := make([]byte, expLen, int64(b.GrowthCoeff*float64(expLen)))
+			copy(newBuf, b.buf)
+			b.buf = newBuf
+		}
+		b.buf = b.buf[:expLen]
+	}
+	copy(b.buf[pos:], p)
+	return pLen, nil
+}
+
+// Bytes returns a slice of bytes written to the buffer.
+func (b *WriteAtBuffer) Bytes() []byte {
+	b.m.Lock()
+	defer b.m.Unlock()
+	return b.buf
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/url.go b/vendor/github.com/aws/aws-sdk-go/aws/url.go
new file mode 100644
index 000000000..6192b2455
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/url.go
@@ -0,0 +1,12 @@
+// +build go1.8
+
+package aws
+
+import "net/url"
+
+// URLHostname will extract the Hostname without port from the URL value.
+//
+// Wrapper of net/url#URL.Hostname for backwards Go version compatibility.
+func URLHostname(url *url.URL) string {
+	return url.Hostname()
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/url_1_7.go b/vendor/github.com/aws/aws-sdk-go/aws/url_1_7.go
new file mode 100644
index 000000000..0210d2720
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/url_1_7.go
@@ -0,0 +1,29 @@
+// +build !go1.8
+
+package aws
+
+import (
+	"net/url"
+	"strings"
+)
+
+// URLHostname will extract the Hostname without port from the URL value.
+//
+// Copy of Go 1.8's net/url#URL.Hostname functionality.
+func URLHostname(url *url.URL) string {
+	return stripPort(url.Host)
+
+}
+
+// stripPort is copy of Go 1.8 url#URL.Hostname functionality.
+// https://golang.org/src/net/url/url.go
+func stripPort(hostport string) string {
+	colon := strings.IndexByte(hostport, ':')
+	if colon == -1 {
+		return hostport
+	}
+	if i := strings.IndexByte(hostport, ']'); i != -1 {
+		return strings.TrimPrefix(hostport[:i], "[")
+	}
+	return hostport[:colon]
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/version.go b/vendor/github.com/aws/aws-sdk-go/aws/version.go
new file mode 100644
index 000000000..f44b55400
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/aws/version.go
@@ -0,0 +1,8 @@
+// Package aws provides core functionality for making requests to AWS services.
+package aws
+
+// SDKName is the name of this AWS SDK
+const SDKName = "aws-sdk-go"
+
+// SDKVersion is the version of this SDK
+const SDKVersion = "1.15.21"
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.6.go b/vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.6.go
new file mode 100644
index 000000000..5aa9137e0
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.6.go
@@ -0,0 +1,10 @@
+// +build !go1.7
+
+package sdkio
+
+// Copy of Go 1.7 io package's Seeker constants.
+const (
+	SeekStart   = 0 // seek relative to the origin of the file
+	SeekCurrent = 1 // seek relative to the current offset
+	SeekEnd     = 2 // seek relative to the end
+)
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.7.go b/vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.7.go
new file mode 100644
index 000000000..e5f005613
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.7.go
@@ -0,0 +1,12 @@
+// +build go1.7
+
+package sdkio
+
+import "io"
+
+// Alias for Go 1.7 io package Seeker constants
+const (
+	SeekStart   = io.SeekStart   // seek relative to the origin of the file
+	SeekCurrent = io.SeekCurrent // seek relative to the current offset
+	SeekEnd     = io.SeekEnd     // seek relative to the end
+)
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/sdkrand/locked_source.go b/vendor/github.com/aws/aws-sdk-go/internal/sdkrand/locked_source.go
new file mode 100644
index 000000000..0c9802d87
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/sdkrand/locked_source.go
@@ -0,0 +1,29 @@
+package sdkrand
+
+import (
+	"math/rand"
+	"sync"
+	"time"
+)
+
+// lockedSource is a thread-safe implementation of rand.Source
+type lockedSource struct {
+	lk  sync.Mutex
+	src rand.Source
+}
+
+func (r *lockedSource) Int63() (n int64) {
+	r.lk.Lock()
+	n = r.src.Int63()
+	r.lk.Unlock()
+	return
+}
+
+func (r *lockedSource) Seed(seed int64) {
+	r.lk.Lock()
+	r.src.Seed(seed)
+	r.lk.Unlock()
+}
+
+// SeededRand is a new RNG using a thread safe implementation of rand.Source
+var SeededRand = rand.New(&lockedSource{src: rand.NewSource(time.Now().UnixNano())})
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/sdkuri/path.go b/vendor/github.com/aws/aws-sdk-go/internal/sdkuri/path.go
new file mode 100644
index 000000000..38ea61afe
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/sdkuri/path.go
@@ -0,0 +1,23 @@
+package sdkuri
+
+import (
+	"path"
+	"strings"
+)
+
+// PathJoin will join the elements of the path delimited by the "/"
+// character. Similar to path.Join with the exception the trailing "/"
+// character is preserved if present.
+func PathJoin(elems ...string) string {
+	if len(elems) == 0 {
+		return ""
+	}
+
+	hasTrailing := strings.HasSuffix(elems[len(elems)-1], "/")
+	str := path.Join(elems...)
+	if hasTrailing && str != "/" {
+		str += "/"
+	}
+
+	return str
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/shared_config.go b/vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/shared_config.go
new file mode 100644
index 000000000..ebcbc2b40
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/shared_config.go
@@ -0,0 +1,40 @@
+package shareddefaults
+
+import (
+	"os"
+	"path/filepath"
+	"runtime"
+)
+
+// SharedCredentialsFilename returns the SDK's default file path
+// for the shared credentials file.
+//
+// Builds the shared config file path based on the OS's platform.
+//
+//   - Linux/Unix: $HOME/.aws/credentials
+//   - Windows: %USERPROFILE%\.aws\credentials
+func SharedCredentialsFilename() string {
+	return filepath.Join(UserHomeDir(), ".aws", "credentials")
+}
+
+// SharedConfigFilename returns the SDK's default file path for
+// the shared config file.
+//
+// Builds the shared config file path based on the OS's platform.
+//
+//   - Linux/Unix: $HOME/.aws/config
+//   - Windows: %USERPROFILE%\.aws\config
+func SharedConfigFilename() string {
+	return filepath.Join(UserHomeDir(), ".aws", "config")
+}
+
+// UserHomeDir returns the home directory for the user the process is
+// running under.
+func UserHomeDir() string {
+	if runtime.GOOS == "windows" { // Windows
+		return os.Getenv("USERPROFILE")
+	}
+
+	// *nix
+	return os.Getenv("HOME")
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/debug.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/debug.go
new file mode 100644
index 000000000..ecc7bf82f
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/debug.go
@@ -0,0 +1,144 @@
+package eventstream
+
+import (
+	"bytes"
+	"encoding/base64"
+	"encoding/json"
+	"fmt"
+	"strconv"
+)
+
+type decodedMessage struct {
+	rawMessage
+	Headers decodedHeaders `json:"headers"`
+}
+type jsonMessage struct {
+	Length     json.Number    `json:"total_length"`
+	HeadersLen json.Number    `json:"headers_length"`
+	PreludeCRC json.Number    `json:"prelude_crc"`
+	Headers    decodedHeaders `json:"headers"`
+	Payload    []byte         `json:"payload"`
+	CRC        json.Number    `json:"message_crc"`
+}
+
+func (d *decodedMessage) UnmarshalJSON(b []byte) (err error) {
+	var jsonMsg jsonMessage
+	if err = json.Unmarshal(b, &jsonMsg); err != nil {
+		return err
+	}
+
+	d.Length, err = numAsUint32(jsonMsg.Length)
+	if err != nil {
+		return err
+	}
+	d.HeadersLen, err = numAsUint32(jsonMsg.HeadersLen)
+	if err != nil {
+		return err
+	}
+	d.PreludeCRC, err = numAsUint32(jsonMsg.PreludeCRC)
+	if err != nil {
+		return err
+	}
+	d.Headers = jsonMsg.Headers
+	d.Payload = jsonMsg.Payload
+	d.CRC, err = numAsUint32(jsonMsg.CRC)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (d *decodedMessage) MarshalJSON() ([]byte, error) {
+	jsonMsg := jsonMessage{
+		Length:     json.Number(strconv.Itoa(int(d.Length))),
+		HeadersLen: json.Number(strconv.Itoa(int(d.HeadersLen))),
+		PreludeCRC: json.Number(strconv.Itoa(int(d.PreludeCRC))),
+		Headers:    d.Headers,
+		Payload:    d.Payload,
+		CRC:        json.Number(strconv.Itoa(int(d.CRC))),
+	}
+
+	return json.Marshal(jsonMsg)
+}
+
+func numAsUint32(n json.Number) (uint32, error) {
+	v, err := n.Int64()
+	if err != nil {
+		return 0, fmt.Errorf("failed to get int64 json number, %v", err)
+	}
+
+	return uint32(v), nil
+}
+
+func (d decodedMessage) Message() Message {
+	return Message{
+		Headers: Headers(d.Headers),
+		Payload: d.Payload,
+	}
+}
+
+type decodedHeaders Headers
+
+func (hs *decodedHeaders) UnmarshalJSON(b []byte) error {
+	var jsonHeaders []struct {
+		Name  string      `json:"name"`
+		Type  valueType   `json:"type"`
+		Value interface{} `json:"value"`
+	}
+
+	decoder := json.NewDecoder(bytes.NewReader(b))
+	decoder.UseNumber()
+	if err := decoder.Decode(&jsonHeaders); err != nil {
+		return err
+	}
+
+	var headers Headers
+	for _, h := range jsonHeaders {
+		value, err := valueFromType(h.Type, h.Value)
+		if err != nil {
+			return err
+		}
+		headers.Set(h.Name, value)
+	}
+	(*hs) = decodedHeaders(headers)
+
+	return nil
+}
+
+func valueFromType(typ valueType, val interface{}) (Value, error) {
+	switch typ {
+	case trueValueType:
+		return BoolValue(true), nil
+	case falseValueType:
+		return BoolValue(false), nil
+	case int8ValueType:
+		v, err := val.(json.Number).Int64()
+		return Int8Value(int8(v)), err
+	case int16ValueType:
+		v, err := val.(json.Number).Int64()
+		return Int16Value(int16(v)), err
+	case int32ValueType:
+		v, err := val.(json.Number).Int64()
+		return Int32Value(int32(v)), err
+	case int64ValueType:
+		v, err := val.(json.Number).Int64()
+		return Int64Value(v), err
+	case bytesValueType:
+		v, err := base64.StdEncoding.DecodeString(val.(string))
+		return BytesValue(v), err
+	case stringValueType:
+		v, err := base64.StdEncoding.DecodeString(val.(string))
+		return StringValue(string(v)), err
+	case timestampValueType:
+		v, err := val.(json.Number).Int64()
+		return TimestampValue(timeFromEpochMilli(v)), err
+	case uuidValueType:
+		v, err := base64.StdEncoding.DecodeString(val.(string))
+		var tv UUIDValue
+		copy(tv[:], v)
+		return tv, err
+	default:
+		panic(fmt.Sprintf("unknown type, %s, %T", typ.String(), val))
+	}
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/decode.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/decode.go
new file mode 100644
index 000000000..4b972b2d6
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/decode.go
@@ -0,0 +1,199 @@
+package eventstream
+
+import (
+	"bytes"
+	"encoding/binary"
+	"encoding/hex"
+	"encoding/json"
+	"fmt"
+	"hash"
+	"hash/crc32"
+	"io"
+
+	"github.com/aws/aws-sdk-go/aws"
+)
+
+// Decoder provides decoding of an Event Stream messages.
+type Decoder struct {
+	r      io.Reader
+	logger aws.Logger
+}
+
+// NewDecoder initializes and returns a Decoder for decoding event
+// stream messages from the reader provided.
+func NewDecoder(r io.Reader) *Decoder {
+	return &Decoder{
+		r: r,
+	}
+}
+
+// Decode attempts to decode a single message from the event stream reader.
+// Will return the event stream message, or error if Decode fails to read
+// the message from the stream.
+func (d *Decoder) Decode(payloadBuf []byte) (m Message, err error) {
+	reader := d.r
+	if d.logger != nil {
+		debugMsgBuf := bytes.NewBuffer(nil)
+		reader = io.TeeReader(reader, debugMsgBuf)
+		defer func() {
+			logMessageDecode(d.logger, debugMsgBuf, m, err)
+		}()
+	}
+
+	crc := crc32.New(crc32IEEETable)
+	hashReader := io.TeeReader(reader, crc)
+
+	prelude, err := decodePrelude(hashReader, crc)
+	if err != nil {
+		return Message{}, err
+	}
+
+	if prelude.HeadersLen > 0 {
+		lr := io.LimitReader(hashReader, int64(prelude.HeadersLen))
+		m.Headers, err = decodeHeaders(lr)
+		if err != nil {
+			return Message{}, err
+		}
+	}
+
+	if payloadLen := prelude.PayloadLen(); payloadLen > 0 {
+		buf, err := decodePayload(payloadBuf, io.LimitReader(hashReader, int64(payloadLen)))
+		if err != nil {
+			return Message{}, err
+		}
+		m.Payload = buf
+	}
+
+	msgCRC := crc.Sum32()
+	if err := validateCRC(reader, msgCRC); err != nil {
+		return Message{}, err
+	}
+
+	return m, nil
+}
+
+// UseLogger specifies the Logger that that the decoder should use to log the
+// message decode to.
+func (d *Decoder) UseLogger(logger aws.Logger) {
+	d.logger = logger
+}
+
+func logMessageDecode(logger aws.Logger, msgBuf *bytes.Buffer, msg Message, decodeErr error) {
+	w := bytes.NewBuffer(nil)
+	defer func() { logger.Log(w.String()) }()
+
+	fmt.Fprintf(w, "Raw message:\n%s\n",
+		hex.Dump(msgBuf.Bytes()))
+
+	if decodeErr != nil {
+		fmt.Fprintf(w, "Decode error: %v\n", decodeErr)
+		return
+	}
+
+	rawMsg, err := msg.rawMessage()
+	if err != nil {
+		fmt.Fprintf(w, "failed to create raw message, %v\n", err)
+		return
+	}
+
+	decodedMsg := decodedMessage{
+		rawMessage: rawMsg,
+		Headers:    decodedHeaders(msg.Headers),
+	}
+
+	fmt.Fprintf(w, "Decoded message:\n")
+	encoder := json.NewEncoder(w)
+	if err := encoder.Encode(decodedMsg); err != nil {
+		fmt.Fprintf(w, "failed to generate decoded message, %v\n", err)
+	}
+}
+
+func decodePrelude(r io.Reader, crc hash.Hash32) (messagePrelude, error) {
+	var p messagePrelude
+
+	var err error
+	p.Length, err = decodeUint32(r)
+	if err != nil {
+		return messagePrelude{}, err
+	}
+
+	p.HeadersLen, err = decodeUint32(r)
+	if err != nil {
+		return messagePrelude{}, err
+	}
+
+	if err := p.ValidateLens(); err != nil {
+		return messagePrelude{}, err
+	}
+
+	preludeCRC := crc.Sum32()
+	if err := validateCRC(r, preludeCRC); err != nil {
+		return messagePrelude{}, err
+	}
+
+	p.PreludeCRC = preludeCRC
+
+	return p, nil
+}
+
+func decodePayload(buf []byte, r io.Reader) ([]byte, error) {
+	w := bytes.NewBuffer(buf[0:0])
+
+	_, err := io.Copy(w, r)
+	return w.Bytes(), err
+}
+
+func decodeUint8(r io.Reader) (uint8, error) {
+	type byteReader interface {
+		ReadByte() (byte, error)
+	}
+
+	if br, ok := r.(byteReader); ok {
+		v, err := br.ReadByte()
+		return uint8(v), err
+	}
+
+	var b [1]byte
+	_, err := io.ReadFull(r, b[:])
+	return uint8(b[0]), err
+}
+func decodeUint16(r io.Reader) (uint16, error) {
+	var b [2]byte
+	bs := b[:]
+	_, err := io.ReadFull(r, bs)
+	if err != nil {
+		return 0, err
+	}
+	return binary.BigEndian.Uint16(bs), nil
+}
+func decodeUint32(r io.Reader) (uint32, error) {
+	var b [4]byte
+	bs := b[:]
+	_, err := io.ReadFull(r, bs)
+	if err != nil {
+		return 0, err
+	}
+	return binary.BigEndian.Uint32(bs), nil
+}
+func decodeUint64(r io.Reader) (uint64, error) {
+	var b [8]byte
+	bs := b[:]
+	_, err := io.ReadFull(r, bs)
+	if err != nil {
+		return 0, err
+	}
+	return binary.BigEndian.Uint64(bs), nil
+}
+
+func validateCRC(r io.Reader, expect uint32) error {
+	msgCRC, err := decodeUint32(r)
+	if err != nil {
+		return err
+	}
+
+	if msgCRC != expect {
+		return ChecksumError{}
+	}
+
+	return nil
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/encode.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/encode.go
new file mode 100644
index 000000000..150a60981
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/encode.go
@@ -0,0 +1,114 @@
+package eventstream
+
+import (
+	"bytes"
+	"encoding/binary"
+	"hash"
+	"hash/crc32"
+	"io"
+)
+
+// Encoder provides EventStream message encoding.
+type Encoder struct {
+	w io.Writer
+
+	headersBuf *bytes.Buffer
+}
+
+// NewEncoder initializes and returns an Encoder to encode Event Stream
+// messages to an io.Writer.
+func NewEncoder(w io.Writer) *Encoder {
+	return &Encoder{
+		w:          w,
+		headersBuf: bytes.NewBuffer(nil),
+	}
+}
+
+// Encode encodes a single EventStream message to the io.Writer the Encoder
+// was created with. An error is returned if writing the message fails.
+func (e *Encoder) Encode(msg Message) error {
+	e.headersBuf.Reset()
+
+	err := encodeHeaders(e.headersBuf, msg.Headers)
+	if err != nil {
+		return err
+	}
+
+	crc := crc32.New(crc32IEEETable)
+	hashWriter := io.MultiWriter(e.w, crc)
+
+	headersLen := uint32(e.headersBuf.Len())
+	payloadLen := uint32(len(msg.Payload))
+
+	if err := encodePrelude(hashWriter, crc, headersLen, payloadLen); err != nil {
+		return err
+	}
+
+	if headersLen > 0 {
+		if _, err := io.Copy(hashWriter, e.headersBuf); err != nil {
+			return err
+		}
+	}
+
+	if payloadLen > 0 {
+		if _, err := hashWriter.Write(msg.Payload); err != nil {
+			return err
+		}
+	}
+
+	msgCRC := crc.Sum32()
+	return binary.Write(e.w, binary.BigEndian, msgCRC)
+}
+
+func encodePrelude(w io.Writer, crc hash.Hash32, headersLen, payloadLen uint32) error {
+	p := messagePrelude{
+		Length:     minMsgLen + headersLen + payloadLen,
+		HeadersLen: headersLen,
+	}
+	if err := p.ValidateLens(); err != nil {
+		return err
+	}
+
+	err := binaryWriteFields(w, binary.BigEndian,
+		p.Length,
+		p.HeadersLen,
+	)
+	if err != nil {
+		return err
+	}
+
+	p.PreludeCRC = crc.Sum32()
+	err = binary.Write(w, binary.BigEndian, p.PreludeCRC)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func encodeHeaders(w io.Writer, headers Headers) error {
+	for _, h := range headers {
+		hn := headerName{
+			Len: uint8(len(h.Name)),
+		}
+		copy(hn.Name[:hn.Len], h.Name)
+		if err := hn.encode(w); err != nil {
+			return err
+		}
+
+		if err := h.Value.encode(w); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func binaryWriteFields(w io.Writer, order binary.ByteOrder, vs ...interface{}) error {
+	for _, v := range vs {
+		if err := binary.Write(w, order, v); err != nil {
+			return err
+		}
+	}
+	return nil
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/error.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/error.go
new file mode 100644
index 000000000..5481ef307
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/error.go
@@ -0,0 +1,23 @@
+package eventstream
+
+import "fmt"
+
+// LengthError provides the error for items being larger than a maximum length.
+type LengthError struct {
+	Part  string
+	Want  int
+	Have  int
+	Value interface{}
+}
+
+func (e LengthError) Error() string {
+	return fmt.Sprintf("%s length invalid, %d/%d, %v",
+		e.Part, e.Want, e.Have, e.Value)
+}
+
+// ChecksumError provides the error for message checksum invalidation errors.
+type ChecksumError struct{}
+
+func (e ChecksumError) Error() string {
+	return "message checksum mismatch"
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamapi/api.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamapi/api.go
new file mode 100644
index 000000000..97937c8e5
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamapi/api.go
@@ -0,0 +1,196 @@
+package eventstreamapi
+
+import (
+	"fmt"
+	"io"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/private/protocol"
+	"github.com/aws/aws-sdk-go/private/protocol/eventstream"
+)
+
+// Unmarshaler provides the interface for unmarshaling a EventStream
+// message into a SDK type.
+type Unmarshaler interface {
+	UnmarshalEvent(protocol.PayloadUnmarshaler, eventstream.Message) error
+}
+
+// EventStream headers with specific meaning to async API functionality.
+const (
+	MessageTypeHeader    = `:message-type` // Identifies type of message.
+	EventMessageType     = `event`
+	ErrorMessageType     = `error`
+	ExceptionMessageType = `exception`
+
+	// Message Events
+	EventTypeHeader = `:event-type` // Identifies message event type e.g. "Stats".
+
+	// Message Error
+	ErrorCodeHeader    = `:error-code`
+	ErrorMessageHeader = `:error-message`
+
+	// Message Exception
+	ExceptionTypeHeader = `:exception-type`
+)
+
+// EventReader provides reading from the EventStream of an reader.
+type EventReader struct {
+	reader  io.ReadCloser
+	decoder *eventstream.Decoder
+
+	unmarshalerForEventType func(string) (Unmarshaler, error)
+	payloadUnmarshaler      protocol.PayloadUnmarshaler
+
+	payloadBuf []byte
+}
+
+// NewEventReader returns a EventReader built from the reader and unmarshaler
+// provided.  Use ReadStream method to start reading from the EventStream.
+func NewEventReader(
+	reader io.ReadCloser,
+	payloadUnmarshaler protocol.PayloadUnmarshaler,
+	unmarshalerForEventType func(string) (Unmarshaler, error),
+) *EventReader {
+	return &EventReader{
+		reader:                  reader,
+		decoder:                 eventstream.NewDecoder(reader),
+		payloadUnmarshaler:      payloadUnmarshaler,
+		unmarshalerForEventType: unmarshalerForEventType,
+		payloadBuf:              make([]byte, 10*1024),
+	}
+}
+
+// UseLogger instructs the EventReader to use the logger and log level
+// specified.
+func (r *EventReader) UseLogger(logger aws.Logger, logLevel aws.LogLevelType) {
+	if logger != nil && logLevel.Matches(aws.LogDebugWithEventStreamBody) {
+		r.decoder.UseLogger(logger)
+	}
+}
+
+// ReadEvent attempts to read a message from the EventStream and return the
+// unmarshaled event value that the message is for.
+//
+// For EventStream API errors check if the returned error satisfies the
+// awserr.Error interface to get the error's Code and Message components.
+//
+// EventUnmarshalers called with EventStream messages must take copies of the
+// message's Payload. The payload will is reused between events read.
+func (r *EventReader) ReadEvent() (event interface{}, err error) {
+	msg, err := r.decoder.Decode(r.payloadBuf)
+	if err != nil {
+		return nil, err
+	}
+	defer func() {
+		// Reclaim payload buffer for next message read.
+		r.payloadBuf = msg.Payload[0:0]
+	}()
+
+	typ, err := GetHeaderString(msg, MessageTypeHeader)
+	if err != nil {
+		return nil, err
+	}
+
+	switch typ {
+	case EventMessageType:
+		return r.unmarshalEventMessage(msg)
+	case ExceptionMessageType:
+		err = r.unmarshalEventException(msg)
+		return nil, err
+	case ErrorMessageType:
+		return nil, r.unmarshalErrorMessage(msg)
+	default:
+		return nil, fmt.Errorf("unknown eventstream message type, %v", typ)
+	}
+}
+
+func (r *EventReader) unmarshalEventMessage(
+	msg eventstream.Message,
+) (event interface{}, err error) {
+	eventType, err := GetHeaderString(msg, EventTypeHeader)
+	if err != nil {
+		return nil, err
+	}
+
+	ev, err := r.unmarshalerForEventType(eventType)
+	if err != nil {
+		return nil, err
+	}
+
+	err = ev.UnmarshalEvent(r.payloadUnmarshaler, msg)
+	if err != nil {
+		return nil, err
+	}
+
+	return ev, nil
+}
+
+func (r *EventReader) unmarshalEventException(
+	msg eventstream.Message,
+) (err error) {
+	eventType, err := GetHeaderString(msg, ExceptionTypeHeader)
+	if err != nil {
+		return err
+	}
+
+	ev, err := r.unmarshalerForEventType(eventType)
+	if err != nil {
+		return err
+	}
+
+	err = ev.UnmarshalEvent(r.payloadUnmarshaler, msg)
+	if err != nil {
+		return err
+	}
+
+	var ok bool
+	err, ok = ev.(error)
+	if !ok {
+		err = messageError{
+			code: "SerializationError",
+			msg: fmt.Sprintf(
+				"event stream exception %s mapped to non-error %T, %v",
+				eventType, ev, ev,
+			),
+		}
+	}
+
+	return err
+}
+
+func (r *EventReader) unmarshalErrorMessage(msg eventstream.Message) (err error) {
+	var msgErr messageError
+
+	msgErr.code, err = GetHeaderString(msg, ErrorCodeHeader)
+	if err != nil {
+		return err
+	}
+
+	msgErr.msg, err = GetHeaderString(msg, ErrorMessageHeader)
+	if err != nil {
+		return err
+	}
+
+	return msgErr
+}
+
+// Close closes the EventReader's EventStream reader.
+func (r *EventReader) Close() error {
+	return r.reader.Close()
+}
+
+// GetHeaderString returns the value of the header as a string. If the header
+// is not set or the value is not a string an error will be returned.
+func GetHeaderString(msg eventstream.Message, headerName string) (string, error) {
+	headerVal := msg.Headers.Get(headerName)
+	if headerVal == nil {
+		return "", fmt.Errorf("error header %s not present", headerName)
+	}
+
+	v, ok := headerVal.Get().(string)
+	if !ok {
+		return "", fmt.Errorf("error header value is not a string, %T", headerVal)
+	}
+
+	return v, nil
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamapi/error.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamapi/error.go
new file mode 100644
index 000000000..5ea5a988b
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamapi/error.go
@@ -0,0 +1,24 @@
+package eventstreamapi
+
+import "fmt"
+
+type messageError struct {
+	code string
+	msg  string
+}
+
+func (e messageError) Code() string {
+	return e.code
+}
+
+func (e messageError) Message() string {
+	return e.msg
+}
+
+func (e messageError) Error() string {
+	return fmt.Sprintf("%s: %s", e.code, e.msg)
+}
+
+func (e messageError) OrigErr() error {
+	return nil
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/header.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/header.go
new file mode 100644
index 000000000..3b44dde2f
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/header.go
@@ -0,0 +1,166 @@
+package eventstream
+
+import (
+	"encoding/binary"
+	"fmt"
+	"io"
+)
+
+// Headers are a collection of EventStream header values.
+type Headers []Header
+
+// Header is a single EventStream Key Value header pair.
+type Header struct {
+	Name  string
+	Value Value
+}
+
+// Set associates the name with a value. If the header name already exists in
+// the Headers the value will be replaced with the new one.
+func (hs *Headers) Set(name string, value Value) {
+	var i int
+	for ; i < len(*hs); i++ {
+		if (*hs)[i].Name == name {
+			(*hs)[i].Value = value
+			return
+		}
+	}
+
+	*hs = append(*hs, Header{
+		Name: name, Value: value,
+	})
+}
+
+// Get returns the Value associated with the header. Nil is returned if the
+// value does not exist.
+func (hs Headers) Get(name string) Value {
+	for i := 0; i < len(hs); i++ {
+		if h := hs[i]; h.Name == name {
+			return h.Value
+		}
+	}
+	return nil
+}
+
+// Del deletes the value in the Headers if it exists.
+func (hs *Headers) Del(name string) {
+	for i := 0; i < len(*hs); i++ {
+		if (*hs)[i].Name == name {
+			copy((*hs)[i:], (*hs)[i+1:])
+			(*hs) = (*hs)[:len(*hs)-1]
+		}
+	}
+}
+
+func decodeHeaders(r io.Reader) (Headers, error) {
+	hs := Headers{}
+
+	for {
+		name, err := decodeHeaderName(r)
+		if err != nil {
+			if err == io.EOF {
+				// EOF while getting header name means no more headers
+				break
+			}
+			return nil, err
+		}
+
+		value, err := decodeHeaderValue(r)
+		if err != nil {
+			return nil, err
+		}
+
+		hs.Set(name, value)
+	}
+
+	return hs, nil
+}
+
+func decodeHeaderName(r io.Reader) (string, error) {
+	var n headerName
+
+	var err error
+	n.Len, err = decodeUint8(r)
+	if err != nil {
+		return "", err
+	}
+
+	name := n.Name[:n.Len]
+	if _, err := io.ReadFull(r, name); err != nil {
+		return "", err
+	}
+
+	return string(name), nil
+}
+
+func decodeHeaderValue(r io.Reader) (Value, error) {
+	var raw rawValue
+
+	typ, err := decodeUint8(r)
+	if err != nil {
+		return nil, err
+	}
+	raw.Type = valueType(typ)
+
+	var v Value
+
+	switch raw.Type {
+	case trueValueType:
+		v = BoolValue(true)
+	case falseValueType:
+		v = BoolValue(false)
+	case int8ValueType:
+		var tv Int8Value
+		err = tv.decode(r)
+		v = tv
+	case int16ValueType:
+		var tv Int16Value
+		err = tv.decode(r)
+		v = tv
+	case int32ValueType:
+		var tv Int32Value
+		err = tv.decode(r)
+		v = tv
+	case int64ValueType:
+		var tv Int64Value
+		err = tv.decode(r)
+		v = tv
+	case bytesValueType:
+		var tv BytesValue
+		err = tv.decode(r)
+		v = tv
+	case stringValueType:
+		var tv StringValue
+		err = tv.decode(r)
+		v = tv
+	case timestampValueType:
+		var tv TimestampValue
+		err = tv.decode(r)
+		v = tv
+	case uuidValueType:
+		var tv UUIDValue
+		err = tv.decode(r)
+		v = tv
+	default:
+		panic(fmt.Sprintf("unknown value type %d", raw.Type))
+	}
+
+	// Error could be EOF, let caller deal with it
+	return v, err
+}
+
+const maxHeaderNameLen = 255
+
+type headerName struct {
+	Len  uint8
+	Name [maxHeaderNameLen]byte
+}
+
+func (v headerName) encode(w io.Writer) error {
+	if err := binary.Write(w, binary.BigEndian, v.Len); err != nil {
+		return err
+	}
+
+	_, err := w.Write(v.Name[:v.Len])
+	return err
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/header_value.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/header_value.go
new file mode 100644
index 000000000..e3fc0766a
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/header_value.go
@@ -0,0 +1,501 @@
+package eventstream
+
+import (
+	"encoding/base64"
+	"encoding/binary"
+	"fmt"
+	"io"
+	"strconv"
+	"time"
+)
+
+const maxHeaderValueLen = 1<<15 - 1 // 2^15-1 or 32KB - 1
+
+// valueType is the EventStream header value type.
+type valueType uint8
+
+// Header value types
+const (
+	trueValueType valueType = iota
+	falseValueType
+	int8ValueType  // Byte
+	int16ValueType // Short
+	int32ValueType // Integer
+	int64ValueType // Long
+	bytesValueType
+	stringValueType
+	timestampValueType
+	uuidValueType
+)
+
+func (t valueType) String() string {
+	switch t {
+	case trueValueType:
+		return "bool"
+	case falseValueType:
+		return "bool"
+	case int8ValueType:
+		return "int8"
+	case int16ValueType:
+		return "int16"
+	case int32ValueType:
+		return "int32"
+	case int64ValueType:
+		return "int64"
+	case bytesValueType:
+		return "byte_array"
+	case stringValueType:
+		return "string"
+	case timestampValueType:
+		return "timestamp"
+	case uuidValueType:
+		return "uuid"
+	default:
+		return fmt.Sprintf("unknown value type %d", uint8(t))
+	}
+}
+
+type rawValue struct {
+	Type  valueType
+	Len   uint16 // Only set for variable length slices
+	Value []byte // byte representation of value, BigEndian encoding.
+}
+
+func (r rawValue) encodeScalar(w io.Writer, v interface{}) error {
+	return binaryWriteFields(w, binary.BigEndian,
+		r.Type,
+		v,
+	)
+}
+
+func (r rawValue) encodeFixedSlice(w io.Writer, v []byte) error {
+	binary.Write(w, binary.BigEndian, r.Type)
+
+	_, err := w.Write(v)
+	return err
+}
+
+func (r rawValue) encodeBytes(w io.Writer, v []byte) error {
+	if len(v) > maxHeaderValueLen {
+		return LengthError{
+			Part: "header value",
+			Want: maxHeaderValueLen, Have: len(v),
+			Value: v,
+		}
+	}
+	r.Len = uint16(len(v))
+
+	err := binaryWriteFields(w, binary.BigEndian,
+		r.Type,
+		r.Len,
+	)
+	if err != nil {
+		return err
+	}
+
+	_, err = w.Write(v)
+	return err
+}
+
+func (r rawValue) encodeString(w io.Writer, v string) error {
+	if len(v) > maxHeaderValueLen {
+		return LengthError{
+			Part: "header value",
+			Want: maxHeaderValueLen, Have: len(v),
+			Value: v,
+		}
+	}
+	r.Len = uint16(len(v))
+
+	type stringWriter interface {
+		WriteString(string) (int, error)
+	}
+
+	err := binaryWriteFields(w, binary.BigEndian,
+		r.Type,
+		r.Len,
+	)
+	if err != nil {
+		return err
+	}
+
+	if sw, ok := w.(stringWriter); ok {
+		_, err = sw.WriteString(v)
+	} else {
+		_, err = w.Write([]byte(v))
+	}
+
+	return err
+}
+
+func decodeFixedBytesValue(r io.Reader, buf []byte) error {
+	_, err := io.ReadFull(r, buf)
+	return err
+}
+
+func decodeBytesValue(r io.Reader) ([]byte, error) {
+	var raw rawValue
+	var err error
+	raw.Len, err = decodeUint16(r)
+	if err != nil {
+		return nil, err
+	}
+
+	buf := make([]byte, raw.Len)
+	_, err = io.ReadFull(r, buf)
+	if err != nil {
+		return nil, err
+	}
+
+	return buf, nil
+}
+
+func decodeStringValue(r io.Reader) (string, error) {
+	v, err := decodeBytesValue(r)
+	return string(v), err
+}
+
+// Value represents the abstract header value.
+type Value interface {
+	Get() interface{}
+	String() string
+	valueType() valueType
+	encode(io.Writer) error
+}
+
+// An BoolValue provides eventstream encoding, and representation
+// of a Go bool value.
+type BoolValue bool
+
+// Get returns the underlying type
+func (v BoolValue) Get() interface{} {
+	return bool(v)
+}
+
+// valueType returns the EventStream header value type value.
+func (v BoolValue) valueType() valueType {
+	if v {
+		return trueValueType
+	}
+	return falseValueType
+}
+
+func (v BoolValue) String() string {
+	return strconv.FormatBool(bool(v))
+}
+
+// encode encodes the BoolValue into an eventstream binary value
+// representation.
+func (v BoolValue) encode(w io.Writer) error {
+	return binary.Write(w, binary.BigEndian, v.valueType())
+}
+
+// An Int8Value provides eventstream encoding, and representation of a Go
+// int8 value.
+type Int8Value int8
+
+// Get returns the underlying value.
+func (v Int8Value) Get() interface{} {
+	return int8(v)
+}
+
+// valueType returns the EventStream header value type value.
+func (Int8Value) valueType() valueType {
+	return int8ValueType
+}
+
+func (v Int8Value) String() string {
+	return fmt.Sprintf("0x%02x", int8(v))
+}
+
+// encode encodes the Int8Value into an eventstream binary value
+// representation.
+func (v Int8Value) encode(w io.Writer) error {
+	raw := rawValue{
+		Type: v.valueType(),
+	}
+
+	return raw.encodeScalar(w, v)
+}
+
+func (v *Int8Value) decode(r io.Reader) error {
+	n, err := decodeUint8(r)
+	if err != nil {
+		return err
+	}
+
+	*v = Int8Value(n)
+	return nil
+}
+
+// An Int16Value provides eventstream encoding, and representation of a Go
+// int16 value.
+type Int16Value int16
+
+// Get returns the underlying value.
+func (v Int16Value) Get() interface{} {
+	return int16(v)
+}
+
+// valueType returns the EventStream header value type value.
+func (Int16Value) valueType() valueType {
+	return int16ValueType
+}
+
+func (v Int16Value) String() string {
+	return fmt.Sprintf("0x%04x", int16(v))
+}
+
+// encode encodes the Int16Value into an eventstream binary value
+// representation.
+func (v Int16Value) encode(w io.Writer) error {
+	raw := rawValue{
+		Type: v.valueType(),
+	}
+	return raw.encodeScalar(w, v)
+}
+
+func (v *Int16Value) decode(r io.Reader) error {
+	n, err := decodeUint16(r)
+	if err != nil {
+		return err
+	}
+
+	*v = Int16Value(n)
+	return nil
+}
+
+// An Int32Value provides eventstream encoding, and representation of a Go
+// int32 value.
+type Int32Value int32
+
+// Get returns the underlying value.
+func (v Int32Value) Get() interface{} {
+	return int32(v)
+}
+
+// valueType returns the EventStream header value type value.
+func (Int32Value) valueType() valueType {
+	return int32ValueType
+}
+
+func (v Int32Value) String() string {
+	return fmt.Sprintf("0x%08x", int32(v))
+}
+
+// encode encodes the Int32Value into an eventstream binary value
+// representation.
+func (v Int32Value) encode(w io.Writer) error {
+	raw := rawValue{
+		Type: v.valueType(),
+	}
+	return raw.encodeScalar(w, v)
+}
+
+func (v *Int32Value) decode(r io.Reader) error {
+	n, err := decodeUint32(r)
+	if err != nil {
+		return err
+	}
+
+	*v = Int32Value(n)
+	return nil
+}
+
+// An Int64Value provides eventstream encoding, and representation of a Go
+// int64 value.
+type Int64Value int64
+
+// Get returns the underlying value.
+func (v Int64Value) Get() interface{} {
+	return int64(v)
+}
+
+// valueType returns the EventStream header value type value.
+func (Int64Value) valueType() valueType {
+	return int64ValueType
+}
+
+func (v Int64Value) String() string {
+	return fmt.Sprintf("0x%016x", int64(v))
+}
+
+// encode encodes the Int64Value into an eventstream binary value
+// representation.
+func (v Int64Value) encode(w io.Writer) error {
+	raw := rawValue{
+		Type: v.valueType(),
+	}
+	return raw.encodeScalar(w, v)
+}
+
+func (v *Int64Value) decode(r io.Reader) error {
+	n, err := decodeUint64(r)
+	if err != nil {
+		return err
+	}
+
+	*v = Int64Value(n)
+	return nil
+}
+
+// An BytesValue provides eventstream encoding, and representation of a Go
+// byte slice.
+type BytesValue []byte
+
+// Get returns the underlying value.
+func (v BytesValue) Get() interface{} {
+	return []byte(v)
+}
+
+// valueType returns the EventStream header value type value.
+func (BytesValue) valueType() valueType {
+	return bytesValueType
+}
+
+func (v BytesValue) String() string {
+	return base64.StdEncoding.EncodeToString([]byte(v))
+}
+
+// encode encodes the BytesValue into an eventstream binary value
+// representation.
+func (v BytesValue) encode(w io.Writer) error {
+	raw := rawValue{
+		Type: v.valueType(),
+	}
+
+	return raw.encodeBytes(w, []byte(v))
+}
+
+func (v *BytesValue) decode(r io.Reader) error {
+	buf, err := decodeBytesValue(r)
+	if err != nil {
+		return err
+	}
+
+	*v = BytesValue(buf)
+	return nil
+}
+
+// An StringValue provides eventstream encoding, and representation of a Go
+// string.
+type StringValue string
+
+// Get returns the underlying value.
+func (v StringValue) Get() interface{} {
+	return string(v)
+}
+
+// valueType returns the EventStream header value type value.
+func (StringValue) valueType() valueType {
+	return stringValueType
+}
+
+func (v StringValue) String() string {
+	return string(v)
+}
+
+// encode encodes the StringValue into an eventstream binary value
+// representation.
+func (v StringValue) encode(w io.Writer) error {
+	raw := rawValue{
+		Type: v.valueType(),
+	}
+
+	return raw.encodeString(w, string(v))
+}
+
+func (v *StringValue) decode(r io.Reader) error {
+	s, err := decodeStringValue(r)
+	if err != nil {
+		return err
+	}
+
+	*v = StringValue(s)
+	return nil
+}
+
+// An TimestampValue provides eventstream encoding, and representation of a Go
+// timestamp.
+type TimestampValue time.Time
+
+// Get returns the underlying value.
+func (v TimestampValue) Get() interface{} {
+	return time.Time(v)
+}
+
+// valueType returns the EventStream header value type value.
+func (TimestampValue) valueType() valueType {
+	return timestampValueType
+}
+
+func (v TimestampValue) epochMilli() int64 {
+	nano := time.Time(v).UnixNano()
+	msec := nano / int64(time.Millisecond)
+	return msec
+}
+
+func (v TimestampValue) String() string {
+	msec := v.epochMilli()
+	return strconv.FormatInt(msec, 10)
+}
+
+// encode encodes the TimestampValue into an eventstream binary value
+// representation.
+func (v TimestampValue) encode(w io.Writer) error {
+	raw := rawValue{
+		Type: v.valueType(),
+	}
+
+	msec := v.epochMilli()
+	return raw.encodeScalar(w, msec)
+}
+
+func (v *TimestampValue) decode(r io.Reader) error {
+	n, err := decodeUint64(r)
+	if err != nil {
+		return err
+	}
+
+	*v = TimestampValue(timeFromEpochMilli(int64(n)))
+	return nil
+}
+
+func timeFromEpochMilli(t int64) time.Time {
+	secs := t / 1e3
+	msec := t % 1e3
+	return time.Unix(secs, msec*int64(time.Millisecond)).UTC()
+}
+
+// An UUIDValue provides eventstream encoding, and representation of a UUID
+// value.
+type UUIDValue [16]byte
+
+// Get returns the underlying value.
+func (v UUIDValue) Get() interface{} {
+	return v[:]
+}
+
+// valueType returns the EventStream header value type value.
+func (UUIDValue) valueType() valueType {
+	return uuidValueType
+}
+
+func (v UUIDValue) String() string {
+	return fmt.Sprintf(`%X-%X-%X-%X-%X`, v[0:4], v[4:6], v[6:8], v[8:10], v[10:])
+}
+
+// encode encodes the UUIDValue into an eventstream binary value
+// representation.
+func (v UUIDValue) encode(w io.Writer) error {
+	raw := rawValue{
+		Type: v.valueType(),
+	}
+
+	return raw.encodeFixedSlice(w, v[:])
+}
+
+func (v *UUIDValue) decode(r io.Reader) error {
+	tv := (*v)[:]
+	return decodeFixedBytesValue(r, tv)
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/message.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/message.go
new file mode 100644
index 000000000..2dc012a66
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/eventstream/message.go
@@ -0,0 +1,103 @@
+package eventstream
+
+import (
+	"bytes"
+	"encoding/binary"
+	"hash/crc32"
+)
+
+const preludeLen = 8
+const preludeCRCLen = 4
+const msgCRCLen = 4
+const minMsgLen = preludeLen + preludeCRCLen + msgCRCLen
+const maxPayloadLen = 1024 * 1024 * 16 // 16MB
+const maxHeadersLen = 1024 * 128       // 128KB
+const maxMsgLen = minMsgLen + maxHeadersLen + maxPayloadLen
+
+var crc32IEEETable = crc32.MakeTable(crc32.IEEE)
+
+// A Message provides the eventstream message representation.
+type Message struct {
+	Headers Headers
+	Payload []byte
+}
+
+func (m *Message) rawMessage() (rawMessage, error) {
+	var raw rawMessage
+
+	if len(m.Headers) > 0 {
+		var headers bytes.Buffer
+		if err := encodeHeaders(&headers, m.Headers); err != nil {
+			return rawMessage{}, err
+		}
+		raw.Headers = headers.Bytes()
+		raw.HeadersLen = uint32(len(raw.Headers))
+	}
+
+	raw.Length = raw.HeadersLen + uint32(len(m.Payload)) + minMsgLen
+
+	hash := crc32.New(crc32IEEETable)
+	binaryWriteFields(hash, binary.BigEndian, raw.Length, raw.HeadersLen)
+	raw.PreludeCRC = hash.Sum32()
+
+	binaryWriteFields(hash, binary.BigEndian, raw.PreludeCRC)
+
+	if raw.HeadersLen > 0 {
+		hash.Write(raw.Headers)
+	}
+
+	// Read payload bytes and update hash for it as well.
+	if len(m.Payload) > 0 {
+		raw.Payload = m.Payload
+		hash.Write(raw.Payload)
+	}
+
+	raw.CRC = hash.Sum32()
+
+	return raw, nil
+}
+
+type messagePrelude struct {
+	Length     uint32
+	HeadersLen uint32
+	PreludeCRC uint32
+}
+
+func (p messagePrelude) PayloadLen() uint32 {
+	return p.Length - p.HeadersLen - minMsgLen
+}
+
+func (p messagePrelude) ValidateLens() error {
+	if p.Length == 0 || p.Length > maxMsgLen {
+		return LengthError{
+			Part: "message prelude",
+			Want: maxMsgLen,
+			Have: int(p.Length),
+		}
+	}
+	if p.HeadersLen > maxHeadersLen {
+		return LengthError{
+			Part: "message headers",
+			Want: maxHeadersLen,
+			Have: int(p.HeadersLen),
+		}
+	}
+	if payloadLen := p.PayloadLen(); payloadLen > maxPayloadLen {
+		return LengthError{
+			Part: "message payload",
+			Want: maxPayloadLen,
+			Have: int(payloadLen),
+		}
+	}
+
+	return nil
+}
+
+type rawMessage struct {
+	messagePrelude
+
+	Headers []byte
+	Payload []byte
+
+	CRC uint32
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/idempotency.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/idempotency.go
new file mode 100644
index 000000000..53831dff9
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/idempotency.go
@@ -0,0 +1,75 @@
+package protocol
+
+import (
+	"crypto/rand"
+	"fmt"
+	"reflect"
+)
+
+// RandReader is the random reader the protocol package will use to read
+// random bytes from. This is exported for testing, and should not be used.
+var RandReader = rand.Reader
+
+const idempotencyTokenFillTag = `idempotencyToken`
+
+// CanSetIdempotencyToken returns true if the struct field should be
+// automatically populated with a Idempotency token.
+//
+// Only *string and string type fields that are tagged with idempotencyToken
+// which are not already set can be auto filled.
+func CanSetIdempotencyToken(v reflect.Value, f reflect.StructField) bool {
+	switch u := v.Interface().(type) {
+	// To auto fill an Idempotency token the field must be a string,
+	// tagged for auto fill, and have a zero value.
+	case *string:
+		return u == nil && len(f.Tag.Get(idempotencyTokenFillTag)) != 0
+	case string:
+		return len(u) == 0 && len(f.Tag.Get(idempotencyTokenFillTag)) != 0
+	}
+
+	return false
+}
+
+// GetIdempotencyToken returns a randomly generated idempotency token.
+func GetIdempotencyToken() string {
+	b := make([]byte, 16)
+	RandReader.Read(b)
+
+	return UUIDVersion4(b)
+}
+
+// SetIdempotencyToken will set the value provided with a Idempotency Token.
+// Given that the value can be set. Will panic if value is not setable.
+func SetIdempotencyToken(v reflect.Value) {
+	if v.Kind() == reflect.Ptr {
+		if v.IsNil() && v.CanSet() {
+			v.Set(reflect.New(v.Type().Elem()))
+		}
+		v = v.Elem()
+	}
+	v = reflect.Indirect(v)
+
+	if !v.CanSet() {
+		panic(fmt.Sprintf("unable to set idempotnecy token %v", v))
+	}
+
+	b := make([]byte, 16)
+	_, err := rand.Read(b)
+	if err != nil {
+		// TODO handle error
+		return
+	}
+
+	v.Set(reflect.ValueOf(UUIDVersion4(b)))
+}
+
+// UUIDVersion4 returns a Version 4 random UUID from the byte slice provided
+func UUIDVersion4(u []byte) string {
+	// https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_.28random.29
+	// 13th character is "4"
+	u[6] = (u[6] | 0x40) & 0x4F
+	// 17th character is "8", "9", "a", or "b"
+	u[8] = (u[8] | 0x80) & 0xBF
+
+	return fmt.Sprintf(`%X-%X-%X-%X-%X`, u[0:4], u[4:6], u[6:8], u[8:10], u[10:])
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonvalue.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonvalue.go
new file mode 100644
index 000000000..776d11018
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonvalue.go
@@ -0,0 +1,76 @@
+package protocol
+
+import (
+	"encoding/base64"
+	"encoding/json"
+	"fmt"
+	"strconv"
+
+	"github.com/aws/aws-sdk-go/aws"
+)
+
+// EscapeMode is the mode that should be use for escaping a value
+type EscapeMode uint
+
+// The modes for escaping a value before it is marshaled, and unmarshaled.
+const (
+	NoEscape EscapeMode = iota
+	Base64Escape
+	QuotedEscape
+)
+
+// EncodeJSONValue marshals the value into a JSON string, and optionally base64
+// encodes the string before returning it.
+//
+// Will panic if the escape mode is unknown.
+func EncodeJSONValue(v aws.JSONValue, escape EscapeMode) (string, error) {
+	b, err := json.Marshal(v)
+	if err != nil {
+		return "", err
+	}
+
+	switch escape {
+	case NoEscape:
+		return string(b), nil
+	case Base64Escape:
+		return base64.StdEncoding.EncodeToString(b), nil
+	case QuotedEscape:
+		return strconv.Quote(string(b)), nil
+	}
+
+	panic(fmt.Sprintf("EncodeJSONValue called with unknown EscapeMode, %v", escape))
+}
+
+// DecodeJSONValue will attempt to decode the string input as a JSONValue.
+// Optionally decoding base64 the value first before JSON unmarshaling.
+//
+// Will panic if the escape mode is unknown.
+func DecodeJSONValue(v string, escape EscapeMode) (aws.JSONValue, error) {
+	var b []byte
+	var err error
+
+	switch escape {
+	case NoEscape:
+		b = []byte(v)
+	case Base64Escape:
+		b, err = base64.StdEncoding.DecodeString(v)
+	case QuotedEscape:
+		var u string
+		u, err = strconv.Unquote(v)
+		b = []byte(u)
+	default:
+		panic(fmt.Sprintf("DecodeJSONValue called with unknown EscapeMode, %v", escape))
+	}
+
+	if err != nil {
+		return nil, err
+	}
+
+	m := aws.JSONValue{}
+	err = json.Unmarshal(b, &m)
+	if err != nil {
+		return nil, err
+	}
+
+	return m, nil
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/payload.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/payload.go
new file mode 100644
index 000000000..e21614a12
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/payload.go
@@ -0,0 +1,81 @@
+package protocol
+
+import (
+	"io"
+	"io/ioutil"
+	"net/http"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/client/metadata"
+	"github.com/aws/aws-sdk-go/aws/request"
+)
+
+// PayloadUnmarshaler provides the interface for unmarshaling a payload's
+// reader into a SDK shape.
+type PayloadUnmarshaler interface {
+	UnmarshalPayload(io.Reader, interface{}) error
+}
+
+// HandlerPayloadUnmarshal implements the PayloadUnmarshaler from a
+// HandlerList. This provides the support for unmarshaling a payload reader to
+// a shape without needing a SDK request first.
+type HandlerPayloadUnmarshal struct {
+	Unmarshalers request.HandlerList
+}
+
+// UnmarshalPayload unmarshals the io.Reader payload into the SDK shape using
+// the Unmarshalers HandlerList provided. Returns an error if unable
+// unmarshaling fails.
+func (h HandlerPayloadUnmarshal) UnmarshalPayload(r io.Reader, v interface{}) error {
+	req := &request.Request{
+		HTTPRequest: &http.Request{},
+		HTTPResponse: &http.Response{
+			StatusCode: 200,
+			Header:     http.Header{},
+			Body:       ioutil.NopCloser(r),
+		},
+		Data: v,
+	}
+
+	h.Unmarshalers.Run(req)
+
+	return req.Error
+}
+
+// PayloadMarshaler provides the interface for marshaling a SDK shape into and
+// io.Writer.
+type PayloadMarshaler interface {
+	MarshalPayload(io.Writer, interface{}) error
+}
+
+// HandlerPayloadMarshal implements the PayloadMarshaler from a HandlerList.
+// This provides support for marshaling a SDK shape into an io.Writer without
+// needing a SDK request first.
+type HandlerPayloadMarshal struct {
+	Marshalers request.HandlerList
+}
+
+// MarshalPayload marshals the SDK shape into the io.Writer using the
+// Marshalers HandlerList provided. Returns an error if unable if marshal
+// fails.
+func (h HandlerPayloadMarshal) MarshalPayload(w io.Writer, v interface{}) error {
+	req := request.New(
+		aws.Config{},
+		metadata.ClientInfo{},
+		request.Handlers{},
+		nil,
+		&request.Operation{HTTPMethod: "GET"},
+		v,
+		nil,
+	)
+
+	h.Marshalers.Run(req)
+
+	if req.Error != nil {
+		return req.Error
+	}
+
+	io.Copy(w, req.GetBody())
+
+	return nil
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/query/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/build.go
new file mode 100644
index 000000000..60e5b09d5
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/build.go
@@ -0,0 +1,36 @@
+// Package query provides serialization of AWS query requests, and responses.
+package query
+
+//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/query.json build_test.go
+
+import (
+	"net/url"
+
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/request"
+	"github.com/aws/aws-sdk-go/private/protocol/query/queryutil"
+)
+
+// BuildHandler is a named request handler for building query protocol requests
+var BuildHandler = request.NamedHandler{Name: "awssdk.query.Build", Fn: Build}
+
+// Build builds a request for an AWS Query service.
+func Build(r *request.Request) {
+	body := url.Values{
+		"Action":  {r.Operation.Name},
+		"Version": {r.ClientInfo.APIVersion},
+	}
+	if err := queryutil.Parse(body, r.Params, false); err != nil {
+		r.Error = awserr.New("SerializationError", "failed encoding Query request", err)
+		return
+	}
+
+	if !r.IsPresigned() {
+		r.HTTPRequest.Method = "POST"
+		r.HTTPRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
+		r.SetBufferBody([]byte(body.Encode()))
+	} else { // This is a pre-signed request
+		r.HTTPRequest.Method = "GET"
+		r.HTTPRequest.URL.RawQuery = body.Encode()
+	}
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go
new file mode 100644
index 000000000..75866d012
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go
@@ -0,0 +1,246 @@
+package queryutil
+
+import (
+	"encoding/base64"
+	"fmt"
+	"net/url"
+	"reflect"
+	"sort"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/aws/aws-sdk-go/private/protocol"
+)
+
+// Parse parses an object i and fills a url.Values object. The isEC2 flag
+// indicates if this is the EC2 Query sub-protocol.
+func Parse(body url.Values, i interface{}, isEC2 bool) error {
+	q := queryParser{isEC2: isEC2}
+	return q.parseValue(body, reflect.ValueOf(i), "", "")
+}
+
+func elemOf(value reflect.Value) reflect.Value {
+	for value.Kind() == reflect.Ptr {
+		value = value.Elem()
+	}
+	return value
+}
+
+type queryParser struct {
+	isEC2 bool
+}
+
+func (q *queryParser) parseValue(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error {
+	value = elemOf(value)
+
+	// no need to handle zero values
+	if !value.IsValid() {
+		return nil
+	}
+
+	t := tag.Get("type")
+	if t == "" {
+		switch value.Kind() {
+		case reflect.Struct:
+			t = "structure"
+		case reflect.Slice:
+			t = "list"
+		case reflect.Map:
+			t = "map"
+		}
+	}
+
+	switch t {
+	case "structure":
+		return q.parseStruct(v, value, prefix)
+	case "list":
+		return q.parseList(v, value, prefix, tag)
+	case "map":
+		return q.parseMap(v, value, prefix, tag)
+	default:
+		return q.parseScalar(v, value, prefix, tag)
+	}
+}
+
+func (q *queryParser) parseStruct(v url.Values, value reflect.Value, prefix string) error {
+	if !value.IsValid() {
+		return nil
+	}
+
+	t := value.Type()
+	for i := 0; i < value.NumField(); i++ {
+		elemValue := elemOf(value.Field(i))
+		field := t.Field(i)
+
+		if field.PkgPath != "" {
+			continue // ignore unexported fields
+		}
+		if field.Tag.Get("ignore") != "" {
+			continue
+		}
+
+		if protocol.CanSetIdempotencyToken(value.Field(i), field) {
+			token := protocol.GetIdempotencyToken()
+			elemValue = reflect.ValueOf(token)
+		}
+
+		var name string
+		if q.isEC2 {
+			name = field.Tag.Get("queryName")
+		}
+		if name == "" {
+			if field.Tag.Get("flattened") != "" && field.Tag.Get("locationNameList") != "" {
+				name = field.Tag.Get("locationNameList")
+			} else if locName := field.Tag.Get("locationName"); locName != "" {
+				name = locName
+			}
+			if name != "" && q.isEC2 {
+				name = strings.ToUpper(name[0:1]) + name[1:]
+			}
+		}
+		if name == "" {
+			name = field.Name
+		}
+
+		if prefix != "" {
+			name = prefix + "." + name
+		}
+
+		if err := q.parseValue(v, elemValue, name, field.Tag); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func (q *queryParser) parseList(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error {
+	// If it's empty, generate an empty value
+	if !value.IsNil() && value.Len() == 0 {
+		v.Set(prefix, "")
+		return nil
+	}
+
+	if _, ok := value.Interface().([]byte); ok {
+		return q.parseScalar(v, value, prefix, tag)
+	}
+
+	// check for unflattened list member
+	if !q.isEC2 && tag.Get("flattened") == "" {
+		if listName := tag.Get("locationNameList"); listName == "" {
+			prefix += ".member"
+		} else {
+			prefix += "." + listName
+		}
+	}
+
+	for i := 0; i < value.Len(); i++ {
+		slicePrefix := prefix
+		if slicePrefix == "" {
+			slicePrefix = strconv.Itoa(i + 1)
+		} else {
+			slicePrefix = slicePrefix + "." + strconv.Itoa(i+1)
+		}
+		if err := q.parseValue(v, value.Index(i), slicePrefix, ""); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func (q *queryParser) parseMap(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error {
+	// If it's empty, generate an empty value
+	if !value.IsNil() && value.Len() == 0 {
+		v.Set(prefix, "")
+		return nil
+	}
+
+	// check for unflattened list member
+	if !q.isEC2 && tag.Get("flattened") == "" {
+		prefix += ".entry"
+	}
+
+	// sort keys for improved serialization consistency.
+	// this is not strictly necessary for protocol support.
+	mapKeyValues := value.MapKeys()
+	mapKeys := map[string]reflect.Value{}
+	mapKeyNames := make([]string, len(mapKeyValues))
+	for i, mapKey := range mapKeyValues {
+		name := mapKey.String()
+		mapKeys[name] = mapKey
+		mapKeyNames[i] = name
+	}
+	sort.Strings(mapKeyNames)
+
+	for i, mapKeyName := range mapKeyNames {
+		mapKey := mapKeys[mapKeyName]
+		mapValue := value.MapIndex(mapKey)
+
+		kname := tag.Get("locationNameKey")
+		if kname == "" {
+			kname = "key"
+		}
+		vname := tag.Get("locationNameValue")
+		if vname == "" {
+			vname = "value"
+		}
+
+		// serialize key
+		var keyName string
+		if prefix == "" {
+			keyName = strconv.Itoa(i+1) + "." + kname
+		} else {
+			keyName = prefix + "." + strconv.Itoa(i+1) + "." + kname
+		}
+
+		if err := q.parseValue(v, mapKey, keyName, ""); err != nil {
+			return err
+		}
+
+		// serialize value
+		var valueName string
+		if prefix == "" {
+			valueName = strconv.Itoa(i+1) + "." + vname
+		} else {
+			valueName = prefix + "." + strconv.Itoa(i+1) + "." + vname
+		}
+
+		if err := q.parseValue(v, mapValue, valueName, ""); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func (q *queryParser) parseScalar(v url.Values, r reflect.Value, name string, tag reflect.StructTag) error {
+	switch value := r.Interface().(type) {
+	case string:
+		v.Set(name, value)
+	case []byte:
+		if !r.IsNil() {
+			v.Set(name, base64.StdEncoding.EncodeToString(value))
+		}
+	case bool:
+		v.Set(name, strconv.FormatBool(value))
+	case int64:
+		v.Set(name, strconv.FormatInt(value, 10))
+	case int:
+		v.Set(name, strconv.Itoa(value))
+	case float64:
+		v.Set(name, strconv.FormatFloat(value, 'f', -1, 64))
+	case float32:
+		v.Set(name, strconv.FormatFloat(float64(value), 'f', -1, 32))
+	case time.Time:
+		const ISO8601UTC = "2006-01-02T15:04:05Z"
+		format := tag.Get("timestampFormat")
+		if len(format) == 0 {
+			format = protocol.ISO8601TimeFormatName
+		}
+
+		v.Set(name, protocol.FormatTime(format, value))
+	default:
+		return fmt.Errorf("unsupported value for param %s: %v (%s)", name, r.Interface(), r.Type().Name())
+	}
+	return nil
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal.go
new file mode 100644
index 000000000..e0f4d5a54
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal.go
@@ -0,0 +1,35 @@
+package query
+
+//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/query.json unmarshal_test.go
+
+import (
+	"encoding/xml"
+
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/request"
+	"github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil"
+)
+
+// UnmarshalHandler is a named request handler for unmarshaling query protocol requests
+var UnmarshalHandler = request.NamedHandler{Name: "awssdk.query.Unmarshal", Fn: Unmarshal}
+
+// UnmarshalMetaHandler is a named request handler for unmarshaling query protocol request metadata
+var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.query.UnmarshalMeta", Fn: UnmarshalMeta}
+
+// Unmarshal unmarshals a response for an AWS Query service.
+func Unmarshal(r *request.Request) {
+	defer r.HTTPResponse.Body.Close()
+	if r.DataFilled() {
+		decoder := xml.NewDecoder(r.HTTPResponse.Body)
+		err := xmlutil.UnmarshalXML(r.Data, decoder, r.Operation.Name+"Result")
+		if err != nil {
+			r.Error = awserr.New("SerializationError", "failed decoding Query response", err)
+			return
+		}
+	}
+}
+
+// UnmarshalMeta unmarshals header response values for an AWS Query service.
+func UnmarshalMeta(r *request.Request) {
+	r.RequestID = r.HTTPResponse.Header.Get("X-Amzn-Requestid")
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_error.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_error.go
new file mode 100644
index 000000000..f21429617
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_error.go
@@ -0,0 +1,66 @@
+package query
+
+import (
+	"encoding/xml"
+	"io/ioutil"
+
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/request"
+)
+
+type xmlErrorResponse struct {
+	XMLName   xml.Name `xml:"ErrorResponse"`
+	Code      string   `xml:"Error>Code"`
+	Message   string   `xml:"Error>Message"`
+	RequestID string   `xml:"RequestId"`
+}
+
+type xmlServiceUnavailableResponse struct {
+	XMLName xml.Name `xml:"ServiceUnavailableException"`
+}
+
+// UnmarshalErrorHandler is a name request handler to unmarshal request errors
+var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.query.UnmarshalError", Fn: UnmarshalError}
+
+// UnmarshalError unmarshals an error response for an AWS Query service.
+func UnmarshalError(r *request.Request) {
+	defer r.HTTPResponse.Body.Close()
+
+	bodyBytes, err := ioutil.ReadAll(r.HTTPResponse.Body)
+	if err != nil {
+		r.Error = awserr.New("SerializationError", "failed to read from query HTTP response body", err)
+		return
+	}
+
+	// First check for specific error
+	resp := xmlErrorResponse{}
+	decodeErr := xml.Unmarshal(bodyBytes, &resp)
+	if decodeErr == nil {
+		reqID := resp.RequestID
+		if reqID == "" {
+			reqID = r.RequestID
+		}
+		r.Error = awserr.NewRequestFailure(
+			awserr.New(resp.Code, resp.Message, nil),
+			r.HTTPResponse.StatusCode,
+			reqID,
+		)
+		return
+	}
+
+	// Check for unhandled error
+	servUnavailResp := xmlServiceUnavailableResponse{}
+	unavailErr := xml.Unmarshal(bodyBytes, &servUnavailResp)
+	if unavailErr == nil {
+		r.Error = awserr.NewRequestFailure(
+			awserr.New("ServiceUnavailableException", "service is unavailable", nil),
+			r.HTTPResponse.StatusCode,
+			r.RequestID,
+		)
+		return
+	}
+
+	// Failed to retrieve any error message from the response body
+	r.Error = awserr.New("SerializationError",
+		"failed to decode query XML error response", decodeErr)
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go
new file mode 100644
index 000000000..b34f5258a
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go
@@ -0,0 +1,295 @@
+// Package rest provides RESTful serialization of AWS requests and responses.
+package rest
+
+import (
+	"bytes"
+	"encoding/base64"
+	"fmt"
+	"io"
+	"net/http"
+	"net/url"
+	"path"
+	"reflect"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/request"
+	"github.com/aws/aws-sdk-go/private/protocol"
+)
+
+// Whether the byte value can be sent without escaping in AWS URLs
+var noEscape [256]bool
+
+var errValueNotSet = fmt.Errorf("value not set")
+
+func init() {
+	for i := 0; i < len(noEscape); i++ {
+		// AWS expects every character except these to be escaped
+		noEscape[i] = (i >= 'A' && i <= 'Z') ||
+			(i >= 'a' && i <= 'z') ||
+			(i >= '0' && i <= '9') ||
+			i == '-' ||
+			i == '.' ||
+			i == '_' ||
+			i == '~'
+	}
+}
+
+// BuildHandler is a named request handler for building rest protocol requests
+var BuildHandler = request.NamedHandler{Name: "awssdk.rest.Build", Fn: Build}
+
+// Build builds the REST component of a service request.
+func Build(r *request.Request) {
+	if r.ParamsFilled() {
+		v := reflect.ValueOf(r.Params).Elem()
+		buildLocationElements(r, v, false)
+		buildBody(r, v)
+	}
+}
+
+// BuildAsGET builds the REST component of a service request with the ability to hoist
+// data from the body.
+func BuildAsGET(r *request.Request) {
+	if r.ParamsFilled() {
+		v := reflect.ValueOf(r.Params).Elem()
+		buildLocationElements(r, v, true)
+		buildBody(r, v)
+	}
+}
+
+func buildLocationElements(r *request.Request, v reflect.Value, buildGETQuery bool) {
+	query := r.HTTPRequest.URL.Query()
+
+	// Setup the raw path to match the base path pattern. This is needed
+	// so that when the path is mutated a custom escaped version can be
+	// stored in RawPath that will be used by the Go client.
+	r.HTTPRequest.URL.RawPath = r.HTTPRequest.URL.Path
+
+	for i := 0; i < v.NumField(); i++ {
+		m := v.Field(i)
+		if n := v.Type().Field(i).Name; n[0:1] == strings.ToLower(n[0:1]) {
+			continue
+		}
+
+		if m.IsValid() {
+			field := v.Type().Field(i)
+			name := field.Tag.Get("locationName")
+			if name == "" {
+				name = field.Name
+			}
+			if kind := m.Kind(); kind == reflect.Ptr {
+				m = m.Elem()
+			} else if kind == reflect.Interface {
+				if !m.Elem().IsValid() {
+					continue
+				}
+			}
+			if !m.IsValid() {
+				continue
+			}
+			if field.Tag.Get("ignore") != "" {
+				continue
+			}
+
+			var err error
+			switch field.Tag.Get("location") {
+			case "headers": // header maps
+				err = buildHeaderMap(&r.HTTPRequest.Header, m, field.Tag)
+			case "header":
+				err = buildHeader(&r.HTTPRequest.Header, m, name, field.Tag)
+			case "uri":
+				err = buildURI(r.HTTPRequest.URL, m, name, field.Tag)
+			case "querystring":
+				err = buildQueryString(query, m, name, field.Tag)
+			default:
+				if buildGETQuery {
+					err = buildQueryString(query, m, name, field.Tag)
+				}
+			}
+			r.Error = err
+		}
+		if r.Error != nil {
+			return
+		}
+	}
+
+	r.HTTPRequest.URL.RawQuery = query.Encode()
+	if !aws.BoolValue(r.Config.DisableRestProtocolURICleaning) {
+		cleanPath(r.HTTPRequest.URL)
+	}
+}
+
+func buildBody(r *request.Request, v reflect.Value) {
+	if field, ok := v.Type().FieldByName("_"); ok {
+		if payloadName := field.Tag.Get("payload"); payloadName != "" {
+			pfield, _ := v.Type().FieldByName(payloadName)
+			if ptag := pfield.Tag.Get("type"); ptag != "" && ptag != "structure" {
+				payload := reflect.Indirect(v.FieldByName(payloadName))
+				if payload.IsValid() && payload.Interface() != nil {
+					switch reader := payload.Interface().(type) {
+					case io.ReadSeeker:
+						r.SetReaderBody(reader)
+					case []byte:
+						r.SetBufferBody(reader)
+					case string:
+						r.SetStringBody(reader)
+					default:
+						r.Error = awserr.New("SerializationError",
+							"failed to encode REST request",
+							fmt.Errorf("unknown payload type %s", payload.Type()))
+					}
+				}
+			}
+		}
+	}
+}
+
+func buildHeader(header *http.Header, v reflect.Value, name string, tag reflect.StructTag) error {
+	str, err := convertType(v, tag)
+	if err == errValueNotSet {
+		return nil
+	} else if err != nil {
+		return awserr.New("SerializationError", "failed to encode REST request", err)
+	}
+
+	header.Add(name, str)
+
+	return nil
+}
+
+func buildHeaderMap(header *http.Header, v reflect.Value, tag reflect.StructTag) error {
+	prefix := tag.Get("locationName")
+	for _, key := range v.MapKeys() {
+		str, err := convertType(v.MapIndex(key), tag)
+		if err == errValueNotSet {
+			continue
+		} else if err != nil {
+			return awserr.New("SerializationError", "failed to encode REST request", err)
+
+		}
+
+		header.Add(prefix+key.String(), str)
+	}
+	return nil
+}
+
+func buildURI(u *url.URL, v reflect.Value, name string, tag reflect.StructTag) error {
+	value, err := convertType(v, tag)
+	if err == errValueNotSet {
+		return nil
+	} else if err != nil {
+		return awserr.New("SerializationError", "failed to encode REST request", err)
+	}
+
+	u.Path = strings.Replace(u.Path, "{"+name+"}", value, -1)
+	u.Path = strings.Replace(u.Path, "{"+name+"+}", value, -1)
+
+	u.RawPath = strings.Replace(u.RawPath, "{"+name+"}", EscapePath(value, true), -1)
+	u.RawPath = strings.Replace(u.RawPath, "{"+name+"+}", EscapePath(value, false), -1)
+
+	return nil
+}
+
+func buildQueryString(query url.Values, v reflect.Value, name string, tag reflect.StructTag) error {
+	switch value := v.Interface().(type) {
+	case []*string:
+		for _, item := range value {
+			query.Add(name, *item)
+		}
+	case map[string]*string:
+		for key, item := range value {
+			query.Add(key, *item)
+		}
+	case map[string][]*string:
+		for key, items := range value {
+			for _, item := range items {
+				query.Add(key, *item)
+			}
+		}
+	default:
+		str, err := convertType(v, tag)
+		if err == errValueNotSet {
+			return nil
+		} else if err != nil {
+			return awserr.New("SerializationError", "failed to encode REST request", err)
+		}
+		query.Set(name, str)
+	}
+
+	return nil
+}
+
+func cleanPath(u *url.URL) {
+	hasSlash := strings.HasSuffix(u.Path, "/")
+
+	// clean up path, removing duplicate `/`
+	u.Path = path.Clean(u.Path)
+	u.RawPath = path.Clean(u.RawPath)
+
+	if hasSlash && !strings.HasSuffix(u.Path, "/") {
+		u.Path += "/"
+		u.RawPath += "/"
+	}
+}
+
+// EscapePath escapes part of a URL path in Amazon style
+func EscapePath(path string, encodeSep bool) string {
+	var buf bytes.Buffer
+	for i := 0; i < len(path); i++ {
+		c := path[i]
+		if noEscape[c] || (c == '/' && !encodeSep) {
+			buf.WriteByte(c)
+		} else {
+			fmt.Fprintf(&buf, "%%%02X", c)
+		}
+	}
+	return buf.String()
+}
+
+func convertType(v reflect.Value, tag reflect.StructTag) (str string, err error) {
+	v = reflect.Indirect(v)
+	if !v.IsValid() {
+		return "", errValueNotSet
+	}
+
+	switch value := v.Interface().(type) {
+	case string:
+		str = value
+	case []byte:
+		str = base64.StdEncoding.EncodeToString(value)
+	case bool:
+		str = strconv.FormatBool(value)
+	case int64:
+		str = strconv.FormatInt(value, 10)
+	case float64:
+		str = strconv.FormatFloat(value, 'f', -1, 64)
+	case time.Time:
+		format := tag.Get("timestampFormat")
+		if len(format) == 0 {
+			format = protocol.RFC822TimeFormatName
+			if tag.Get("location") == "querystring" {
+				format = protocol.ISO8601TimeFormatName
+			}
+		}
+		str = protocol.FormatTime(format, value)
+	case aws.JSONValue:
+		if len(value) == 0 {
+			return "", errValueNotSet
+		}
+		escaping := protocol.NoEscape
+		if tag.Get("location") == "header" {
+			escaping = protocol.Base64Escape
+		}
+		str, err = protocol.EncodeJSONValue(value, escaping)
+		if err != nil {
+			return "", fmt.Errorf("unable to encode JSONValue, %v", err)
+		}
+	default:
+		err := fmt.Errorf("unsupported value for param %v (%s)", v.Interface(), v.Type())
+		return "", err
+	}
+	return str, nil
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go
new file mode 100644
index 000000000..4366de2e1
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go
@@ -0,0 +1,45 @@
+package rest
+
+import "reflect"
+
+// PayloadMember returns the payload field member of i if there is one, or nil.
+func PayloadMember(i interface{}) interface{} {
+	if i == nil {
+		return nil
+	}
+
+	v := reflect.ValueOf(i).Elem()
+	if !v.IsValid() {
+		return nil
+	}
+	if field, ok := v.Type().FieldByName("_"); ok {
+		if payloadName := field.Tag.Get("payload"); payloadName != "" {
+			field, _ := v.Type().FieldByName(payloadName)
+			if field.Tag.Get("type") != "structure" {
+				return nil
+			}
+
+			payload := v.FieldByName(payloadName)
+			if payload.IsValid() || (payload.Kind() == reflect.Ptr && !payload.IsNil()) {
+				return payload.Interface()
+			}
+		}
+	}
+	return nil
+}
+
+// PayloadType returns the type of a payload field member of i if there is one, or "".
+func PayloadType(i interface{}) string {
+	v := reflect.Indirect(reflect.ValueOf(i))
+	if !v.IsValid() {
+		return ""
+	}
+	if field, ok := v.Type().FieldByName("_"); ok {
+		if payloadName := field.Tag.Get("payload"); payloadName != "" {
+			if member, ok := v.Type().FieldByName(payloadName); ok {
+				return member.Tag.Get("type")
+			}
+		}
+	}
+	return ""
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go
new file mode 100644
index 000000000..33fd53b12
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go
@@ -0,0 +1,225 @@
+package rest
+
+import (
+	"bytes"
+	"encoding/base64"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net/http"
+	"reflect"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/request"
+	"github.com/aws/aws-sdk-go/private/protocol"
+)
+
+// UnmarshalHandler is a named request handler for unmarshaling rest protocol requests
+var UnmarshalHandler = request.NamedHandler{Name: "awssdk.rest.Unmarshal", Fn: Unmarshal}
+
+// UnmarshalMetaHandler is a named request handler for unmarshaling rest protocol request metadata
+var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.rest.UnmarshalMeta", Fn: UnmarshalMeta}
+
+// Unmarshal unmarshals the REST component of a response in a REST service.
+func Unmarshal(r *request.Request) {
+	if r.DataFilled() {
+		v := reflect.Indirect(reflect.ValueOf(r.Data))
+		unmarshalBody(r, v)
+	}
+}
+
+// UnmarshalMeta unmarshals the REST metadata of a response in a REST service
+func UnmarshalMeta(r *request.Request) {
+	r.RequestID = r.HTTPResponse.Header.Get("X-Amzn-Requestid")
+	if r.RequestID == "" {
+		// Alternative version of request id in the header
+		r.RequestID = r.HTTPResponse.Header.Get("X-Amz-Request-Id")
+	}
+	if r.DataFilled() {
+		v := reflect.Indirect(reflect.ValueOf(r.Data))
+		unmarshalLocationElements(r, v)
+	}
+}
+
+func unmarshalBody(r *request.Request, v reflect.Value) {
+	if field, ok := v.Type().FieldByName("_"); ok {
+		if payloadName := field.Tag.Get("payload"); payloadName != "" {
+			pfield, _ := v.Type().FieldByName(payloadName)
+			if ptag := pfield.Tag.Get("type"); ptag != "" && ptag != "structure" {
+				payload := v.FieldByName(payloadName)
+				if payload.IsValid() {
+					switch payload.Interface().(type) {
+					case []byte:
+						defer r.HTTPResponse.Body.Close()
+						b, err := ioutil.ReadAll(r.HTTPResponse.Body)
+						if err != nil {
+							r.Error = awserr.New("SerializationError", "failed to decode REST response", err)
+						} else {
+							payload.Set(reflect.ValueOf(b))
+						}
+					case *string:
+						defer r.HTTPResponse.Body.Close()
+						b, err := ioutil.ReadAll(r.HTTPResponse.Body)
+						if err != nil {
+							r.Error = awserr.New("SerializationError", "failed to decode REST response", err)
+						} else {
+							str := string(b)
+							payload.Set(reflect.ValueOf(&str))
+						}
+					default:
+						switch payload.Type().String() {
+						case "io.ReadCloser":
+							payload.Set(reflect.ValueOf(r.HTTPResponse.Body))
+						case "io.ReadSeeker":
+							b, err := ioutil.ReadAll(r.HTTPResponse.Body)
+							if err != nil {
+								r.Error = awserr.New("SerializationError",
+									"failed to read response body", err)
+								return
+							}
+							payload.Set(reflect.ValueOf(ioutil.NopCloser(bytes.NewReader(b))))
+						default:
+							io.Copy(ioutil.Discard, r.HTTPResponse.Body)
+							defer r.HTTPResponse.Body.Close()
+							r.Error = awserr.New("SerializationError",
+								"failed to decode REST response",
+								fmt.Errorf("unknown payload type %s", payload.Type()))
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+func unmarshalLocationElements(r *request.Request, v reflect.Value) {
+	for i := 0; i < v.NumField(); i++ {
+		m, field := v.Field(i), v.Type().Field(i)
+		if n := field.Name; n[0:1] == strings.ToLower(n[0:1]) {
+			continue
+		}
+
+		if m.IsValid() {
+			name := field.Tag.Get("locationName")
+			if name == "" {
+				name = field.Name
+			}
+
+			switch field.Tag.Get("location") {
+			case "statusCode":
+				unmarshalStatusCode(m, r.HTTPResponse.StatusCode)
+			case "header":
+				err := unmarshalHeader(m, r.HTTPResponse.Header.Get(name), field.Tag)
+				if err != nil {
+					r.Error = awserr.New("SerializationError", "failed to decode REST response", err)
+					break
+				}
+			case "headers":
+				prefix := field.Tag.Get("locationName")
+				err := unmarshalHeaderMap(m, r.HTTPResponse.Header, prefix)
+				if err != nil {
+					r.Error = awserr.New("SerializationError", "failed to decode REST response", err)
+					break
+				}
+			}
+		}
+		if r.Error != nil {
+			return
+		}
+	}
+}
+
+func unmarshalStatusCode(v reflect.Value, statusCode int) {
+	if !v.IsValid() {
+		return
+	}
+
+	switch v.Interface().(type) {
+	case *int64:
+		s := int64(statusCode)
+		v.Set(reflect.ValueOf(&s))
+	}
+}
+
+func unmarshalHeaderMap(r reflect.Value, headers http.Header, prefix string) error {
+	switch r.Interface().(type) {
+	case map[string]*string: // we only support string map value types
+		out := map[string]*string{}
+		for k, v := range headers {
+			k = http.CanonicalHeaderKey(k)
+			if strings.HasPrefix(strings.ToLower(k), strings.ToLower(prefix)) {
+				out[k[len(prefix):]] = &v[0]
+			}
+		}
+		r.Set(reflect.ValueOf(out))
+	}
+	return nil
+}
+
+func unmarshalHeader(v reflect.Value, header string, tag reflect.StructTag) error {
+	isJSONValue := tag.Get("type") == "jsonvalue"
+	if isJSONValue {
+		if len(header) == 0 {
+			return nil
+		}
+	} else if !v.IsValid() || (header == "" && v.Elem().Kind() != reflect.String) {
+		return nil
+	}
+
+	switch v.Interface().(type) {
+	case *string:
+		v.Set(reflect.ValueOf(&header))
+	case []byte:
+		b, err := base64.StdEncoding.DecodeString(header)
+		if err != nil {
+			return err
+		}
+		v.Set(reflect.ValueOf(&b))
+	case *bool:
+		b, err := strconv.ParseBool(header)
+		if err != nil {
+			return err
+		}
+		v.Set(reflect.ValueOf(&b))
+	case *int64:
+		i, err := strconv.ParseInt(header, 10, 64)
+		if err != nil {
+			return err
+		}
+		v.Set(reflect.ValueOf(&i))
+	case *float64:
+		f, err := strconv.ParseFloat(header, 64)
+		if err != nil {
+			return err
+		}
+		v.Set(reflect.ValueOf(&f))
+	case *time.Time:
+		format := tag.Get("timestampFormat")
+		if len(format) == 0 {
+			format = protocol.RFC822TimeFormatName
+		}
+		t, err := protocol.ParseTime(format, header)
+		if err != nil {
+			return err
+		}
+		v.Set(reflect.ValueOf(&t))
+	case aws.JSONValue:
+		escaping := protocol.NoEscape
+		if tag.Get("location") == "header" {
+			escaping = protocol.Base64Escape
+		}
+		m, err := protocol.DecodeJSONValue(header, escaping)
+		if err != nil {
+			return err
+		}
+		v.Set(reflect.ValueOf(m))
+	default:
+		err := fmt.Errorf("Unsupported value for param %v (%s)", v.Interface(), v.Type())
+		return err
+	}
+	return nil
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/restxml/restxml.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/restxml/restxml.go
new file mode 100644
index 000000000..7bdf4c853
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/restxml/restxml.go
@@ -0,0 +1,69 @@
+// Package restxml provides RESTful XML serialization of AWS
+// requests and responses.
+package restxml
+
+//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/rest-xml.json build_test.go
+//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/rest-xml.json unmarshal_test.go
+
+import (
+	"bytes"
+	"encoding/xml"
+
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/request"
+	"github.com/aws/aws-sdk-go/private/protocol/query"
+	"github.com/aws/aws-sdk-go/private/protocol/rest"
+	"github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil"
+)
+
+// BuildHandler is a named request handler for building restxml protocol requests
+var BuildHandler = request.NamedHandler{Name: "awssdk.restxml.Build", Fn: Build}
+
+// UnmarshalHandler is a named request handler for unmarshaling restxml protocol requests
+var UnmarshalHandler = request.NamedHandler{Name: "awssdk.restxml.Unmarshal", Fn: Unmarshal}
+
+// UnmarshalMetaHandler is a named request handler for unmarshaling restxml protocol request metadata
+var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.restxml.UnmarshalMeta", Fn: UnmarshalMeta}
+
+// UnmarshalErrorHandler is a named request handler for unmarshaling restxml protocol request errors
+var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.restxml.UnmarshalError", Fn: UnmarshalError}
+
+// Build builds a request payload for the REST XML protocol.
+func Build(r *request.Request) {
+	rest.Build(r)
+
+	if t := rest.PayloadType(r.Params); t == "structure" || t == "" {
+		var buf bytes.Buffer
+		err := xmlutil.BuildXML(r.Params, xml.NewEncoder(&buf))
+		if err != nil {
+			r.Error = awserr.New("SerializationError", "failed to encode rest XML request", err)
+			return
+		}
+		r.SetBufferBody(buf.Bytes())
+	}
+}
+
+// Unmarshal unmarshals a payload response for the REST XML protocol.
+func Unmarshal(r *request.Request) {
+	if t := rest.PayloadType(r.Data); t == "structure" || t == "" {
+		defer r.HTTPResponse.Body.Close()
+		decoder := xml.NewDecoder(r.HTTPResponse.Body)
+		err := xmlutil.UnmarshalXML(r.Data, decoder, "")
+		if err != nil {
+			r.Error = awserr.New("SerializationError", "failed to decode REST XML response", err)
+			return
+		}
+	} else {
+		rest.Unmarshal(r)
+	}
+}
+
+// UnmarshalMeta unmarshals response headers for the REST XML protocol.
+func UnmarshalMeta(r *request.Request) {
+	rest.UnmarshalMeta(r)
+}
+
+// UnmarshalError unmarshals a response error for the REST XML protocol.
+func UnmarshalError(r *request.Request) {
+	query.UnmarshalError(r)
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/timestamp.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/timestamp.go
new file mode 100644
index 000000000..b7ed6c6f8
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/timestamp.go
@@ -0,0 +1,72 @@
+package protocol
+
+import (
+	"strconv"
+	"time"
+)
+
+// Names of time formats supported by the SDK
+const (
+	RFC822TimeFormatName  = "rfc822"
+	ISO8601TimeFormatName = "iso8601"
+	UnixTimeFormatName    = "unixTimestamp"
+)
+
+// Time formats supported by the SDK
+const (
+	// RFC 7231#section-7.1.1.1 timetamp format. e.g Tue, 29 Apr 2014 18:30:38 GMT
+	RFC822TimeFormat = "Mon, 2 Jan 2006 15:04:05 GMT"
+
+	// RFC3339 a subset of the ISO8601 timestamp format. e.g 2014-04-29T18:30:38Z
+	ISO8601TimeFormat = "2006-01-02T15:04:05Z"
+)
+
+// IsKnownTimestampFormat returns if the timestamp format name
+// is know to the SDK's protocols.
+func IsKnownTimestampFormat(name string) bool {
+	switch name {
+	case RFC822TimeFormatName:
+		fallthrough
+	case ISO8601TimeFormatName:
+		fallthrough
+	case UnixTimeFormatName:
+		return true
+	default:
+		return false
+	}
+}
+
+// FormatTime returns a string value of the time.
+func FormatTime(name string, t time.Time) string {
+	t = t.UTC()
+
+	switch name {
+	case RFC822TimeFormatName:
+		return t.Format(RFC822TimeFormat)
+	case ISO8601TimeFormatName:
+		return t.Format(ISO8601TimeFormat)
+	case UnixTimeFormatName:
+		return strconv.FormatInt(t.Unix(), 10)
+	default:
+		panic("unknown timestamp format name, " + name)
+	}
+}
+
+// ParseTime attempts to parse the time given the format. Returns
+// the time if it was able to be parsed, and fails otherwise.
+func ParseTime(formatName, value string) (time.Time, error) {
+	switch formatName {
+	case RFC822TimeFormatName:
+		return time.Parse(RFC822TimeFormat, value)
+	case ISO8601TimeFormatName:
+		return time.Parse(ISO8601TimeFormat, value)
+	case UnixTimeFormatName:
+		v, err := strconv.ParseFloat(value, 64)
+		if err != nil {
+			return time.Time{}, err
+		}
+		return time.Unix(int64(v), 0), nil
+	default:
+		panic("unknown timestamp format name, " + formatName)
+	}
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal.go
new file mode 100644
index 000000000..da1a68111
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal.go
@@ -0,0 +1,21 @@
+package protocol
+
+import (
+	"io"
+	"io/ioutil"
+
+	"github.com/aws/aws-sdk-go/aws/request"
+)
+
+// UnmarshalDiscardBodyHandler is a named request handler to empty and close a response's body
+var UnmarshalDiscardBodyHandler = request.NamedHandler{Name: "awssdk.shared.UnmarshalDiscardBody", Fn: UnmarshalDiscardBody}
+
+// UnmarshalDiscardBody is a request handler to empty a response's body and closing it.
+func UnmarshalDiscardBody(r *request.Request) {
+	if r.HTTPResponse == nil || r.HTTPResponse.Body == nil {
+		return
+	}
+
+	io.Copy(ioutil.Discard, r.HTTPResponse.Body)
+	r.HTTPResponse.Body.Close()
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go
new file mode 100644
index 000000000..1bfe45f65
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go
@@ -0,0 +1,306 @@
+// Package xmlutil provides XML serialization of AWS requests and responses.
+package xmlutil
+
+import (
+	"encoding/base64"
+	"encoding/xml"
+	"fmt"
+	"reflect"
+	"sort"
+	"strconv"
+	"time"
+
+	"github.com/aws/aws-sdk-go/private/protocol"
+)
+
+// BuildXML will serialize params into an xml.Encoder. Error will be returned
+// if the serialization of any of the params or nested values fails.
+func BuildXML(params interface{}, e *xml.Encoder) error {
+	return buildXML(params, e, false)
+}
+
+func buildXML(params interface{}, e *xml.Encoder, sorted bool) error {
+	b := xmlBuilder{encoder: e, namespaces: map[string]string{}}
+	root := NewXMLElement(xml.Name{})
+	if err := b.buildValue(reflect.ValueOf(params), root, ""); err != nil {
+		return err
+	}
+	for _, c := range root.Children {
+		for _, v := range c {
+			return StructToXML(e, v, sorted)
+		}
+	}
+	return nil
+}
+
+// Returns the reflection element of a value, if it is a pointer.
+func elemOf(value reflect.Value) reflect.Value {
+	for value.Kind() == reflect.Ptr {
+		value = value.Elem()
+	}
+	return value
+}
+
+// A xmlBuilder serializes values from Go code to XML
+type xmlBuilder struct {
+	encoder    *xml.Encoder
+	namespaces map[string]string
+}
+
+// buildValue generic XMLNode builder for any type. Will build value for their specific type
+// struct, list, map, scalar.
+//
+// Also takes a "type" tag value to set what type a value should be converted to XMLNode as. If
+// type is not provided reflect will be used to determine the value's type.
+func (b *xmlBuilder) buildValue(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
+	value = elemOf(value)
+	if !value.IsValid() { // no need to handle zero values
+		return nil
+	} else if tag.Get("location") != "" { // don't handle non-body location values
+		return nil
+	}
+
+	t := tag.Get("type")
+	if t == "" {
+		switch value.Kind() {
+		case reflect.Struct:
+			t = "structure"
+		case reflect.Slice:
+			t = "list"
+		case reflect.Map:
+			t = "map"
+		}
+	}
+
+	switch t {
+	case "structure":
+		if field, ok := value.Type().FieldByName("_"); ok {
+			tag = tag + reflect.StructTag(" ") + field.Tag
+		}
+		return b.buildStruct(value, current, tag)
+	case "list":
+		return b.buildList(value, current, tag)
+	case "map":
+		return b.buildMap(value, current, tag)
+	default:
+		return b.buildScalar(value, current, tag)
+	}
+}
+
+// buildStruct adds a struct and its fields to the current XMLNode. All fields any any nested
+// types are converted to XMLNodes also.
+func (b *xmlBuilder) buildStruct(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
+	if !value.IsValid() {
+		return nil
+	}
+
+	// unwrap payloads
+	if payload := tag.Get("payload"); payload != "" {
+		field, _ := value.Type().FieldByName(payload)
+		tag = field.Tag
+		value = elemOf(value.FieldByName(payload))
+
+		if !value.IsValid() {
+			return nil
+		}
+	}
+
+	child := NewXMLElement(xml.Name{Local: tag.Get("locationName")})
+
+	// there is an xmlNamespace associated with this struct
+	if prefix, uri := tag.Get("xmlPrefix"), tag.Get("xmlURI"); uri != "" {
+		ns := xml.Attr{
+			Name:  xml.Name{Local: "xmlns"},
+			Value: uri,
+		}
+		if prefix != "" {
+			b.namespaces[prefix] = uri // register the namespace
+			ns.Name.Local = "xmlns:" + prefix
+		}
+
+		child.Attr = append(child.Attr, ns)
+	}
+
+	var payloadFields, nonPayloadFields int
+
+	t := value.Type()
+	for i := 0; i < value.NumField(); i++ {
+		member := elemOf(value.Field(i))
+		field := t.Field(i)
+
+		if field.PkgPath != "" {
+			continue // ignore unexported fields
+		}
+		if field.Tag.Get("ignore") != "" {
+			continue
+		}
+
+		mTag := field.Tag
+		if mTag.Get("location") != "" { // skip non-body members
+			nonPayloadFields++
+			continue
+		}
+		payloadFields++
+
+		if protocol.CanSetIdempotencyToken(value.Field(i), field) {
+			token := protocol.GetIdempotencyToken()
+			member = reflect.ValueOf(token)
+		}
+
+		memberName := mTag.Get("locationName")
+		if memberName == "" {
+			memberName = field.Name
+			mTag = reflect.StructTag(string(mTag) + ` locationName:"` + memberName + `"`)
+		}
+		if err := b.buildValue(member, child, mTag); err != nil {
+			return err
+		}
+	}
+
+	// Only case where the child shape is not added is if the shape only contains
+	// non-payload fields, e.g headers/query.
+	if !(payloadFields == 0 && nonPayloadFields > 0) {
+		current.AddChild(child)
+	}
+
+	return nil
+}
+
+// buildList adds the value's list items to the current XMLNode as children nodes. All
+// nested values in the list are converted to XMLNodes also.
+func (b *xmlBuilder) buildList(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
+	if value.IsNil() { // don't build omitted lists
+		return nil
+	}
+
+	// check for unflattened list member
+	flattened := tag.Get("flattened") != ""
+
+	xname := xml.Name{Local: tag.Get("locationName")}
+	if flattened {
+		for i := 0; i < value.Len(); i++ {
+			child := NewXMLElement(xname)
+			current.AddChild(child)
+			if err := b.buildValue(value.Index(i), child, ""); err != nil {
+				return err
+			}
+		}
+	} else {
+		list := NewXMLElement(xname)
+		current.AddChild(list)
+
+		for i := 0; i < value.Len(); i++ {
+			iname := tag.Get("locationNameList")
+			if iname == "" {
+				iname = "member"
+			}
+
+			child := NewXMLElement(xml.Name{Local: iname})
+			list.AddChild(child)
+			if err := b.buildValue(value.Index(i), child, ""); err != nil {
+				return err
+			}
+		}
+	}
+
+	return nil
+}
+
+// buildMap adds the value's key/value pairs to the current XMLNode as children nodes. All
+// nested values in the map are converted to XMLNodes also.
+//
+// Error will be returned if it is unable to build the map's values into XMLNodes
+func (b *xmlBuilder) buildMap(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
+	if value.IsNil() { // don't build omitted maps
+		return nil
+	}
+
+	maproot := NewXMLElement(xml.Name{Local: tag.Get("locationName")})
+	current.AddChild(maproot)
+	current = maproot
+
+	kname, vname := "key", "value"
+	if n := tag.Get("locationNameKey"); n != "" {
+		kname = n
+	}
+	if n := tag.Get("locationNameValue"); n != "" {
+		vname = n
+	}
+
+	// sorting is not required for compliance, but it makes testing easier
+	keys := make([]string, value.Len())
+	for i, k := range value.MapKeys() {
+		keys[i] = k.String()
+	}
+	sort.Strings(keys)
+
+	for _, k := range keys {
+		v := value.MapIndex(reflect.ValueOf(k))
+
+		mapcur := current
+		if tag.Get("flattened") == "" { // add "entry" tag to non-flat maps
+			child := NewXMLElement(xml.Name{Local: "entry"})
+			mapcur.AddChild(child)
+			mapcur = child
+		}
+
+		kchild := NewXMLElement(xml.Name{Local: kname})
+		kchild.Text = k
+		vchild := NewXMLElement(xml.Name{Local: vname})
+		mapcur.AddChild(kchild)
+		mapcur.AddChild(vchild)
+
+		if err := b.buildValue(v, vchild, ""); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+// buildScalar will convert the value into a string and append it as a attribute or child
+// of the current XMLNode.
+//
+// The value will be added as an attribute if tag contains a "xmlAttribute" attribute value.
+//
+// Error will be returned if the value type is unsupported.
+func (b *xmlBuilder) buildScalar(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
+	var str string
+	switch converted := value.Interface().(type) {
+	case string:
+		str = converted
+	case []byte:
+		if !value.IsNil() {
+			str = base64.StdEncoding.EncodeToString(converted)
+		}
+	case bool:
+		str = strconv.FormatBool(converted)
+	case int64:
+		str = strconv.FormatInt(converted, 10)
+	case int:
+		str = strconv.Itoa(converted)
+	case float64:
+		str = strconv.FormatFloat(converted, 'f', -1, 64)
+	case float32:
+		str = strconv.FormatFloat(float64(converted), 'f', -1, 32)
+	case time.Time:
+		format := tag.Get("timestampFormat")
+		if len(format) == 0 {
+			format = protocol.ISO8601TimeFormatName
+		}
+
+		str = protocol.FormatTime(format, converted)
+	default:
+		return fmt.Errorf("unsupported value for param %s: %v (%s)",
+			tag.Get("locationName"), value.Interface(), value.Type().Name())
+	}
+
+	xname := xml.Name{Local: tag.Get("locationName")}
+	if tag.Get("xmlAttribute") != "" { // put into current node's attribute list
+		attr := xml.Attr{Name: xname, Value: str}
+		current.Attr = append(current.Attr, attr)
+	} else { // regular text node
+		current.AddChild(&XMLNode{Name: xname, Text: str})
+	}
+	return nil
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go
new file mode 100644
index 000000000..ff1ef6830
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go
@@ -0,0 +1,272 @@
+package xmlutil
+
+import (
+	"encoding/base64"
+	"encoding/xml"
+	"fmt"
+	"io"
+	"reflect"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/aws/aws-sdk-go/private/protocol"
+)
+
+// UnmarshalXML deserializes an xml.Decoder into the container v. V
+// needs to match the shape of the XML expected to be decoded.
+// If the shape doesn't match unmarshaling will fail.
+func UnmarshalXML(v interface{}, d *xml.Decoder, wrapper string) error {
+	n, err := XMLToStruct(d, nil)
+	if err != nil {
+		return err
+	}
+	if n.Children != nil {
+		for _, root := range n.Children {
+			for _, c := range root {
+				if wrappedChild, ok := c.Children[wrapper]; ok {
+					c = wrappedChild[0] // pull out wrapped element
+				}
+
+				err = parse(reflect.ValueOf(v), c, "")
+				if err != nil {
+					if err == io.EOF {
+						return nil
+					}
+					return err
+				}
+			}
+		}
+		return nil
+	}
+	return nil
+}
+
+// parse deserializes any value from the XMLNode. The type tag is used to infer the type, or reflect
+// will be used to determine the type from r.
+func parse(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
+	rtype := r.Type()
+	if rtype.Kind() == reflect.Ptr {
+		rtype = rtype.Elem() // check kind of actual element type
+	}
+
+	t := tag.Get("type")
+	if t == "" {
+		switch rtype.Kind() {
+		case reflect.Struct:
+			// also it can't be a time object
+			if _, ok := r.Interface().(*time.Time); !ok {
+				t = "structure"
+			}
+		case reflect.Slice:
+			// also it can't be a byte slice
+			if _, ok := r.Interface().([]byte); !ok {
+				t = "list"
+			}
+		case reflect.Map:
+			t = "map"
+		}
+	}
+
+	switch t {
+	case "structure":
+		if field, ok := rtype.FieldByName("_"); ok {
+			tag = field.Tag
+		}
+		return parseStruct(r, node, tag)
+	case "list":
+		return parseList(r, node, tag)
+	case "map":
+		return parseMap(r, node, tag)
+	default:
+		return parseScalar(r, node, tag)
+	}
+}
+
+// parseStruct deserializes a structure and its fields from an XMLNode. Any nested
+// types in the structure will also be deserialized.
+func parseStruct(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
+	t := r.Type()
+	if r.Kind() == reflect.Ptr {
+		if r.IsNil() { // create the structure if it's nil
+			s := reflect.New(r.Type().Elem())
+			r.Set(s)
+			r = s
+		}
+
+		r = r.Elem()
+		t = t.Elem()
+	}
+
+	// unwrap any payloads
+	if payload := tag.Get("payload"); payload != "" {
+		field, _ := t.FieldByName(payload)
+		return parseStruct(r.FieldByName(payload), node, field.Tag)
+	}
+
+	for i := 0; i < t.NumField(); i++ {
+		field := t.Field(i)
+		if c := field.Name[0:1]; strings.ToLower(c) == c {
+			continue // ignore unexported fields
+		}
+
+		// figure out what this field is called
+		name := field.Name
+		if field.Tag.Get("flattened") != "" && field.Tag.Get("locationNameList") != "" {
+			name = field.Tag.Get("locationNameList")
+		} else if locName := field.Tag.Get("locationName"); locName != "" {
+			name = locName
+		}
+
+		// try to find the field by name in elements
+		elems := node.Children[name]
+
+		if elems == nil { // try to find the field in attributes
+			if val, ok := node.findElem(name); ok {
+				elems = []*XMLNode{{Text: val}}
+			}
+		}
+
+		member := r.FieldByName(field.Name)
+		for _, elem := range elems {
+			err := parse(member, elem, field.Tag)
+			if err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+// parseList deserializes a list of values from an XML node. Each list entry
+// will also be deserialized.
+func parseList(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
+	t := r.Type()
+
+	if tag.Get("flattened") == "" { // look at all item entries
+		mname := "member"
+		if name := tag.Get("locationNameList"); name != "" {
+			mname = name
+		}
+
+		if Children, ok := node.Children[mname]; ok {
+			if r.IsNil() {
+				r.Set(reflect.MakeSlice(t, len(Children), len(Children)))
+			}
+
+			for i, c := range Children {
+				err := parse(r.Index(i), c, "")
+				if err != nil {
+					return err
+				}
+			}
+		}
+	} else { // flattened list means this is a single element
+		if r.IsNil() {
+			r.Set(reflect.MakeSlice(t, 0, 0))
+		}
+
+		childR := reflect.Zero(t.Elem())
+		r.Set(reflect.Append(r, childR))
+		err := parse(r.Index(r.Len()-1), node, "")
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+// parseMap deserializes a map from an XMLNode. The direct children of the XMLNode
+// will also be deserialized as map entries.
+func parseMap(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
+	if r.IsNil() {
+		r.Set(reflect.MakeMap(r.Type()))
+	}
+
+	if tag.Get("flattened") == "" { // look at all child entries
+		for _, entry := range node.Children["entry"] {
+			parseMapEntry(r, entry, tag)
+		}
+	} else { // this element is itself an entry
+		parseMapEntry(r, node, tag)
+	}
+
+	return nil
+}
+
+// parseMapEntry deserializes a map entry from a XML node.
+func parseMapEntry(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
+	kname, vname := "key", "value"
+	if n := tag.Get("locationNameKey"); n != "" {
+		kname = n
+	}
+	if n := tag.Get("locationNameValue"); n != "" {
+		vname = n
+	}
+
+	keys, ok := node.Children[kname]
+	values := node.Children[vname]
+	if ok {
+		for i, key := range keys {
+			keyR := reflect.ValueOf(key.Text)
+			value := values[i]
+			valueR := reflect.New(r.Type().Elem()).Elem()
+
+			parse(valueR, value, "")
+			r.SetMapIndex(keyR, valueR)
+		}
+	}
+	return nil
+}
+
+// parseScaller deserializes an XMLNode value into a concrete type based on the
+// interface type of r.
+//
+// Error is returned if the deserialization fails due to invalid type conversion,
+// or unsupported interface type.
+func parseScalar(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
+	switch r.Interface().(type) {
+	case *string:
+		r.Set(reflect.ValueOf(&node.Text))
+		return nil
+	case []byte:
+		b, err := base64.StdEncoding.DecodeString(node.Text)
+		if err != nil {
+			return err
+		}
+		r.Set(reflect.ValueOf(b))
+	case *bool:
+		v, err := strconv.ParseBool(node.Text)
+		if err != nil {
+			return err
+		}
+		r.Set(reflect.ValueOf(&v))
+	case *int64:
+		v, err := strconv.ParseInt(node.Text, 10, 64)
+		if err != nil {
+			return err
+		}
+		r.Set(reflect.ValueOf(&v))
+	case *float64:
+		v, err := strconv.ParseFloat(node.Text, 64)
+		if err != nil {
+			return err
+		}
+		r.Set(reflect.ValueOf(&v))
+	case *time.Time:
+		format := tag.Get("timestampFormat")
+		if len(format) == 0 {
+			format = protocol.ISO8601TimeFormatName
+		}
+
+		t, err := protocol.ParseTime(format, node.Text)
+		if err != nil {
+			return err
+		}
+		r.Set(reflect.ValueOf(&t))
+	default:
+		return fmt.Errorf("unsupported value: %v (%s)", r.Interface(), r.Type())
+	}
+	return nil
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go
new file mode 100644
index 000000000..515ce1521
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go
@@ -0,0 +1,148 @@
+package xmlutil
+
+import (
+	"encoding/xml"
+	"fmt"
+	"io"
+	"sort"
+)
+
+// A XMLNode contains the values to be encoded or decoded.
+type XMLNode struct {
+	Name     xml.Name              `json:",omitempty"`
+	Children map[string][]*XMLNode `json:",omitempty"`
+	Text     string                `json:",omitempty"`
+	Attr     []xml.Attr            `json:",omitempty"`
+
+	namespaces map[string]string
+	parent     *XMLNode
+}
+
+// NewXMLElement returns a pointer to a new XMLNode initialized to default values.
+func NewXMLElement(name xml.Name) *XMLNode {
+	return &XMLNode{
+		Name:     name,
+		Children: map[string][]*XMLNode{},
+		Attr:     []xml.Attr{},
+	}
+}
+
+// AddChild adds child to the XMLNode.
+func (n *XMLNode) AddChild(child *XMLNode) {
+	child.parent = n
+	if _, ok := n.Children[child.Name.Local]; !ok {
+		n.Children[child.Name.Local] = []*XMLNode{}
+	}
+	n.Children[child.Name.Local] = append(n.Children[child.Name.Local], child)
+}
+
+// XMLToStruct converts a xml.Decoder stream to XMLNode with nested values.
+func XMLToStruct(d *xml.Decoder, s *xml.StartElement) (*XMLNode, error) {
+	out := &XMLNode{}
+	for {
+		tok, err := d.Token()
+		if err != nil {
+			if err == io.EOF {
+				break
+			} else {
+				return out, err
+			}
+		}
+
+		if tok == nil {
+			break
+		}
+
+		switch typed := tok.(type) {
+		case xml.CharData:
+			out.Text = string(typed.Copy())
+		case xml.StartElement:
+			el := typed.Copy()
+			out.Attr = el.Attr
+			if out.Children == nil {
+				out.Children = map[string][]*XMLNode{}
+			}
+
+			name := typed.Name.Local
+			slice := out.Children[name]
+			if slice == nil {
+				slice = []*XMLNode{}
+			}
+			node, e := XMLToStruct(d, &el)
+			out.findNamespaces()
+			if e != nil {
+				return out, e
+			}
+			node.Name = typed.Name
+			node.findNamespaces()
+			tempOut := *out
+			// Save into a temp variable, simply because out gets squashed during
+			// loop iterations
+			node.parent = &tempOut
+			slice = append(slice, node)
+			out.Children[name] = slice
+		case xml.EndElement:
+			if s != nil && s.Name.Local == typed.Name.Local { // matching end token
+				return out, nil
+			}
+			out = &XMLNode{}
+		}
+	}
+	return out, nil
+}
+
+func (n *XMLNode) findNamespaces() {
+	ns := map[string]string{}
+	for _, a := range n.Attr {
+		if a.Name.Space == "xmlns" {
+			ns[a.Value] = a.Name.Local
+		}
+	}
+
+	n.namespaces = ns
+}
+
+func (n *XMLNode) findElem(name string) (string, bool) {
+	for node := n; node != nil; node = node.parent {
+		for _, a := range node.Attr {
+			namespace := a.Name.Space
+			if v, ok := node.namespaces[namespace]; ok {
+				namespace = v
+			}
+			if name == fmt.Sprintf("%s:%s", namespace, a.Name.Local) {
+				return a.Value, true
+			}
+		}
+	}
+	return "", false
+}
+
+// StructToXML writes an XMLNode to a xml.Encoder as tokens.
+func StructToXML(e *xml.Encoder, node *XMLNode, sorted bool) error {
+	e.EncodeToken(xml.StartElement{Name: node.Name, Attr: node.Attr})
+
+	if node.Text != "" {
+		e.EncodeToken(xml.CharData([]byte(node.Text)))
+	} else if sorted {
+		sortedNames := []string{}
+		for k := range node.Children {
+			sortedNames = append(sortedNames, k)
+		}
+		sort.Strings(sortedNames)
+
+		for _, k := range sortedNames {
+			for _, v := range node.Children[k] {
+				StructToXML(e, v, sorted)
+			}
+		}
+	} else {
+		for _, c := range node.Children {
+			for _, v := range c {
+				StructToXML(e, v, sorted)
+			}
+		}
+	}
+
+	e.EncodeToken(xml.EndElement{Name: node.Name})
+	return e.Flush()
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/api.go b/vendor/github.com/aws/aws-sdk-go/service/s3/api.go
new file mode 100644
index 000000000..0e999ca33
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/service/s3/api.go
@@ -0,0 +1,22068 @@
+// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
+
+package s3
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"sync"
+	"sync/atomic"
+	"time"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/awsutil"
+	"github.com/aws/aws-sdk-go/aws/client"
+	"github.com/aws/aws-sdk-go/aws/request"
+	"github.com/aws/aws-sdk-go/private/protocol"
+	"github.com/aws/aws-sdk-go/private/protocol/eventstream"
+	"github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamapi"
+	"github.com/aws/aws-sdk-go/private/protocol/rest"
+	"github.com/aws/aws-sdk-go/private/protocol/restxml"
+)
+
+const opAbortMultipartUpload = "AbortMultipartUpload"
+
+// AbortMultipartUploadRequest generates a "aws/request.Request" representing the
+// client's request for the AbortMultipartUpload operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See AbortMultipartUpload for more information on using the AbortMultipartUpload
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the AbortMultipartUploadRequest method.
+//    req, resp := client.AbortMultipartUploadRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AbortMultipartUpload
+func (c *S3) AbortMultipartUploadRequest(input *AbortMultipartUploadInput) (req *request.Request, output *AbortMultipartUploadOutput) {
+	op := &request.Operation{
+		Name:       opAbortMultipartUpload,
+		HTTPMethod: "DELETE",
+		HTTPPath:   "/{Bucket}/{Key+}",
+	}
+
+	if input == nil {
+		input = &AbortMultipartUploadInput{}
+	}
+
+	output = &AbortMultipartUploadOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// AbortMultipartUpload API operation for Amazon Simple Storage Service.
+//
+// Aborts a multipart upload.
+//
+// To verify that all parts have been removed, so you don't get charged for
+// the part storage, you should call the List Parts operation and ensure the
+// parts list is empty.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation AbortMultipartUpload for usage and error information.
+//
+// Returned Error Codes:
+//   * ErrCodeNoSuchUpload "NoSuchUpload"
+//   The specified multipart upload does not exist.
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/AbortMultipartUpload
+func (c *S3) AbortMultipartUpload(input *AbortMultipartUploadInput) (*AbortMultipartUploadOutput, error) {
+	req, out := c.AbortMultipartUploadRequest(input)
+	return out, req.Send()
+}
+
+// AbortMultipartUploadWithContext is the same as AbortMultipartUpload with the addition of
+// the ability to pass a context and additional request options.
+//
+// See AbortMultipartUpload for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) AbortMultipartUploadWithContext(ctx aws.Context, input *AbortMultipartUploadInput, opts ...request.Option) (*AbortMultipartUploadOutput, error) {
+	req, out := c.AbortMultipartUploadRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opCompleteMultipartUpload = "CompleteMultipartUpload"
+
+// CompleteMultipartUploadRequest generates a "aws/request.Request" representing the
+// client's request for the CompleteMultipartUpload operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See CompleteMultipartUpload for more information on using the CompleteMultipartUpload
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the CompleteMultipartUploadRequest method.
+//    req, resp := client.CompleteMultipartUploadRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CompleteMultipartUpload
+func (c *S3) CompleteMultipartUploadRequest(input *CompleteMultipartUploadInput) (req *request.Request, output *CompleteMultipartUploadOutput) {
+	op := &request.Operation{
+		Name:       opCompleteMultipartUpload,
+		HTTPMethod: "POST",
+		HTTPPath:   "/{Bucket}/{Key+}",
+	}
+
+	if input == nil {
+		input = &CompleteMultipartUploadInput{}
+	}
+
+	output = &CompleteMultipartUploadOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// CompleteMultipartUpload API operation for Amazon Simple Storage Service.
+//
+// Completes a multipart upload by assembling previously uploaded parts.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation CompleteMultipartUpload for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CompleteMultipartUpload
+func (c *S3) CompleteMultipartUpload(input *CompleteMultipartUploadInput) (*CompleteMultipartUploadOutput, error) {
+	req, out := c.CompleteMultipartUploadRequest(input)
+	return out, req.Send()
+}
+
+// CompleteMultipartUploadWithContext is the same as CompleteMultipartUpload with the addition of
+// the ability to pass a context and additional request options.
+//
+// See CompleteMultipartUpload for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) CompleteMultipartUploadWithContext(ctx aws.Context, input *CompleteMultipartUploadInput, opts ...request.Option) (*CompleteMultipartUploadOutput, error) {
+	req, out := c.CompleteMultipartUploadRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opCopyObject = "CopyObject"
+
+// CopyObjectRequest generates a "aws/request.Request" representing the
+// client's request for the CopyObject operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See CopyObject for more information on using the CopyObject
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the CopyObjectRequest method.
+//    req, resp := client.CopyObjectRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CopyObject
+func (c *S3) CopyObjectRequest(input *CopyObjectInput) (req *request.Request, output *CopyObjectOutput) {
+	op := &request.Operation{
+		Name:       opCopyObject,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}/{Key+}",
+	}
+
+	if input == nil {
+		input = &CopyObjectInput{}
+	}
+
+	output = &CopyObjectOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// CopyObject API operation for Amazon Simple Storage Service.
+//
+// Creates a copy of an object that is already stored in Amazon S3.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation CopyObject for usage and error information.
+//
+// Returned Error Codes:
+//   * ErrCodeObjectNotInActiveTierError "ObjectNotInActiveTierError"
+//   The source object of the COPY operation is not in the active tier and is
+//   only stored in Amazon Glacier.
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CopyObject
+func (c *S3) CopyObject(input *CopyObjectInput) (*CopyObjectOutput, error) {
+	req, out := c.CopyObjectRequest(input)
+	return out, req.Send()
+}
+
+// CopyObjectWithContext is the same as CopyObject with the addition of
+// the ability to pass a context and additional request options.
+//
+// See CopyObject for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) CopyObjectWithContext(ctx aws.Context, input *CopyObjectInput, opts ...request.Option) (*CopyObjectOutput, error) {
+	req, out := c.CopyObjectRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opCreateBucket = "CreateBucket"
+
+// CreateBucketRequest generates a "aws/request.Request" representing the
+// client's request for the CreateBucket operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See CreateBucket for more information on using the CreateBucket
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the CreateBucketRequest method.
+//    req, resp := client.CreateBucketRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateBucket
+func (c *S3) CreateBucketRequest(input *CreateBucketInput) (req *request.Request, output *CreateBucketOutput) {
+	op := &request.Operation{
+		Name:       opCreateBucket,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}",
+	}
+
+	if input == nil {
+		input = &CreateBucketInput{}
+	}
+
+	output = &CreateBucketOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// CreateBucket API operation for Amazon Simple Storage Service.
+//
+// Creates a new bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation CreateBucket for usage and error information.
+//
+// Returned Error Codes:
+//   * ErrCodeBucketAlreadyExists "BucketAlreadyExists"
+//   The requested bucket name is not available. The bucket namespace is shared
+//   by all users of the system. Please select a different name and try again.
+//
+//   * ErrCodeBucketAlreadyOwnedByYou "BucketAlreadyOwnedByYou"
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateBucket
+func (c *S3) CreateBucket(input *CreateBucketInput) (*CreateBucketOutput, error) {
+	req, out := c.CreateBucketRequest(input)
+	return out, req.Send()
+}
+
+// CreateBucketWithContext is the same as CreateBucket with the addition of
+// the ability to pass a context and additional request options.
+//
+// See CreateBucket for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) CreateBucketWithContext(ctx aws.Context, input *CreateBucketInput, opts ...request.Option) (*CreateBucketOutput, error) {
+	req, out := c.CreateBucketRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opCreateMultipartUpload = "CreateMultipartUpload"
+
+// CreateMultipartUploadRequest generates a "aws/request.Request" representing the
+// client's request for the CreateMultipartUpload operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See CreateMultipartUpload for more information on using the CreateMultipartUpload
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the CreateMultipartUploadRequest method.
+//    req, resp := client.CreateMultipartUploadRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateMultipartUpload
+func (c *S3) CreateMultipartUploadRequest(input *CreateMultipartUploadInput) (req *request.Request, output *CreateMultipartUploadOutput) {
+	op := &request.Operation{
+		Name:       opCreateMultipartUpload,
+		HTTPMethod: "POST",
+		HTTPPath:   "/{Bucket}/{Key+}?uploads",
+	}
+
+	if input == nil {
+		input = &CreateMultipartUploadInput{}
+	}
+
+	output = &CreateMultipartUploadOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// CreateMultipartUpload API operation for Amazon Simple Storage Service.
+//
+// Initiates a multipart upload and returns an upload ID.
+//
+// Note: After you initiate multipart upload and upload one or more parts, you
+// must either complete or abort multipart upload in order to stop getting charged
+// for storage of the uploaded parts. Only after you either complete or abort
+// multipart upload, Amazon S3 frees up the parts storage and stops charging
+// you for the parts storage.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation CreateMultipartUpload for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/CreateMultipartUpload
+func (c *S3) CreateMultipartUpload(input *CreateMultipartUploadInput) (*CreateMultipartUploadOutput, error) {
+	req, out := c.CreateMultipartUploadRequest(input)
+	return out, req.Send()
+}
+
+// CreateMultipartUploadWithContext is the same as CreateMultipartUpload with the addition of
+// the ability to pass a context and additional request options.
+//
+// See CreateMultipartUpload for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) CreateMultipartUploadWithContext(ctx aws.Context, input *CreateMultipartUploadInput, opts ...request.Option) (*CreateMultipartUploadOutput, error) {
+	req, out := c.CreateMultipartUploadRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opDeleteBucket = "DeleteBucket"
+
+// DeleteBucketRequest generates a "aws/request.Request" representing the
+// client's request for the DeleteBucket operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See DeleteBucket for more information on using the DeleteBucket
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the DeleteBucketRequest method.
+//    req, resp := client.DeleteBucketRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucket
+func (c *S3) DeleteBucketRequest(input *DeleteBucketInput) (req *request.Request, output *DeleteBucketOutput) {
+	op := &request.Operation{
+		Name:       opDeleteBucket,
+		HTTPMethod: "DELETE",
+		HTTPPath:   "/{Bucket}",
+	}
+
+	if input == nil {
+		input = &DeleteBucketInput{}
+	}
+
+	output = &DeleteBucketOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// DeleteBucket API operation for Amazon Simple Storage Service.
+//
+// Deletes the bucket. All objects (including all object versions and Delete
+// Markers) in the bucket must be deleted before the bucket itself can be deleted.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation DeleteBucket for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucket
+func (c *S3) DeleteBucket(input *DeleteBucketInput) (*DeleteBucketOutput, error) {
+	req, out := c.DeleteBucketRequest(input)
+	return out, req.Send()
+}
+
+// DeleteBucketWithContext is the same as DeleteBucket with the addition of
+// the ability to pass a context and additional request options.
+//
+// See DeleteBucket for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) DeleteBucketWithContext(ctx aws.Context, input *DeleteBucketInput, opts ...request.Option) (*DeleteBucketOutput, error) {
+	req, out := c.DeleteBucketRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opDeleteBucketAnalyticsConfiguration = "DeleteBucketAnalyticsConfiguration"
+
+// DeleteBucketAnalyticsConfigurationRequest generates a "aws/request.Request" representing the
+// client's request for the DeleteBucketAnalyticsConfiguration operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See DeleteBucketAnalyticsConfiguration for more information on using the DeleteBucketAnalyticsConfiguration
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the DeleteBucketAnalyticsConfigurationRequest method.
+//    req, resp := client.DeleteBucketAnalyticsConfigurationRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketAnalyticsConfiguration
+func (c *S3) DeleteBucketAnalyticsConfigurationRequest(input *DeleteBucketAnalyticsConfigurationInput) (req *request.Request, output *DeleteBucketAnalyticsConfigurationOutput) {
+	op := &request.Operation{
+		Name:       opDeleteBucketAnalyticsConfiguration,
+		HTTPMethod: "DELETE",
+		HTTPPath:   "/{Bucket}?analytics",
+	}
+
+	if input == nil {
+		input = &DeleteBucketAnalyticsConfigurationInput{}
+	}
+
+	output = &DeleteBucketAnalyticsConfigurationOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// DeleteBucketAnalyticsConfiguration API operation for Amazon Simple Storage Service.
+//
+// Deletes an analytics configuration for the bucket (specified by the analytics
+// configuration ID).
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation DeleteBucketAnalyticsConfiguration for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketAnalyticsConfiguration
+func (c *S3) DeleteBucketAnalyticsConfiguration(input *DeleteBucketAnalyticsConfigurationInput) (*DeleteBucketAnalyticsConfigurationOutput, error) {
+	req, out := c.DeleteBucketAnalyticsConfigurationRequest(input)
+	return out, req.Send()
+}
+
+// DeleteBucketAnalyticsConfigurationWithContext is the same as DeleteBucketAnalyticsConfiguration with the addition of
+// the ability to pass a context and additional request options.
+//
+// See DeleteBucketAnalyticsConfiguration for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) DeleteBucketAnalyticsConfigurationWithContext(ctx aws.Context, input *DeleteBucketAnalyticsConfigurationInput, opts ...request.Option) (*DeleteBucketAnalyticsConfigurationOutput, error) {
+	req, out := c.DeleteBucketAnalyticsConfigurationRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opDeleteBucketCors = "DeleteBucketCors"
+
+// DeleteBucketCorsRequest generates a "aws/request.Request" representing the
+// client's request for the DeleteBucketCors operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See DeleteBucketCors for more information on using the DeleteBucketCors
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the DeleteBucketCorsRequest method.
+//    req, resp := client.DeleteBucketCorsRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketCors
+func (c *S3) DeleteBucketCorsRequest(input *DeleteBucketCorsInput) (req *request.Request, output *DeleteBucketCorsOutput) {
+	op := &request.Operation{
+		Name:       opDeleteBucketCors,
+		HTTPMethod: "DELETE",
+		HTTPPath:   "/{Bucket}?cors",
+	}
+
+	if input == nil {
+		input = &DeleteBucketCorsInput{}
+	}
+
+	output = &DeleteBucketCorsOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// DeleteBucketCors API operation for Amazon Simple Storage Service.
+//
+// Deletes the cors configuration information set for the bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation DeleteBucketCors for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketCors
+func (c *S3) DeleteBucketCors(input *DeleteBucketCorsInput) (*DeleteBucketCorsOutput, error) {
+	req, out := c.DeleteBucketCorsRequest(input)
+	return out, req.Send()
+}
+
+// DeleteBucketCorsWithContext is the same as DeleteBucketCors with the addition of
+// the ability to pass a context and additional request options.
+//
+// See DeleteBucketCors for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) DeleteBucketCorsWithContext(ctx aws.Context, input *DeleteBucketCorsInput, opts ...request.Option) (*DeleteBucketCorsOutput, error) {
+	req, out := c.DeleteBucketCorsRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opDeleteBucketEncryption = "DeleteBucketEncryption"
+
+// DeleteBucketEncryptionRequest generates a "aws/request.Request" representing the
+// client's request for the DeleteBucketEncryption operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See DeleteBucketEncryption for more information on using the DeleteBucketEncryption
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the DeleteBucketEncryptionRequest method.
+//    req, resp := client.DeleteBucketEncryptionRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketEncryption
+func (c *S3) DeleteBucketEncryptionRequest(input *DeleteBucketEncryptionInput) (req *request.Request, output *DeleteBucketEncryptionOutput) {
+	op := &request.Operation{
+		Name:       opDeleteBucketEncryption,
+		HTTPMethod: "DELETE",
+		HTTPPath:   "/{Bucket}?encryption",
+	}
+
+	if input == nil {
+		input = &DeleteBucketEncryptionInput{}
+	}
+
+	output = &DeleteBucketEncryptionOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// DeleteBucketEncryption API operation for Amazon Simple Storage Service.
+//
+// Deletes the server-side encryption configuration from the bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation DeleteBucketEncryption for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketEncryption
+func (c *S3) DeleteBucketEncryption(input *DeleteBucketEncryptionInput) (*DeleteBucketEncryptionOutput, error) {
+	req, out := c.DeleteBucketEncryptionRequest(input)
+	return out, req.Send()
+}
+
+// DeleteBucketEncryptionWithContext is the same as DeleteBucketEncryption with the addition of
+// the ability to pass a context and additional request options.
+//
+// See DeleteBucketEncryption for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) DeleteBucketEncryptionWithContext(ctx aws.Context, input *DeleteBucketEncryptionInput, opts ...request.Option) (*DeleteBucketEncryptionOutput, error) {
+	req, out := c.DeleteBucketEncryptionRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opDeleteBucketInventoryConfiguration = "DeleteBucketInventoryConfiguration"
+
+// DeleteBucketInventoryConfigurationRequest generates a "aws/request.Request" representing the
+// client's request for the DeleteBucketInventoryConfiguration operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See DeleteBucketInventoryConfiguration for more information on using the DeleteBucketInventoryConfiguration
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the DeleteBucketInventoryConfigurationRequest method.
+//    req, resp := client.DeleteBucketInventoryConfigurationRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketInventoryConfiguration
+func (c *S3) DeleteBucketInventoryConfigurationRequest(input *DeleteBucketInventoryConfigurationInput) (req *request.Request, output *DeleteBucketInventoryConfigurationOutput) {
+	op := &request.Operation{
+		Name:       opDeleteBucketInventoryConfiguration,
+		HTTPMethod: "DELETE",
+		HTTPPath:   "/{Bucket}?inventory",
+	}
+
+	if input == nil {
+		input = &DeleteBucketInventoryConfigurationInput{}
+	}
+
+	output = &DeleteBucketInventoryConfigurationOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// DeleteBucketInventoryConfiguration API operation for Amazon Simple Storage Service.
+//
+// Deletes an inventory configuration (identified by the inventory ID) from
+// the bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation DeleteBucketInventoryConfiguration for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketInventoryConfiguration
+func (c *S3) DeleteBucketInventoryConfiguration(input *DeleteBucketInventoryConfigurationInput) (*DeleteBucketInventoryConfigurationOutput, error) {
+	req, out := c.DeleteBucketInventoryConfigurationRequest(input)
+	return out, req.Send()
+}
+
+// DeleteBucketInventoryConfigurationWithContext is the same as DeleteBucketInventoryConfiguration with the addition of
+// the ability to pass a context and additional request options.
+//
+// See DeleteBucketInventoryConfiguration for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) DeleteBucketInventoryConfigurationWithContext(ctx aws.Context, input *DeleteBucketInventoryConfigurationInput, opts ...request.Option) (*DeleteBucketInventoryConfigurationOutput, error) {
+	req, out := c.DeleteBucketInventoryConfigurationRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opDeleteBucketLifecycle = "DeleteBucketLifecycle"
+
+// DeleteBucketLifecycleRequest generates a "aws/request.Request" representing the
+// client's request for the DeleteBucketLifecycle operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See DeleteBucketLifecycle for more information on using the DeleteBucketLifecycle
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the DeleteBucketLifecycleRequest method.
+//    req, resp := client.DeleteBucketLifecycleRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketLifecycle
+func (c *S3) DeleteBucketLifecycleRequest(input *DeleteBucketLifecycleInput) (req *request.Request, output *DeleteBucketLifecycleOutput) {
+	op := &request.Operation{
+		Name:       opDeleteBucketLifecycle,
+		HTTPMethod: "DELETE",
+		HTTPPath:   "/{Bucket}?lifecycle",
+	}
+
+	if input == nil {
+		input = &DeleteBucketLifecycleInput{}
+	}
+
+	output = &DeleteBucketLifecycleOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// DeleteBucketLifecycle API operation for Amazon Simple Storage Service.
+//
+// Deletes the lifecycle configuration from the bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation DeleteBucketLifecycle for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketLifecycle
+func (c *S3) DeleteBucketLifecycle(input *DeleteBucketLifecycleInput) (*DeleteBucketLifecycleOutput, error) {
+	req, out := c.DeleteBucketLifecycleRequest(input)
+	return out, req.Send()
+}
+
+// DeleteBucketLifecycleWithContext is the same as DeleteBucketLifecycle with the addition of
+// the ability to pass a context and additional request options.
+//
+// See DeleteBucketLifecycle for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) DeleteBucketLifecycleWithContext(ctx aws.Context, input *DeleteBucketLifecycleInput, opts ...request.Option) (*DeleteBucketLifecycleOutput, error) {
+	req, out := c.DeleteBucketLifecycleRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opDeleteBucketMetricsConfiguration = "DeleteBucketMetricsConfiguration"
+
+// DeleteBucketMetricsConfigurationRequest generates a "aws/request.Request" representing the
+// client's request for the DeleteBucketMetricsConfiguration operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See DeleteBucketMetricsConfiguration for more information on using the DeleteBucketMetricsConfiguration
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the DeleteBucketMetricsConfigurationRequest method.
+//    req, resp := client.DeleteBucketMetricsConfigurationRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketMetricsConfiguration
+func (c *S3) DeleteBucketMetricsConfigurationRequest(input *DeleteBucketMetricsConfigurationInput) (req *request.Request, output *DeleteBucketMetricsConfigurationOutput) {
+	op := &request.Operation{
+		Name:       opDeleteBucketMetricsConfiguration,
+		HTTPMethod: "DELETE",
+		HTTPPath:   "/{Bucket}?metrics",
+	}
+
+	if input == nil {
+		input = &DeleteBucketMetricsConfigurationInput{}
+	}
+
+	output = &DeleteBucketMetricsConfigurationOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// DeleteBucketMetricsConfiguration API operation for Amazon Simple Storage Service.
+//
+// Deletes a metrics configuration (specified by the metrics configuration ID)
+// from the bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation DeleteBucketMetricsConfiguration for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketMetricsConfiguration
+func (c *S3) DeleteBucketMetricsConfiguration(input *DeleteBucketMetricsConfigurationInput) (*DeleteBucketMetricsConfigurationOutput, error) {
+	req, out := c.DeleteBucketMetricsConfigurationRequest(input)
+	return out, req.Send()
+}
+
+// DeleteBucketMetricsConfigurationWithContext is the same as DeleteBucketMetricsConfiguration with the addition of
+// the ability to pass a context and additional request options.
+//
+// See DeleteBucketMetricsConfiguration for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) DeleteBucketMetricsConfigurationWithContext(ctx aws.Context, input *DeleteBucketMetricsConfigurationInput, opts ...request.Option) (*DeleteBucketMetricsConfigurationOutput, error) {
+	req, out := c.DeleteBucketMetricsConfigurationRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opDeleteBucketPolicy = "DeleteBucketPolicy"
+
+// DeleteBucketPolicyRequest generates a "aws/request.Request" representing the
+// client's request for the DeleteBucketPolicy operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See DeleteBucketPolicy for more information on using the DeleteBucketPolicy
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the DeleteBucketPolicyRequest method.
+//    req, resp := client.DeleteBucketPolicyRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketPolicy
+func (c *S3) DeleteBucketPolicyRequest(input *DeleteBucketPolicyInput) (req *request.Request, output *DeleteBucketPolicyOutput) {
+	op := &request.Operation{
+		Name:       opDeleteBucketPolicy,
+		HTTPMethod: "DELETE",
+		HTTPPath:   "/{Bucket}?policy",
+	}
+
+	if input == nil {
+		input = &DeleteBucketPolicyInput{}
+	}
+
+	output = &DeleteBucketPolicyOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// DeleteBucketPolicy API operation for Amazon Simple Storage Service.
+//
+// Deletes the policy from the bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation DeleteBucketPolicy for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketPolicy
+func (c *S3) DeleteBucketPolicy(input *DeleteBucketPolicyInput) (*DeleteBucketPolicyOutput, error) {
+	req, out := c.DeleteBucketPolicyRequest(input)
+	return out, req.Send()
+}
+
+// DeleteBucketPolicyWithContext is the same as DeleteBucketPolicy with the addition of
+// the ability to pass a context and additional request options.
+//
+// See DeleteBucketPolicy for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) DeleteBucketPolicyWithContext(ctx aws.Context, input *DeleteBucketPolicyInput, opts ...request.Option) (*DeleteBucketPolicyOutput, error) {
+	req, out := c.DeleteBucketPolicyRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opDeleteBucketReplication = "DeleteBucketReplication"
+
+// DeleteBucketReplicationRequest generates a "aws/request.Request" representing the
+// client's request for the DeleteBucketReplication operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See DeleteBucketReplication for more information on using the DeleteBucketReplication
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the DeleteBucketReplicationRequest method.
+//    req, resp := client.DeleteBucketReplicationRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketReplication
+func (c *S3) DeleteBucketReplicationRequest(input *DeleteBucketReplicationInput) (req *request.Request, output *DeleteBucketReplicationOutput) {
+	op := &request.Operation{
+		Name:       opDeleteBucketReplication,
+		HTTPMethod: "DELETE",
+		HTTPPath:   "/{Bucket}?replication",
+	}
+
+	if input == nil {
+		input = &DeleteBucketReplicationInput{}
+	}
+
+	output = &DeleteBucketReplicationOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// DeleteBucketReplication API operation for Amazon Simple Storage Service.
+//
+// Deletes the replication configuration from the bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation DeleteBucketReplication for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketReplication
+func (c *S3) DeleteBucketReplication(input *DeleteBucketReplicationInput) (*DeleteBucketReplicationOutput, error) {
+	req, out := c.DeleteBucketReplicationRequest(input)
+	return out, req.Send()
+}
+
+// DeleteBucketReplicationWithContext is the same as DeleteBucketReplication with the addition of
+// the ability to pass a context and additional request options.
+//
+// See DeleteBucketReplication for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) DeleteBucketReplicationWithContext(ctx aws.Context, input *DeleteBucketReplicationInput, opts ...request.Option) (*DeleteBucketReplicationOutput, error) {
+	req, out := c.DeleteBucketReplicationRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opDeleteBucketTagging = "DeleteBucketTagging"
+
+// DeleteBucketTaggingRequest generates a "aws/request.Request" representing the
+// client's request for the DeleteBucketTagging operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See DeleteBucketTagging for more information on using the DeleteBucketTagging
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the DeleteBucketTaggingRequest method.
+//    req, resp := client.DeleteBucketTaggingRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketTagging
+func (c *S3) DeleteBucketTaggingRequest(input *DeleteBucketTaggingInput) (req *request.Request, output *DeleteBucketTaggingOutput) {
+	op := &request.Operation{
+		Name:       opDeleteBucketTagging,
+		HTTPMethod: "DELETE",
+		HTTPPath:   "/{Bucket}?tagging",
+	}
+
+	if input == nil {
+		input = &DeleteBucketTaggingInput{}
+	}
+
+	output = &DeleteBucketTaggingOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// DeleteBucketTagging API operation for Amazon Simple Storage Service.
+//
+// Deletes the tags from the bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation DeleteBucketTagging for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketTagging
+func (c *S3) DeleteBucketTagging(input *DeleteBucketTaggingInput) (*DeleteBucketTaggingOutput, error) {
+	req, out := c.DeleteBucketTaggingRequest(input)
+	return out, req.Send()
+}
+
+// DeleteBucketTaggingWithContext is the same as DeleteBucketTagging with the addition of
+// the ability to pass a context and additional request options.
+//
+// See DeleteBucketTagging for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) DeleteBucketTaggingWithContext(ctx aws.Context, input *DeleteBucketTaggingInput, opts ...request.Option) (*DeleteBucketTaggingOutput, error) {
+	req, out := c.DeleteBucketTaggingRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opDeleteBucketWebsite = "DeleteBucketWebsite"
+
+// DeleteBucketWebsiteRequest generates a "aws/request.Request" representing the
+// client's request for the DeleteBucketWebsite operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See DeleteBucketWebsite for more information on using the DeleteBucketWebsite
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the DeleteBucketWebsiteRequest method.
+//    req, resp := client.DeleteBucketWebsiteRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketWebsite
+func (c *S3) DeleteBucketWebsiteRequest(input *DeleteBucketWebsiteInput) (req *request.Request, output *DeleteBucketWebsiteOutput) {
+	op := &request.Operation{
+		Name:       opDeleteBucketWebsite,
+		HTTPMethod: "DELETE",
+		HTTPPath:   "/{Bucket}?website",
+	}
+
+	if input == nil {
+		input = &DeleteBucketWebsiteInput{}
+	}
+
+	output = &DeleteBucketWebsiteOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// DeleteBucketWebsite API operation for Amazon Simple Storage Service.
+//
+// This operation removes the website configuration from the bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation DeleteBucketWebsite for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteBucketWebsite
+func (c *S3) DeleteBucketWebsite(input *DeleteBucketWebsiteInput) (*DeleteBucketWebsiteOutput, error) {
+	req, out := c.DeleteBucketWebsiteRequest(input)
+	return out, req.Send()
+}
+
+// DeleteBucketWebsiteWithContext is the same as DeleteBucketWebsite with the addition of
+// the ability to pass a context and additional request options.
+//
+// See DeleteBucketWebsite for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) DeleteBucketWebsiteWithContext(ctx aws.Context, input *DeleteBucketWebsiteInput, opts ...request.Option) (*DeleteBucketWebsiteOutput, error) {
+	req, out := c.DeleteBucketWebsiteRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opDeleteObject = "DeleteObject"
+
+// DeleteObjectRequest generates a "aws/request.Request" representing the
+// client's request for the DeleteObject operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See DeleteObject for more information on using the DeleteObject
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the DeleteObjectRequest method.
+//    req, resp := client.DeleteObjectRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObject
+func (c *S3) DeleteObjectRequest(input *DeleteObjectInput) (req *request.Request, output *DeleteObjectOutput) {
+	op := &request.Operation{
+		Name:       opDeleteObject,
+		HTTPMethod: "DELETE",
+		HTTPPath:   "/{Bucket}/{Key+}",
+	}
+
+	if input == nil {
+		input = &DeleteObjectInput{}
+	}
+
+	output = &DeleteObjectOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// DeleteObject API operation for Amazon Simple Storage Service.
+//
+// Removes the null version (if there is one) of an object and inserts a delete
+// marker, which becomes the latest version of the object. If there isn't a
+// null version, Amazon S3 does not remove any objects.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation DeleteObject for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObject
+func (c *S3) DeleteObject(input *DeleteObjectInput) (*DeleteObjectOutput, error) {
+	req, out := c.DeleteObjectRequest(input)
+	return out, req.Send()
+}
+
+// DeleteObjectWithContext is the same as DeleteObject with the addition of
+// the ability to pass a context and additional request options.
+//
+// See DeleteObject for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) DeleteObjectWithContext(ctx aws.Context, input *DeleteObjectInput, opts ...request.Option) (*DeleteObjectOutput, error) {
+	req, out := c.DeleteObjectRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opDeleteObjectTagging = "DeleteObjectTagging"
+
+// DeleteObjectTaggingRequest generates a "aws/request.Request" representing the
+// client's request for the DeleteObjectTagging operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See DeleteObjectTagging for more information on using the DeleteObjectTagging
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the DeleteObjectTaggingRequest method.
+//    req, resp := client.DeleteObjectTaggingRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectTagging
+func (c *S3) DeleteObjectTaggingRequest(input *DeleteObjectTaggingInput) (req *request.Request, output *DeleteObjectTaggingOutput) {
+	op := &request.Operation{
+		Name:       opDeleteObjectTagging,
+		HTTPMethod: "DELETE",
+		HTTPPath:   "/{Bucket}/{Key+}?tagging",
+	}
+
+	if input == nil {
+		input = &DeleteObjectTaggingInput{}
+	}
+
+	output = &DeleteObjectTaggingOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// DeleteObjectTagging API operation for Amazon Simple Storage Service.
+//
+// Removes the tag-set from an existing object.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation DeleteObjectTagging for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjectTagging
+func (c *S3) DeleteObjectTagging(input *DeleteObjectTaggingInput) (*DeleteObjectTaggingOutput, error) {
+	req, out := c.DeleteObjectTaggingRequest(input)
+	return out, req.Send()
+}
+
+// DeleteObjectTaggingWithContext is the same as DeleteObjectTagging with the addition of
+// the ability to pass a context and additional request options.
+//
+// See DeleteObjectTagging for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) DeleteObjectTaggingWithContext(ctx aws.Context, input *DeleteObjectTaggingInput, opts ...request.Option) (*DeleteObjectTaggingOutput, error) {
+	req, out := c.DeleteObjectTaggingRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opDeleteObjects = "DeleteObjects"
+
+// DeleteObjectsRequest generates a "aws/request.Request" representing the
+// client's request for the DeleteObjects operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See DeleteObjects for more information on using the DeleteObjects
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the DeleteObjectsRequest method.
+//    req, resp := client.DeleteObjectsRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjects
+func (c *S3) DeleteObjectsRequest(input *DeleteObjectsInput) (req *request.Request, output *DeleteObjectsOutput) {
+	op := &request.Operation{
+		Name:       opDeleteObjects,
+		HTTPMethod: "POST",
+		HTTPPath:   "/{Bucket}?delete",
+	}
+
+	if input == nil {
+		input = &DeleteObjectsInput{}
+	}
+
+	output = &DeleteObjectsOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// DeleteObjects API operation for Amazon Simple Storage Service.
+//
+// This operation enables you to delete multiple objects from a bucket using
+// a single HTTP request. You may specify up to 1000 keys.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation DeleteObjects for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/DeleteObjects
+func (c *S3) DeleteObjects(input *DeleteObjectsInput) (*DeleteObjectsOutput, error) {
+	req, out := c.DeleteObjectsRequest(input)
+	return out, req.Send()
+}
+
+// DeleteObjectsWithContext is the same as DeleteObjects with the addition of
+// the ability to pass a context and additional request options.
+//
+// See DeleteObjects for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) DeleteObjectsWithContext(ctx aws.Context, input *DeleteObjectsInput, opts ...request.Option) (*DeleteObjectsOutput, error) {
+	req, out := c.DeleteObjectsRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetBucketAccelerateConfiguration = "GetBucketAccelerateConfiguration"
+
+// GetBucketAccelerateConfigurationRequest generates a "aws/request.Request" representing the
+// client's request for the GetBucketAccelerateConfiguration operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetBucketAccelerateConfiguration for more information on using the GetBucketAccelerateConfiguration
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetBucketAccelerateConfigurationRequest method.
+//    req, resp := client.GetBucketAccelerateConfigurationRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAccelerateConfiguration
+func (c *S3) GetBucketAccelerateConfigurationRequest(input *GetBucketAccelerateConfigurationInput) (req *request.Request, output *GetBucketAccelerateConfigurationOutput) {
+	op := &request.Operation{
+		Name:       opGetBucketAccelerateConfiguration,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?accelerate",
+	}
+
+	if input == nil {
+		input = &GetBucketAccelerateConfigurationInput{}
+	}
+
+	output = &GetBucketAccelerateConfigurationOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetBucketAccelerateConfiguration API operation for Amazon Simple Storage Service.
+//
+// Returns the accelerate configuration of a bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetBucketAccelerateConfiguration for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAccelerateConfiguration
+func (c *S3) GetBucketAccelerateConfiguration(input *GetBucketAccelerateConfigurationInput) (*GetBucketAccelerateConfigurationOutput, error) {
+	req, out := c.GetBucketAccelerateConfigurationRequest(input)
+	return out, req.Send()
+}
+
+// GetBucketAccelerateConfigurationWithContext is the same as GetBucketAccelerateConfiguration with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetBucketAccelerateConfiguration for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetBucketAccelerateConfigurationWithContext(ctx aws.Context, input *GetBucketAccelerateConfigurationInput, opts ...request.Option) (*GetBucketAccelerateConfigurationOutput, error) {
+	req, out := c.GetBucketAccelerateConfigurationRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetBucketAcl = "GetBucketAcl"
+
+// GetBucketAclRequest generates a "aws/request.Request" representing the
+// client's request for the GetBucketAcl operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetBucketAcl for more information on using the GetBucketAcl
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetBucketAclRequest method.
+//    req, resp := client.GetBucketAclRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAcl
+func (c *S3) GetBucketAclRequest(input *GetBucketAclInput) (req *request.Request, output *GetBucketAclOutput) {
+	op := &request.Operation{
+		Name:       opGetBucketAcl,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?acl",
+	}
+
+	if input == nil {
+		input = &GetBucketAclInput{}
+	}
+
+	output = &GetBucketAclOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetBucketAcl API operation for Amazon Simple Storage Service.
+//
+// Gets the access control policy for the bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetBucketAcl for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAcl
+func (c *S3) GetBucketAcl(input *GetBucketAclInput) (*GetBucketAclOutput, error) {
+	req, out := c.GetBucketAclRequest(input)
+	return out, req.Send()
+}
+
+// GetBucketAclWithContext is the same as GetBucketAcl with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetBucketAcl for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetBucketAclWithContext(ctx aws.Context, input *GetBucketAclInput, opts ...request.Option) (*GetBucketAclOutput, error) {
+	req, out := c.GetBucketAclRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetBucketAnalyticsConfiguration = "GetBucketAnalyticsConfiguration"
+
+// GetBucketAnalyticsConfigurationRequest generates a "aws/request.Request" representing the
+// client's request for the GetBucketAnalyticsConfiguration operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetBucketAnalyticsConfiguration for more information on using the GetBucketAnalyticsConfiguration
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetBucketAnalyticsConfigurationRequest method.
+//    req, resp := client.GetBucketAnalyticsConfigurationRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAnalyticsConfiguration
+func (c *S3) GetBucketAnalyticsConfigurationRequest(input *GetBucketAnalyticsConfigurationInput) (req *request.Request, output *GetBucketAnalyticsConfigurationOutput) {
+	op := &request.Operation{
+		Name:       opGetBucketAnalyticsConfiguration,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?analytics",
+	}
+
+	if input == nil {
+		input = &GetBucketAnalyticsConfigurationInput{}
+	}
+
+	output = &GetBucketAnalyticsConfigurationOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetBucketAnalyticsConfiguration API operation for Amazon Simple Storage Service.
+//
+// Gets an analytics configuration for the bucket (specified by the analytics
+// configuration ID).
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetBucketAnalyticsConfiguration for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketAnalyticsConfiguration
+func (c *S3) GetBucketAnalyticsConfiguration(input *GetBucketAnalyticsConfigurationInput) (*GetBucketAnalyticsConfigurationOutput, error) {
+	req, out := c.GetBucketAnalyticsConfigurationRequest(input)
+	return out, req.Send()
+}
+
+// GetBucketAnalyticsConfigurationWithContext is the same as GetBucketAnalyticsConfiguration with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetBucketAnalyticsConfiguration for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetBucketAnalyticsConfigurationWithContext(ctx aws.Context, input *GetBucketAnalyticsConfigurationInput, opts ...request.Option) (*GetBucketAnalyticsConfigurationOutput, error) {
+	req, out := c.GetBucketAnalyticsConfigurationRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetBucketCors = "GetBucketCors"
+
+// GetBucketCorsRequest generates a "aws/request.Request" representing the
+// client's request for the GetBucketCors operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetBucketCors for more information on using the GetBucketCors
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetBucketCorsRequest method.
+//    req, resp := client.GetBucketCorsRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketCors
+func (c *S3) GetBucketCorsRequest(input *GetBucketCorsInput) (req *request.Request, output *GetBucketCorsOutput) {
+	op := &request.Operation{
+		Name:       opGetBucketCors,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?cors",
+	}
+
+	if input == nil {
+		input = &GetBucketCorsInput{}
+	}
+
+	output = &GetBucketCorsOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetBucketCors API operation for Amazon Simple Storage Service.
+//
+// Returns the cors configuration for the bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetBucketCors for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketCors
+func (c *S3) GetBucketCors(input *GetBucketCorsInput) (*GetBucketCorsOutput, error) {
+	req, out := c.GetBucketCorsRequest(input)
+	return out, req.Send()
+}
+
+// GetBucketCorsWithContext is the same as GetBucketCors with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetBucketCors for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetBucketCorsWithContext(ctx aws.Context, input *GetBucketCorsInput, opts ...request.Option) (*GetBucketCorsOutput, error) {
+	req, out := c.GetBucketCorsRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetBucketEncryption = "GetBucketEncryption"
+
+// GetBucketEncryptionRequest generates a "aws/request.Request" representing the
+// client's request for the GetBucketEncryption operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetBucketEncryption for more information on using the GetBucketEncryption
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetBucketEncryptionRequest method.
+//    req, resp := client.GetBucketEncryptionRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketEncryption
+func (c *S3) GetBucketEncryptionRequest(input *GetBucketEncryptionInput) (req *request.Request, output *GetBucketEncryptionOutput) {
+	op := &request.Operation{
+		Name:       opGetBucketEncryption,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?encryption",
+	}
+
+	if input == nil {
+		input = &GetBucketEncryptionInput{}
+	}
+
+	output = &GetBucketEncryptionOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetBucketEncryption API operation for Amazon Simple Storage Service.
+//
+// Returns the server-side encryption configuration of a bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetBucketEncryption for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketEncryption
+func (c *S3) GetBucketEncryption(input *GetBucketEncryptionInput) (*GetBucketEncryptionOutput, error) {
+	req, out := c.GetBucketEncryptionRequest(input)
+	return out, req.Send()
+}
+
+// GetBucketEncryptionWithContext is the same as GetBucketEncryption with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetBucketEncryption for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetBucketEncryptionWithContext(ctx aws.Context, input *GetBucketEncryptionInput, opts ...request.Option) (*GetBucketEncryptionOutput, error) {
+	req, out := c.GetBucketEncryptionRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetBucketInventoryConfiguration = "GetBucketInventoryConfiguration"
+
+// GetBucketInventoryConfigurationRequest generates a "aws/request.Request" representing the
+// client's request for the GetBucketInventoryConfiguration operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetBucketInventoryConfiguration for more information on using the GetBucketInventoryConfiguration
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetBucketInventoryConfigurationRequest method.
+//    req, resp := client.GetBucketInventoryConfigurationRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketInventoryConfiguration
+func (c *S3) GetBucketInventoryConfigurationRequest(input *GetBucketInventoryConfigurationInput) (req *request.Request, output *GetBucketInventoryConfigurationOutput) {
+	op := &request.Operation{
+		Name:       opGetBucketInventoryConfiguration,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?inventory",
+	}
+
+	if input == nil {
+		input = &GetBucketInventoryConfigurationInput{}
+	}
+
+	output = &GetBucketInventoryConfigurationOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetBucketInventoryConfiguration API operation for Amazon Simple Storage Service.
+//
+// Returns an inventory configuration (identified by the inventory ID) from
+// the bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetBucketInventoryConfiguration for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketInventoryConfiguration
+func (c *S3) GetBucketInventoryConfiguration(input *GetBucketInventoryConfigurationInput) (*GetBucketInventoryConfigurationOutput, error) {
+	req, out := c.GetBucketInventoryConfigurationRequest(input)
+	return out, req.Send()
+}
+
+// GetBucketInventoryConfigurationWithContext is the same as GetBucketInventoryConfiguration with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetBucketInventoryConfiguration for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetBucketInventoryConfigurationWithContext(ctx aws.Context, input *GetBucketInventoryConfigurationInput, opts ...request.Option) (*GetBucketInventoryConfigurationOutput, error) {
+	req, out := c.GetBucketInventoryConfigurationRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetBucketLifecycle = "GetBucketLifecycle"
+
+// GetBucketLifecycleRequest generates a "aws/request.Request" representing the
+// client's request for the GetBucketLifecycle operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetBucketLifecycle for more information on using the GetBucketLifecycle
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetBucketLifecycleRequest method.
+//    req, resp := client.GetBucketLifecycleRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycle
+func (c *S3) GetBucketLifecycleRequest(input *GetBucketLifecycleInput) (req *request.Request, output *GetBucketLifecycleOutput) {
+	if c.Client.Config.Logger != nil {
+		c.Client.Config.Logger.Log("This operation, GetBucketLifecycle, has been deprecated")
+	}
+	op := &request.Operation{
+		Name:       opGetBucketLifecycle,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?lifecycle",
+	}
+
+	if input == nil {
+		input = &GetBucketLifecycleInput{}
+	}
+
+	output = &GetBucketLifecycleOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetBucketLifecycle API operation for Amazon Simple Storage Service.
+//
+// Deprecated, see the GetBucketLifecycleConfiguration operation.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetBucketLifecycle for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycle
+func (c *S3) GetBucketLifecycle(input *GetBucketLifecycleInput) (*GetBucketLifecycleOutput, error) {
+	req, out := c.GetBucketLifecycleRequest(input)
+	return out, req.Send()
+}
+
+// GetBucketLifecycleWithContext is the same as GetBucketLifecycle with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetBucketLifecycle for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetBucketLifecycleWithContext(ctx aws.Context, input *GetBucketLifecycleInput, opts ...request.Option) (*GetBucketLifecycleOutput, error) {
+	req, out := c.GetBucketLifecycleRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetBucketLifecycleConfiguration = "GetBucketLifecycleConfiguration"
+
+// GetBucketLifecycleConfigurationRequest generates a "aws/request.Request" representing the
+// client's request for the GetBucketLifecycleConfiguration operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetBucketLifecycleConfiguration for more information on using the GetBucketLifecycleConfiguration
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetBucketLifecycleConfigurationRequest method.
+//    req, resp := client.GetBucketLifecycleConfigurationRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycleConfiguration
+func (c *S3) GetBucketLifecycleConfigurationRequest(input *GetBucketLifecycleConfigurationInput) (req *request.Request, output *GetBucketLifecycleConfigurationOutput) {
+	op := &request.Operation{
+		Name:       opGetBucketLifecycleConfiguration,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?lifecycle",
+	}
+
+	if input == nil {
+		input = &GetBucketLifecycleConfigurationInput{}
+	}
+
+	output = &GetBucketLifecycleConfigurationOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetBucketLifecycleConfiguration API operation for Amazon Simple Storage Service.
+//
+// Returns the lifecycle configuration information set on the bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetBucketLifecycleConfiguration for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLifecycleConfiguration
+func (c *S3) GetBucketLifecycleConfiguration(input *GetBucketLifecycleConfigurationInput) (*GetBucketLifecycleConfigurationOutput, error) {
+	req, out := c.GetBucketLifecycleConfigurationRequest(input)
+	return out, req.Send()
+}
+
+// GetBucketLifecycleConfigurationWithContext is the same as GetBucketLifecycleConfiguration with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetBucketLifecycleConfiguration for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetBucketLifecycleConfigurationWithContext(ctx aws.Context, input *GetBucketLifecycleConfigurationInput, opts ...request.Option) (*GetBucketLifecycleConfigurationOutput, error) {
+	req, out := c.GetBucketLifecycleConfigurationRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetBucketLocation = "GetBucketLocation"
+
+// GetBucketLocationRequest generates a "aws/request.Request" representing the
+// client's request for the GetBucketLocation operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetBucketLocation for more information on using the GetBucketLocation
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetBucketLocationRequest method.
+//    req, resp := client.GetBucketLocationRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLocation
+func (c *S3) GetBucketLocationRequest(input *GetBucketLocationInput) (req *request.Request, output *GetBucketLocationOutput) {
+	op := &request.Operation{
+		Name:       opGetBucketLocation,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?location",
+	}
+
+	if input == nil {
+		input = &GetBucketLocationInput{}
+	}
+
+	output = &GetBucketLocationOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetBucketLocation API operation for Amazon Simple Storage Service.
+//
+// Returns the region the bucket resides in.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetBucketLocation for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLocation
+func (c *S3) GetBucketLocation(input *GetBucketLocationInput) (*GetBucketLocationOutput, error) {
+	req, out := c.GetBucketLocationRequest(input)
+	return out, req.Send()
+}
+
+// GetBucketLocationWithContext is the same as GetBucketLocation with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetBucketLocation for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetBucketLocationWithContext(ctx aws.Context, input *GetBucketLocationInput, opts ...request.Option) (*GetBucketLocationOutput, error) {
+	req, out := c.GetBucketLocationRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetBucketLogging = "GetBucketLogging"
+
+// GetBucketLoggingRequest generates a "aws/request.Request" representing the
+// client's request for the GetBucketLogging operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetBucketLogging for more information on using the GetBucketLogging
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetBucketLoggingRequest method.
+//    req, resp := client.GetBucketLoggingRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLogging
+func (c *S3) GetBucketLoggingRequest(input *GetBucketLoggingInput) (req *request.Request, output *GetBucketLoggingOutput) {
+	op := &request.Operation{
+		Name:       opGetBucketLogging,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?logging",
+	}
+
+	if input == nil {
+		input = &GetBucketLoggingInput{}
+	}
+
+	output = &GetBucketLoggingOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetBucketLogging API operation for Amazon Simple Storage Service.
+//
+// Returns the logging status of a bucket and the permissions users have to
+// view and modify that status. To use GET, you must be the bucket owner.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetBucketLogging for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketLogging
+func (c *S3) GetBucketLogging(input *GetBucketLoggingInput) (*GetBucketLoggingOutput, error) {
+	req, out := c.GetBucketLoggingRequest(input)
+	return out, req.Send()
+}
+
+// GetBucketLoggingWithContext is the same as GetBucketLogging with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetBucketLogging for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetBucketLoggingWithContext(ctx aws.Context, input *GetBucketLoggingInput, opts ...request.Option) (*GetBucketLoggingOutput, error) {
+	req, out := c.GetBucketLoggingRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetBucketMetricsConfiguration = "GetBucketMetricsConfiguration"
+
+// GetBucketMetricsConfigurationRequest generates a "aws/request.Request" representing the
+// client's request for the GetBucketMetricsConfiguration operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetBucketMetricsConfiguration for more information on using the GetBucketMetricsConfiguration
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetBucketMetricsConfigurationRequest method.
+//    req, resp := client.GetBucketMetricsConfigurationRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketMetricsConfiguration
+func (c *S3) GetBucketMetricsConfigurationRequest(input *GetBucketMetricsConfigurationInput) (req *request.Request, output *GetBucketMetricsConfigurationOutput) {
+	op := &request.Operation{
+		Name:       opGetBucketMetricsConfiguration,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?metrics",
+	}
+
+	if input == nil {
+		input = &GetBucketMetricsConfigurationInput{}
+	}
+
+	output = &GetBucketMetricsConfigurationOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetBucketMetricsConfiguration API operation for Amazon Simple Storage Service.
+//
+// Gets a metrics configuration (specified by the metrics configuration ID)
+// from the bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetBucketMetricsConfiguration for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketMetricsConfiguration
+func (c *S3) GetBucketMetricsConfiguration(input *GetBucketMetricsConfigurationInput) (*GetBucketMetricsConfigurationOutput, error) {
+	req, out := c.GetBucketMetricsConfigurationRequest(input)
+	return out, req.Send()
+}
+
+// GetBucketMetricsConfigurationWithContext is the same as GetBucketMetricsConfiguration with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetBucketMetricsConfiguration for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetBucketMetricsConfigurationWithContext(ctx aws.Context, input *GetBucketMetricsConfigurationInput, opts ...request.Option) (*GetBucketMetricsConfigurationOutput, error) {
+	req, out := c.GetBucketMetricsConfigurationRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetBucketNotification = "GetBucketNotification"
+
+// GetBucketNotificationRequest generates a "aws/request.Request" representing the
+// client's request for the GetBucketNotification operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetBucketNotification for more information on using the GetBucketNotification
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetBucketNotificationRequest method.
+//    req, resp := client.GetBucketNotificationRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketNotification
+func (c *S3) GetBucketNotificationRequest(input *GetBucketNotificationConfigurationRequest) (req *request.Request, output *NotificationConfigurationDeprecated) {
+	if c.Client.Config.Logger != nil {
+		c.Client.Config.Logger.Log("This operation, GetBucketNotification, has been deprecated")
+	}
+	op := &request.Operation{
+		Name:       opGetBucketNotification,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?notification",
+	}
+
+	if input == nil {
+		input = &GetBucketNotificationConfigurationRequest{}
+	}
+
+	output = &NotificationConfigurationDeprecated{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetBucketNotification API operation for Amazon Simple Storage Service.
+//
+// Deprecated, see the GetBucketNotificationConfiguration operation.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetBucketNotification for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketNotification
+func (c *S3) GetBucketNotification(input *GetBucketNotificationConfigurationRequest) (*NotificationConfigurationDeprecated, error) {
+	req, out := c.GetBucketNotificationRequest(input)
+	return out, req.Send()
+}
+
+// GetBucketNotificationWithContext is the same as GetBucketNotification with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetBucketNotification for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetBucketNotificationWithContext(ctx aws.Context, input *GetBucketNotificationConfigurationRequest, opts ...request.Option) (*NotificationConfigurationDeprecated, error) {
+	req, out := c.GetBucketNotificationRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetBucketNotificationConfiguration = "GetBucketNotificationConfiguration"
+
+// GetBucketNotificationConfigurationRequest generates a "aws/request.Request" representing the
+// client's request for the GetBucketNotificationConfiguration operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetBucketNotificationConfiguration for more information on using the GetBucketNotificationConfiguration
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetBucketNotificationConfigurationRequest method.
+//    req, resp := client.GetBucketNotificationConfigurationRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketNotificationConfiguration
+func (c *S3) GetBucketNotificationConfigurationRequest(input *GetBucketNotificationConfigurationRequest) (req *request.Request, output *NotificationConfiguration) {
+	op := &request.Operation{
+		Name:       opGetBucketNotificationConfiguration,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?notification",
+	}
+
+	if input == nil {
+		input = &GetBucketNotificationConfigurationRequest{}
+	}
+
+	output = &NotificationConfiguration{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetBucketNotificationConfiguration API operation for Amazon Simple Storage Service.
+//
+// Returns the notification configuration of a bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetBucketNotificationConfiguration for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketNotificationConfiguration
+func (c *S3) GetBucketNotificationConfiguration(input *GetBucketNotificationConfigurationRequest) (*NotificationConfiguration, error) {
+	req, out := c.GetBucketNotificationConfigurationRequest(input)
+	return out, req.Send()
+}
+
+// GetBucketNotificationConfigurationWithContext is the same as GetBucketNotificationConfiguration with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetBucketNotificationConfiguration for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetBucketNotificationConfigurationWithContext(ctx aws.Context, input *GetBucketNotificationConfigurationRequest, opts ...request.Option) (*NotificationConfiguration, error) {
+	req, out := c.GetBucketNotificationConfigurationRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetBucketPolicy = "GetBucketPolicy"
+
+// GetBucketPolicyRequest generates a "aws/request.Request" representing the
+// client's request for the GetBucketPolicy operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetBucketPolicy for more information on using the GetBucketPolicy
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetBucketPolicyRequest method.
+//    req, resp := client.GetBucketPolicyRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketPolicy
+func (c *S3) GetBucketPolicyRequest(input *GetBucketPolicyInput) (req *request.Request, output *GetBucketPolicyOutput) {
+	op := &request.Operation{
+		Name:       opGetBucketPolicy,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?policy",
+	}
+
+	if input == nil {
+		input = &GetBucketPolicyInput{}
+	}
+
+	output = &GetBucketPolicyOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetBucketPolicy API operation for Amazon Simple Storage Service.
+//
+// Returns the policy of a specified bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetBucketPolicy for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketPolicy
+func (c *S3) GetBucketPolicy(input *GetBucketPolicyInput) (*GetBucketPolicyOutput, error) {
+	req, out := c.GetBucketPolicyRequest(input)
+	return out, req.Send()
+}
+
+// GetBucketPolicyWithContext is the same as GetBucketPolicy with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetBucketPolicy for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetBucketPolicyWithContext(ctx aws.Context, input *GetBucketPolicyInput, opts ...request.Option) (*GetBucketPolicyOutput, error) {
+	req, out := c.GetBucketPolicyRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetBucketReplication = "GetBucketReplication"
+
+// GetBucketReplicationRequest generates a "aws/request.Request" representing the
+// client's request for the GetBucketReplication operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetBucketReplication for more information on using the GetBucketReplication
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetBucketReplicationRequest method.
+//    req, resp := client.GetBucketReplicationRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketReplication
+func (c *S3) GetBucketReplicationRequest(input *GetBucketReplicationInput) (req *request.Request, output *GetBucketReplicationOutput) {
+	op := &request.Operation{
+		Name:       opGetBucketReplication,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?replication",
+	}
+
+	if input == nil {
+		input = &GetBucketReplicationInput{}
+	}
+
+	output = &GetBucketReplicationOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetBucketReplication API operation for Amazon Simple Storage Service.
+//
+// Returns the replication configuration of a bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetBucketReplication for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketReplication
+func (c *S3) GetBucketReplication(input *GetBucketReplicationInput) (*GetBucketReplicationOutput, error) {
+	req, out := c.GetBucketReplicationRequest(input)
+	return out, req.Send()
+}
+
+// GetBucketReplicationWithContext is the same as GetBucketReplication with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetBucketReplication for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetBucketReplicationWithContext(ctx aws.Context, input *GetBucketReplicationInput, opts ...request.Option) (*GetBucketReplicationOutput, error) {
+	req, out := c.GetBucketReplicationRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetBucketRequestPayment = "GetBucketRequestPayment"
+
+// GetBucketRequestPaymentRequest generates a "aws/request.Request" representing the
+// client's request for the GetBucketRequestPayment operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetBucketRequestPayment for more information on using the GetBucketRequestPayment
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetBucketRequestPaymentRequest method.
+//    req, resp := client.GetBucketRequestPaymentRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketRequestPayment
+func (c *S3) GetBucketRequestPaymentRequest(input *GetBucketRequestPaymentInput) (req *request.Request, output *GetBucketRequestPaymentOutput) {
+	op := &request.Operation{
+		Name:       opGetBucketRequestPayment,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?requestPayment",
+	}
+
+	if input == nil {
+		input = &GetBucketRequestPaymentInput{}
+	}
+
+	output = &GetBucketRequestPaymentOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetBucketRequestPayment API operation for Amazon Simple Storage Service.
+//
+// Returns the request payment configuration of a bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetBucketRequestPayment for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketRequestPayment
+func (c *S3) GetBucketRequestPayment(input *GetBucketRequestPaymentInput) (*GetBucketRequestPaymentOutput, error) {
+	req, out := c.GetBucketRequestPaymentRequest(input)
+	return out, req.Send()
+}
+
+// GetBucketRequestPaymentWithContext is the same as GetBucketRequestPayment with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetBucketRequestPayment for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetBucketRequestPaymentWithContext(ctx aws.Context, input *GetBucketRequestPaymentInput, opts ...request.Option) (*GetBucketRequestPaymentOutput, error) {
+	req, out := c.GetBucketRequestPaymentRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetBucketTagging = "GetBucketTagging"
+
+// GetBucketTaggingRequest generates a "aws/request.Request" representing the
+// client's request for the GetBucketTagging operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetBucketTagging for more information on using the GetBucketTagging
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetBucketTaggingRequest method.
+//    req, resp := client.GetBucketTaggingRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketTagging
+func (c *S3) GetBucketTaggingRequest(input *GetBucketTaggingInput) (req *request.Request, output *GetBucketTaggingOutput) {
+	op := &request.Operation{
+		Name:       opGetBucketTagging,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?tagging",
+	}
+
+	if input == nil {
+		input = &GetBucketTaggingInput{}
+	}
+
+	output = &GetBucketTaggingOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetBucketTagging API operation for Amazon Simple Storage Service.
+//
+// Returns the tag set associated with the bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetBucketTagging for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketTagging
+func (c *S3) GetBucketTagging(input *GetBucketTaggingInput) (*GetBucketTaggingOutput, error) {
+	req, out := c.GetBucketTaggingRequest(input)
+	return out, req.Send()
+}
+
+// GetBucketTaggingWithContext is the same as GetBucketTagging with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetBucketTagging for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetBucketTaggingWithContext(ctx aws.Context, input *GetBucketTaggingInput, opts ...request.Option) (*GetBucketTaggingOutput, error) {
+	req, out := c.GetBucketTaggingRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetBucketVersioning = "GetBucketVersioning"
+
+// GetBucketVersioningRequest generates a "aws/request.Request" representing the
+// client's request for the GetBucketVersioning operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetBucketVersioning for more information on using the GetBucketVersioning
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetBucketVersioningRequest method.
+//    req, resp := client.GetBucketVersioningRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketVersioning
+func (c *S3) GetBucketVersioningRequest(input *GetBucketVersioningInput) (req *request.Request, output *GetBucketVersioningOutput) {
+	op := &request.Operation{
+		Name:       opGetBucketVersioning,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?versioning",
+	}
+
+	if input == nil {
+		input = &GetBucketVersioningInput{}
+	}
+
+	output = &GetBucketVersioningOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetBucketVersioning API operation for Amazon Simple Storage Service.
+//
+// Returns the versioning state of a bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetBucketVersioning for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketVersioning
+func (c *S3) GetBucketVersioning(input *GetBucketVersioningInput) (*GetBucketVersioningOutput, error) {
+	req, out := c.GetBucketVersioningRequest(input)
+	return out, req.Send()
+}
+
+// GetBucketVersioningWithContext is the same as GetBucketVersioning with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetBucketVersioning for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetBucketVersioningWithContext(ctx aws.Context, input *GetBucketVersioningInput, opts ...request.Option) (*GetBucketVersioningOutput, error) {
+	req, out := c.GetBucketVersioningRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetBucketWebsite = "GetBucketWebsite"
+
+// GetBucketWebsiteRequest generates a "aws/request.Request" representing the
+// client's request for the GetBucketWebsite operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetBucketWebsite for more information on using the GetBucketWebsite
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetBucketWebsiteRequest method.
+//    req, resp := client.GetBucketWebsiteRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketWebsite
+func (c *S3) GetBucketWebsiteRequest(input *GetBucketWebsiteInput) (req *request.Request, output *GetBucketWebsiteOutput) {
+	op := &request.Operation{
+		Name:       opGetBucketWebsite,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?website",
+	}
+
+	if input == nil {
+		input = &GetBucketWebsiteInput{}
+	}
+
+	output = &GetBucketWebsiteOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetBucketWebsite API operation for Amazon Simple Storage Service.
+//
+// Returns the website configuration for a bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetBucketWebsite for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetBucketWebsite
+func (c *S3) GetBucketWebsite(input *GetBucketWebsiteInput) (*GetBucketWebsiteOutput, error) {
+	req, out := c.GetBucketWebsiteRequest(input)
+	return out, req.Send()
+}
+
+// GetBucketWebsiteWithContext is the same as GetBucketWebsite with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetBucketWebsite for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetBucketWebsiteWithContext(ctx aws.Context, input *GetBucketWebsiteInput, opts ...request.Option) (*GetBucketWebsiteOutput, error) {
+	req, out := c.GetBucketWebsiteRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetObject = "GetObject"
+
+// GetObjectRequest generates a "aws/request.Request" representing the
+// client's request for the GetObject operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetObject for more information on using the GetObject
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetObjectRequest method.
+//    req, resp := client.GetObjectRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObject
+func (c *S3) GetObjectRequest(input *GetObjectInput) (req *request.Request, output *GetObjectOutput) {
+	op := &request.Operation{
+		Name:       opGetObject,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}/{Key+}",
+	}
+
+	if input == nil {
+		input = &GetObjectInput{}
+	}
+
+	output = &GetObjectOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetObject API operation for Amazon Simple Storage Service.
+//
+// Retrieves objects from Amazon S3.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetObject for usage and error information.
+//
+// Returned Error Codes:
+//   * ErrCodeNoSuchKey "NoSuchKey"
+//   The specified key does not exist.
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObject
+func (c *S3) GetObject(input *GetObjectInput) (*GetObjectOutput, error) {
+	req, out := c.GetObjectRequest(input)
+	return out, req.Send()
+}
+
+// GetObjectWithContext is the same as GetObject with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetObject for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetObjectWithContext(ctx aws.Context, input *GetObjectInput, opts ...request.Option) (*GetObjectOutput, error) {
+	req, out := c.GetObjectRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetObjectAcl = "GetObjectAcl"
+
+// GetObjectAclRequest generates a "aws/request.Request" representing the
+// client's request for the GetObjectAcl operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetObjectAcl for more information on using the GetObjectAcl
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetObjectAclRequest method.
+//    req, resp := client.GetObjectAclRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectAcl
+func (c *S3) GetObjectAclRequest(input *GetObjectAclInput) (req *request.Request, output *GetObjectAclOutput) {
+	op := &request.Operation{
+		Name:       opGetObjectAcl,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}/{Key+}?acl",
+	}
+
+	if input == nil {
+		input = &GetObjectAclInput{}
+	}
+
+	output = &GetObjectAclOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetObjectAcl API operation for Amazon Simple Storage Service.
+//
+// Returns the access control list (ACL) of an object.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetObjectAcl for usage and error information.
+//
+// Returned Error Codes:
+//   * ErrCodeNoSuchKey "NoSuchKey"
+//   The specified key does not exist.
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectAcl
+func (c *S3) GetObjectAcl(input *GetObjectAclInput) (*GetObjectAclOutput, error) {
+	req, out := c.GetObjectAclRequest(input)
+	return out, req.Send()
+}
+
+// GetObjectAclWithContext is the same as GetObjectAcl with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetObjectAcl for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetObjectAclWithContext(ctx aws.Context, input *GetObjectAclInput, opts ...request.Option) (*GetObjectAclOutput, error) {
+	req, out := c.GetObjectAclRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetObjectTagging = "GetObjectTagging"
+
+// GetObjectTaggingRequest generates a "aws/request.Request" representing the
+// client's request for the GetObjectTagging operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetObjectTagging for more information on using the GetObjectTagging
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetObjectTaggingRequest method.
+//    req, resp := client.GetObjectTaggingRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTagging
+func (c *S3) GetObjectTaggingRequest(input *GetObjectTaggingInput) (req *request.Request, output *GetObjectTaggingOutput) {
+	op := &request.Operation{
+		Name:       opGetObjectTagging,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}/{Key+}?tagging",
+	}
+
+	if input == nil {
+		input = &GetObjectTaggingInput{}
+	}
+
+	output = &GetObjectTaggingOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetObjectTagging API operation for Amazon Simple Storage Service.
+//
+// Returns the tag-set of an object.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetObjectTagging for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTagging
+func (c *S3) GetObjectTagging(input *GetObjectTaggingInput) (*GetObjectTaggingOutput, error) {
+	req, out := c.GetObjectTaggingRequest(input)
+	return out, req.Send()
+}
+
+// GetObjectTaggingWithContext is the same as GetObjectTagging with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetObjectTagging for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetObjectTaggingWithContext(ctx aws.Context, input *GetObjectTaggingInput, opts ...request.Option) (*GetObjectTaggingOutput, error) {
+	req, out := c.GetObjectTaggingRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetObjectTorrent = "GetObjectTorrent"
+
+// GetObjectTorrentRequest generates a "aws/request.Request" representing the
+// client's request for the GetObjectTorrent operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetObjectTorrent for more information on using the GetObjectTorrent
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetObjectTorrentRequest method.
+//    req, resp := client.GetObjectTorrentRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTorrent
+func (c *S3) GetObjectTorrentRequest(input *GetObjectTorrentInput) (req *request.Request, output *GetObjectTorrentOutput) {
+	op := &request.Operation{
+		Name:       opGetObjectTorrent,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}/{Key+}?torrent",
+	}
+
+	if input == nil {
+		input = &GetObjectTorrentInput{}
+	}
+
+	output = &GetObjectTorrentOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetObjectTorrent API operation for Amazon Simple Storage Service.
+//
+// Return torrent files from a bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation GetObjectTorrent for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/GetObjectTorrent
+func (c *S3) GetObjectTorrent(input *GetObjectTorrentInput) (*GetObjectTorrentOutput, error) {
+	req, out := c.GetObjectTorrentRequest(input)
+	return out, req.Send()
+}
+
+// GetObjectTorrentWithContext is the same as GetObjectTorrent with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetObjectTorrent for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) GetObjectTorrentWithContext(ctx aws.Context, input *GetObjectTorrentInput, opts ...request.Option) (*GetObjectTorrentOutput, error) {
+	req, out := c.GetObjectTorrentRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opHeadBucket = "HeadBucket"
+
+// HeadBucketRequest generates a "aws/request.Request" representing the
+// client's request for the HeadBucket operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See HeadBucket for more information on using the HeadBucket
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the HeadBucketRequest method.
+//    req, resp := client.HeadBucketRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadBucket
+func (c *S3) HeadBucketRequest(input *HeadBucketInput) (req *request.Request, output *HeadBucketOutput) {
+	op := &request.Operation{
+		Name:       opHeadBucket,
+		HTTPMethod: "HEAD",
+		HTTPPath:   "/{Bucket}",
+	}
+
+	if input == nil {
+		input = &HeadBucketInput{}
+	}
+
+	output = &HeadBucketOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// HeadBucket API operation for Amazon Simple Storage Service.
+//
+// This operation is useful to determine if a bucket exists and you have permission
+// to access it.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation HeadBucket for usage and error information.
+//
+// Returned Error Codes:
+//   * ErrCodeNoSuchBucket "NoSuchBucket"
+//   The specified bucket does not exist.
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadBucket
+func (c *S3) HeadBucket(input *HeadBucketInput) (*HeadBucketOutput, error) {
+	req, out := c.HeadBucketRequest(input)
+	return out, req.Send()
+}
+
+// HeadBucketWithContext is the same as HeadBucket with the addition of
+// the ability to pass a context and additional request options.
+//
+// See HeadBucket for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) HeadBucketWithContext(ctx aws.Context, input *HeadBucketInput, opts ...request.Option) (*HeadBucketOutput, error) {
+	req, out := c.HeadBucketRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opHeadObject = "HeadObject"
+
+// HeadObjectRequest generates a "aws/request.Request" representing the
+// client's request for the HeadObject operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See HeadObject for more information on using the HeadObject
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the HeadObjectRequest method.
+//    req, resp := client.HeadObjectRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadObject
+func (c *S3) HeadObjectRequest(input *HeadObjectInput) (req *request.Request, output *HeadObjectOutput) {
+	op := &request.Operation{
+		Name:       opHeadObject,
+		HTTPMethod: "HEAD",
+		HTTPPath:   "/{Bucket}/{Key+}",
+	}
+
+	if input == nil {
+		input = &HeadObjectInput{}
+	}
+
+	output = &HeadObjectOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// HeadObject API operation for Amazon Simple Storage Service.
+//
+// The HEAD operation retrieves metadata from an object without returning the
+// object itself. This operation is useful if you're only interested in an object's
+// metadata. To use HEAD, you must have READ access to the object.
+//
+// See http://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#RESTErrorResponses
+// for more information on returned errors.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation HeadObject for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/HeadObject
+func (c *S3) HeadObject(input *HeadObjectInput) (*HeadObjectOutput, error) {
+	req, out := c.HeadObjectRequest(input)
+	return out, req.Send()
+}
+
+// HeadObjectWithContext is the same as HeadObject with the addition of
+// the ability to pass a context and additional request options.
+//
+// See HeadObject for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) HeadObjectWithContext(ctx aws.Context, input *HeadObjectInput, opts ...request.Option) (*HeadObjectOutput, error) {
+	req, out := c.HeadObjectRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opListBucketAnalyticsConfigurations = "ListBucketAnalyticsConfigurations"
+
+// ListBucketAnalyticsConfigurationsRequest generates a "aws/request.Request" representing the
+// client's request for the ListBucketAnalyticsConfigurations operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See ListBucketAnalyticsConfigurations for more information on using the ListBucketAnalyticsConfigurations
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the ListBucketAnalyticsConfigurationsRequest method.
+//    req, resp := client.ListBucketAnalyticsConfigurationsRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketAnalyticsConfigurations
+func (c *S3) ListBucketAnalyticsConfigurationsRequest(input *ListBucketAnalyticsConfigurationsInput) (req *request.Request, output *ListBucketAnalyticsConfigurationsOutput) {
+	op := &request.Operation{
+		Name:       opListBucketAnalyticsConfigurations,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?analytics",
+	}
+
+	if input == nil {
+		input = &ListBucketAnalyticsConfigurationsInput{}
+	}
+
+	output = &ListBucketAnalyticsConfigurationsOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// ListBucketAnalyticsConfigurations API operation for Amazon Simple Storage Service.
+//
+// Lists the analytics configurations for the bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation ListBucketAnalyticsConfigurations for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketAnalyticsConfigurations
+func (c *S3) ListBucketAnalyticsConfigurations(input *ListBucketAnalyticsConfigurationsInput) (*ListBucketAnalyticsConfigurationsOutput, error) {
+	req, out := c.ListBucketAnalyticsConfigurationsRequest(input)
+	return out, req.Send()
+}
+
+// ListBucketAnalyticsConfigurationsWithContext is the same as ListBucketAnalyticsConfigurations with the addition of
+// the ability to pass a context and additional request options.
+//
+// See ListBucketAnalyticsConfigurations for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) ListBucketAnalyticsConfigurationsWithContext(ctx aws.Context, input *ListBucketAnalyticsConfigurationsInput, opts ...request.Option) (*ListBucketAnalyticsConfigurationsOutput, error) {
+	req, out := c.ListBucketAnalyticsConfigurationsRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opListBucketInventoryConfigurations = "ListBucketInventoryConfigurations"
+
+// ListBucketInventoryConfigurationsRequest generates a "aws/request.Request" representing the
+// client's request for the ListBucketInventoryConfigurations operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See ListBucketInventoryConfigurations for more information on using the ListBucketInventoryConfigurations
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the ListBucketInventoryConfigurationsRequest method.
+//    req, resp := client.ListBucketInventoryConfigurationsRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketInventoryConfigurations
+func (c *S3) ListBucketInventoryConfigurationsRequest(input *ListBucketInventoryConfigurationsInput) (req *request.Request, output *ListBucketInventoryConfigurationsOutput) {
+	op := &request.Operation{
+		Name:       opListBucketInventoryConfigurations,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?inventory",
+	}
+
+	if input == nil {
+		input = &ListBucketInventoryConfigurationsInput{}
+	}
+
+	output = &ListBucketInventoryConfigurationsOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// ListBucketInventoryConfigurations API operation for Amazon Simple Storage Service.
+//
+// Returns a list of inventory configurations for the bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation ListBucketInventoryConfigurations for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketInventoryConfigurations
+func (c *S3) ListBucketInventoryConfigurations(input *ListBucketInventoryConfigurationsInput) (*ListBucketInventoryConfigurationsOutput, error) {
+	req, out := c.ListBucketInventoryConfigurationsRequest(input)
+	return out, req.Send()
+}
+
+// ListBucketInventoryConfigurationsWithContext is the same as ListBucketInventoryConfigurations with the addition of
+// the ability to pass a context and additional request options.
+//
+// See ListBucketInventoryConfigurations for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) ListBucketInventoryConfigurationsWithContext(ctx aws.Context, input *ListBucketInventoryConfigurationsInput, opts ...request.Option) (*ListBucketInventoryConfigurationsOutput, error) {
+	req, out := c.ListBucketInventoryConfigurationsRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opListBucketMetricsConfigurations = "ListBucketMetricsConfigurations"
+
+// ListBucketMetricsConfigurationsRequest generates a "aws/request.Request" representing the
+// client's request for the ListBucketMetricsConfigurations operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See ListBucketMetricsConfigurations for more information on using the ListBucketMetricsConfigurations
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the ListBucketMetricsConfigurationsRequest method.
+//    req, resp := client.ListBucketMetricsConfigurationsRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketMetricsConfigurations
+func (c *S3) ListBucketMetricsConfigurationsRequest(input *ListBucketMetricsConfigurationsInput) (req *request.Request, output *ListBucketMetricsConfigurationsOutput) {
+	op := &request.Operation{
+		Name:       opListBucketMetricsConfigurations,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?metrics",
+	}
+
+	if input == nil {
+		input = &ListBucketMetricsConfigurationsInput{}
+	}
+
+	output = &ListBucketMetricsConfigurationsOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// ListBucketMetricsConfigurations API operation for Amazon Simple Storage Service.
+//
+// Lists the metrics configurations for the bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation ListBucketMetricsConfigurations for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBucketMetricsConfigurations
+func (c *S3) ListBucketMetricsConfigurations(input *ListBucketMetricsConfigurationsInput) (*ListBucketMetricsConfigurationsOutput, error) {
+	req, out := c.ListBucketMetricsConfigurationsRequest(input)
+	return out, req.Send()
+}
+
+// ListBucketMetricsConfigurationsWithContext is the same as ListBucketMetricsConfigurations with the addition of
+// the ability to pass a context and additional request options.
+//
+// See ListBucketMetricsConfigurations for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) ListBucketMetricsConfigurationsWithContext(ctx aws.Context, input *ListBucketMetricsConfigurationsInput, opts ...request.Option) (*ListBucketMetricsConfigurationsOutput, error) {
+	req, out := c.ListBucketMetricsConfigurationsRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opListBuckets = "ListBuckets"
+
+// ListBucketsRequest generates a "aws/request.Request" representing the
+// client's request for the ListBuckets operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See ListBuckets for more information on using the ListBuckets
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the ListBucketsRequest method.
+//    req, resp := client.ListBucketsRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBuckets
+func (c *S3) ListBucketsRequest(input *ListBucketsInput) (req *request.Request, output *ListBucketsOutput) {
+	op := &request.Operation{
+		Name:       opListBuckets,
+		HTTPMethod: "GET",
+		HTTPPath:   "/",
+	}
+
+	if input == nil {
+		input = &ListBucketsInput{}
+	}
+
+	output = &ListBucketsOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// ListBuckets API operation for Amazon Simple Storage Service.
+//
+// Returns a list of all buckets owned by the authenticated sender of the request.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation ListBuckets for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListBuckets
+func (c *S3) ListBuckets(input *ListBucketsInput) (*ListBucketsOutput, error) {
+	req, out := c.ListBucketsRequest(input)
+	return out, req.Send()
+}
+
+// ListBucketsWithContext is the same as ListBuckets with the addition of
+// the ability to pass a context and additional request options.
+//
+// See ListBuckets for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) ListBucketsWithContext(ctx aws.Context, input *ListBucketsInput, opts ...request.Option) (*ListBucketsOutput, error) {
+	req, out := c.ListBucketsRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opListMultipartUploads = "ListMultipartUploads"
+
+// ListMultipartUploadsRequest generates a "aws/request.Request" representing the
+// client's request for the ListMultipartUploads operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See ListMultipartUploads for more information on using the ListMultipartUploads
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the ListMultipartUploadsRequest method.
+//    req, resp := client.ListMultipartUploadsRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListMultipartUploads
+func (c *S3) ListMultipartUploadsRequest(input *ListMultipartUploadsInput) (req *request.Request, output *ListMultipartUploadsOutput) {
+	op := &request.Operation{
+		Name:       opListMultipartUploads,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?uploads",
+		Paginator: &request.Paginator{
+			InputTokens:     []string{"KeyMarker", "UploadIdMarker"},
+			OutputTokens:    []string{"NextKeyMarker", "NextUploadIdMarker"},
+			LimitToken:      "MaxUploads",
+			TruncationToken: "IsTruncated",
+		},
+	}
+
+	if input == nil {
+		input = &ListMultipartUploadsInput{}
+	}
+
+	output = &ListMultipartUploadsOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// ListMultipartUploads API operation for Amazon Simple Storage Service.
+//
+// This operation lists in-progress multipart uploads.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation ListMultipartUploads for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListMultipartUploads
+func (c *S3) ListMultipartUploads(input *ListMultipartUploadsInput) (*ListMultipartUploadsOutput, error) {
+	req, out := c.ListMultipartUploadsRequest(input)
+	return out, req.Send()
+}
+
+// ListMultipartUploadsWithContext is the same as ListMultipartUploads with the addition of
+// the ability to pass a context and additional request options.
+//
+// See ListMultipartUploads for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) ListMultipartUploadsWithContext(ctx aws.Context, input *ListMultipartUploadsInput, opts ...request.Option) (*ListMultipartUploadsOutput, error) {
+	req, out := c.ListMultipartUploadsRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+// ListMultipartUploadsPages iterates over the pages of a ListMultipartUploads operation,
+// calling the "fn" function with the response data for each page. To stop
+// iterating, return false from the fn function.
+//
+// See ListMultipartUploads method for more information on how to use this operation.
+//
+// Note: This operation can generate multiple requests to a service.
+//
+//    // Example iterating over at most 3 pages of a ListMultipartUploads operation.
+//    pageNum := 0
+//    err := client.ListMultipartUploadsPages(params,
+//        func(page *ListMultipartUploadsOutput, lastPage bool) bool {
+//            pageNum++
+//            fmt.Println(page)
+//            return pageNum <= 3
+//        })
+//
+func (c *S3) ListMultipartUploadsPages(input *ListMultipartUploadsInput, fn func(*ListMultipartUploadsOutput, bool) bool) error {
+	return c.ListMultipartUploadsPagesWithContext(aws.BackgroundContext(), input, fn)
+}
+
+// ListMultipartUploadsPagesWithContext same as ListMultipartUploadsPages except
+// it takes a Context and allows setting request options on the pages.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) ListMultipartUploadsPagesWithContext(ctx aws.Context, input *ListMultipartUploadsInput, fn func(*ListMultipartUploadsOutput, bool) bool, opts ...request.Option) error {
+	p := request.Pagination{
+		NewRequest: func() (*request.Request, error) {
+			var inCpy *ListMultipartUploadsInput
+			if input != nil {
+				tmp := *input
+				inCpy = &tmp
+			}
+			req, _ := c.ListMultipartUploadsRequest(inCpy)
+			req.SetContext(ctx)
+			req.ApplyOptions(opts...)
+			return req, nil
+		},
+	}
+
+	cont := true
+	for p.Next() && cont {
+		cont = fn(p.Page().(*ListMultipartUploadsOutput), !p.HasNextPage())
+	}
+	return p.Err()
+}
+
+const opListObjectVersions = "ListObjectVersions"
+
+// ListObjectVersionsRequest generates a "aws/request.Request" representing the
+// client's request for the ListObjectVersions operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See ListObjectVersions for more information on using the ListObjectVersions
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the ListObjectVersionsRequest method.
+//    req, resp := client.ListObjectVersionsRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectVersions
+func (c *S3) ListObjectVersionsRequest(input *ListObjectVersionsInput) (req *request.Request, output *ListObjectVersionsOutput) {
+	op := &request.Operation{
+		Name:       opListObjectVersions,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?versions",
+		Paginator: &request.Paginator{
+			InputTokens:     []string{"KeyMarker", "VersionIdMarker"},
+			OutputTokens:    []string{"NextKeyMarker", "NextVersionIdMarker"},
+			LimitToken:      "MaxKeys",
+			TruncationToken: "IsTruncated",
+		},
+	}
+
+	if input == nil {
+		input = &ListObjectVersionsInput{}
+	}
+
+	output = &ListObjectVersionsOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// ListObjectVersions API operation for Amazon Simple Storage Service.
+//
+// Returns metadata about all of the versions of objects in a bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation ListObjectVersions for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectVersions
+func (c *S3) ListObjectVersions(input *ListObjectVersionsInput) (*ListObjectVersionsOutput, error) {
+	req, out := c.ListObjectVersionsRequest(input)
+	return out, req.Send()
+}
+
+// ListObjectVersionsWithContext is the same as ListObjectVersions with the addition of
+// the ability to pass a context and additional request options.
+//
+// See ListObjectVersions for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) ListObjectVersionsWithContext(ctx aws.Context, input *ListObjectVersionsInput, opts ...request.Option) (*ListObjectVersionsOutput, error) {
+	req, out := c.ListObjectVersionsRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+// ListObjectVersionsPages iterates over the pages of a ListObjectVersions operation,
+// calling the "fn" function with the response data for each page. To stop
+// iterating, return false from the fn function.
+//
+// See ListObjectVersions method for more information on how to use this operation.
+//
+// Note: This operation can generate multiple requests to a service.
+//
+//    // Example iterating over at most 3 pages of a ListObjectVersions operation.
+//    pageNum := 0
+//    err := client.ListObjectVersionsPages(params,
+//        func(page *ListObjectVersionsOutput, lastPage bool) bool {
+//            pageNum++
+//            fmt.Println(page)
+//            return pageNum <= 3
+//        })
+//
+func (c *S3) ListObjectVersionsPages(input *ListObjectVersionsInput, fn func(*ListObjectVersionsOutput, bool) bool) error {
+	return c.ListObjectVersionsPagesWithContext(aws.BackgroundContext(), input, fn)
+}
+
+// ListObjectVersionsPagesWithContext same as ListObjectVersionsPages except
+// it takes a Context and allows setting request options on the pages.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) ListObjectVersionsPagesWithContext(ctx aws.Context, input *ListObjectVersionsInput, fn func(*ListObjectVersionsOutput, bool) bool, opts ...request.Option) error {
+	p := request.Pagination{
+		NewRequest: func() (*request.Request, error) {
+			var inCpy *ListObjectVersionsInput
+			if input != nil {
+				tmp := *input
+				inCpy = &tmp
+			}
+			req, _ := c.ListObjectVersionsRequest(inCpy)
+			req.SetContext(ctx)
+			req.ApplyOptions(opts...)
+			return req, nil
+		},
+	}
+
+	cont := true
+	for p.Next() && cont {
+		cont = fn(p.Page().(*ListObjectVersionsOutput), !p.HasNextPage())
+	}
+	return p.Err()
+}
+
+const opListObjects = "ListObjects"
+
+// ListObjectsRequest generates a "aws/request.Request" representing the
+// client's request for the ListObjects operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See ListObjects for more information on using the ListObjects
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the ListObjectsRequest method.
+//    req, resp := client.ListObjectsRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjects
+func (c *S3) ListObjectsRequest(input *ListObjectsInput) (req *request.Request, output *ListObjectsOutput) {
+	op := &request.Operation{
+		Name:       opListObjects,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}",
+		Paginator: &request.Paginator{
+			InputTokens:     []string{"Marker"},
+			OutputTokens:    []string{"NextMarker || Contents[-1].Key"},
+			LimitToken:      "MaxKeys",
+			TruncationToken: "IsTruncated",
+		},
+	}
+
+	if input == nil {
+		input = &ListObjectsInput{}
+	}
+
+	output = &ListObjectsOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// ListObjects API operation for Amazon Simple Storage Service.
+//
+// Returns some or all (up to 1000) of the objects in a bucket. You can use
+// the request parameters as selection criteria to return a subset of the objects
+// in a bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation ListObjects for usage and error information.
+//
+// Returned Error Codes:
+//   * ErrCodeNoSuchBucket "NoSuchBucket"
+//   The specified bucket does not exist.
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjects
+func (c *S3) ListObjects(input *ListObjectsInput) (*ListObjectsOutput, error) {
+	req, out := c.ListObjectsRequest(input)
+	return out, req.Send()
+}
+
+// ListObjectsWithContext is the same as ListObjects with the addition of
+// the ability to pass a context and additional request options.
+//
+// See ListObjects for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) ListObjectsWithContext(ctx aws.Context, input *ListObjectsInput, opts ...request.Option) (*ListObjectsOutput, error) {
+	req, out := c.ListObjectsRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+// ListObjectsPages iterates over the pages of a ListObjects operation,
+// calling the "fn" function with the response data for each page. To stop
+// iterating, return false from the fn function.
+//
+// See ListObjects method for more information on how to use this operation.
+//
+// Note: This operation can generate multiple requests to a service.
+//
+//    // Example iterating over at most 3 pages of a ListObjects operation.
+//    pageNum := 0
+//    err := client.ListObjectsPages(params,
+//        func(page *ListObjectsOutput, lastPage bool) bool {
+//            pageNum++
+//            fmt.Println(page)
+//            return pageNum <= 3
+//        })
+//
+func (c *S3) ListObjectsPages(input *ListObjectsInput, fn func(*ListObjectsOutput, bool) bool) error {
+	return c.ListObjectsPagesWithContext(aws.BackgroundContext(), input, fn)
+}
+
+// ListObjectsPagesWithContext same as ListObjectsPages except
+// it takes a Context and allows setting request options on the pages.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) ListObjectsPagesWithContext(ctx aws.Context, input *ListObjectsInput, fn func(*ListObjectsOutput, bool) bool, opts ...request.Option) error {
+	p := request.Pagination{
+		NewRequest: func() (*request.Request, error) {
+			var inCpy *ListObjectsInput
+			if input != nil {
+				tmp := *input
+				inCpy = &tmp
+			}
+			req, _ := c.ListObjectsRequest(inCpy)
+			req.SetContext(ctx)
+			req.ApplyOptions(opts...)
+			return req, nil
+		},
+	}
+
+	cont := true
+	for p.Next() && cont {
+		cont = fn(p.Page().(*ListObjectsOutput), !p.HasNextPage())
+	}
+	return p.Err()
+}
+
+const opListObjectsV2 = "ListObjectsV2"
+
+// ListObjectsV2Request generates a "aws/request.Request" representing the
+// client's request for the ListObjectsV2 operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See ListObjectsV2 for more information on using the ListObjectsV2
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the ListObjectsV2Request method.
+//    req, resp := client.ListObjectsV2Request(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectsV2
+func (c *S3) ListObjectsV2Request(input *ListObjectsV2Input) (req *request.Request, output *ListObjectsV2Output) {
+	op := &request.Operation{
+		Name:       opListObjectsV2,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}?list-type=2",
+		Paginator: &request.Paginator{
+			InputTokens:     []string{"ContinuationToken"},
+			OutputTokens:    []string{"NextContinuationToken"},
+			LimitToken:      "MaxKeys",
+			TruncationToken: "",
+		},
+	}
+
+	if input == nil {
+		input = &ListObjectsV2Input{}
+	}
+
+	output = &ListObjectsV2Output{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// ListObjectsV2 API operation for Amazon Simple Storage Service.
+//
+// Returns some or all (up to 1000) of the objects in a bucket. You can use
+// the request parameters as selection criteria to return a subset of the objects
+// in a bucket. Note: ListObjectsV2 is the revised List Objects API and we recommend
+// you use this revised API for new application development.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation ListObjectsV2 for usage and error information.
+//
+// Returned Error Codes:
+//   * ErrCodeNoSuchBucket "NoSuchBucket"
+//   The specified bucket does not exist.
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListObjectsV2
+func (c *S3) ListObjectsV2(input *ListObjectsV2Input) (*ListObjectsV2Output, error) {
+	req, out := c.ListObjectsV2Request(input)
+	return out, req.Send()
+}
+
+// ListObjectsV2WithContext is the same as ListObjectsV2 with the addition of
+// the ability to pass a context and additional request options.
+//
+// See ListObjectsV2 for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) ListObjectsV2WithContext(ctx aws.Context, input *ListObjectsV2Input, opts ...request.Option) (*ListObjectsV2Output, error) {
+	req, out := c.ListObjectsV2Request(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+// ListObjectsV2Pages iterates over the pages of a ListObjectsV2 operation,
+// calling the "fn" function with the response data for each page. To stop
+// iterating, return false from the fn function.
+//
+// See ListObjectsV2 method for more information on how to use this operation.
+//
+// Note: This operation can generate multiple requests to a service.
+//
+//    // Example iterating over at most 3 pages of a ListObjectsV2 operation.
+//    pageNum := 0
+//    err := client.ListObjectsV2Pages(params,
+//        func(page *ListObjectsV2Output, lastPage bool) bool {
+//            pageNum++
+//            fmt.Println(page)
+//            return pageNum <= 3
+//        })
+//
+func (c *S3) ListObjectsV2Pages(input *ListObjectsV2Input, fn func(*ListObjectsV2Output, bool) bool) error {
+	return c.ListObjectsV2PagesWithContext(aws.BackgroundContext(), input, fn)
+}
+
+// ListObjectsV2PagesWithContext same as ListObjectsV2Pages except
+// it takes a Context and allows setting request options on the pages.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) ListObjectsV2PagesWithContext(ctx aws.Context, input *ListObjectsV2Input, fn func(*ListObjectsV2Output, bool) bool, opts ...request.Option) error {
+	p := request.Pagination{
+		NewRequest: func() (*request.Request, error) {
+			var inCpy *ListObjectsV2Input
+			if input != nil {
+				tmp := *input
+				inCpy = &tmp
+			}
+			req, _ := c.ListObjectsV2Request(inCpy)
+			req.SetContext(ctx)
+			req.ApplyOptions(opts...)
+			return req, nil
+		},
+	}
+
+	cont := true
+	for p.Next() && cont {
+		cont = fn(p.Page().(*ListObjectsV2Output), !p.HasNextPage())
+	}
+	return p.Err()
+}
+
+const opListParts = "ListParts"
+
+// ListPartsRequest generates a "aws/request.Request" representing the
+// client's request for the ListParts operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See ListParts for more information on using the ListParts
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the ListPartsRequest method.
+//    req, resp := client.ListPartsRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListParts
+func (c *S3) ListPartsRequest(input *ListPartsInput) (req *request.Request, output *ListPartsOutput) {
+	op := &request.Operation{
+		Name:       opListParts,
+		HTTPMethod: "GET",
+		HTTPPath:   "/{Bucket}/{Key+}",
+		Paginator: &request.Paginator{
+			InputTokens:     []string{"PartNumberMarker"},
+			OutputTokens:    []string{"NextPartNumberMarker"},
+			LimitToken:      "MaxParts",
+			TruncationToken: "IsTruncated",
+		},
+	}
+
+	if input == nil {
+		input = &ListPartsInput{}
+	}
+
+	output = &ListPartsOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// ListParts API operation for Amazon Simple Storage Service.
+//
+// Lists the parts that have been uploaded for a specific multipart upload.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation ListParts for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/ListParts
+func (c *S3) ListParts(input *ListPartsInput) (*ListPartsOutput, error) {
+	req, out := c.ListPartsRequest(input)
+	return out, req.Send()
+}
+
+// ListPartsWithContext is the same as ListParts with the addition of
+// the ability to pass a context and additional request options.
+//
+// See ListParts for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) ListPartsWithContext(ctx aws.Context, input *ListPartsInput, opts ...request.Option) (*ListPartsOutput, error) {
+	req, out := c.ListPartsRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+// ListPartsPages iterates over the pages of a ListParts operation,
+// calling the "fn" function with the response data for each page. To stop
+// iterating, return false from the fn function.
+//
+// See ListParts method for more information on how to use this operation.
+//
+// Note: This operation can generate multiple requests to a service.
+//
+//    // Example iterating over at most 3 pages of a ListParts operation.
+//    pageNum := 0
+//    err := client.ListPartsPages(params,
+//        func(page *ListPartsOutput, lastPage bool) bool {
+//            pageNum++
+//            fmt.Println(page)
+//            return pageNum <= 3
+//        })
+//
+func (c *S3) ListPartsPages(input *ListPartsInput, fn func(*ListPartsOutput, bool) bool) error {
+	return c.ListPartsPagesWithContext(aws.BackgroundContext(), input, fn)
+}
+
+// ListPartsPagesWithContext same as ListPartsPages except
+// it takes a Context and allows setting request options on the pages.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) ListPartsPagesWithContext(ctx aws.Context, input *ListPartsInput, fn func(*ListPartsOutput, bool) bool, opts ...request.Option) error {
+	p := request.Pagination{
+		NewRequest: func() (*request.Request, error) {
+			var inCpy *ListPartsInput
+			if input != nil {
+				tmp := *input
+				inCpy = &tmp
+			}
+			req, _ := c.ListPartsRequest(inCpy)
+			req.SetContext(ctx)
+			req.ApplyOptions(opts...)
+			return req, nil
+		},
+	}
+
+	cont := true
+	for p.Next() && cont {
+		cont = fn(p.Page().(*ListPartsOutput), !p.HasNextPage())
+	}
+	return p.Err()
+}
+
+const opPutBucketAccelerateConfiguration = "PutBucketAccelerateConfiguration"
+
+// PutBucketAccelerateConfigurationRequest generates a "aws/request.Request" representing the
+// client's request for the PutBucketAccelerateConfiguration operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See PutBucketAccelerateConfiguration for more information on using the PutBucketAccelerateConfiguration
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the PutBucketAccelerateConfigurationRequest method.
+//    req, resp := client.PutBucketAccelerateConfigurationRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAccelerateConfiguration
+func (c *S3) PutBucketAccelerateConfigurationRequest(input *PutBucketAccelerateConfigurationInput) (req *request.Request, output *PutBucketAccelerateConfigurationOutput) {
+	op := &request.Operation{
+		Name:       opPutBucketAccelerateConfiguration,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}?accelerate",
+	}
+
+	if input == nil {
+		input = &PutBucketAccelerateConfigurationInput{}
+	}
+
+	output = &PutBucketAccelerateConfigurationOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// PutBucketAccelerateConfiguration API operation for Amazon Simple Storage Service.
+//
+// Sets the accelerate configuration of an existing bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation PutBucketAccelerateConfiguration for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAccelerateConfiguration
+func (c *S3) PutBucketAccelerateConfiguration(input *PutBucketAccelerateConfigurationInput) (*PutBucketAccelerateConfigurationOutput, error) {
+	req, out := c.PutBucketAccelerateConfigurationRequest(input)
+	return out, req.Send()
+}
+
+// PutBucketAccelerateConfigurationWithContext is the same as PutBucketAccelerateConfiguration with the addition of
+// the ability to pass a context and additional request options.
+//
+// See PutBucketAccelerateConfiguration for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) PutBucketAccelerateConfigurationWithContext(ctx aws.Context, input *PutBucketAccelerateConfigurationInput, opts ...request.Option) (*PutBucketAccelerateConfigurationOutput, error) {
+	req, out := c.PutBucketAccelerateConfigurationRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opPutBucketAcl = "PutBucketAcl"
+
+// PutBucketAclRequest generates a "aws/request.Request" representing the
+// client's request for the PutBucketAcl operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See PutBucketAcl for more information on using the PutBucketAcl
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the PutBucketAclRequest method.
+//    req, resp := client.PutBucketAclRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAcl
+func (c *S3) PutBucketAclRequest(input *PutBucketAclInput) (req *request.Request, output *PutBucketAclOutput) {
+	op := &request.Operation{
+		Name:       opPutBucketAcl,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}?acl",
+	}
+
+	if input == nil {
+		input = &PutBucketAclInput{}
+	}
+
+	output = &PutBucketAclOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// PutBucketAcl API operation for Amazon Simple Storage Service.
+//
+// Sets the permissions on a bucket using access control lists (ACL).
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation PutBucketAcl for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAcl
+func (c *S3) PutBucketAcl(input *PutBucketAclInput) (*PutBucketAclOutput, error) {
+	req, out := c.PutBucketAclRequest(input)
+	return out, req.Send()
+}
+
+// PutBucketAclWithContext is the same as PutBucketAcl with the addition of
+// the ability to pass a context and additional request options.
+//
+// See PutBucketAcl for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) PutBucketAclWithContext(ctx aws.Context, input *PutBucketAclInput, opts ...request.Option) (*PutBucketAclOutput, error) {
+	req, out := c.PutBucketAclRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opPutBucketAnalyticsConfiguration = "PutBucketAnalyticsConfiguration"
+
+// PutBucketAnalyticsConfigurationRequest generates a "aws/request.Request" representing the
+// client's request for the PutBucketAnalyticsConfiguration operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See PutBucketAnalyticsConfiguration for more information on using the PutBucketAnalyticsConfiguration
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the PutBucketAnalyticsConfigurationRequest method.
+//    req, resp := client.PutBucketAnalyticsConfigurationRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAnalyticsConfiguration
+func (c *S3) PutBucketAnalyticsConfigurationRequest(input *PutBucketAnalyticsConfigurationInput) (req *request.Request, output *PutBucketAnalyticsConfigurationOutput) {
+	op := &request.Operation{
+		Name:       opPutBucketAnalyticsConfiguration,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}?analytics",
+	}
+
+	if input == nil {
+		input = &PutBucketAnalyticsConfigurationInput{}
+	}
+
+	output = &PutBucketAnalyticsConfigurationOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// PutBucketAnalyticsConfiguration API operation for Amazon Simple Storage Service.
+//
+// Sets an analytics configuration for the bucket (specified by the analytics
+// configuration ID).
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation PutBucketAnalyticsConfiguration for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketAnalyticsConfiguration
+func (c *S3) PutBucketAnalyticsConfiguration(input *PutBucketAnalyticsConfigurationInput) (*PutBucketAnalyticsConfigurationOutput, error) {
+	req, out := c.PutBucketAnalyticsConfigurationRequest(input)
+	return out, req.Send()
+}
+
+// PutBucketAnalyticsConfigurationWithContext is the same as PutBucketAnalyticsConfiguration with the addition of
+// the ability to pass a context and additional request options.
+//
+// See PutBucketAnalyticsConfiguration for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) PutBucketAnalyticsConfigurationWithContext(ctx aws.Context, input *PutBucketAnalyticsConfigurationInput, opts ...request.Option) (*PutBucketAnalyticsConfigurationOutput, error) {
+	req, out := c.PutBucketAnalyticsConfigurationRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opPutBucketCors = "PutBucketCors"
+
+// PutBucketCorsRequest generates a "aws/request.Request" representing the
+// client's request for the PutBucketCors operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See PutBucketCors for more information on using the PutBucketCors
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the PutBucketCorsRequest method.
+//    req, resp := client.PutBucketCorsRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketCors
+func (c *S3) PutBucketCorsRequest(input *PutBucketCorsInput) (req *request.Request, output *PutBucketCorsOutput) {
+	op := &request.Operation{
+		Name:       opPutBucketCors,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}?cors",
+	}
+
+	if input == nil {
+		input = &PutBucketCorsInput{}
+	}
+
+	output = &PutBucketCorsOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// PutBucketCors API operation for Amazon Simple Storage Service.
+//
+// Sets the cors configuration for a bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation PutBucketCors for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketCors
+func (c *S3) PutBucketCors(input *PutBucketCorsInput) (*PutBucketCorsOutput, error) {
+	req, out := c.PutBucketCorsRequest(input)
+	return out, req.Send()
+}
+
+// PutBucketCorsWithContext is the same as PutBucketCors with the addition of
+// the ability to pass a context and additional request options.
+//
+// See PutBucketCors for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) PutBucketCorsWithContext(ctx aws.Context, input *PutBucketCorsInput, opts ...request.Option) (*PutBucketCorsOutput, error) {
+	req, out := c.PutBucketCorsRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opPutBucketEncryption = "PutBucketEncryption"
+
+// PutBucketEncryptionRequest generates a "aws/request.Request" representing the
+// client's request for the PutBucketEncryption operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See PutBucketEncryption for more information on using the PutBucketEncryption
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the PutBucketEncryptionRequest method.
+//    req, resp := client.PutBucketEncryptionRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketEncryption
+func (c *S3) PutBucketEncryptionRequest(input *PutBucketEncryptionInput) (req *request.Request, output *PutBucketEncryptionOutput) {
+	op := &request.Operation{
+		Name:       opPutBucketEncryption,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}?encryption",
+	}
+
+	if input == nil {
+		input = &PutBucketEncryptionInput{}
+	}
+
+	output = &PutBucketEncryptionOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// PutBucketEncryption API operation for Amazon Simple Storage Service.
+//
+// Creates a new server-side encryption configuration (or replaces an existing
+// one, if present).
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation PutBucketEncryption for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketEncryption
+func (c *S3) PutBucketEncryption(input *PutBucketEncryptionInput) (*PutBucketEncryptionOutput, error) {
+	req, out := c.PutBucketEncryptionRequest(input)
+	return out, req.Send()
+}
+
+// PutBucketEncryptionWithContext is the same as PutBucketEncryption with the addition of
+// the ability to pass a context and additional request options.
+//
+// See PutBucketEncryption for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) PutBucketEncryptionWithContext(ctx aws.Context, input *PutBucketEncryptionInput, opts ...request.Option) (*PutBucketEncryptionOutput, error) {
+	req, out := c.PutBucketEncryptionRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opPutBucketInventoryConfiguration = "PutBucketInventoryConfiguration"
+
+// PutBucketInventoryConfigurationRequest generates a "aws/request.Request" representing the
+// client's request for the PutBucketInventoryConfiguration operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See PutBucketInventoryConfiguration for more information on using the PutBucketInventoryConfiguration
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the PutBucketInventoryConfigurationRequest method.
+//    req, resp := client.PutBucketInventoryConfigurationRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketInventoryConfiguration
+func (c *S3) PutBucketInventoryConfigurationRequest(input *PutBucketInventoryConfigurationInput) (req *request.Request, output *PutBucketInventoryConfigurationOutput) {
+	op := &request.Operation{
+		Name:       opPutBucketInventoryConfiguration,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}?inventory",
+	}
+
+	if input == nil {
+		input = &PutBucketInventoryConfigurationInput{}
+	}
+
+	output = &PutBucketInventoryConfigurationOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// PutBucketInventoryConfiguration API operation for Amazon Simple Storage Service.
+//
+// Adds an inventory configuration (identified by the inventory ID) from the
+// bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation PutBucketInventoryConfiguration for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketInventoryConfiguration
+func (c *S3) PutBucketInventoryConfiguration(input *PutBucketInventoryConfigurationInput) (*PutBucketInventoryConfigurationOutput, error) {
+	req, out := c.PutBucketInventoryConfigurationRequest(input)
+	return out, req.Send()
+}
+
+// PutBucketInventoryConfigurationWithContext is the same as PutBucketInventoryConfiguration with the addition of
+// the ability to pass a context and additional request options.
+//
+// See PutBucketInventoryConfiguration for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) PutBucketInventoryConfigurationWithContext(ctx aws.Context, input *PutBucketInventoryConfigurationInput, opts ...request.Option) (*PutBucketInventoryConfigurationOutput, error) {
+	req, out := c.PutBucketInventoryConfigurationRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opPutBucketLifecycle = "PutBucketLifecycle"
+
+// PutBucketLifecycleRequest generates a "aws/request.Request" representing the
+// client's request for the PutBucketLifecycle operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See PutBucketLifecycle for more information on using the PutBucketLifecycle
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the PutBucketLifecycleRequest method.
+//    req, resp := client.PutBucketLifecycleRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycle
+func (c *S3) PutBucketLifecycleRequest(input *PutBucketLifecycleInput) (req *request.Request, output *PutBucketLifecycleOutput) {
+	if c.Client.Config.Logger != nil {
+		c.Client.Config.Logger.Log("This operation, PutBucketLifecycle, has been deprecated")
+	}
+	op := &request.Operation{
+		Name:       opPutBucketLifecycle,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}?lifecycle",
+	}
+
+	if input == nil {
+		input = &PutBucketLifecycleInput{}
+	}
+
+	output = &PutBucketLifecycleOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// PutBucketLifecycle API operation for Amazon Simple Storage Service.
+//
+// Deprecated, see the PutBucketLifecycleConfiguration operation.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation PutBucketLifecycle for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycle
+func (c *S3) PutBucketLifecycle(input *PutBucketLifecycleInput) (*PutBucketLifecycleOutput, error) {
+	req, out := c.PutBucketLifecycleRequest(input)
+	return out, req.Send()
+}
+
+// PutBucketLifecycleWithContext is the same as PutBucketLifecycle with the addition of
+// the ability to pass a context and additional request options.
+//
+// See PutBucketLifecycle for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) PutBucketLifecycleWithContext(ctx aws.Context, input *PutBucketLifecycleInput, opts ...request.Option) (*PutBucketLifecycleOutput, error) {
+	req, out := c.PutBucketLifecycleRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opPutBucketLifecycleConfiguration = "PutBucketLifecycleConfiguration"
+
+// PutBucketLifecycleConfigurationRequest generates a "aws/request.Request" representing the
+// client's request for the PutBucketLifecycleConfiguration operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See PutBucketLifecycleConfiguration for more information on using the PutBucketLifecycleConfiguration
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the PutBucketLifecycleConfigurationRequest method.
+//    req, resp := client.PutBucketLifecycleConfigurationRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycleConfiguration
+func (c *S3) PutBucketLifecycleConfigurationRequest(input *PutBucketLifecycleConfigurationInput) (req *request.Request, output *PutBucketLifecycleConfigurationOutput) {
+	op := &request.Operation{
+		Name:       opPutBucketLifecycleConfiguration,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}?lifecycle",
+	}
+
+	if input == nil {
+		input = &PutBucketLifecycleConfigurationInput{}
+	}
+
+	output = &PutBucketLifecycleConfigurationOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// PutBucketLifecycleConfiguration API operation for Amazon Simple Storage Service.
+//
+// Sets lifecycle configuration for your bucket. If a lifecycle configuration
+// exists, it replaces it.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation PutBucketLifecycleConfiguration for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLifecycleConfiguration
+func (c *S3) PutBucketLifecycleConfiguration(input *PutBucketLifecycleConfigurationInput) (*PutBucketLifecycleConfigurationOutput, error) {
+	req, out := c.PutBucketLifecycleConfigurationRequest(input)
+	return out, req.Send()
+}
+
+// PutBucketLifecycleConfigurationWithContext is the same as PutBucketLifecycleConfiguration with the addition of
+// the ability to pass a context and additional request options.
+//
+// See PutBucketLifecycleConfiguration for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) PutBucketLifecycleConfigurationWithContext(ctx aws.Context, input *PutBucketLifecycleConfigurationInput, opts ...request.Option) (*PutBucketLifecycleConfigurationOutput, error) {
+	req, out := c.PutBucketLifecycleConfigurationRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opPutBucketLogging = "PutBucketLogging"
+
+// PutBucketLoggingRequest generates a "aws/request.Request" representing the
+// client's request for the PutBucketLogging operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See PutBucketLogging for more information on using the PutBucketLogging
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the PutBucketLoggingRequest method.
+//    req, resp := client.PutBucketLoggingRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLogging
+func (c *S3) PutBucketLoggingRequest(input *PutBucketLoggingInput) (req *request.Request, output *PutBucketLoggingOutput) {
+	op := &request.Operation{
+		Name:       opPutBucketLogging,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}?logging",
+	}
+
+	if input == nil {
+		input = &PutBucketLoggingInput{}
+	}
+
+	output = &PutBucketLoggingOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// PutBucketLogging API operation for Amazon Simple Storage Service.
+//
+// Set the logging parameters for a bucket and to specify permissions for who
+// can view and modify the logging parameters. To set the logging status of
+// a bucket, you must be the bucket owner.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation PutBucketLogging for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketLogging
+func (c *S3) PutBucketLogging(input *PutBucketLoggingInput) (*PutBucketLoggingOutput, error) {
+	req, out := c.PutBucketLoggingRequest(input)
+	return out, req.Send()
+}
+
+// PutBucketLoggingWithContext is the same as PutBucketLogging with the addition of
+// the ability to pass a context and additional request options.
+//
+// See PutBucketLogging for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) PutBucketLoggingWithContext(ctx aws.Context, input *PutBucketLoggingInput, opts ...request.Option) (*PutBucketLoggingOutput, error) {
+	req, out := c.PutBucketLoggingRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opPutBucketMetricsConfiguration = "PutBucketMetricsConfiguration"
+
+// PutBucketMetricsConfigurationRequest generates a "aws/request.Request" representing the
+// client's request for the PutBucketMetricsConfiguration operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See PutBucketMetricsConfiguration for more information on using the PutBucketMetricsConfiguration
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the PutBucketMetricsConfigurationRequest method.
+//    req, resp := client.PutBucketMetricsConfigurationRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketMetricsConfiguration
+func (c *S3) PutBucketMetricsConfigurationRequest(input *PutBucketMetricsConfigurationInput) (req *request.Request, output *PutBucketMetricsConfigurationOutput) {
+	op := &request.Operation{
+		Name:       opPutBucketMetricsConfiguration,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}?metrics",
+	}
+
+	if input == nil {
+		input = &PutBucketMetricsConfigurationInput{}
+	}
+
+	output = &PutBucketMetricsConfigurationOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// PutBucketMetricsConfiguration API operation for Amazon Simple Storage Service.
+//
+// Sets a metrics configuration (specified by the metrics configuration ID)
+// for the bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation PutBucketMetricsConfiguration for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketMetricsConfiguration
+func (c *S3) PutBucketMetricsConfiguration(input *PutBucketMetricsConfigurationInput) (*PutBucketMetricsConfigurationOutput, error) {
+	req, out := c.PutBucketMetricsConfigurationRequest(input)
+	return out, req.Send()
+}
+
+// PutBucketMetricsConfigurationWithContext is the same as PutBucketMetricsConfiguration with the addition of
+// the ability to pass a context and additional request options.
+//
+// See PutBucketMetricsConfiguration for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) PutBucketMetricsConfigurationWithContext(ctx aws.Context, input *PutBucketMetricsConfigurationInput, opts ...request.Option) (*PutBucketMetricsConfigurationOutput, error) {
+	req, out := c.PutBucketMetricsConfigurationRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opPutBucketNotification = "PutBucketNotification"
+
+// PutBucketNotificationRequest generates a "aws/request.Request" representing the
+// client's request for the PutBucketNotification operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See PutBucketNotification for more information on using the PutBucketNotification
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the PutBucketNotificationRequest method.
+//    req, resp := client.PutBucketNotificationRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotification
+func (c *S3) PutBucketNotificationRequest(input *PutBucketNotificationInput) (req *request.Request, output *PutBucketNotificationOutput) {
+	if c.Client.Config.Logger != nil {
+		c.Client.Config.Logger.Log("This operation, PutBucketNotification, has been deprecated")
+	}
+	op := &request.Operation{
+		Name:       opPutBucketNotification,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}?notification",
+	}
+
+	if input == nil {
+		input = &PutBucketNotificationInput{}
+	}
+
+	output = &PutBucketNotificationOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// PutBucketNotification API operation for Amazon Simple Storage Service.
+//
+// Deprecated, see the PutBucketNotificationConfiguraiton operation.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation PutBucketNotification for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotification
+func (c *S3) PutBucketNotification(input *PutBucketNotificationInput) (*PutBucketNotificationOutput, error) {
+	req, out := c.PutBucketNotificationRequest(input)
+	return out, req.Send()
+}
+
+// PutBucketNotificationWithContext is the same as PutBucketNotification with the addition of
+// the ability to pass a context and additional request options.
+//
+// See PutBucketNotification for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) PutBucketNotificationWithContext(ctx aws.Context, input *PutBucketNotificationInput, opts ...request.Option) (*PutBucketNotificationOutput, error) {
+	req, out := c.PutBucketNotificationRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opPutBucketNotificationConfiguration = "PutBucketNotificationConfiguration"
+
+// PutBucketNotificationConfigurationRequest generates a "aws/request.Request" representing the
+// client's request for the PutBucketNotificationConfiguration operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See PutBucketNotificationConfiguration for more information on using the PutBucketNotificationConfiguration
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the PutBucketNotificationConfigurationRequest method.
+//    req, resp := client.PutBucketNotificationConfigurationRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotificationConfiguration
+func (c *S3) PutBucketNotificationConfigurationRequest(input *PutBucketNotificationConfigurationInput) (req *request.Request, output *PutBucketNotificationConfigurationOutput) {
+	op := &request.Operation{
+		Name:       opPutBucketNotificationConfiguration,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}?notification",
+	}
+
+	if input == nil {
+		input = &PutBucketNotificationConfigurationInput{}
+	}
+
+	output = &PutBucketNotificationConfigurationOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// PutBucketNotificationConfiguration API operation for Amazon Simple Storage Service.
+//
+// Enables notifications of specified events for a bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation PutBucketNotificationConfiguration for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketNotificationConfiguration
+func (c *S3) PutBucketNotificationConfiguration(input *PutBucketNotificationConfigurationInput) (*PutBucketNotificationConfigurationOutput, error) {
+	req, out := c.PutBucketNotificationConfigurationRequest(input)
+	return out, req.Send()
+}
+
+// PutBucketNotificationConfigurationWithContext is the same as PutBucketNotificationConfiguration with the addition of
+// the ability to pass a context and additional request options.
+//
+// See PutBucketNotificationConfiguration for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) PutBucketNotificationConfigurationWithContext(ctx aws.Context, input *PutBucketNotificationConfigurationInput, opts ...request.Option) (*PutBucketNotificationConfigurationOutput, error) {
+	req, out := c.PutBucketNotificationConfigurationRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opPutBucketPolicy = "PutBucketPolicy"
+
+// PutBucketPolicyRequest generates a "aws/request.Request" representing the
+// client's request for the PutBucketPolicy operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See PutBucketPolicy for more information on using the PutBucketPolicy
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the PutBucketPolicyRequest method.
+//    req, resp := client.PutBucketPolicyRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketPolicy
+func (c *S3) PutBucketPolicyRequest(input *PutBucketPolicyInput) (req *request.Request, output *PutBucketPolicyOutput) {
+	op := &request.Operation{
+		Name:       opPutBucketPolicy,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}?policy",
+	}
+
+	if input == nil {
+		input = &PutBucketPolicyInput{}
+	}
+
+	output = &PutBucketPolicyOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// PutBucketPolicy API operation for Amazon Simple Storage Service.
+//
+// Replaces a policy on a bucket. If the bucket already has a policy, the one
+// in this request completely replaces it.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation PutBucketPolicy for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketPolicy
+func (c *S3) PutBucketPolicy(input *PutBucketPolicyInput) (*PutBucketPolicyOutput, error) {
+	req, out := c.PutBucketPolicyRequest(input)
+	return out, req.Send()
+}
+
+// PutBucketPolicyWithContext is the same as PutBucketPolicy with the addition of
+// the ability to pass a context and additional request options.
+//
+// See PutBucketPolicy for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) PutBucketPolicyWithContext(ctx aws.Context, input *PutBucketPolicyInput, opts ...request.Option) (*PutBucketPolicyOutput, error) {
+	req, out := c.PutBucketPolicyRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opPutBucketReplication = "PutBucketReplication"
+
+// PutBucketReplicationRequest generates a "aws/request.Request" representing the
+// client's request for the PutBucketReplication operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See PutBucketReplication for more information on using the PutBucketReplication
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the PutBucketReplicationRequest method.
+//    req, resp := client.PutBucketReplicationRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketReplication
+func (c *S3) PutBucketReplicationRequest(input *PutBucketReplicationInput) (req *request.Request, output *PutBucketReplicationOutput) {
+	op := &request.Operation{
+		Name:       opPutBucketReplication,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}?replication",
+	}
+
+	if input == nil {
+		input = &PutBucketReplicationInput{}
+	}
+
+	output = &PutBucketReplicationOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// PutBucketReplication API operation for Amazon Simple Storage Service.
+//
+// Creates a new replication configuration (or replaces an existing one, if
+// present).
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation PutBucketReplication for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketReplication
+func (c *S3) PutBucketReplication(input *PutBucketReplicationInput) (*PutBucketReplicationOutput, error) {
+	req, out := c.PutBucketReplicationRequest(input)
+	return out, req.Send()
+}
+
+// PutBucketReplicationWithContext is the same as PutBucketReplication with the addition of
+// the ability to pass a context and additional request options.
+//
+// See PutBucketReplication for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) PutBucketReplicationWithContext(ctx aws.Context, input *PutBucketReplicationInput, opts ...request.Option) (*PutBucketReplicationOutput, error) {
+	req, out := c.PutBucketReplicationRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opPutBucketRequestPayment = "PutBucketRequestPayment"
+
+// PutBucketRequestPaymentRequest generates a "aws/request.Request" representing the
+// client's request for the PutBucketRequestPayment operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See PutBucketRequestPayment for more information on using the PutBucketRequestPayment
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the PutBucketRequestPaymentRequest method.
+//    req, resp := client.PutBucketRequestPaymentRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketRequestPayment
+func (c *S3) PutBucketRequestPaymentRequest(input *PutBucketRequestPaymentInput) (req *request.Request, output *PutBucketRequestPaymentOutput) {
+	op := &request.Operation{
+		Name:       opPutBucketRequestPayment,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}?requestPayment",
+	}
+
+	if input == nil {
+		input = &PutBucketRequestPaymentInput{}
+	}
+
+	output = &PutBucketRequestPaymentOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// PutBucketRequestPayment API operation for Amazon Simple Storage Service.
+//
+// Sets the request payment configuration for a bucket. By default, the bucket
+// owner pays for downloads from the bucket. This configuration parameter enables
+// the bucket owner (only) to specify that the person requesting the download
+// will be charged for the download. Documentation on requester pays buckets
+// can be found at http://docs.aws.amazon.com/AmazonS3/latest/dev/RequesterPaysBuckets.html
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation PutBucketRequestPayment for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketRequestPayment
+func (c *S3) PutBucketRequestPayment(input *PutBucketRequestPaymentInput) (*PutBucketRequestPaymentOutput, error) {
+	req, out := c.PutBucketRequestPaymentRequest(input)
+	return out, req.Send()
+}
+
+// PutBucketRequestPaymentWithContext is the same as PutBucketRequestPayment with the addition of
+// the ability to pass a context and additional request options.
+//
+// See PutBucketRequestPayment for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) PutBucketRequestPaymentWithContext(ctx aws.Context, input *PutBucketRequestPaymentInput, opts ...request.Option) (*PutBucketRequestPaymentOutput, error) {
+	req, out := c.PutBucketRequestPaymentRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opPutBucketTagging = "PutBucketTagging"
+
+// PutBucketTaggingRequest generates a "aws/request.Request" representing the
+// client's request for the PutBucketTagging operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See PutBucketTagging for more information on using the PutBucketTagging
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the PutBucketTaggingRequest method.
+//    req, resp := client.PutBucketTaggingRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketTagging
+func (c *S3) PutBucketTaggingRequest(input *PutBucketTaggingInput) (req *request.Request, output *PutBucketTaggingOutput) {
+	op := &request.Operation{
+		Name:       opPutBucketTagging,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}?tagging",
+	}
+
+	if input == nil {
+		input = &PutBucketTaggingInput{}
+	}
+
+	output = &PutBucketTaggingOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// PutBucketTagging API operation for Amazon Simple Storage Service.
+//
+// Sets the tags for a bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation PutBucketTagging for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketTagging
+func (c *S3) PutBucketTagging(input *PutBucketTaggingInput) (*PutBucketTaggingOutput, error) {
+	req, out := c.PutBucketTaggingRequest(input)
+	return out, req.Send()
+}
+
+// PutBucketTaggingWithContext is the same as PutBucketTagging with the addition of
+// the ability to pass a context and additional request options.
+//
+// See PutBucketTagging for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) PutBucketTaggingWithContext(ctx aws.Context, input *PutBucketTaggingInput, opts ...request.Option) (*PutBucketTaggingOutput, error) {
+	req, out := c.PutBucketTaggingRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opPutBucketVersioning = "PutBucketVersioning"
+
+// PutBucketVersioningRequest generates a "aws/request.Request" representing the
+// client's request for the PutBucketVersioning operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See PutBucketVersioning for more information on using the PutBucketVersioning
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the PutBucketVersioningRequest method.
+//    req, resp := client.PutBucketVersioningRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketVersioning
+func (c *S3) PutBucketVersioningRequest(input *PutBucketVersioningInput) (req *request.Request, output *PutBucketVersioningOutput) {
+	op := &request.Operation{
+		Name:       opPutBucketVersioning,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}?versioning",
+	}
+
+	if input == nil {
+		input = &PutBucketVersioningInput{}
+	}
+
+	output = &PutBucketVersioningOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// PutBucketVersioning API operation for Amazon Simple Storage Service.
+//
+// Sets the versioning state of an existing bucket. To set the versioning state,
+// you must be the bucket owner.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation PutBucketVersioning for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketVersioning
+func (c *S3) PutBucketVersioning(input *PutBucketVersioningInput) (*PutBucketVersioningOutput, error) {
+	req, out := c.PutBucketVersioningRequest(input)
+	return out, req.Send()
+}
+
+// PutBucketVersioningWithContext is the same as PutBucketVersioning with the addition of
+// the ability to pass a context and additional request options.
+//
+// See PutBucketVersioning for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) PutBucketVersioningWithContext(ctx aws.Context, input *PutBucketVersioningInput, opts ...request.Option) (*PutBucketVersioningOutput, error) {
+	req, out := c.PutBucketVersioningRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opPutBucketWebsite = "PutBucketWebsite"
+
+// PutBucketWebsiteRequest generates a "aws/request.Request" representing the
+// client's request for the PutBucketWebsite operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See PutBucketWebsite for more information on using the PutBucketWebsite
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the PutBucketWebsiteRequest method.
+//    req, resp := client.PutBucketWebsiteRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketWebsite
+func (c *S3) PutBucketWebsiteRequest(input *PutBucketWebsiteInput) (req *request.Request, output *PutBucketWebsiteOutput) {
+	op := &request.Operation{
+		Name:       opPutBucketWebsite,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}?website",
+	}
+
+	if input == nil {
+		input = &PutBucketWebsiteInput{}
+	}
+
+	output = &PutBucketWebsiteOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Unmarshal.Remove(restxml.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
+	return
+}
+
+// PutBucketWebsite API operation for Amazon Simple Storage Service.
+//
+// Set the website configuration for a bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation PutBucketWebsite for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutBucketWebsite
+func (c *S3) PutBucketWebsite(input *PutBucketWebsiteInput) (*PutBucketWebsiteOutput, error) {
+	req, out := c.PutBucketWebsiteRequest(input)
+	return out, req.Send()
+}
+
+// PutBucketWebsiteWithContext is the same as PutBucketWebsite with the addition of
+// the ability to pass a context and additional request options.
+//
+// See PutBucketWebsite for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) PutBucketWebsiteWithContext(ctx aws.Context, input *PutBucketWebsiteInput, opts ...request.Option) (*PutBucketWebsiteOutput, error) {
+	req, out := c.PutBucketWebsiteRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opPutObject = "PutObject"
+
+// PutObjectRequest generates a "aws/request.Request" representing the
+// client's request for the PutObject operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See PutObject for more information on using the PutObject
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the PutObjectRequest method.
+//    req, resp := client.PutObjectRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObject
+func (c *S3) PutObjectRequest(input *PutObjectInput) (req *request.Request, output *PutObjectOutput) {
+	op := &request.Operation{
+		Name:       opPutObject,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}/{Key+}",
+	}
+
+	if input == nil {
+		input = &PutObjectInput{}
+	}
+
+	output = &PutObjectOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// PutObject API operation for Amazon Simple Storage Service.
+//
+// Adds an object to a bucket.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation PutObject for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObject
+func (c *S3) PutObject(input *PutObjectInput) (*PutObjectOutput, error) {
+	req, out := c.PutObjectRequest(input)
+	return out, req.Send()
+}
+
+// PutObjectWithContext is the same as PutObject with the addition of
+// the ability to pass a context and additional request options.
+//
+// See PutObject for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) PutObjectWithContext(ctx aws.Context, input *PutObjectInput, opts ...request.Option) (*PutObjectOutput, error) {
+	req, out := c.PutObjectRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opPutObjectAcl = "PutObjectAcl"
+
+// PutObjectAclRequest generates a "aws/request.Request" representing the
+// client's request for the PutObjectAcl operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See PutObjectAcl for more information on using the PutObjectAcl
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the PutObjectAclRequest method.
+//    req, resp := client.PutObjectAclRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectAcl
+func (c *S3) PutObjectAclRequest(input *PutObjectAclInput) (req *request.Request, output *PutObjectAclOutput) {
+	op := &request.Operation{
+		Name:       opPutObjectAcl,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}/{Key+}?acl",
+	}
+
+	if input == nil {
+		input = &PutObjectAclInput{}
+	}
+
+	output = &PutObjectAclOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// PutObjectAcl API operation for Amazon Simple Storage Service.
+//
+// uses the acl subresource to set the access control list (ACL) permissions
+// for an object that already exists in a bucket
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation PutObjectAcl for usage and error information.
+//
+// Returned Error Codes:
+//   * ErrCodeNoSuchKey "NoSuchKey"
+//   The specified key does not exist.
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectAcl
+func (c *S3) PutObjectAcl(input *PutObjectAclInput) (*PutObjectAclOutput, error) {
+	req, out := c.PutObjectAclRequest(input)
+	return out, req.Send()
+}
+
+// PutObjectAclWithContext is the same as PutObjectAcl with the addition of
+// the ability to pass a context and additional request options.
+//
+// See PutObjectAcl for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) PutObjectAclWithContext(ctx aws.Context, input *PutObjectAclInput, opts ...request.Option) (*PutObjectAclOutput, error) {
+	req, out := c.PutObjectAclRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opPutObjectTagging = "PutObjectTagging"
+
+// PutObjectTaggingRequest generates a "aws/request.Request" representing the
+// client's request for the PutObjectTagging operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See PutObjectTagging for more information on using the PutObjectTagging
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the PutObjectTaggingRequest method.
+//    req, resp := client.PutObjectTaggingRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectTagging
+func (c *S3) PutObjectTaggingRequest(input *PutObjectTaggingInput) (req *request.Request, output *PutObjectTaggingOutput) {
+	op := &request.Operation{
+		Name:       opPutObjectTagging,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}/{Key+}?tagging",
+	}
+
+	if input == nil {
+		input = &PutObjectTaggingInput{}
+	}
+
+	output = &PutObjectTaggingOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// PutObjectTagging API operation for Amazon Simple Storage Service.
+//
+// Sets the supplied tag-set to an object that already exists in a bucket
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation PutObjectTagging for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/PutObjectTagging
+func (c *S3) PutObjectTagging(input *PutObjectTaggingInput) (*PutObjectTaggingOutput, error) {
+	req, out := c.PutObjectTaggingRequest(input)
+	return out, req.Send()
+}
+
+// PutObjectTaggingWithContext is the same as PutObjectTagging with the addition of
+// the ability to pass a context and additional request options.
+//
+// See PutObjectTagging for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) PutObjectTaggingWithContext(ctx aws.Context, input *PutObjectTaggingInput, opts ...request.Option) (*PutObjectTaggingOutput, error) {
+	req, out := c.PutObjectTaggingRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opRestoreObject = "RestoreObject"
+
+// RestoreObjectRequest generates a "aws/request.Request" representing the
+// client's request for the RestoreObject operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See RestoreObject for more information on using the RestoreObject
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the RestoreObjectRequest method.
+//    req, resp := client.RestoreObjectRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RestoreObject
+func (c *S3) RestoreObjectRequest(input *RestoreObjectInput) (req *request.Request, output *RestoreObjectOutput) {
+	op := &request.Operation{
+		Name:       opRestoreObject,
+		HTTPMethod: "POST",
+		HTTPPath:   "/{Bucket}/{Key+}?restore",
+	}
+
+	if input == nil {
+		input = &RestoreObjectInput{}
+	}
+
+	output = &RestoreObjectOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// RestoreObject API operation for Amazon Simple Storage Service.
+//
+// Restores an archived copy of an object back into Amazon S3
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation RestoreObject for usage and error information.
+//
+// Returned Error Codes:
+//   * ErrCodeObjectAlreadyInActiveTierError "ObjectAlreadyInActiveTierError"
+//   This operation is not allowed against this storage tier
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/RestoreObject
+func (c *S3) RestoreObject(input *RestoreObjectInput) (*RestoreObjectOutput, error) {
+	req, out := c.RestoreObjectRequest(input)
+	return out, req.Send()
+}
+
+// RestoreObjectWithContext is the same as RestoreObject with the addition of
+// the ability to pass a context and additional request options.
+//
+// See RestoreObject for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) RestoreObjectWithContext(ctx aws.Context, input *RestoreObjectInput, opts ...request.Option) (*RestoreObjectOutput, error) {
+	req, out := c.RestoreObjectRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opSelectObjectContent = "SelectObjectContent"
+
+// SelectObjectContentRequest generates a "aws/request.Request" representing the
+// client's request for the SelectObjectContent operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See SelectObjectContent for more information on using the SelectObjectContent
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the SelectObjectContentRequest method.
+//    req, resp := client.SelectObjectContentRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/SelectObjectContent
+func (c *S3) SelectObjectContentRequest(input *SelectObjectContentInput) (req *request.Request, output *SelectObjectContentOutput) {
+	op := &request.Operation{
+		Name:       opSelectObjectContent,
+		HTTPMethod: "POST",
+		HTTPPath:   "/{Bucket}/{Key+}?select&select-type=2",
+	}
+
+	if input == nil {
+		input = &SelectObjectContentInput{}
+	}
+
+	output = &SelectObjectContentOutput{}
+	req = c.newRequest(op, input, output)
+	req.Handlers.Send.Swap(client.LogHTTPResponseHandler.Name, client.LogHTTPResponseHeaderHandler)
+	req.Handlers.Unmarshal.Swap(restxml.UnmarshalHandler.Name, rest.UnmarshalHandler)
+	req.Handlers.Unmarshal.PushBack(output.runEventStreamLoop)
+	return
+}
+
+// SelectObjectContent API operation for Amazon Simple Storage Service.
+//
+// This operation filters the contents of an Amazon S3 object based on a simple
+// Structured Query Language (SQL) statement. In the request, along with the
+// SQL expression, you must also specify a data serialization format (JSON or
+// CSV) of the object. Amazon S3 uses this to parse object data into records,
+// and returns only records that match the specified SQL expression. You must
+// also specify the data serialization format for the response.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation SelectObjectContent for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/SelectObjectContent
+func (c *S3) SelectObjectContent(input *SelectObjectContentInput) (*SelectObjectContentOutput, error) {
+	req, out := c.SelectObjectContentRequest(input)
+	return out, req.Send()
+}
+
+// SelectObjectContentWithContext is the same as SelectObjectContent with the addition of
+// the ability to pass a context and additional request options.
+//
+// See SelectObjectContent for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) SelectObjectContentWithContext(ctx aws.Context, input *SelectObjectContentInput, opts ...request.Option) (*SelectObjectContentOutput, error) {
+	req, out := c.SelectObjectContentRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opUploadPart = "UploadPart"
+
+// UploadPartRequest generates a "aws/request.Request" representing the
+// client's request for the UploadPart operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See UploadPart for more information on using the UploadPart
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the UploadPartRequest method.
+//    req, resp := client.UploadPartRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPart
+func (c *S3) UploadPartRequest(input *UploadPartInput) (req *request.Request, output *UploadPartOutput) {
+	op := &request.Operation{
+		Name:       opUploadPart,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}/{Key+}",
+	}
+
+	if input == nil {
+		input = &UploadPartInput{}
+	}
+
+	output = &UploadPartOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// UploadPart API operation for Amazon Simple Storage Service.
+//
+// Uploads a part in a multipart upload.
+//
+// Note: After you initiate multipart upload and upload one or more parts, you
+// must either complete or abort multipart upload in order to stop getting charged
+// for storage of the uploaded parts. Only after you either complete or abort
+// multipart upload, Amazon S3 frees up the parts storage and stops charging
+// you for the parts storage.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation UploadPart for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPart
+func (c *S3) UploadPart(input *UploadPartInput) (*UploadPartOutput, error) {
+	req, out := c.UploadPartRequest(input)
+	return out, req.Send()
+}
+
+// UploadPartWithContext is the same as UploadPart with the addition of
+// the ability to pass a context and additional request options.
+//
+// See UploadPart for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) UploadPartWithContext(ctx aws.Context, input *UploadPartInput, opts ...request.Option) (*UploadPartOutput, error) {
+	req, out := c.UploadPartRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opUploadPartCopy = "UploadPartCopy"
+
+// UploadPartCopyRequest generates a "aws/request.Request" representing the
+// client's request for the UploadPartCopy operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See UploadPartCopy for more information on using the UploadPartCopy
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the UploadPartCopyRequest method.
+//    req, resp := client.UploadPartCopyRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPartCopy
+func (c *S3) UploadPartCopyRequest(input *UploadPartCopyInput) (req *request.Request, output *UploadPartCopyOutput) {
+	op := &request.Operation{
+		Name:       opUploadPartCopy,
+		HTTPMethod: "PUT",
+		HTTPPath:   "/{Bucket}/{Key+}",
+	}
+
+	if input == nil {
+		input = &UploadPartCopyInput{}
+	}
+
+	output = &UploadPartCopyOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// UploadPartCopy API operation for Amazon Simple Storage Service.
+//
+// Uploads a part by copying data from an existing object as data source.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for Amazon Simple Storage Service's
+// API operation UploadPartCopy for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01/UploadPartCopy
+func (c *S3) UploadPartCopy(input *UploadPartCopyInput) (*UploadPartCopyOutput, error) {
+	req, out := c.UploadPartCopyRequest(input)
+	return out, req.Send()
+}
+
+// UploadPartCopyWithContext is the same as UploadPartCopy with the addition of
+// the ability to pass a context and additional request options.
+//
+// See UploadPartCopy for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) UploadPartCopyWithContext(ctx aws.Context, input *UploadPartCopyInput, opts ...request.Option) (*UploadPartCopyOutput, error) {
+	req, out := c.UploadPartCopyRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+// Specifies the days since the initiation of an Incomplete Multipart Upload
+// that Lifecycle will wait before permanently removing all parts of the upload.
+type AbortIncompleteMultipartUpload struct {
+	_ struct{} `type:"structure"`
+
+	// Indicates the number of days that must pass since initiation for Lifecycle
+	// to abort an Incomplete Multipart Upload.
+	DaysAfterInitiation *int64 `type:"integer"`
+}
+
+// String returns the string representation
+func (s AbortIncompleteMultipartUpload) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AbortIncompleteMultipartUpload) GoString() string {
+	return s.String()
+}
+
+// SetDaysAfterInitiation sets the DaysAfterInitiation field's value.
+func (s *AbortIncompleteMultipartUpload) SetDaysAfterInitiation(v int64) *AbortIncompleteMultipartUpload {
+	s.DaysAfterInitiation = &v
+	return s
+}
+
+type AbortMultipartUploadInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Key is a required field
+	Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"`
+
+	// Confirms that the requester knows that she or he will be charged for the
+	// request. Bucket owners need not specify this parameter in their requests.
+	// Documentation on downloading objects from requester pays buckets can be found
+	// at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
+	RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"`
+
+	// UploadId is a required field
+	UploadId *string `location:"querystring" locationName:"uploadId" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s AbortMultipartUploadInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AbortMultipartUploadInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *AbortMultipartUploadInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "AbortMultipartUploadInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Key == nil {
+		invalidParams.Add(request.NewErrParamRequired("Key"))
+	}
+	if s.Key != nil && len(*s.Key) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
+	}
+	if s.UploadId == nil {
+		invalidParams.Add(request.NewErrParamRequired("UploadId"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *AbortMultipartUploadInput) SetBucket(v string) *AbortMultipartUploadInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *AbortMultipartUploadInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetKey sets the Key field's value.
+func (s *AbortMultipartUploadInput) SetKey(v string) *AbortMultipartUploadInput {
+	s.Key = &v
+	return s
+}
+
+// SetRequestPayer sets the RequestPayer field's value.
+func (s *AbortMultipartUploadInput) SetRequestPayer(v string) *AbortMultipartUploadInput {
+	s.RequestPayer = &v
+	return s
+}
+
+// SetUploadId sets the UploadId field's value.
+func (s *AbortMultipartUploadInput) SetUploadId(v string) *AbortMultipartUploadInput {
+	s.UploadId = &v
+	return s
+}
+
+type AbortMultipartUploadOutput struct {
+	_ struct{} `type:"structure"`
+
+	// If present, indicates that the requester was successfully charged for the
+	// request.
+	RequestCharged *string `location:"header" locationName:"x-amz-request-charged" type:"string" enum:"RequestCharged"`
+}
+
+// String returns the string representation
+func (s AbortMultipartUploadOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AbortMultipartUploadOutput) GoString() string {
+	return s.String()
+}
+
+// SetRequestCharged sets the RequestCharged field's value.
+func (s *AbortMultipartUploadOutput) SetRequestCharged(v string) *AbortMultipartUploadOutput {
+	s.RequestCharged = &v
+	return s
+}
+
+type AccelerateConfiguration struct {
+	_ struct{} `type:"structure"`
+
+	// The accelerate configuration of the bucket.
+	Status *string `type:"string" enum:"BucketAccelerateStatus"`
+}
+
+// String returns the string representation
+func (s AccelerateConfiguration) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AccelerateConfiguration) GoString() string {
+	return s.String()
+}
+
+// SetStatus sets the Status field's value.
+func (s *AccelerateConfiguration) SetStatus(v string) *AccelerateConfiguration {
+	s.Status = &v
+	return s
+}
+
+type AccessControlPolicy struct {
+	_ struct{} `type:"structure"`
+
+	// A list of grants.
+	Grants []*Grant `locationName:"AccessControlList" locationNameList:"Grant" type:"list"`
+
+	Owner *Owner `type:"structure"`
+}
+
+// String returns the string representation
+func (s AccessControlPolicy) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AccessControlPolicy) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *AccessControlPolicy) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "AccessControlPolicy"}
+	if s.Grants != nil {
+		for i, v := range s.Grants {
+			if v == nil {
+				continue
+			}
+			if err := v.Validate(); err != nil {
+				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Grants", i), err.(request.ErrInvalidParams))
+			}
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetGrants sets the Grants field's value.
+func (s *AccessControlPolicy) SetGrants(v []*Grant) *AccessControlPolicy {
+	s.Grants = v
+	return s
+}
+
+// SetOwner sets the Owner field's value.
+func (s *AccessControlPolicy) SetOwner(v *Owner) *AccessControlPolicy {
+	s.Owner = v
+	return s
+}
+
+// Container for information regarding the access control for replicas.
+type AccessControlTranslation struct {
+	_ struct{} `type:"structure"`
+
+	// The override value for the owner of the replica object.
+	//
+	// Owner is a required field
+	Owner *string `type:"string" required:"true" enum:"OwnerOverride"`
+}
+
+// String returns the string representation
+func (s AccessControlTranslation) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AccessControlTranslation) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *AccessControlTranslation) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "AccessControlTranslation"}
+	if s.Owner == nil {
+		invalidParams.Add(request.NewErrParamRequired("Owner"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetOwner sets the Owner field's value.
+func (s *AccessControlTranslation) SetOwner(v string) *AccessControlTranslation {
+	s.Owner = &v
+	return s
+}
+
+type AnalyticsAndOperator struct {
+	_ struct{} `type:"structure"`
+
+	// The prefix to use when evaluating an AND predicate.
+	Prefix *string `type:"string"`
+
+	// The list of tags to use when evaluating an AND predicate.
+	Tags []*Tag `locationName:"Tag" locationNameList:"Tag" type:"list" flattened:"true"`
+}
+
+// String returns the string representation
+func (s AnalyticsAndOperator) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AnalyticsAndOperator) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *AnalyticsAndOperator) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "AnalyticsAndOperator"}
+	if s.Tags != nil {
+		for i, v := range s.Tags {
+			if v == nil {
+				continue
+			}
+			if err := v.Validate(); err != nil {
+				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Tags", i), err.(request.ErrInvalidParams))
+			}
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetPrefix sets the Prefix field's value.
+func (s *AnalyticsAndOperator) SetPrefix(v string) *AnalyticsAndOperator {
+	s.Prefix = &v
+	return s
+}
+
+// SetTags sets the Tags field's value.
+func (s *AnalyticsAndOperator) SetTags(v []*Tag) *AnalyticsAndOperator {
+	s.Tags = v
+	return s
+}
+
+type AnalyticsConfiguration struct {
+	_ struct{} `type:"structure"`
+
+	// The filter used to describe a set of objects for analyses. A filter must
+	// have exactly one prefix, one tag, or one conjunction (AnalyticsAndOperator).
+	// If no filter is provided, all objects will be considered in any analysis.
+	Filter *AnalyticsFilter `type:"structure"`
+
+	// The identifier used to represent an analytics configuration.
+	//
+	// Id is a required field
+	Id *string `type:"string" required:"true"`
+
+	// If present, it indicates that data related to access patterns will be collected
+	// and made available to analyze the tradeoffs between different storage classes.
+	//
+	// StorageClassAnalysis is a required field
+	StorageClassAnalysis *StorageClassAnalysis `type:"structure" required:"true"`
+}
+
+// String returns the string representation
+func (s AnalyticsConfiguration) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AnalyticsConfiguration) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *AnalyticsConfiguration) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "AnalyticsConfiguration"}
+	if s.Id == nil {
+		invalidParams.Add(request.NewErrParamRequired("Id"))
+	}
+	if s.StorageClassAnalysis == nil {
+		invalidParams.Add(request.NewErrParamRequired("StorageClassAnalysis"))
+	}
+	if s.Filter != nil {
+		if err := s.Filter.Validate(); err != nil {
+			invalidParams.AddNested("Filter", err.(request.ErrInvalidParams))
+		}
+	}
+	if s.StorageClassAnalysis != nil {
+		if err := s.StorageClassAnalysis.Validate(); err != nil {
+			invalidParams.AddNested("StorageClassAnalysis", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetFilter sets the Filter field's value.
+func (s *AnalyticsConfiguration) SetFilter(v *AnalyticsFilter) *AnalyticsConfiguration {
+	s.Filter = v
+	return s
+}
+
+// SetId sets the Id field's value.
+func (s *AnalyticsConfiguration) SetId(v string) *AnalyticsConfiguration {
+	s.Id = &v
+	return s
+}
+
+// SetStorageClassAnalysis sets the StorageClassAnalysis field's value.
+func (s *AnalyticsConfiguration) SetStorageClassAnalysis(v *StorageClassAnalysis) *AnalyticsConfiguration {
+	s.StorageClassAnalysis = v
+	return s
+}
+
+type AnalyticsExportDestination struct {
+	_ struct{} `type:"structure"`
+
+	// A destination signifying output to an S3 bucket.
+	//
+	// S3BucketDestination is a required field
+	S3BucketDestination *AnalyticsS3BucketDestination `type:"structure" required:"true"`
+}
+
+// String returns the string representation
+func (s AnalyticsExportDestination) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AnalyticsExportDestination) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *AnalyticsExportDestination) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "AnalyticsExportDestination"}
+	if s.S3BucketDestination == nil {
+		invalidParams.Add(request.NewErrParamRequired("S3BucketDestination"))
+	}
+	if s.S3BucketDestination != nil {
+		if err := s.S3BucketDestination.Validate(); err != nil {
+			invalidParams.AddNested("S3BucketDestination", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetS3BucketDestination sets the S3BucketDestination field's value.
+func (s *AnalyticsExportDestination) SetS3BucketDestination(v *AnalyticsS3BucketDestination) *AnalyticsExportDestination {
+	s.S3BucketDestination = v
+	return s
+}
+
+type AnalyticsFilter struct {
+	_ struct{} `type:"structure"`
+
+	// A conjunction (logical AND) of predicates, which is used in evaluating an
+	// analytics filter. The operator must have at least two predicates.
+	And *AnalyticsAndOperator `type:"structure"`
+
+	// The prefix to use when evaluating an analytics filter.
+	Prefix *string `type:"string"`
+
+	// The tag to use when evaluating an analytics filter.
+	Tag *Tag `type:"structure"`
+}
+
+// String returns the string representation
+func (s AnalyticsFilter) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AnalyticsFilter) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *AnalyticsFilter) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "AnalyticsFilter"}
+	if s.And != nil {
+		if err := s.And.Validate(); err != nil {
+			invalidParams.AddNested("And", err.(request.ErrInvalidParams))
+		}
+	}
+	if s.Tag != nil {
+		if err := s.Tag.Validate(); err != nil {
+			invalidParams.AddNested("Tag", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetAnd sets the And field's value.
+func (s *AnalyticsFilter) SetAnd(v *AnalyticsAndOperator) *AnalyticsFilter {
+	s.And = v
+	return s
+}
+
+// SetPrefix sets the Prefix field's value.
+func (s *AnalyticsFilter) SetPrefix(v string) *AnalyticsFilter {
+	s.Prefix = &v
+	return s
+}
+
+// SetTag sets the Tag field's value.
+func (s *AnalyticsFilter) SetTag(v *Tag) *AnalyticsFilter {
+	s.Tag = v
+	return s
+}
+
+type AnalyticsS3BucketDestination struct {
+	_ struct{} `type:"structure"`
+
+	// The Amazon resource name (ARN) of the bucket to which data is exported.
+	//
+	// Bucket is a required field
+	Bucket *string `type:"string" required:"true"`
+
+	// The account ID that owns the destination bucket. If no account ID is provided,
+	// the owner will not be validated prior to exporting data.
+	BucketAccountId *string `type:"string"`
+
+	// The file format used when exporting data to Amazon S3.
+	//
+	// Format is a required field
+	Format *string `type:"string" required:"true" enum:"AnalyticsS3ExportFileFormat"`
+
+	// The prefix to use when exporting data. The exported data begins with this
+	// prefix.
+	Prefix *string `type:"string"`
+}
+
+// String returns the string representation
+func (s AnalyticsS3BucketDestination) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AnalyticsS3BucketDestination) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *AnalyticsS3BucketDestination) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "AnalyticsS3BucketDestination"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Format == nil {
+		invalidParams.Add(request.NewErrParamRequired("Format"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *AnalyticsS3BucketDestination) SetBucket(v string) *AnalyticsS3BucketDestination {
+	s.Bucket = &v
+	return s
+}
+
+func (s *AnalyticsS3BucketDestination) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetBucketAccountId sets the BucketAccountId field's value.
+func (s *AnalyticsS3BucketDestination) SetBucketAccountId(v string) *AnalyticsS3BucketDestination {
+	s.BucketAccountId = &v
+	return s
+}
+
+// SetFormat sets the Format field's value.
+func (s *AnalyticsS3BucketDestination) SetFormat(v string) *AnalyticsS3BucketDestination {
+	s.Format = &v
+	return s
+}
+
+// SetPrefix sets the Prefix field's value.
+func (s *AnalyticsS3BucketDestination) SetPrefix(v string) *AnalyticsS3BucketDestination {
+	s.Prefix = &v
+	return s
+}
+
+type Bucket struct {
+	_ struct{} `type:"structure"`
+
+	// Date the bucket was created.
+	CreationDate *time.Time `type:"timestamp"`
+
+	// The name of the bucket.
+	Name *string `type:"string"`
+}
+
+// String returns the string representation
+func (s Bucket) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s Bucket) GoString() string {
+	return s.String()
+}
+
+// SetCreationDate sets the CreationDate field's value.
+func (s *Bucket) SetCreationDate(v time.Time) *Bucket {
+	s.CreationDate = &v
+	return s
+}
+
+// SetName sets the Name field's value.
+func (s *Bucket) SetName(v string) *Bucket {
+	s.Name = &v
+	return s
+}
+
+type BucketLifecycleConfiguration struct {
+	_ struct{} `type:"structure"`
+
+	// Rules is a required field
+	Rules []*LifecycleRule `locationName:"Rule" type:"list" flattened:"true" required:"true"`
+}
+
+// String returns the string representation
+func (s BucketLifecycleConfiguration) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s BucketLifecycleConfiguration) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *BucketLifecycleConfiguration) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "BucketLifecycleConfiguration"}
+	if s.Rules == nil {
+		invalidParams.Add(request.NewErrParamRequired("Rules"))
+	}
+	if s.Rules != nil {
+		for i, v := range s.Rules {
+			if v == nil {
+				continue
+			}
+			if err := v.Validate(); err != nil {
+				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Rules", i), err.(request.ErrInvalidParams))
+			}
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetRules sets the Rules field's value.
+func (s *BucketLifecycleConfiguration) SetRules(v []*LifecycleRule) *BucketLifecycleConfiguration {
+	s.Rules = v
+	return s
+}
+
+type BucketLoggingStatus struct {
+	_ struct{} `type:"structure"`
+
+	// Container for logging information. Presence of this element indicates that
+	// logging is enabled. Parameters TargetBucket and TargetPrefix are required
+	// in this case.
+	LoggingEnabled *LoggingEnabled `type:"structure"`
+}
+
+// String returns the string representation
+func (s BucketLoggingStatus) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s BucketLoggingStatus) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *BucketLoggingStatus) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "BucketLoggingStatus"}
+	if s.LoggingEnabled != nil {
+		if err := s.LoggingEnabled.Validate(); err != nil {
+			invalidParams.AddNested("LoggingEnabled", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetLoggingEnabled sets the LoggingEnabled field's value.
+func (s *BucketLoggingStatus) SetLoggingEnabled(v *LoggingEnabled) *BucketLoggingStatus {
+	s.LoggingEnabled = v
+	return s
+}
+
+type CORSConfiguration struct {
+	_ struct{} `type:"structure"`
+
+	// CORSRules is a required field
+	CORSRules []*CORSRule `locationName:"CORSRule" type:"list" flattened:"true" required:"true"`
+}
+
+// String returns the string representation
+func (s CORSConfiguration) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s CORSConfiguration) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *CORSConfiguration) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "CORSConfiguration"}
+	if s.CORSRules == nil {
+		invalidParams.Add(request.NewErrParamRequired("CORSRules"))
+	}
+	if s.CORSRules != nil {
+		for i, v := range s.CORSRules {
+			if v == nil {
+				continue
+			}
+			if err := v.Validate(); err != nil {
+				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "CORSRules", i), err.(request.ErrInvalidParams))
+			}
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetCORSRules sets the CORSRules field's value.
+func (s *CORSConfiguration) SetCORSRules(v []*CORSRule) *CORSConfiguration {
+	s.CORSRules = v
+	return s
+}
+
+type CORSRule struct {
+	_ struct{} `type:"structure"`
+
+	// Specifies which headers are allowed in a pre-flight OPTIONS request.
+	AllowedHeaders []*string `locationName:"AllowedHeader" type:"list" flattened:"true"`
+
+	// Identifies HTTP methods that the domain/origin specified in the rule is allowed
+	// to execute.
+	//
+	// AllowedMethods is a required field
+	AllowedMethods []*string `locationName:"AllowedMethod" type:"list" flattened:"true" required:"true"`
+
+	// One or more origins you want customers to be able to access the bucket from.
+	//
+	// AllowedOrigins is a required field
+	AllowedOrigins []*string `locationName:"AllowedOrigin" type:"list" flattened:"true" required:"true"`
+
+	// One or more headers in the response that you want customers to be able to
+	// access from their applications (for example, from a JavaScript XMLHttpRequest
+	// object).
+	ExposeHeaders []*string `locationName:"ExposeHeader" type:"list" flattened:"true"`
+
+	// The time in seconds that your browser is to cache the preflight response
+	// for the specified resource.
+	MaxAgeSeconds *int64 `type:"integer"`
+}
+
+// String returns the string representation
+func (s CORSRule) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s CORSRule) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *CORSRule) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "CORSRule"}
+	if s.AllowedMethods == nil {
+		invalidParams.Add(request.NewErrParamRequired("AllowedMethods"))
+	}
+	if s.AllowedOrigins == nil {
+		invalidParams.Add(request.NewErrParamRequired("AllowedOrigins"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetAllowedHeaders sets the AllowedHeaders field's value.
+func (s *CORSRule) SetAllowedHeaders(v []*string) *CORSRule {
+	s.AllowedHeaders = v
+	return s
+}
+
+// SetAllowedMethods sets the AllowedMethods field's value.
+func (s *CORSRule) SetAllowedMethods(v []*string) *CORSRule {
+	s.AllowedMethods = v
+	return s
+}
+
+// SetAllowedOrigins sets the AllowedOrigins field's value.
+func (s *CORSRule) SetAllowedOrigins(v []*string) *CORSRule {
+	s.AllowedOrigins = v
+	return s
+}
+
+// SetExposeHeaders sets the ExposeHeaders field's value.
+func (s *CORSRule) SetExposeHeaders(v []*string) *CORSRule {
+	s.ExposeHeaders = v
+	return s
+}
+
+// SetMaxAgeSeconds sets the MaxAgeSeconds field's value.
+func (s *CORSRule) SetMaxAgeSeconds(v int64) *CORSRule {
+	s.MaxAgeSeconds = &v
+	return s
+}
+
+// Describes how a CSV-formatted input object is formatted.
+type CSVInput struct {
+	_ struct{} `type:"structure"`
+
+	// Specifies that CSV field values may contain quoted record delimiters and
+	// such records should be allowed. Default value is FALSE. Setting this value
+	// to TRUE may lower performance.
+	AllowQuotedRecordDelimiter *bool `type:"boolean"`
+
+	// Single character used to indicate a row should be ignored when present at
+	// the start of a row.
+	Comments *string `type:"string"`
+
+	// Value used to separate individual fields in a record.
+	FieldDelimiter *string `type:"string"`
+
+	// Describes the first line of input. Valid values: None, Ignore, Use.
+	FileHeaderInfo *string `type:"string" enum:"FileHeaderInfo"`
+
+	// Value used for escaping where the field delimiter is part of the value.
+	QuoteCharacter *string `type:"string"`
+
+	// Single character used for escaping the quote character inside an already
+	// escaped value.
+	QuoteEscapeCharacter *string `type:"string"`
+
+	// Value used to separate individual records.
+	RecordDelimiter *string `type:"string"`
+}
+
+// String returns the string representation
+func (s CSVInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s CSVInput) GoString() string {
+	return s.String()
+}
+
+// SetAllowQuotedRecordDelimiter sets the AllowQuotedRecordDelimiter field's value.
+func (s *CSVInput) SetAllowQuotedRecordDelimiter(v bool) *CSVInput {
+	s.AllowQuotedRecordDelimiter = &v
+	return s
+}
+
+// SetComments sets the Comments field's value.
+func (s *CSVInput) SetComments(v string) *CSVInput {
+	s.Comments = &v
+	return s
+}
+
+// SetFieldDelimiter sets the FieldDelimiter field's value.
+func (s *CSVInput) SetFieldDelimiter(v string) *CSVInput {
+	s.FieldDelimiter = &v
+	return s
+}
+
+// SetFileHeaderInfo sets the FileHeaderInfo field's value.
+func (s *CSVInput) SetFileHeaderInfo(v string) *CSVInput {
+	s.FileHeaderInfo = &v
+	return s
+}
+
+// SetQuoteCharacter sets the QuoteCharacter field's value.
+func (s *CSVInput) SetQuoteCharacter(v string) *CSVInput {
+	s.QuoteCharacter = &v
+	return s
+}
+
+// SetQuoteEscapeCharacter sets the QuoteEscapeCharacter field's value.
+func (s *CSVInput) SetQuoteEscapeCharacter(v string) *CSVInput {
+	s.QuoteEscapeCharacter = &v
+	return s
+}
+
+// SetRecordDelimiter sets the RecordDelimiter field's value.
+func (s *CSVInput) SetRecordDelimiter(v string) *CSVInput {
+	s.RecordDelimiter = &v
+	return s
+}
+
+// Describes how CSV-formatted results are formatted.
+type CSVOutput struct {
+	_ struct{} `type:"structure"`
+
+	// Value used to separate individual fields in a record.
+	FieldDelimiter *string `type:"string"`
+
+	// Value used for escaping where the field delimiter is part of the value.
+	QuoteCharacter *string `type:"string"`
+
+	// Single character used for escaping the quote character inside an already
+	// escaped value.
+	QuoteEscapeCharacter *string `type:"string"`
+
+	// Indicates whether or not all output fields should be quoted.
+	QuoteFields *string `type:"string" enum:"QuoteFields"`
+
+	// Value used to separate individual records.
+	RecordDelimiter *string `type:"string"`
+}
+
+// String returns the string representation
+func (s CSVOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s CSVOutput) GoString() string {
+	return s.String()
+}
+
+// SetFieldDelimiter sets the FieldDelimiter field's value.
+func (s *CSVOutput) SetFieldDelimiter(v string) *CSVOutput {
+	s.FieldDelimiter = &v
+	return s
+}
+
+// SetQuoteCharacter sets the QuoteCharacter field's value.
+func (s *CSVOutput) SetQuoteCharacter(v string) *CSVOutput {
+	s.QuoteCharacter = &v
+	return s
+}
+
+// SetQuoteEscapeCharacter sets the QuoteEscapeCharacter field's value.
+func (s *CSVOutput) SetQuoteEscapeCharacter(v string) *CSVOutput {
+	s.QuoteEscapeCharacter = &v
+	return s
+}
+
+// SetQuoteFields sets the QuoteFields field's value.
+func (s *CSVOutput) SetQuoteFields(v string) *CSVOutput {
+	s.QuoteFields = &v
+	return s
+}
+
+// SetRecordDelimiter sets the RecordDelimiter field's value.
+func (s *CSVOutput) SetRecordDelimiter(v string) *CSVOutput {
+	s.RecordDelimiter = &v
+	return s
+}
+
+type CloudFunctionConfiguration struct {
+	_ struct{} `type:"structure"`
+
+	CloudFunction *string `type:"string"`
+
+	// Bucket event for which to send notifications.
+	Event *string `deprecated:"true" type:"string" enum:"Event"`
+
+	Events []*string `locationName:"Event" type:"list" flattened:"true"`
+
+	// Optional unique identifier for configurations in a notification configuration.
+	// If you don't provide one, Amazon S3 will assign an ID.
+	Id *string `type:"string"`
+
+	InvocationRole *string `type:"string"`
+}
+
+// String returns the string representation
+func (s CloudFunctionConfiguration) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s CloudFunctionConfiguration) GoString() string {
+	return s.String()
+}
+
+// SetCloudFunction sets the CloudFunction field's value.
+func (s *CloudFunctionConfiguration) SetCloudFunction(v string) *CloudFunctionConfiguration {
+	s.CloudFunction = &v
+	return s
+}
+
+// SetEvent sets the Event field's value.
+func (s *CloudFunctionConfiguration) SetEvent(v string) *CloudFunctionConfiguration {
+	s.Event = &v
+	return s
+}
+
+// SetEvents sets the Events field's value.
+func (s *CloudFunctionConfiguration) SetEvents(v []*string) *CloudFunctionConfiguration {
+	s.Events = v
+	return s
+}
+
+// SetId sets the Id field's value.
+func (s *CloudFunctionConfiguration) SetId(v string) *CloudFunctionConfiguration {
+	s.Id = &v
+	return s
+}
+
+// SetInvocationRole sets the InvocationRole field's value.
+func (s *CloudFunctionConfiguration) SetInvocationRole(v string) *CloudFunctionConfiguration {
+	s.InvocationRole = &v
+	return s
+}
+
+type CommonPrefix struct {
+	_ struct{} `type:"structure"`
+
+	Prefix *string `type:"string"`
+}
+
+// String returns the string representation
+func (s CommonPrefix) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s CommonPrefix) GoString() string {
+	return s.String()
+}
+
+// SetPrefix sets the Prefix field's value.
+func (s *CommonPrefix) SetPrefix(v string) *CommonPrefix {
+	s.Prefix = &v
+	return s
+}
+
+type CompleteMultipartUploadInput struct {
+	_ struct{} `type:"structure" payload:"MultipartUpload"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Key is a required field
+	Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"`
+
+	MultipartUpload *CompletedMultipartUpload `locationName:"CompleteMultipartUpload" type:"structure" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+
+	// Confirms that the requester knows that she or he will be charged for the
+	// request. Bucket owners need not specify this parameter in their requests.
+	// Documentation on downloading objects from requester pays buckets can be found
+	// at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
+	RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"`
+
+	// UploadId is a required field
+	UploadId *string `location:"querystring" locationName:"uploadId" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s CompleteMultipartUploadInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s CompleteMultipartUploadInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *CompleteMultipartUploadInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "CompleteMultipartUploadInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Key == nil {
+		invalidParams.Add(request.NewErrParamRequired("Key"))
+	}
+	if s.Key != nil && len(*s.Key) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
+	}
+	if s.UploadId == nil {
+		invalidParams.Add(request.NewErrParamRequired("UploadId"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *CompleteMultipartUploadInput) SetBucket(v string) *CompleteMultipartUploadInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *CompleteMultipartUploadInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetKey sets the Key field's value.
+func (s *CompleteMultipartUploadInput) SetKey(v string) *CompleteMultipartUploadInput {
+	s.Key = &v
+	return s
+}
+
+// SetMultipartUpload sets the MultipartUpload field's value.
+func (s *CompleteMultipartUploadInput) SetMultipartUpload(v *CompletedMultipartUpload) *CompleteMultipartUploadInput {
+	s.MultipartUpload = v
+	return s
+}
+
+// SetRequestPayer sets the RequestPayer field's value.
+func (s *CompleteMultipartUploadInput) SetRequestPayer(v string) *CompleteMultipartUploadInput {
+	s.RequestPayer = &v
+	return s
+}
+
+// SetUploadId sets the UploadId field's value.
+func (s *CompleteMultipartUploadInput) SetUploadId(v string) *CompleteMultipartUploadInput {
+	s.UploadId = &v
+	return s
+}
+
+type CompleteMultipartUploadOutput struct {
+	_ struct{} `type:"structure"`
+
+	Bucket *string `type:"string"`
+
+	// Entity tag of the object.
+	ETag *string `type:"string"`
+
+	// If the object expiration is configured, this will contain the expiration
+	// date (expiry-date) and rule ID (rule-id). The value of rule-id is URL encoded.
+	Expiration *string `location:"header" locationName:"x-amz-expiration" type:"string"`
+
+	Key *string `min:"1" type:"string"`
+
+	Location *string `type:"string"`
+
+	// If present, indicates that the requester was successfully charged for the
+	// request.
+	RequestCharged *string `location:"header" locationName:"x-amz-request-charged" type:"string" enum:"RequestCharged"`
+
+	// If present, specifies the ID of the AWS Key Management Service (KMS) master
+	// encryption key that was used for the object.
+	SSEKMSKeyId *string `location:"header" locationName:"x-amz-server-side-encryption-aws-kms-key-id" type:"string"`
+
+	// The Server-side encryption algorithm used when storing this object in S3
+	// (e.g., AES256, aws:kms).
+	ServerSideEncryption *string `location:"header" locationName:"x-amz-server-side-encryption" type:"string" enum:"ServerSideEncryption"`
+
+	// Version of the object.
+	VersionId *string `location:"header" locationName:"x-amz-version-id" type:"string"`
+}
+
+// String returns the string representation
+func (s CompleteMultipartUploadOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s CompleteMultipartUploadOutput) GoString() string {
+	return s.String()
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *CompleteMultipartUploadOutput) SetBucket(v string) *CompleteMultipartUploadOutput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *CompleteMultipartUploadOutput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetETag sets the ETag field's value.
+func (s *CompleteMultipartUploadOutput) SetETag(v string) *CompleteMultipartUploadOutput {
+	s.ETag = &v
+	return s
+}
+
+// SetExpiration sets the Expiration field's value.
+func (s *CompleteMultipartUploadOutput) SetExpiration(v string) *CompleteMultipartUploadOutput {
+	s.Expiration = &v
+	return s
+}
+
+// SetKey sets the Key field's value.
+func (s *CompleteMultipartUploadOutput) SetKey(v string) *CompleteMultipartUploadOutput {
+	s.Key = &v
+	return s
+}
+
+// SetLocation sets the Location field's value.
+func (s *CompleteMultipartUploadOutput) SetLocation(v string) *CompleteMultipartUploadOutput {
+	s.Location = &v
+	return s
+}
+
+// SetRequestCharged sets the RequestCharged field's value.
+func (s *CompleteMultipartUploadOutput) SetRequestCharged(v string) *CompleteMultipartUploadOutput {
+	s.RequestCharged = &v
+	return s
+}
+
+// SetSSEKMSKeyId sets the SSEKMSKeyId field's value.
+func (s *CompleteMultipartUploadOutput) SetSSEKMSKeyId(v string) *CompleteMultipartUploadOutput {
+	s.SSEKMSKeyId = &v
+	return s
+}
+
+// SetServerSideEncryption sets the ServerSideEncryption field's value.
+func (s *CompleteMultipartUploadOutput) SetServerSideEncryption(v string) *CompleteMultipartUploadOutput {
+	s.ServerSideEncryption = &v
+	return s
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *CompleteMultipartUploadOutput) SetVersionId(v string) *CompleteMultipartUploadOutput {
+	s.VersionId = &v
+	return s
+}
+
+type CompletedMultipartUpload struct {
+	_ struct{} `type:"structure"`
+
+	Parts []*CompletedPart `locationName:"Part" type:"list" flattened:"true"`
+}
+
+// String returns the string representation
+func (s CompletedMultipartUpload) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s CompletedMultipartUpload) GoString() string {
+	return s.String()
+}
+
+// SetParts sets the Parts field's value.
+func (s *CompletedMultipartUpload) SetParts(v []*CompletedPart) *CompletedMultipartUpload {
+	s.Parts = v
+	return s
+}
+
+type CompletedPart struct {
+	_ struct{} `type:"structure"`
+
+	// Entity tag returned when the part was uploaded.
+	ETag *string `type:"string"`
+
+	// Part number that identifies the part. This is a positive integer between
+	// 1 and 10,000.
+	PartNumber *int64 `type:"integer"`
+}
+
+// String returns the string representation
+func (s CompletedPart) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s CompletedPart) GoString() string {
+	return s.String()
+}
+
+// SetETag sets the ETag field's value.
+func (s *CompletedPart) SetETag(v string) *CompletedPart {
+	s.ETag = &v
+	return s
+}
+
+// SetPartNumber sets the PartNumber field's value.
+func (s *CompletedPart) SetPartNumber(v int64) *CompletedPart {
+	s.PartNumber = &v
+	return s
+}
+
+type Condition struct {
+	_ struct{} `type:"structure"`
+
+	// The HTTP error code when the redirect is applied. In the event of an error,
+	// if the error code equals this value, then the specified redirect is applied.
+	// Required when parent element Condition is specified and sibling KeyPrefixEquals
+	// is not specified. If both are specified, then both must be true for the redirect
+	// to be applied.
+	HttpErrorCodeReturnedEquals *string `type:"string"`
+
+	// The object key name prefix when the redirect is applied. For example, to
+	// redirect requests for ExamplePage.html, the key prefix will be ExamplePage.html.
+	// To redirect request for all pages with the prefix docs/, the key prefix will
+	// be /docs, which identifies all objects in the docs/ folder. Required when
+	// the parent element Condition is specified and sibling HttpErrorCodeReturnedEquals
+	// is not specified. If both conditions are specified, both must be true for
+	// the redirect to be applied.
+	KeyPrefixEquals *string `type:"string"`
+}
+
+// String returns the string representation
+func (s Condition) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s Condition) GoString() string {
+	return s.String()
+}
+
+// SetHttpErrorCodeReturnedEquals sets the HttpErrorCodeReturnedEquals field's value.
+func (s *Condition) SetHttpErrorCodeReturnedEquals(v string) *Condition {
+	s.HttpErrorCodeReturnedEquals = &v
+	return s
+}
+
+// SetKeyPrefixEquals sets the KeyPrefixEquals field's value.
+func (s *Condition) SetKeyPrefixEquals(v string) *Condition {
+	s.KeyPrefixEquals = &v
+	return s
+}
+
+type ContinuationEvent struct {
+	_ struct{} `locationName:"ContinuationEvent" type:"structure"`
+}
+
+// String returns the string representation
+func (s ContinuationEvent) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ContinuationEvent) GoString() string {
+	return s.String()
+}
+
+// The ContinuationEvent is and event in the SelectObjectContentEventStream group of events.
+func (s *ContinuationEvent) eventSelectObjectContentEventStream() {}
+
+// UnmarshalEvent unmarshals the EventStream Message into the ContinuationEvent value.
+// This method is only used internally within the SDK's EventStream handling.
+func (s *ContinuationEvent) UnmarshalEvent(
+	payloadUnmarshaler protocol.PayloadUnmarshaler,
+	msg eventstream.Message,
+) error {
+	return nil
+}
+
+type CopyObjectInput struct {
+	_ struct{} `type:"structure"`
+
+	// The canned ACL to apply to the object.
+	ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"ObjectCannedACL"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Specifies caching behavior along the request/reply chain.
+	CacheControl *string `location:"header" locationName:"Cache-Control" type:"string"`
+
+	// Specifies presentational information for the object.
+	ContentDisposition *string `location:"header" locationName:"Content-Disposition" type:"string"`
+
+	// Specifies what content encodings have been applied to the object and thus
+	// what decoding mechanisms must be applied to obtain the media-type referenced
+	// by the Content-Type header field.
+	ContentEncoding *string `location:"header" locationName:"Content-Encoding" type:"string"`
+
+	// The language the content is in.
+	ContentLanguage *string `location:"header" locationName:"Content-Language" type:"string"`
+
+	// A standard MIME type describing the format of the object data.
+	ContentType *string `location:"header" locationName:"Content-Type" type:"string"`
+
+	// The name of the source bucket and key name of the source object, separated
+	// by a slash (/). Must be URL-encoded.
+	//
+	// CopySource is a required field
+	CopySource *string `location:"header" locationName:"x-amz-copy-source" type:"string" required:"true"`
+
+	// Copies the object if its entity tag (ETag) matches the specified tag.
+	CopySourceIfMatch *string `location:"header" locationName:"x-amz-copy-source-if-match" type:"string"`
+
+	// Copies the object if it has been modified since the specified time.
+	CopySourceIfModifiedSince *time.Time `location:"header" locationName:"x-amz-copy-source-if-modified-since" type:"timestamp"`
+
+	// Copies the object if its entity tag (ETag) is different than the specified
+	// ETag.
+	CopySourceIfNoneMatch *string `location:"header" locationName:"x-amz-copy-source-if-none-match" type:"string"`
+
+	// Copies the object if it hasn't been modified since the specified time.
+	CopySourceIfUnmodifiedSince *time.Time `location:"header" locationName:"x-amz-copy-source-if-unmodified-since" type:"timestamp"`
+
+	// Specifies the algorithm to use when decrypting the source object (e.g., AES256).
+	CopySourceSSECustomerAlgorithm *string `location:"header" locationName:"x-amz-copy-source-server-side-encryption-customer-algorithm" type:"string"`
+
+	// Specifies the customer-provided encryption key for Amazon S3 to use to decrypt
+	// the source object. The encryption key provided in this header must be one
+	// that was used when the source object was created.
+	CopySourceSSECustomerKey *string `location:"header" locationName:"x-amz-copy-source-server-side-encryption-customer-key" type:"string"`
+
+	// Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321.
+	// Amazon S3 uses this header for a message integrity check to ensure the encryption
+	// key was transmitted without error.
+	CopySourceSSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-copy-source-server-side-encryption-customer-key-MD5" type:"string"`
+
+	// The date and time at which the object is no longer cacheable.
+	Expires *time.Time `location:"header" locationName:"Expires" type:"timestamp"`
+
+	// Gives the grantee READ, READ_ACP, and WRITE_ACP permissions on the object.
+	GrantFullControl *string `location:"header" locationName:"x-amz-grant-full-control" type:"string"`
+
+	// Allows grantee to read the object data and its metadata.
+	GrantRead *string `location:"header" locationName:"x-amz-grant-read" type:"string"`
+
+	// Allows grantee to read the object ACL.
+	GrantReadACP *string `location:"header" locationName:"x-amz-grant-read-acp" type:"string"`
+
+	// Allows grantee to write the ACL for the applicable object.
+	GrantWriteACP *string `location:"header" locationName:"x-amz-grant-write-acp" type:"string"`
+
+	// Key is a required field
+	Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"`
+
+	// A map of metadata to store with the object in S3.
+	Metadata map[string]*string `location:"headers" locationName:"x-amz-meta-" type:"map"`
+
+	// Specifies whether the metadata is copied from the source object or replaced
+	// with metadata provided in the request.
+	MetadataDirective *string `location:"header" locationName:"x-amz-metadata-directive" type:"string" enum:"MetadataDirective"`
+
+	// Confirms that the requester knows that she or he will be charged for the
+	// request. Bucket owners need not specify this parameter in their requests.
+	// Documentation on downloading objects from requester pays buckets can be found
+	// at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
+	RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"`
+
+	// Specifies the algorithm to use to when encrypting the object (e.g., AES256).
+	SSECustomerAlgorithm *string `location:"header" locationName:"x-amz-server-side-encryption-customer-algorithm" type:"string"`
+
+	// Specifies the customer-provided encryption key for Amazon S3 to use in encrypting
+	// data. This value is used to store the object and then it is discarded; Amazon
+	// does not store the encryption key. The key must be appropriate for use with
+	// the algorithm specified in the x-amz-server-side​-encryption​-customer-algorithm
+	// header.
+	SSECustomerKey *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key" type:"string"`
+
+	// Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321.
+	// Amazon S3 uses this header for a message integrity check to ensure the encryption
+	// key was transmitted without error.
+	SSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key-MD5" type:"string"`
+
+	// Specifies the AWS KMS key ID to use for object encryption. All GET and PUT
+	// requests for an object protected by AWS KMS will fail if not made via SSL
+	// or using SigV4. Documentation on configuring any of the officially supported
+	// AWS SDKs and CLI can be found at http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingAWSSDK.html#specify-signature-version
+	SSEKMSKeyId *string `location:"header" locationName:"x-amz-server-side-encryption-aws-kms-key-id" type:"string"`
+
+	// The Server-side encryption algorithm used when storing this object in S3
+	// (e.g., AES256, aws:kms).
+	ServerSideEncryption *string `location:"header" locationName:"x-amz-server-side-encryption" type:"string" enum:"ServerSideEncryption"`
+
+	// The type of storage to use for the object. Defaults to 'STANDARD'.
+	StorageClass *string `location:"header" locationName:"x-amz-storage-class" type:"string" enum:"StorageClass"`
+
+	// The tag-set for the object destination object this value must be used in
+	// conjunction with the TaggingDirective. The tag-set must be encoded as URL
+	// Query parameters
+	Tagging *string `location:"header" locationName:"x-amz-tagging" type:"string"`
+
+	// Specifies whether the object tag-set are copied from the source object or
+	// replaced with tag-set provided in the request.
+	TaggingDirective *string `location:"header" locationName:"x-amz-tagging-directive" type:"string" enum:"TaggingDirective"`
+
+	// If the bucket is configured as a website, redirects requests for this object
+	// to another object in the same bucket or to an external URL. Amazon S3 stores
+	// the value of this header in the object metadata.
+	WebsiteRedirectLocation *string `location:"header" locationName:"x-amz-website-redirect-location" type:"string"`
+}
+
+// String returns the string representation
+func (s CopyObjectInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s CopyObjectInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *CopyObjectInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "CopyObjectInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.CopySource == nil {
+		invalidParams.Add(request.NewErrParamRequired("CopySource"))
+	}
+	if s.Key == nil {
+		invalidParams.Add(request.NewErrParamRequired("Key"))
+	}
+	if s.Key != nil && len(*s.Key) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetACL sets the ACL field's value.
+func (s *CopyObjectInput) SetACL(v string) *CopyObjectInput {
+	s.ACL = &v
+	return s
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *CopyObjectInput) SetBucket(v string) *CopyObjectInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *CopyObjectInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetCacheControl sets the CacheControl field's value.
+func (s *CopyObjectInput) SetCacheControl(v string) *CopyObjectInput {
+	s.CacheControl = &v
+	return s
+}
+
+// SetContentDisposition sets the ContentDisposition field's value.
+func (s *CopyObjectInput) SetContentDisposition(v string) *CopyObjectInput {
+	s.ContentDisposition = &v
+	return s
+}
+
+// SetContentEncoding sets the ContentEncoding field's value.
+func (s *CopyObjectInput) SetContentEncoding(v string) *CopyObjectInput {
+	s.ContentEncoding = &v
+	return s
+}
+
+// SetContentLanguage sets the ContentLanguage field's value.
+func (s *CopyObjectInput) SetContentLanguage(v string) *CopyObjectInput {
+	s.ContentLanguage = &v
+	return s
+}
+
+// SetContentType sets the ContentType field's value.
+func (s *CopyObjectInput) SetContentType(v string) *CopyObjectInput {
+	s.ContentType = &v
+	return s
+}
+
+// SetCopySource sets the CopySource field's value.
+func (s *CopyObjectInput) SetCopySource(v string) *CopyObjectInput {
+	s.CopySource = &v
+	return s
+}
+
+// SetCopySourceIfMatch sets the CopySourceIfMatch field's value.
+func (s *CopyObjectInput) SetCopySourceIfMatch(v string) *CopyObjectInput {
+	s.CopySourceIfMatch = &v
+	return s
+}
+
+// SetCopySourceIfModifiedSince sets the CopySourceIfModifiedSince field's value.
+func (s *CopyObjectInput) SetCopySourceIfModifiedSince(v time.Time) *CopyObjectInput {
+	s.CopySourceIfModifiedSince = &v
+	return s
+}
+
+// SetCopySourceIfNoneMatch sets the CopySourceIfNoneMatch field's value.
+func (s *CopyObjectInput) SetCopySourceIfNoneMatch(v string) *CopyObjectInput {
+	s.CopySourceIfNoneMatch = &v
+	return s
+}
+
+// SetCopySourceIfUnmodifiedSince sets the CopySourceIfUnmodifiedSince field's value.
+func (s *CopyObjectInput) SetCopySourceIfUnmodifiedSince(v time.Time) *CopyObjectInput {
+	s.CopySourceIfUnmodifiedSince = &v
+	return s
+}
+
+// SetCopySourceSSECustomerAlgorithm sets the CopySourceSSECustomerAlgorithm field's value.
+func (s *CopyObjectInput) SetCopySourceSSECustomerAlgorithm(v string) *CopyObjectInput {
+	s.CopySourceSSECustomerAlgorithm = &v
+	return s
+}
+
+// SetCopySourceSSECustomerKey sets the CopySourceSSECustomerKey field's value.
+func (s *CopyObjectInput) SetCopySourceSSECustomerKey(v string) *CopyObjectInput {
+	s.CopySourceSSECustomerKey = &v
+	return s
+}
+
+func (s *CopyObjectInput) getCopySourceSSECustomerKey() (v string) {
+	if s.CopySourceSSECustomerKey == nil {
+		return v
+	}
+	return *s.CopySourceSSECustomerKey
+}
+
+// SetCopySourceSSECustomerKeyMD5 sets the CopySourceSSECustomerKeyMD5 field's value.
+func (s *CopyObjectInput) SetCopySourceSSECustomerKeyMD5(v string) *CopyObjectInput {
+	s.CopySourceSSECustomerKeyMD5 = &v
+	return s
+}
+
+// SetExpires sets the Expires field's value.
+func (s *CopyObjectInput) SetExpires(v time.Time) *CopyObjectInput {
+	s.Expires = &v
+	return s
+}
+
+// SetGrantFullControl sets the GrantFullControl field's value.
+func (s *CopyObjectInput) SetGrantFullControl(v string) *CopyObjectInput {
+	s.GrantFullControl = &v
+	return s
+}
+
+// SetGrantRead sets the GrantRead field's value.
+func (s *CopyObjectInput) SetGrantRead(v string) *CopyObjectInput {
+	s.GrantRead = &v
+	return s
+}
+
+// SetGrantReadACP sets the GrantReadACP field's value.
+func (s *CopyObjectInput) SetGrantReadACP(v string) *CopyObjectInput {
+	s.GrantReadACP = &v
+	return s
+}
+
+// SetGrantWriteACP sets the GrantWriteACP field's value.
+func (s *CopyObjectInput) SetGrantWriteACP(v string) *CopyObjectInput {
+	s.GrantWriteACP = &v
+	return s
+}
+
+// SetKey sets the Key field's value.
+func (s *CopyObjectInput) SetKey(v string) *CopyObjectInput {
+	s.Key = &v
+	return s
+}
+
+// SetMetadata sets the Metadata field's value.
+func (s *CopyObjectInput) SetMetadata(v map[string]*string) *CopyObjectInput {
+	s.Metadata = v
+	return s
+}
+
+// SetMetadataDirective sets the MetadataDirective field's value.
+func (s *CopyObjectInput) SetMetadataDirective(v string) *CopyObjectInput {
+	s.MetadataDirective = &v
+	return s
+}
+
+// SetRequestPayer sets the RequestPayer field's value.
+func (s *CopyObjectInput) SetRequestPayer(v string) *CopyObjectInput {
+	s.RequestPayer = &v
+	return s
+}
+
+// SetSSECustomerAlgorithm sets the SSECustomerAlgorithm field's value.
+func (s *CopyObjectInput) SetSSECustomerAlgorithm(v string) *CopyObjectInput {
+	s.SSECustomerAlgorithm = &v
+	return s
+}
+
+// SetSSECustomerKey sets the SSECustomerKey field's value.
+func (s *CopyObjectInput) SetSSECustomerKey(v string) *CopyObjectInput {
+	s.SSECustomerKey = &v
+	return s
+}
+
+func (s *CopyObjectInput) getSSECustomerKey() (v string) {
+	if s.SSECustomerKey == nil {
+		return v
+	}
+	return *s.SSECustomerKey
+}
+
+// SetSSECustomerKeyMD5 sets the SSECustomerKeyMD5 field's value.
+func (s *CopyObjectInput) SetSSECustomerKeyMD5(v string) *CopyObjectInput {
+	s.SSECustomerKeyMD5 = &v
+	return s
+}
+
+// SetSSEKMSKeyId sets the SSEKMSKeyId field's value.
+func (s *CopyObjectInput) SetSSEKMSKeyId(v string) *CopyObjectInput {
+	s.SSEKMSKeyId = &v
+	return s
+}
+
+// SetServerSideEncryption sets the ServerSideEncryption field's value.
+func (s *CopyObjectInput) SetServerSideEncryption(v string) *CopyObjectInput {
+	s.ServerSideEncryption = &v
+	return s
+}
+
+// SetStorageClass sets the StorageClass field's value.
+func (s *CopyObjectInput) SetStorageClass(v string) *CopyObjectInput {
+	s.StorageClass = &v
+	return s
+}
+
+// SetTagging sets the Tagging field's value.
+func (s *CopyObjectInput) SetTagging(v string) *CopyObjectInput {
+	s.Tagging = &v
+	return s
+}
+
+// SetTaggingDirective sets the TaggingDirective field's value.
+func (s *CopyObjectInput) SetTaggingDirective(v string) *CopyObjectInput {
+	s.TaggingDirective = &v
+	return s
+}
+
+// SetWebsiteRedirectLocation sets the WebsiteRedirectLocation field's value.
+func (s *CopyObjectInput) SetWebsiteRedirectLocation(v string) *CopyObjectInput {
+	s.WebsiteRedirectLocation = &v
+	return s
+}
+
+type CopyObjectOutput struct {
+	_ struct{} `type:"structure" payload:"CopyObjectResult"`
+
+	CopyObjectResult *CopyObjectResult `type:"structure"`
+
+	CopySourceVersionId *string `location:"header" locationName:"x-amz-copy-source-version-id" type:"string"`
+
+	// If the object expiration is configured, the response includes this header.
+	Expiration *string `location:"header" locationName:"x-amz-expiration" type:"string"`
+
+	// If present, indicates that the requester was successfully charged for the
+	// request.
+	RequestCharged *string `location:"header" locationName:"x-amz-request-charged" type:"string" enum:"RequestCharged"`
+
+	// If server-side encryption with a customer-provided encryption key was requested,
+	// the response will include this header confirming the encryption algorithm
+	// used.
+	SSECustomerAlgorithm *string `location:"header" locationName:"x-amz-server-side-encryption-customer-algorithm" type:"string"`
+
+	// If server-side encryption with a customer-provided encryption key was requested,
+	// the response will include this header to provide round trip message integrity
+	// verification of the customer-provided encryption key.
+	SSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key-MD5" type:"string"`
+
+	// If present, specifies the ID of the AWS Key Management Service (KMS) master
+	// encryption key that was used for the object.
+	SSEKMSKeyId *string `location:"header" locationName:"x-amz-server-side-encryption-aws-kms-key-id" type:"string"`
+
+	// The Server-side encryption algorithm used when storing this object in S3
+	// (e.g., AES256, aws:kms).
+	ServerSideEncryption *string `location:"header" locationName:"x-amz-server-side-encryption" type:"string" enum:"ServerSideEncryption"`
+
+	// Version ID of the newly created copy.
+	VersionId *string `location:"header" locationName:"x-amz-version-id" type:"string"`
+}
+
+// String returns the string representation
+func (s CopyObjectOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s CopyObjectOutput) GoString() string {
+	return s.String()
+}
+
+// SetCopyObjectResult sets the CopyObjectResult field's value.
+func (s *CopyObjectOutput) SetCopyObjectResult(v *CopyObjectResult) *CopyObjectOutput {
+	s.CopyObjectResult = v
+	return s
+}
+
+// SetCopySourceVersionId sets the CopySourceVersionId field's value.
+func (s *CopyObjectOutput) SetCopySourceVersionId(v string) *CopyObjectOutput {
+	s.CopySourceVersionId = &v
+	return s
+}
+
+// SetExpiration sets the Expiration field's value.
+func (s *CopyObjectOutput) SetExpiration(v string) *CopyObjectOutput {
+	s.Expiration = &v
+	return s
+}
+
+// SetRequestCharged sets the RequestCharged field's value.
+func (s *CopyObjectOutput) SetRequestCharged(v string) *CopyObjectOutput {
+	s.RequestCharged = &v
+	return s
+}
+
+// SetSSECustomerAlgorithm sets the SSECustomerAlgorithm field's value.
+func (s *CopyObjectOutput) SetSSECustomerAlgorithm(v string) *CopyObjectOutput {
+	s.SSECustomerAlgorithm = &v
+	return s
+}
+
+// SetSSECustomerKeyMD5 sets the SSECustomerKeyMD5 field's value.
+func (s *CopyObjectOutput) SetSSECustomerKeyMD5(v string) *CopyObjectOutput {
+	s.SSECustomerKeyMD5 = &v
+	return s
+}
+
+// SetSSEKMSKeyId sets the SSEKMSKeyId field's value.
+func (s *CopyObjectOutput) SetSSEKMSKeyId(v string) *CopyObjectOutput {
+	s.SSEKMSKeyId = &v
+	return s
+}
+
+// SetServerSideEncryption sets the ServerSideEncryption field's value.
+func (s *CopyObjectOutput) SetServerSideEncryption(v string) *CopyObjectOutput {
+	s.ServerSideEncryption = &v
+	return s
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *CopyObjectOutput) SetVersionId(v string) *CopyObjectOutput {
+	s.VersionId = &v
+	return s
+}
+
+type CopyObjectResult struct {
+	_ struct{} `type:"structure"`
+
+	ETag *string `type:"string"`
+
+	LastModified *time.Time `type:"timestamp"`
+}
+
+// String returns the string representation
+func (s CopyObjectResult) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s CopyObjectResult) GoString() string {
+	return s.String()
+}
+
+// SetETag sets the ETag field's value.
+func (s *CopyObjectResult) SetETag(v string) *CopyObjectResult {
+	s.ETag = &v
+	return s
+}
+
+// SetLastModified sets the LastModified field's value.
+func (s *CopyObjectResult) SetLastModified(v time.Time) *CopyObjectResult {
+	s.LastModified = &v
+	return s
+}
+
+type CopyPartResult struct {
+	_ struct{} `type:"structure"`
+
+	// Entity tag of the object.
+	ETag *string `type:"string"`
+
+	// Date and time at which the object was uploaded.
+	LastModified *time.Time `type:"timestamp"`
+}
+
+// String returns the string representation
+func (s CopyPartResult) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s CopyPartResult) GoString() string {
+	return s.String()
+}
+
+// SetETag sets the ETag field's value.
+func (s *CopyPartResult) SetETag(v string) *CopyPartResult {
+	s.ETag = &v
+	return s
+}
+
+// SetLastModified sets the LastModified field's value.
+func (s *CopyPartResult) SetLastModified(v time.Time) *CopyPartResult {
+	s.LastModified = &v
+	return s
+}
+
+type CreateBucketConfiguration struct {
+	_ struct{} `type:"structure"`
+
+	// Specifies the region where the bucket will be created. If you don't specify
+	// a region, the bucket will be created in US Standard.
+	LocationConstraint *string `type:"string" enum:"BucketLocationConstraint"`
+}
+
+// String returns the string representation
+func (s CreateBucketConfiguration) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s CreateBucketConfiguration) GoString() string {
+	return s.String()
+}
+
+// SetLocationConstraint sets the LocationConstraint field's value.
+func (s *CreateBucketConfiguration) SetLocationConstraint(v string) *CreateBucketConfiguration {
+	s.LocationConstraint = &v
+	return s
+}
+
+type CreateBucketInput struct {
+	_ struct{} `type:"structure" payload:"CreateBucketConfiguration"`
+
+	// The canned ACL to apply to the bucket.
+	ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"BucketCannedACL"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	CreateBucketConfiguration *CreateBucketConfiguration `locationName:"CreateBucketConfiguration" type:"structure" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+
+	// Allows grantee the read, write, read ACP, and write ACP permissions on the
+	// bucket.
+	GrantFullControl *string `location:"header" locationName:"x-amz-grant-full-control" type:"string"`
+
+	// Allows grantee to list the objects in the bucket.
+	GrantRead *string `location:"header" locationName:"x-amz-grant-read" type:"string"`
+
+	// Allows grantee to read the bucket ACL.
+	GrantReadACP *string `location:"header" locationName:"x-amz-grant-read-acp" type:"string"`
+
+	// Allows grantee to create, overwrite, and delete any object in the bucket.
+	GrantWrite *string `location:"header" locationName:"x-amz-grant-write" type:"string"`
+
+	// Allows grantee to write the ACL for the applicable bucket.
+	GrantWriteACP *string `location:"header" locationName:"x-amz-grant-write-acp" type:"string"`
+}
+
+// String returns the string representation
+func (s CreateBucketInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s CreateBucketInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *CreateBucketInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "CreateBucketInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetACL sets the ACL field's value.
+func (s *CreateBucketInput) SetACL(v string) *CreateBucketInput {
+	s.ACL = &v
+	return s
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *CreateBucketInput) SetBucket(v string) *CreateBucketInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *CreateBucketInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetCreateBucketConfiguration sets the CreateBucketConfiguration field's value.
+func (s *CreateBucketInput) SetCreateBucketConfiguration(v *CreateBucketConfiguration) *CreateBucketInput {
+	s.CreateBucketConfiguration = v
+	return s
+}
+
+// SetGrantFullControl sets the GrantFullControl field's value.
+func (s *CreateBucketInput) SetGrantFullControl(v string) *CreateBucketInput {
+	s.GrantFullControl = &v
+	return s
+}
+
+// SetGrantRead sets the GrantRead field's value.
+func (s *CreateBucketInput) SetGrantRead(v string) *CreateBucketInput {
+	s.GrantRead = &v
+	return s
+}
+
+// SetGrantReadACP sets the GrantReadACP field's value.
+func (s *CreateBucketInput) SetGrantReadACP(v string) *CreateBucketInput {
+	s.GrantReadACP = &v
+	return s
+}
+
+// SetGrantWrite sets the GrantWrite field's value.
+func (s *CreateBucketInput) SetGrantWrite(v string) *CreateBucketInput {
+	s.GrantWrite = &v
+	return s
+}
+
+// SetGrantWriteACP sets the GrantWriteACP field's value.
+func (s *CreateBucketInput) SetGrantWriteACP(v string) *CreateBucketInput {
+	s.GrantWriteACP = &v
+	return s
+}
+
+type CreateBucketOutput struct {
+	_ struct{} `type:"structure"`
+
+	Location *string `location:"header" locationName:"Location" type:"string"`
+}
+
+// String returns the string representation
+func (s CreateBucketOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s CreateBucketOutput) GoString() string {
+	return s.String()
+}
+
+// SetLocation sets the Location field's value.
+func (s *CreateBucketOutput) SetLocation(v string) *CreateBucketOutput {
+	s.Location = &v
+	return s
+}
+
+type CreateMultipartUploadInput struct {
+	_ struct{} `type:"structure"`
+
+	// The canned ACL to apply to the object.
+	ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"ObjectCannedACL"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Specifies caching behavior along the request/reply chain.
+	CacheControl *string `location:"header" locationName:"Cache-Control" type:"string"`
+
+	// Specifies presentational information for the object.
+	ContentDisposition *string `location:"header" locationName:"Content-Disposition" type:"string"`
+
+	// Specifies what content encodings have been applied to the object and thus
+	// what decoding mechanisms must be applied to obtain the media-type referenced
+	// by the Content-Type header field.
+	ContentEncoding *string `location:"header" locationName:"Content-Encoding" type:"string"`
+
+	// The language the content is in.
+	ContentLanguage *string `location:"header" locationName:"Content-Language" type:"string"`
+
+	// A standard MIME type describing the format of the object data.
+	ContentType *string `location:"header" locationName:"Content-Type" type:"string"`
+
+	// The date and time at which the object is no longer cacheable.
+	Expires *time.Time `location:"header" locationName:"Expires" type:"timestamp"`
+
+	// Gives the grantee READ, READ_ACP, and WRITE_ACP permissions on the object.
+	GrantFullControl *string `location:"header" locationName:"x-amz-grant-full-control" type:"string"`
+
+	// Allows grantee to read the object data and its metadata.
+	GrantRead *string `location:"header" locationName:"x-amz-grant-read" type:"string"`
+
+	// Allows grantee to read the object ACL.
+	GrantReadACP *string `location:"header" locationName:"x-amz-grant-read-acp" type:"string"`
+
+	// Allows grantee to write the ACL for the applicable object.
+	GrantWriteACP *string `location:"header" locationName:"x-amz-grant-write-acp" type:"string"`
+
+	// Key is a required field
+	Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"`
+
+	// A map of metadata to store with the object in S3.
+	Metadata map[string]*string `location:"headers" locationName:"x-amz-meta-" type:"map"`
+
+	// Confirms that the requester knows that she or he will be charged for the
+	// request. Bucket owners need not specify this parameter in their requests.
+	// Documentation on downloading objects from requester pays buckets can be found
+	// at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
+	RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"`
+
+	// Specifies the algorithm to use to when encrypting the object (e.g., AES256).
+	SSECustomerAlgorithm *string `location:"header" locationName:"x-amz-server-side-encryption-customer-algorithm" type:"string"`
+
+	// Specifies the customer-provided encryption key for Amazon S3 to use in encrypting
+	// data. This value is used to store the object and then it is discarded; Amazon
+	// does not store the encryption key. The key must be appropriate for use with
+	// the algorithm specified in the x-amz-server-side​-encryption​-customer-algorithm
+	// header.
+	SSECustomerKey *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key" type:"string"`
+
+	// Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321.
+	// Amazon S3 uses this header for a message integrity check to ensure the encryption
+	// key was transmitted without error.
+	SSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key-MD5" type:"string"`
+
+	// Specifies the AWS KMS key ID to use for object encryption. All GET and PUT
+	// requests for an object protected by AWS KMS will fail if not made via SSL
+	// or using SigV4. Documentation on configuring any of the officially supported
+	// AWS SDKs and CLI can be found at http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingAWSSDK.html#specify-signature-version
+	SSEKMSKeyId *string `location:"header" locationName:"x-amz-server-side-encryption-aws-kms-key-id" type:"string"`
+
+	// The Server-side encryption algorithm used when storing this object in S3
+	// (e.g., AES256, aws:kms).
+	ServerSideEncryption *string `location:"header" locationName:"x-amz-server-side-encryption" type:"string" enum:"ServerSideEncryption"`
+
+	// The type of storage to use for the object. Defaults to 'STANDARD'.
+	StorageClass *string `location:"header" locationName:"x-amz-storage-class" type:"string" enum:"StorageClass"`
+
+	// The tag-set for the object. The tag-set must be encoded as URL Query parameters
+	Tagging *string `location:"header" locationName:"x-amz-tagging" type:"string"`
+
+	// If the bucket is configured as a website, redirects requests for this object
+	// to another object in the same bucket or to an external URL. Amazon S3 stores
+	// the value of this header in the object metadata.
+	WebsiteRedirectLocation *string `location:"header" locationName:"x-amz-website-redirect-location" type:"string"`
+}
+
+// String returns the string representation
+func (s CreateMultipartUploadInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s CreateMultipartUploadInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *CreateMultipartUploadInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "CreateMultipartUploadInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Key == nil {
+		invalidParams.Add(request.NewErrParamRequired("Key"))
+	}
+	if s.Key != nil && len(*s.Key) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetACL sets the ACL field's value.
+func (s *CreateMultipartUploadInput) SetACL(v string) *CreateMultipartUploadInput {
+	s.ACL = &v
+	return s
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *CreateMultipartUploadInput) SetBucket(v string) *CreateMultipartUploadInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *CreateMultipartUploadInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetCacheControl sets the CacheControl field's value.
+func (s *CreateMultipartUploadInput) SetCacheControl(v string) *CreateMultipartUploadInput {
+	s.CacheControl = &v
+	return s
+}
+
+// SetContentDisposition sets the ContentDisposition field's value.
+func (s *CreateMultipartUploadInput) SetContentDisposition(v string) *CreateMultipartUploadInput {
+	s.ContentDisposition = &v
+	return s
+}
+
+// SetContentEncoding sets the ContentEncoding field's value.
+func (s *CreateMultipartUploadInput) SetContentEncoding(v string) *CreateMultipartUploadInput {
+	s.ContentEncoding = &v
+	return s
+}
+
+// SetContentLanguage sets the ContentLanguage field's value.
+func (s *CreateMultipartUploadInput) SetContentLanguage(v string) *CreateMultipartUploadInput {
+	s.ContentLanguage = &v
+	return s
+}
+
+// SetContentType sets the ContentType field's value.
+func (s *CreateMultipartUploadInput) SetContentType(v string) *CreateMultipartUploadInput {
+	s.ContentType = &v
+	return s
+}
+
+// SetExpires sets the Expires field's value.
+func (s *CreateMultipartUploadInput) SetExpires(v time.Time) *CreateMultipartUploadInput {
+	s.Expires = &v
+	return s
+}
+
+// SetGrantFullControl sets the GrantFullControl field's value.
+func (s *CreateMultipartUploadInput) SetGrantFullControl(v string) *CreateMultipartUploadInput {
+	s.GrantFullControl = &v
+	return s
+}
+
+// SetGrantRead sets the GrantRead field's value.
+func (s *CreateMultipartUploadInput) SetGrantRead(v string) *CreateMultipartUploadInput {
+	s.GrantRead = &v
+	return s
+}
+
+// SetGrantReadACP sets the GrantReadACP field's value.
+func (s *CreateMultipartUploadInput) SetGrantReadACP(v string) *CreateMultipartUploadInput {
+	s.GrantReadACP = &v
+	return s
+}
+
+// SetGrantWriteACP sets the GrantWriteACP field's value.
+func (s *CreateMultipartUploadInput) SetGrantWriteACP(v string) *CreateMultipartUploadInput {
+	s.GrantWriteACP = &v
+	return s
+}
+
+// SetKey sets the Key field's value.
+func (s *CreateMultipartUploadInput) SetKey(v string) *CreateMultipartUploadInput {
+	s.Key = &v
+	return s
+}
+
+// SetMetadata sets the Metadata field's value.
+func (s *CreateMultipartUploadInput) SetMetadata(v map[string]*string) *CreateMultipartUploadInput {
+	s.Metadata = v
+	return s
+}
+
+// SetRequestPayer sets the RequestPayer field's value.
+func (s *CreateMultipartUploadInput) SetRequestPayer(v string) *CreateMultipartUploadInput {
+	s.RequestPayer = &v
+	return s
+}
+
+// SetSSECustomerAlgorithm sets the SSECustomerAlgorithm field's value.
+func (s *CreateMultipartUploadInput) SetSSECustomerAlgorithm(v string) *CreateMultipartUploadInput {
+	s.SSECustomerAlgorithm = &v
+	return s
+}
+
+// SetSSECustomerKey sets the SSECustomerKey field's value.
+func (s *CreateMultipartUploadInput) SetSSECustomerKey(v string) *CreateMultipartUploadInput {
+	s.SSECustomerKey = &v
+	return s
+}
+
+func (s *CreateMultipartUploadInput) getSSECustomerKey() (v string) {
+	if s.SSECustomerKey == nil {
+		return v
+	}
+	return *s.SSECustomerKey
+}
+
+// SetSSECustomerKeyMD5 sets the SSECustomerKeyMD5 field's value.
+func (s *CreateMultipartUploadInput) SetSSECustomerKeyMD5(v string) *CreateMultipartUploadInput {
+	s.SSECustomerKeyMD5 = &v
+	return s
+}
+
+// SetSSEKMSKeyId sets the SSEKMSKeyId field's value.
+func (s *CreateMultipartUploadInput) SetSSEKMSKeyId(v string) *CreateMultipartUploadInput {
+	s.SSEKMSKeyId = &v
+	return s
+}
+
+// SetServerSideEncryption sets the ServerSideEncryption field's value.
+func (s *CreateMultipartUploadInput) SetServerSideEncryption(v string) *CreateMultipartUploadInput {
+	s.ServerSideEncryption = &v
+	return s
+}
+
+// SetStorageClass sets the StorageClass field's value.
+func (s *CreateMultipartUploadInput) SetStorageClass(v string) *CreateMultipartUploadInput {
+	s.StorageClass = &v
+	return s
+}
+
+// SetTagging sets the Tagging field's value.
+func (s *CreateMultipartUploadInput) SetTagging(v string) *CreateMultipartUploadInput {
+	s.Tagging = &v
+	return s
+}
+
+// SetWebsiteRedirectLocation sets the WebsiteRedirectLocation field's value.
+func (s *CreateMultipartUploadInput) SetWebsiteRedirectLocation(v string) *CreateMultipartUploadInput {
+	s.WebsiteRedirectLocation = &v
+	return s
+}
+
+type CreateMultipartUploadOutput struct {
+	_ struct{} `type:"structure"`
+
+	// Date when multipart upload will become eligible for abort operation by lifecycle.
+	AbortDate *time.Time `location:"header" locationName:"x-amz-abort-date" type:"timestamp"`
+
+	// Id of the lifecycle rule that makes a multipart upload eligible for abort
+	// operation.
+	AbortRuleId *string `location:"header" locationName:"x-amz-abort-rule-id" type:"string"`
+
+	// Name of the bucket to which the multipart upload was initiated.
+	Bucket *string `locationName:"Bucket" type:"string"`
+
+	// Object key for which the multipart upload was initiated.
+	Key *string `min:"1" type:"string"`
+
+	// If present, indicates that the requester was successfully charged for the
+	// request.
+	RequestCharged *string `location:"header" locationName:"x-amz-request-charged" type:"string" enum:"RequestCharged"`
+
+	// If server-side encryption with a customer-provided encryption key was requested,
+	// the response will include this header confirming the encryption algorithm
+	// used.
+	SSECustomerAlgorithm *string `location:"header" locationName:"x-amz-server-side-encryption-customer-algorithm" type:"string"`
+
+	// If server-side encryption with a customer-provided encryption key was requested,
+	// the response will include this header to provide round trip message integrity
+	// verification of the customer-provided encryption key.
+	SSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key-MD5" type:"string"`
+
+	// If present, specifies the ID of the AWS Key Management Service (KMS) master
+	// encryption key that was used for the object.
+	SSEKMSKeyId *string `location:"header" locationName:"x-amz-server-side-encryption-aws-kms-key-id" type:"string"`
+
+	// The Server-side encryption algorithm used when storing this object in S3
+	// (e.g., AES256, aws:kms).
+	ServerSideEncryption *string `location:"header" locationName:"x-amz-server-side-encryption" type:"string" enum:"ServerSideEncryption"`
+
+	// ID for the initiated multipart upload.
+	UploadId *string `type:"string"`
+}
+
+// String returns the string representation
+func (s CreateMultipartUploadOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s CreateMultipartUploadOutput) GoString() string {
+	return s.String()
+}
+
+// SetAbortDate sets the AbortDate field's value.
+func (s *CreateMultipartUploadOutput) SetAbortDate(v time.Time) *CreateMultipartUploadOutput {
+	s.AbortDate = &v
+	return s
+}
+
+// SetAbortRuleId sets the AbortRuleId field's value.
+func (s *CreateMultipartUploadOutput) SetAbortRuleId(v string) *CreateMultipartUploadOutput {
+	s.AbortRuleId = &v
+	return s
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *CreateMultipartUploadOutput) SetBucket(v string) *CreateMultipartUploadOutput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *CreateMultipartUploadOutput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetKey sets the Key field's value.
+func (s *CreateMultipartUploadOutput) SetKey(v string) *CreateMultipartUploadOutput {
+	s.Key = &v
+	return s
+}
+
+// SetRequestCharged sets the RequestCharged field's value.
+func (s *CreateMultipartUploadOutput) SetRequestCharged(v string) *CreateMultipartUploadOutput {
+	s.RequestCharged = &v
+	return s
+}
+
+// SetSSECustomerAlgorithm sets the SSECustomerAlgorithm field's value.
+func (s *CreateMultipartUploadOutput) SetSSECustomerAlgorithm(v string) *CreateMultipartUploadOutput {
+	s.SSECustomerAlgorithm = &v
+	return s
+}
+
+// SetSSECustomerKeyMD5 sets the SSECustomerKeyMD5 field's value.
+func (s *CreateMultipartUploadOutput) SetSSECustomerKeyMD5(v string) *CreateMultipartUploadOutput {
+	s.SSECustomerKeyMD5 = &v
+	return s
+}
+
+// SetSSEKMSKeyId sets the SSEKMSKeyId field's value.
+func (s *CreateMultipartUploadOutput) SetSSEKMSKeyId(v string) *CreateMultipartUploadOutput {
+	s.SSEKMSKeyId = &v
+	return s
+}
+
+// SetServerSideEncryption sets the ServerSideEncryption field's value.
+func (s *CreateMultipartUploadOutput) SetServerSideEncryption(v string) *CreateMultipartUploadOutput {
+	s.ServerSideEncryption = &v
+	return s
+}
+
+// SetUploadId sets the UploadId field's value.
+func (s *CreateMultipartUploadOutput) SetUploadId(v string) *CreateMultipartUploadOutput {
+	s.UploadId = &v
+	return s
+}
+
+type Delete struct {
+	_ struct{} `type:"structure"`
+
+	// Objects is a required field
+	Objects []*ObjectIdentifier `locationName:"Object" type:"list" flattened:"true" required:"true"`
+
+	// Element to enable quiet mode for the request. When you add this element,
+	// you must set its value to true.
+	Quiet *bool `type:"boolean"`
+}
+
+// String returns the string representation
+func (s Delete) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s Delete) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *Delete) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "Delete"}
+	if s.Objects == nil {
+		invalidParams.Add(request.NewErrParamRequired("Objects"))
+	}
+	if s.Objects != nil {
+		for i, v := range s.Objects {
+			if v == nil {
+				continue
+			}
+			if err := v.Validate(); err != nil {
+				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Objects", i), err.(request.ErrInvalidParams))
+			}
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetObjects sets the Objects field's value.
+func (s *Delete) SetObjects(v []*ObjectIdentifier) *Delete {
+	s.Objects = v
+	return s
+}
+
+// SetQuiet sets the Quiet field's value.
+func (s *Delete) SetQuiet(v bool) *Delete {
+	s.Quiet = &v
+	return s
+}
+
+type DeleteBucketAnalyticsConfigurationInput struct {
+	_ struct{} `type:"structure"`
+
+	// The name of the bucket from which an analytics configuration is deleted.
+	//
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// The identifier used to represent an analytics configuration.
+	//
+	// Id is a required field
+	Id *string `location:"querystring" locationName:"id" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s DeleteBucketAnalyticsConfigurationInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteBucketAnalyticsConfigurationInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *DeleteBucketAnalyticsConfigurationInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "DeleteBucketAnalyticsConfigurationInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Id == nil {
+		invalidParams.Add(request.NewErrParamRequired("Id"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *DeleteBucketAnalyticsConfigurationInput) SetBucket(v string) *DeleteBucketAnalyticsConfigurationInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *DeleteBucketAnalyticsConfigurationInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetId sets the Id field's value.
+func (s *DeleteBucketAnalyticsConfigurationInput) SetId(v string) *DeleteBucketAnalyticsConfigurationInput {
+	s.Id = &v
+	return s
+}
+
+type DeleteBucketAnalyticsConfigurationOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s DeleteBucketAnalyticsConfigurationOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteBucketAnalyticsConfigurationOutput) GoString() string {
+	return s.String()
+}
+
+type DeleteBucketCorsInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s DeleteBucketCorsInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteBucketCorsInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *DeleteBucketCorsInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "DeleteBucketCorsInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *DeleteBucketCorsInput) SetBucket(v string) *DeleteBucketCorsInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *DeleteBucketCorsInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type DeleteBucketCorsOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s DeleteBucketCorsOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteBucketCorsOutput) GoString() string {
+	return s.String()
+}
+
+type DeleteBucketEncryptionInput struct {
+	_ struct{} `type:"structure"`
+
+	// The name of the bucket containing the server-side encryption configuration
+	// to delete.
+	//
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s DeleteBucketEncryptionInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteBucketEncryptionInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *DeleteBucketEncryptionInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "DeleteBucketEncryptionInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *DeleteBucketEncryptionInput) SetBucket(v string) *DeleteBucketEncryptionInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *DeleteBucketEncryptionInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type DeleteBucketEncryptionOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s DeleteBucketEncryptionOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteBucketEncryptionOutput) GoString() string {
+	return s.String()
+}
+
+type DeleteBucketInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s DeleteBucketInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteBucketInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *DeleteBucketInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "DeleteBucketInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *DeleteBucketInput) SetBucket(v string) *DeleteBucketInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *DeleteBucketInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type DeleteBucketInventoryConfigurationInput struct {
+	_ struct{} `type:"structure"`
+
+	// The name of the bucket containing the inventory configuration to delete.
+	//
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// The ID used to identify the inventory configuration.
+	//
+	// Id is a required field
+	Id *string `location:"querystring" locationName:"id" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s DeleteBucketInventoryConfigurationInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteBucketInventoryConfigurationInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *DeleteBucketInventoryConfigurationInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "DeleteBucketInventoryConfigurationInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Id == nil {
+		invalidParams.Add(request.NewErrParamRequired("Id"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *DeleteBucketInventoryConfigurationInput) SetBucket(v string) *DeleteBucketInventoryConfigurationInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *DeleteBucketInventoryConfigurationInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetId sets the Id field's value.
+func (s *DeleteBucketInventoryConfigurationInput) SetId(v string) *DeleteBucketInventoryConfigurationInput {
+	s.Id = &v
+	return s
+}
+
+type DeleteBucketInventoryConfigurationOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s DeleteBucketInventoryConfigurationOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteBucketInventoryConfigurationOutput) GoString() string {
+	return s.String()
+}
+
+type DeleteBucketLifecycleInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s DeleteBucketLifecycleInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteBucketLifecycleInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *DeleteBucketLifecycleInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "DeleteBucketLifecycleInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *DeleteBucketLifecycleInput) SetBucket(v string) *DeleteBucketLifecycleInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *DeleteBucketLifecycleInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type DeleteBucketLifecycleOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s DeleteBucketLifecycleOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteBucketLifecycleOutput) GoString() string {
+	return s.String()
+}
+
+type DeleteBucketMetricsConfigurationInput struct {
+	_ struct{} `type:"structure"`
+
+	// The name of the bucket containing the metrics configuration to delete.
+	//
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// The ID used to identify the metrics configuration.
+	//
+	// Id is a required field
+	Id *string `location:"querystring" locationName:"id" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s DeleteBucketMetricsConfigurationInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteBucketMetricsConfigurationInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *DeleteBucketMetricsConfigurationInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "DeleteBucketMetricsConfigurationInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Id == nil {
+		invalidParams.Add(request.NewErrParamRequired("Id"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *DeleteBucketMetricsConfigurationInput) SetBucket(v string) *DeleteBucketMetricsConfigurationInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *DeleteBucketMetricsConfigurationInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetId sets the Id field's value.
+func (s *DeleteBucketMetricsConfigurationInput) SetId(v string) *DeleteBucketMetricsConfigurationInput {
+	s.Id = &v
+	return s
+}
+
+type DeleteBucketMetricsConfigurationOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s DeleteBucketMetricsConfigurationOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteBucketMetricsConfigurationOutput) GoString() string {
+	return s.String()
+}
+
+type DeleteBucketOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s DeleteBucketOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteBucketOutput) GoString() string {
+	return s.String()
+}
+
+type DeleteBucketPolicyInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s DeleteBucketPolicyInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteBucketPolicyInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *DeleteBucketPolicyInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "DeleteBucketPolicyInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *DeleteBucketPolicyInput) SetBucket(v string) *DeleteBucketPolicyInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *DeleteBucketPolicyInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type DeleteBucketPolicyOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s DeleteBucketPolicyOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteBucketPolicyOutput) GoString() string {
+	return s.String()
+}
+
+type DeleteBucketReplicationInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s DeleteBucketReplicationInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteBucketReplicationInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *DeleteBucketReplicationInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "DeleteBucketReplicationInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *DeleteBucketReplicationInput) SetBucket(v string) *DeleteBucketReplicationInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *DeleteBucketReplicationInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type DeleteBucketReplicationOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s DeleteBucketReplicationOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteBucketReplicationOutput) GoString() string {
+	return s.String()
+}
+
+type DeleteBucketTaggingInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s DeleteBucketTaggingInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteBucketTaggingInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *DeleteBucketTaggingInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "DeleteBucketTaggingInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *DeleteBucketTaggingInput) SetBucket(v string) *DeleteBucketTaggingInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *DeleteBucketTaggingInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type DeleteBucketTaggingOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s DeleteBucketTaggingOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteBucketTaggingOutput) GoString() string {
+	return s.String()
+}
+
+type DeleteBucketWebsiteInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s DeleteBucketWebsiteInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteBucketWebsiteInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *DeleteBucketWebsiteInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "DeleteBucketWebsiteInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *DeleteBucketWebsiteInput) SetBucket(v string) *DeleteBucketWebsiteInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *DeleteBucketWebsiteInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type DeleteBucketWebsiteOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s DeleteBucketWebsiteOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteBucketWebsiteOutput) GoString() string {
+	return s.String()
+}
+
+type DeleteMarkerEntry struct {
+	_ struct{} `type:"structure"`
+
+	// Specifies whether the object is (true) or is not (false) the latest version
+	// of an object.
+	IsLatest *bool `type:"boolean"`
+
+	// The object key.
+	Key *string `min:"1" type:"string"`
+
+	// Date and time the object was last modified.
+	LastModified *time.Time `type:"timestamp"`
+
+	Owner *Owner `type:"structure"`
+
+	// Version ID of an object.
+	VersionId *string `type:"string"`
+}
+
+// String returns the string representation
+func (s DeleteMarkerEntry) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteMarkerEntry) GoString() string {
+	return s.String()
+}
+
+// SetIsLatest sets the IsLatest field's value.
+func (s *DeleteMarkerEntry) SetIsLatest(v bool) *DeleteMarkerEntry {
+	s.IsLatest = &v
+	return s
+}
+
+// SetKey sets the Key field's value.
+func (s *DeleteMarkerEntry) SetKey(v string) *DeleteMarkerEntry {
+	s.Key = &v
+	return s
+}
+
+// SetLastModified sets the LastModified field's value.
+func (s *DeleteMarkerEntry) SetLastModified(v time.Time) *DeleteMarkerEntry {
+	s.LastModified = &v
+	return s
+}
+
+// SetOwner sets the Owner field's value.
+func (s *DeleteMarkerEntry) SetOwner(v *Owner) *DeleteMarkerEntry {
+	s.Owner = v
+	return s
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *DeleteMarkerEntry) SetVersionId(v string) *DeleteMarkerEntry {
+	s.VersionId = &v
+	return s
+}
+
+type DeleteObjectInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Key is a required field
+	Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"`
+
+	// The concatenation of the authentication device's serial number, a space,
+	// and the value that is displayed on your authentication device.
+	MFA *string `location:"header" locationName:"x-amz-mfa" type:"string"`
+
+	// Confirms that the requester knows that she or he will be charged for the
+	// request. Bucket owners need not specify this parameter in their requests.
+	// Documentation on downloading objects from requester pays buckets can be found
+	// at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
+	RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"`
+
+	// VersionId used to reference a specific version of the object.
+	VersionId *string `location:"querystring" locationName:"versionId" type:"string"`
+}
+
+// String returns the string representation
+func (s DeleteObjectInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteObjectInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *DeleteObjectInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "DeleteObjectInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Key == nil {
+		invalidParams.Add(request.NewErrParamRequired("Key"))
+	}
+	if s.Key != nil && len(*s.Key) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *DeleteObjectInput) SetBucket(v string) *DeleteObjectInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *DeleteObjectInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetKey sets the Key field's value.
+func (s *DeleteObjectInput) SetKey(v string) *DeleteObjectInput {
+	s.Key = &v
+	return s
+}
+
+// SetMFA sets the MFA field's value.
+func (s *DeleteObjectInput) SetMFA(v string) *DeleteObjectInput {
+	s.MFA = &v
+	return s
+}
+
+// SetRequestPayer sets the RequestPayer field's value.
+func (s *DeleteObjectInput) SetRequestPayer(v string) *DeleteObjectInput {
+	s.RequestPayer = &v
+	return s
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *DeleteObjectInput) SetVersionId(v string) *DeleteObjectInput {
+	s.VersionId = &v
+	return s
+}
+
+type DeleteObjectOutput struct {
+	_ struct{} `type:"structure"`
+
+	// Specifies whether the versioned object that was permanently deleted was (true)
+	// or was not (false) a delete marker.
+	DeleteMarker *bool `location:"header" locationName:"x-amz-delete-marker" type:"boolean"`
+
+	// If present, indicates that the requester was successfully charged for the
+	// request.
+	RequestCharged *string `location:"header" locationName:"x-amz-request-charged" type:"string" enum:"RequestCharged"`
+
+	// Returns the version ID of the delete marker created as a result of the DELETE
+	// operation.
+	VersionId *string `location:"header" locationName:"x-amz-version-id" type:"string"`
+}
+
+// String returns the string representation
+func (s DeleteObjectOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteObjectOutput) GoString() string {
+	return s.String()
+}
+
+// SetDeleteMarker sets the DeleteMarker field's value.
+func (s *DeleteObjectOutput) SetDeleteMarker(v bool) *DeleteObjectOutput {
+	s.DeleteMarker = &v
+	return s
+}
+
+// SetRequestCharged sets the RequestCharged field's value.
+func (s *DeleteObjectOutput) SetRequestCharged(v string) *DeleteObjectOutput {
+	s.RequestCharged = &v
+	return s
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *DeleteObjectOutput) SetVersionId(v string) *DeleteObjectOutput {
+	s.VersionId = &v
+	return s
+}
+
+type DeleteObjectTaggingInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Key is a required field
+	Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"`
+
+	// The versionId of the object that the tag-set will be removed from.
+	VersionId *string `location:"querystring" locationName:"versionId" type:"string"`
+}
+
+// String returns the string representation
+func (s DeleteObjectTaggingInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteObjectTaggingInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *DeleteObjectTaggingInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "DeleteObjectTaggingInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Key == nil {
+		invalidParams.Add(request.NewErrParamRequired("Key"))
+	}
+	if s.Key != nil && len(*s.Key) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *DeleteObjectTaggingInput) SetBucket(v string) *DeleteObjectTaggingInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *DeleteObjectTaggingInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetKey sets the Key field's value.
+func (s *DeleteObjectTaggingInput) SetKey(v string) *DeleteObjectTaggingInput {
+	s.Key = &v
+	return s
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *DeleteObjectTaggingInput) SetVersionId(v string) *DeleteObjectTaggingInput {
+	s.VersionId = &v
+	return s
+}
+
+type DeleteObjectTaggingOutput struct {
+	_ struct{} `type:"structure"`
+
+	// The versionId of the object the tag-set was removed from.
+	VersionId *string `location:"header" locationName:"x-amz-version-id" type:"string"`
+}
+
+// String returns the string representation
+func (s DeleteObjectTaggingOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteObjectTaggingOutput) GoString() string {
+	return s.String()
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *DeleteObjectTaggingOutput) SetVersionId(v string) *DeleteObjectTaggingOutput {
+	s.VersionId = &v
+	return s
+}
+
+type DeleteObjectsInput struct {
+	_ struct{} `type:"structure" payload:"Delete"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Delete is a required field
+	Delete *Delete `locationName:"Delete" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+
+	// The concatenation of the authentication device's serial number, a space,
+	// and the value that is displayed on your authentication device.
+	MFA *string `location:"header" locationName:"x-amz-mfa" type:"string"`
+
+	// Confirms that the requester knows that she or he will be charged for the
+	// request. Bucket owners need not specify this parameter in their requests.
+	// Documentation on downloading objects from requester pays buckets can be found
+	// at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
+	RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"`
+}
+
+// String returns the string representation
+func (s DeleteObjectsInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteObjectsInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *DeleteObjectsInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "DeleteObjectsInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Delete == nil {
+		invalidParams.Add(request.NewErrParamRequired("Delete"))
+	}
+	if s.Delete != nil {
+		if err := s.Delete.Validate(); err != nil {
+			invalidParams.AddNested("Delete", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *DeleteObjectsInput) SetBucket(v string) *DeleteObjectsInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *DeleteObjectsInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetDelete sets the Delete field's value.
+func (s *DeleteObjectsInput) SetDelete(v *Delete) *DeleteObjectsInput {
+	s.Delete = v
+	return s
+}
+
+// SetMFA sets the MFA field's value.
+func (s *DeleteObjectsInput) SetMFA(v string) *DeleteObjectsInput {
+	s.MFA = &v
+	return s
+}
+
+// SetRequestPayer sets the RequestPayer field's value.
+func (s *DeleteObjectsInput) SetRequestPayer(v string) *DeleteObjectsInput {
+	s.RequestPayer = &v
+	return s
+}
+
+type DeleteObjectsOutput struct {
+	_ struct{} `type:"structure"`
+
+	Deleted []*DeletedObject `type:"list" flattened:"true"`
+
+	Errors []*Error `locationName:"Error" type:"list" flattened:"true"`
+
+	// If present, indicates that the requester was successfully charged for the
+	// request.
+	RequestCharged *string `location:"header" locationName:"x-amz-request-charged" type:"string" enum:"RequestCharged"`
+}
+
+// String returns the string representation
+func (s DeleteObjectsOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeleteObjectsOutput) GoString() string {
+	return s.String()
+}
+
+// SetDeleted sets the Deleted field's value.
+func (s *DeleteObjectsOutput) SetDeleted(v []*DeletedObject) *DeleteObjectsOutput {
+	s.Deleted = v
+	return s
+}
+
+// SetErrors sets the Errors field's value.
+func (s *DeleteObjectsOutput) SetErrors(v []*Error) *DeleteObjectsOutput {
+	s.Errors = v
+	return s
+}
+
+// SetRequestCharged sets the RequestCharged field's value.
+func (s *DeleteObjectsOutput) SetRequestCharged(v string) *DeleteObjectsOutput {
+	s.RequestCharged = &v
+	return s
+}
+
+type DeletedObject struct {
+	_ struct{} `type:"structure"`
+
+	DeleteMarker *bool `type:"boolean"`
+
+	DeleteMarkerVersionId *string `type:"string"`
+
+	Key *string `min:"1" type:"string"`
+
+	VersionId *string `type:"string"`
+}
+
+// String returns the string representation
+func (s DeletedObject) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DeletedObject) GoString() string {
+	return s.String()
+}
+
+// SetDeleteMarker sets the DeleteMarker field's value.
+func (s *DeletedObject) SetDeleteMarker(v bool) *DeletedObject {
+	s.DeleteMarker = &v
+	return s
+}
+
+// SetDeleteMarkerVersionId sets the DeleteMarkerVersionId field's value.
+func (s *DeletedObject) SetDeleteMarkerVersionId(v string) *DeletedObject {
+	s.DeleteMarkerVersionId = &v
+	return s
+}
+
+// SetKey sets the Key field's value.
+func (s *DeletedObject) SetKey(v string) *DeletedObject {
+	s.Key = &v
+	return s
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *DeletedObject) SetVersionId(v string) *DeletedObject {
+	s.VersionId = &v
+	return s
+}
+
+// Container for replication destination information.
+type Destination struct {
+	_ struct{} `type:"structure"`
+
+	// Container for information regarding the access control for replicas.
+	AccessControlTranslation *AccessControlTranslation `type:"structure"`
+
+	// Account ID of the destination bucket. Currently this is only being verified
+	// if Access Control Translation is enabled
+	Account *string `type:"string"`
+
+	// Amazon resource name (ARN) of the bucket where you want Amazon S3 to store
+	// replicas of the object identified by the rule.
+	//
+	// Bucket is a required field
+	Bucket *string `type:"string" required:"true"`
+
+	// Container for information regarding encryption based configuration for replicas.
+	EncryptionConfiguration *EncryptionConfiguration `type:"structure"`
+
+	// The class of storage used to store the object.
+	StorageClass *string `type:"string" enum:"StorageClass"`
+}
+
+// String returns the string representation
+func (s Destination) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s Destination) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *Destination) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "Destination"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.AccessControlTranslation != nil {
+		if err := s.AccessControlTranslation.Validate(); err != nil {
+			invalidParams.AddNested("AccessControlTranslation", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetAccessControlTranslation sets the AccessControlTranslation field's value.
+func (s *Destination) SetAccessControlTranslation(v *AccessControlTranslation) *Destination {
+	s.AccessControlTranslation = v
+	return s
+}
+
+// SetAccount sets the Account field's value.
+func (s *Destination) SetAccount(v string) *Destination {
+	s.Account = &v
+	return s
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *Destination) SetBucket(v string) *Destination {
+	s.Bucket = &v
+	return s
+}
+
+func (s *Destination) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetEncryptionConfiguration sets the EncryptionConfiguration field's value.
+func (s *Destination) SetEncryptionConfiguration(v *EncryptionConfiguration) *Destination {
+	s.EncryptionConfiguration = v
+	return s
+}
+
+// SetStorageClass sets the StorageClass field's value.
+func (s *Destination) SetStorageClass(v string) *Destination {
+	s.StorageClass = &v
+	return s
+}
+
+// Describes the server-side encryption that will be applied to the restore
+// results.
+type Encryption struct {
+	_ struct{} `type:"structure"`
+
+	// The server-side encryption algorithm used when storing job results in Amazon
+	// S3 (e.g., AES256, aws:kms).
+	//
+	// EncryptionType is a required field
+	EncryptionType *string `type:"string" required:"true" enum:"ServerSideEncryption"`
+
+	// If the encryption type is aws:kms, this optional value can be used to specify
+	// the encryption context for the restore results.
+	KMSContext *string `type:"string"`
+
+	// If the encryption type is aws:kms, this optional value specifies the AWS
+	// KMS key ID to use for encryption of job results.
+	KMSKeyId *string `type:"string"`
+}
+
+// String returns the string representation
+func (s Encryption) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s Encryption) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *Encryption) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "Encryption"}
+	if s.EncryptionType == nil {
+		invalidParams.Add(request.NewErrParamRequired("EncryptionType"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetEncryptionType sets the EncryptionType field's value.
+func (s *Encryption) SetEncryptionType(v string) *Encryption {
+	s.EncryptionType = &v
+	return s
+}
+
+// SetKMSContext sets the KMSContext field's value.
+func (s *Encryption) SetKMSContext(v string) *Encryption {
+	s.KMSContext = &v
+	return s
+}
+
+// SetKMSKeyId sets the KMSKeyId field's value.
+func (s *Encryption) SetKMSKeyId(v string) *Encryption {
+	s.KMSKeyId = &v
+	return s
+}
+
+// Container for information regarding encryption based configuration for replicas.
+type EncryptionConfiguration struct {
+	_ struct{} `type:"structure"`
+
+	// The id of the KMS key used to encrypt the replica object.
+	ReplicaKmsKeyID *string `type:"string"`
+}
+
+// String returns the string representation
+func (s EncryptionConfiguration) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s EncryptionConfiguration) GoString() string {
+	return s.String()
+}
+
+// SetReplicaKmsKeyID sets the ReplicaKmsKeyID field's value.
+func (s *EncryptionConfiguration) SetReplicaKmsKeyID(v string) *EncryptionConfiguration {
+	s.ReplicaKmsKeyID = &v
+	return s
+}
+
+type EndEvent struct {
+	_ struct{} `locationName:"EndEvent" type:"structure"`
+}
+
+// String returns the string representation
+func (s EndEvent) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s EndEvent) GoString() string {
+	return s.String()
+}
+
+// The EndEvent is and event in the SelectObjectContentEventStream group of events.
+func (s *EndEvent) eventSelectObjectContentEventStream() {}
+
+// UnmarshalEvent unmarshals the EventStream Message into the EndEvent value.
+// This method is only used internally within the SDK's EventStream handling.
+func (s *EndEvent) UnmarshalEvent(
+	payloadUnmarshaler protocol.PayloadUnmarshaler,
+	msg eventstream.Message,
+) error {
+	return nil
+}
+
+type Error struct {
+	_ struct{} `type:"structure"`
+
+	Code *string `type:"string"`
+
+	Key *string `min:"1" type:"string"`
+
+	Message *string `type:"string"`
+
+	VersionId *string `type:"string"`
+}
+
+// String returns the string representation
+func (s Error) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s Error) GoString() string {
+	return s.String()
+}
+
+// SetCode sets the Code field's value.
+func (s *Error) SetCode(v string) *Error {
+	s.Code = &v
+	return s
+}
+
+// SetKey sets the Key field's value.
+func (s *Error) SetKey(v string) *Error {
+	s.Key = &v
+	return s
+}
+
+// SetMessage sets the Message field's value.
+func (s *Error) SetMessage(v string) *Error {
+	s.Message = &v
+	return s
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *Error) SetVersionId(v string) *Error {
+	s.VersionId = &v
+	return s
+}
+
+type ErrorDocument struct {
+	_ struct{} `type:"structure"`
+
+	// The object key name to use when a 4XX class error occurs.
+	//
+	// Key is a required field
+	Key *string `min:"1" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s ErrorDocument) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ErrorDocument) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *ErrorDocument) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "ErrorDocument"}
+	if s.Key == nil {
+		invalidParams.Add(request.NewErrParamRequired("Key"))
+	}
+	if s.Key != nil && len(*s.Key) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetKey sets the Key field's value.
+func (s *ErrorDocument) SetKey(v string) *ErrorDocument {
+	s.Key = &v
+	return s
+}
+
+// Container for key value pair that defines the criteria for the filter rule.
+type FilterRule struct {
+	_ struct{} `type:"structure"`
+
+	// Object key name prefix or suffix identifying one or more objects to which
+	// the filtering rule applies. Maximum prefix length can be up to 1,024 characters.
+	// Overlapping prefixes and suffixes are not supported. For more information,
+	// go to Configuring Event Notifications (http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html)
+	// in the Amazon Simple Storage Service Developer Guide.
+	Name *string `type:"string" enum:"FilterRuleName"`
+
+	Value *string `type:"string"`
+}
+
+// String returns the string representation
+func (s FilterRule) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s FilterRule) GoString() string {
+	return s.String()
+}
+
+// SetName sets the Name field's value.
+func (s *FilterRule) SetName(v string) *FilterRule {
+	s.Name = &v
+	return s
+}
+
+// SetValue sets the Value field's value.
+func (s *FilterRule) SetValue(v string) *FilterRule {
+	s.Value = &v
+	return s
+}
+
+type GetBucketAccelerateConfigurationInput struct {
+	_ struct{} `type:"structure"`
+
+	// Name of the bucket for which the accelerate configuration is retrieved.
+	//
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s GetBucketAccelerateConfigurationInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketAccelerateConfigurationInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetBucketAccelerateConfigurationInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetBucketAccelerateConfigurationInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *GetBucketAccelerateConfigurationInput) SetBucket(v string) *GetBucketAccelerateConfigurationInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *GetBucketAccelerateConfigurationInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type GetBucketAccelerateConfigurationOutput struct {
+	_ struct{} `type:"structure"`
+
+	// The accelerate configuration of the bucket.
+	Status *string `type:"string" enum:"BucketAccelerateStatus"`
+}
+
+// String returns the string representation
+func (s GetBucketAccelerateConfigurationOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketAccelerateConfigurationOutput) GoString() string {
+	return s.String()
+}
+
+// SetStatus sets the Status field's value.
+func (s *GetBucketAccelerateConfigurationOutput) SetStatus(v string) *GetBucketAccelerateConfigurationOutput {
+	s.Status = &v
+	return s
+}
+
+type GetBucketAclInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s GetBucketAclInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketAclInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetBucketAclInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetBucketAclInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *GetBucketAclInput) SetBucket(v string) *GetBucketAclInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *GetBucketAclInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type GetBucketAclOutput struct {
+	_ struct{} `type:"structure"`
+
+	// A list of grants.
+	Grants []*Grant `locationName:"AccessControlList" locationNameList:"Grant" type:"list"`
+
+	Owner *Owner `type:"structure"`
+}
+
+// String returns the string representation
+func (s GetBucketAclOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketAclOutput) GoString() string {
+	return s.String()
+}
+
+// SetGrants sets the Grants field's value.
+func (s *GetBucketAclOutput) SetGrants(v []*Grant) *GetBucketAclOutput {
+	s.Grants = v
+	return s
+}
+
+// SetOwner sets the Owner field's value.
+func (s *GetBucketAclOutput) SetOwner(v *Owner) *GetBucketAclOutput {
+	s.Owner = v
+	return s
+}
+
+type GetBucketAnalyticsConfigurationInput struct {
+	_ struct{} `type:"structure"`
+
+	// The name of the bucket from which an analytics configuration is retrieved.
+	//
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// The identifier used to represent an analytics configuration.
+	//
+	// Id is a required field
+	Id *string `location:"querystring" locationName:"id" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s GetBucketAnalyticsConfigurationInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketAnalyticsConfigurationInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetBucketAnalyticsConfigurationInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetBucketAnalyticsConfigurationInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Id == nil {
+		invalidParams.Add(request.NewErrParamRequired("Id"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *GetBucketAnalyticsConfigurationInput) SetBucket(v string) *GetBucketAnalyticsConfigurationInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *GetBucketAnalyticsConfigurationInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetId sets the Id field's value.
+func (s *GetBucketAnalyticsConfigurationInput) SetId(v string) *GetBucketAnalyticsConfigurationInput {
+	s.Id = &v
+	return s
+}
+
+type GetBucketAnalyticsConfigurationOutput struct {
+	_ struct{} `type:"structure" payload:"AnalyticsConfiguration"`
+
+	// The configuration and any analyses for the analytics filter.
+	AnalyticsConfiguration *AnalyticsConfiguration `type:"structure"`
+}
+
+// String returns the string representation
+func (s GetBucketAnalyticsConfigurationOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketAnalyticsConfigurationOutput) GoString() string {
+	return s.String()
+}
+
+// SetAnalyticsConfiguration sets the AnalyticsConfiguration field's value.
+func (s *GetBucketAnalyticsConfigurationOutput) SetAnalyticsConfiguration(v *AnalyticsConfiguration) *GetBucketAnalyticsConfigurationOutput {
+	s.AnalyticsConfiguration = v
+	return s
+}
+
+type GetBucketCorsInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s GetBucketCorsInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketCorsInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetBucketCorsInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetBucketCorsInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *GetBucketCorsInput) SetBucket(v string) *GetBucketCorsInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *GetBucketCorsInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type GetBucketCorsOutput struct {
+	_ struct{} `type:"structure"`
+
+	CORSRules []*CORSRule `locationName:"CORSRule" type:"list" flattened:"true"`
+}
+
+// String returns the string representation
+func (s GetBucketCorsOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketCorsOutput) GoString() string {
+	return s.String()
+}
+
+// SetCORSRules sets the CORSRules field's value.
+func (s *GetBucketCorsOutput) SetCORSRules(v []*CORSRule) *GetBucketCorsOutput {
+	s.CORSRules = v
+	return s
+}
+
+type GetBucketEncryptionInput struct {
+	_ struct{} `type:"structure"`
+
+	// The name of the bucket from which the server-side encryption configuration
+	// is retrieved.
+	//
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s GetBucketEncryptionInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketEncryptionInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetBucketEncryptionInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetBucketEncryptionInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *GetBucketEncryptionInput) SetBucket(v string) *GetBucketEncryptionInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *GetBucketEncryptionInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type GetBucketEncryptionOutput struct {
+	_ struct{} `type:"structure" payload:"ServerSideEncryptionConfiguration"`
+
+	// Container for server-side encryption configuration rules. Currently S3 supports
+	// one rule only.
+	ServerSideEncryptionConfiguration *ServerSideEncryptionConfiguration `type:"structure"`
+}
+
+// String returns the string representation
+func (s GetBucketEncryptionOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketEncryptionOutput) GoString() string {
+	return s.String()
+}
+
+// SetServerSideEncryptionConfiguration sets the ServerSideEncryptionConfiguration field's value.
+func (s *GetBucketEncryptionOutput) SetServerSideEncryptionConfiguration(v *ServerSideEncryptionConfiguration) *GetBucketEncryptionOutput {
+	s.ServerSideEncryptionConfiguration = v
+	return s
+}
+
+type GetBucketInventoryConfigurationInput struct {
+	_ struct{} `type:"structure"`
+
+	// The name of the bucket containing the inventory configuration to retrieve.
+	//
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// The ID used to identify the inventory configuration.
+	//
+	// Id is a required field
+	Id *string `location:"querystring" locationName:"id" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s GetBucketInventoryConfigurationInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketInventoryConfigurationInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetBucketInventoryConfigurationInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetBucketInventoryConfigurationInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Id == nil {
+		invalidParams.Add(request.NewErrParamRequired("Id"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *GetBucketInventoryConfigurationInput) SetBucket(v string) *GetBucketInventoryConfigurationInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *GetBucketInventoryConfigurationInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetId sets the Id field's value.
+func (s *GetBucketInventoryConfigurationInput) SetId(v string) *GetBucketInventoryConfigurationInput {
+	s.Id = &v
+	return s
+}
+
+type GetBucketInventoryConfigurationOutput struct {
+	_ struct{} `type:"structure" payload:"InventoryConfiguration"`
+
+	// Specifies the inventory configuration.
+	InventoryConfiguration *InventoryConfiguration `type:"structure"`
+}
+
+// String returns the string representation
+func (s GetBucketInventoryConfigurationOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketInventoryConfigurationOutput) GoString() string {
+	return s.String()
+}
+
+// SetInventoryConfiguration sets the InventoryConfiguration field's value.
+func (s *GetBucketInventoryConfigurationOutput) SetInventoryConfiguration(v *InventoryConfiguration) *GetBucketInventoryConfigurationOutput {
+	s.InventoryConfiguration = v
+	return s
+}
+
+type GetBucketLifecycleConfigurationInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s GetBucketLifecycleConfigurationInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketLifecycleConfigurationInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetBucketLifecycleConfigurationInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetBucketLifecycleConfigurationInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *GetBucketLifecycleConfigurationInput) SetBucket(v string) *GetBucketLifecycleConfigurationInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *GetBucketLifecycleConfigurationInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type GetBucketLifecycleConfigurationOutput struct {
+	_ struct{} `type:"structure"`
+
+	Rules []*LifecycleRule `locationName:"Rule" type:"list" flattened:"true"`
+}
+
+// String returns the string representation
+func (s GetBucketLifecycleConfigurationOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketLifecycleConfigurationOutput) GoString() string {
+	return s.String()
+}
+
+// SetRules sets the Rules field's value.
+func (s *GetBucketLifecycleConfigurationOutput) SetRules(v []*LifecycleRule) *GetBucketLifecycleConfigurationOutput {
+	s.Rules = v
+	return s
+}
+
+type GetBucketLifecycleInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s GetBucketLifecycleInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketLifecycleInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetBucketLifecycleInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetBucketLifecycleInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *GetBucketLifecycleInput) SetBucket(v string) *GetBucketLifecycleInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *GetBucketLifecycleInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type GetBucketLifecycleOutput struct {
+	_ struct{} `type:"structure"`
+
+	Rules []*Rule `locationName:"Rule" type:"list" flattened:"true"`
+}
+
+// String returns the string representation
+func (s GetBucketLifecycleOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketLifecycleOutput) GoString() string {
+	return s.String()
+}
+
+// SetRules sets the Rules field's value.
+func (s *GetBucketLifecycleOutput) SetRules(v []*Rule) *GetBucketLifecycleOutput {
+	s.Rules = v
+	return s
+}
+
+type GetBucketLocationInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s GetBucketLocationInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketLocationInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetBucketLocationInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetBucketLocationInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *GetBucketLocationInput) SetBucket(v string) *GetBucketLocationInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *GetBucketLocationInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type GetBucketLocationOutput struct {
+	_ struct{} `type:"structure"`
+
+	LocationConstraint *string `type:"string" enum:"BucketLocationConstraint"`
+}
+
+// String returns the string representation
+func (s GetBucketLocationOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketLocationOutput) GoString() string {
+	return s.String()
+}
+
+// SetLocationConstraint sets the LocationConstraint field's value.
+func (s *GetBucketLocationOutput) SetLocationConstraint(v string) *GetBucketLocationOutput {
+	s.LocationConstraint = &v
+	return s
+}
+
+type GetBucketLoggingInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s GetBucketLoggingInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketLoggingInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetBucketLoggingInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetBucketLoggingInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *GetBucketLoggingInput) SetBucket(v string) *GetBucketLoggingInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *GetBucketLoggingInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type GetBucketLoggingOutput struct {
+	_ struct{} `type:"structure"`
+
+	// Container for logging information. Presence of this element indicates that
+	// logging is enabled. Parameters TargetBucket and TargetPrefix are required
+	// in this case.
+	LoggingEnabled *LoggingEnabled `type:"structure"`
+}
+
+// String returns the string representation
+func (s GetBucketLoggingOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketLoggingOutput) GoString() string {
+	return s.String()
+}
+
+// SetLoggingEnabled sets the LoggingEnabled field's value.
+func (s *GetBucketLoggingOutput) SetLoggingEnabled(v *LoggingEnabled) *GetBucketLoggingOutput {
+	s.LoggingEnabled = v
+	return s
+}
+
+type GetBucketMetricsConfigurationInput struct {
+	_ struct{} `type:"structure"`
+
+	// The name of the bucket containing the metrics configuration to retrieve.
+	//
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// The ID used to identify the metrics configuration.
+	//
+	// Id is a required field
+	Id *string `location:"querystring" locationName:"id" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s GetBucketMetricsConfigurationInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketMetricsConfigurationInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetBucketMetricsConfigurationInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetBucketMetricsConfigurationInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Id == nil {
+		invalidParams.Add(request.NewErrParamRequired("Id"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *GetBucketMetricsConfigurationInput) SetBucket(v string) *GetBucketMetricsConfigurationInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *GetBucketMetricsConfigurationInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetId sets the Id field's value.
+func (s *GetBucketMetricsConfigurationInput) SetId(v string) *GetBucketMetricsConfigurationInput {
+	s.Id = &v
+	return s
+}
+
+type GetBucketMetricsConfigurationOutput struct {
+	_ struct{} `type:"structure" payload:"MetricsConfiguration"`
+
+	// Specifies the metrics configuration.
+	MetricsConfiguration *MetricsConfiguration `type:"structure"`
+}
+
+// String returns the string representation
+func (s GetBucketMetricsConfigurationOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketMetricsConfigurationOutput) GoString() string {
+	return s.String()
+}
+
+// SetMetricsConfiguration sets the MetricsConfiguration field's value.
+func (s *GetBucketMetricsConfigurationOutput) SetMetricsConfiguration(v *MetricsConfiguration) *GetBucketMetricsConfigurationOutput {
+	s.MetricsConfiguration = v
+	return s
+}
+
+type GetBucketNotificationConfigurationRequest struct {
+	_ struct{} `type:"structure"`
+
+	// Name of the bucket to get the notification configuration for.
+	//
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s GetBucketNotificationConfigurationRequest) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketNotificationConfigurationRequest) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetBucketNotificationConfigurationRequest) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetBucketNotificationConfigurationRequest"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *GetBucketNotificationConfigurationRequest) SetBucket(v string) *GetBucketNotificationConfigurationRequest {
+	s.Bucket = &v
+	return s
+}
+
+func (s *GetBucketNotificationConfigurationRequest) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type GetBucketPolicyInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s GetBucketPolicyInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketPolicyInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetBucketPolicyInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetBucketPolicyInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *GetBucketPolicyInput) SetBucket(v string) *GetBucketPolicyInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *GetBucketPolicyInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type GetBucketPolicyOutput struct {
+	_ struct{} `type:"structure" payload:"Policy"`
+
+	// The bucket policy as a JSON document.
+	Policy *string `type:"string"`
+}
+
+// String returns the string representation
+func (s GetBucketPolicyOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketPolicyOutput) GoString() string {
+	return s.String()
+}
+
+// SetPolicy sets the Policy field's value.
+func (s *GetBucketPolicyOutput) SetPolicy(v string) *GetBucketPolicyOutput {
+	s.Policy = &v
+	return s
+}
+
+type GetBucketReplicationInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s GetBucketReplicationInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketReplicationInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetBucketReplicationInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetBucketReplicationInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *GetBucketReplicationInput) SetBucket(v string) *GetBucketReplicationInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *GetBucketReplicationInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type GetBucketReplicationOutput struct {
+	_ struct{} `type:"structure" payload:"ReplicationConfiguration"`
+
+	// Container for replication rules. You can add as many as 1,000 rules. Total
+	// replication configuration size can be up to 2 MB.
+	ReplicationConfiguration *ReplicationConfiguration `type:"structure"`
+}
+
+// String returns the string representation
+func (s GetBucketReplicationOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketReplicationOutput) GoString() string {
+	return s.String()
+}
+
+// SetReplicationConfiguration sets the ReplicationConfiguration field's value.
+func (s *GetBucketReplicationOutput) SetReplicationConfiguration(v *ReplicationConfiguration) *GetBucketReplicationOutput {
+	s.ReplicationConfiguration = v
+	return s
+}
+
+type GetBucketRequestPaymentInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s GetBucketRequestPaymentInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketRequestPaymentInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetBucketRequestPaymentInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetBucketRequestPaymentInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *GetBucketRequestPaymentInput) SetBucket(v string) *GetBucketRequestPaymentInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *GetBucketRequestPaymentInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type GetBucketRequestPaymentOutput struct {
+	_ struct{} `type:"structure"`
+
+	// Specifies who pays for the download and request fees.
+	Payer *string `type:"string" enum:"Payer"`
+}
+
+// String returns the string representation
+func (s GetBucketRequestPaymentOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketRequestPaymentOutput) GoString() string {
+	return s.String()
+}
+
+// SetPayer sets the Payer field's value.
+func (s *GetBucketRequestPaymentOutput) SetPayer(v string) *GetBucketRequestPaymentOutput {
+	s.Payer = &v
+	return s
+}
+
+type GetBucketTaggingInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s GetBucketTaggingInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketTaggingInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetBucketTaggingInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetBucketTaggingInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *GetBucketTaggingInput) SetBucket(v string) *GetBucketTaggingInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *GetBucketTaggingInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type GetBucketTaggingOutput struct {
+	_ struct{} `type:"structure"`
+
+	// TagSet is a required field
+	TagSet []*Tag `locationNameList:"Tag" type:"list" required:"true"`
+}
+
+// String returns the string representation
+func (s GetBucketTaggingOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketTaggingOutput) GoString() string {
+	return s.String()
+}
+
+// SetTagSet sets the TagSet field's value.
+func (s *GetBucketTaggingOutput) SetTagSet(v []*Tag) *GetBucketTaggingOutput {
+	s.TagSet = v
+	return s
+}
+
+type GetBucketVersioningInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s GetBucketVersioningInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketVersioningInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetBucketVersioningInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetBucketVersioningInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *GetBucketVersioningInput) SetBucket(v string) *GetBucketVersioningInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *GetBucketVersioningInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type GetBucketVersioningOutput struct {
+	_ struct{} `type:"structure"`
+
+	// Specifies whether MFA delete is enabled in the bucket versioning configuration.
+	// This element is only returned if the bucket has been configured with MFA
+	// delete. If the bucket has never been so configured, this element is not returned.
+	MFADelete *string `locationName:"MfaDelete" type:"string" enum:"MFADeleteStatus"`
+
+	// The versioning state of the bucket.
+	Status *string `type:"string" enum:"BucketVersioningStatus"`
+}
+
+// String returns the string representation
+func (s GetBucketVersioningOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketVersioningOutput) GoString() string {
+	return s.String()
+}
+
+// SetMFADelete sets the MFADelete field's value.
+func (s *GetBucketVersioningOutput) SetMFADelete(v string) *GetBucketVersioningOutput {
+	s.MFADelete = &v
+	return s
+}
+
+// SetStatus sets the Status field's value.
+func (s *GetBucketVersioningOutput) SetStatus(v string) *GetBucketVersioningOutput {
+	s.Status = &v
+	return s
+}
+
+type GetBucketWebsiteInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s GetBucketWebsiteInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketWebsiteInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetBucketWebsiteInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetBucketWebsiteInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *GetBucketWebsiteInput) SetBucket(v string) *GetBucketWebsiteInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *GetBucketWebsiteInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type GetBucketWebsiteOutput struct {
+	_ struct{} `type:"structure"`
+
+	ErrorDocument *ErrorDocument `type:"structure"`
+
+	IndexDocument *IndexDocument `type:"structure"`
+
+	RedirectAllRequestsTo *RedirectAllRequestsTo `type:"structure"`
+
+	RoutingRules []*RoutingRule `locationNameList:"RoutingRule" type:"list"`
+}
+
+// String returns the string representation
+func (s GetBucketWebsiteOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetBucketWebsiteOutput) GoString() string {
+	return s.String()
+}
+
+// SetErrorDocument sets the ErrorDocument field's value.
+func (s *GetBucketWebsiteOutput) SetErrorDocument(v *ErrorDocument) *GetBucketWebsiteOutput {
+	s.ErrorDocument = v
+	return s
+}
+
+// SetIndexDocument sets the IndexDocument field's value.
+func (s *GetBucketWebsiteOutput) SetIndexDocument(v *IndexDocument) *GetBucketWebsiteOutput {
+	s.IndexDocument = v
+	return s
+}
+
+// SetRedirectAllRequestsTo sets the RedirectAllRequestsTo field's value.
+func (s *GetBucketWebsiteOutput) SetRedirectAllRequestsTo(v *RedirectAllRequestsTo) *GetBucketWebsiteOutput {
+	s.RedirectAllRequestsTo = v
+	return s
+}
+
+// SetRoutingRules sets the RoutingRules field's value.
+func (s *GetBucketWebsiteOutput) SetRoutingRules(v []*RoutingRule) *GetBucketWebsiteOutput {
+	s.RoutingRules = v
+	return s
+}
+
+type GetObjectAclInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Key is a required field
+	Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"`
+
+	// Confirms that the requester knows that she or he will be charged for the
+	// request. Bucket owners need not specify this parameter in their requests.
+	// Documentation on downloading objects from requester pays buckets can be found
+	// at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
+	RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"`
+
+	// VersionId used to reference a specific version of the object.
+	VersionId *string `location:"querystring" locationName:"versionId" type:"string"`
+}
+
+// String returns the string representation
+func (s GetObjectAclInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetObjectAclInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetObjectAclInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetObjectAclInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Key == nil {
+		invalidParams.Add(request.NewErrParamRequired("Key"))
+	}
+	if s.Key != nil && len(*s.Key) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *GetObjectAclInput) SetBucket(v string) *GetObjectAclInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *GetObjectAclInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetKey sets the Key field's value.
+func (s *GetObjectAclInput) SetKey(v string) *GetObjectAclInput {
+	s.Key = &v
+	return s
+}
+
+// SetRequestPayer sets the RequestPayer field's value.
+func (s *GetObjectAclInput) SetRequestPayer(v string) *GetObjectAclInput {
+	s.RequestPayer = &v
+	return s
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *GetObjectAclInput) SetVersionId(v string) *GetObjectAclInput {
+	s.VersionId = &v
+	return s
+}
+
+type GetObjectAclOutput struct {
+	_ struct{} `type:"structure"`
+
+	// A list of grants.
+	Grants []*Grant `locationName:"AccessControlList" locationNameList:"Grant" type:"list"`
+
+	Owner *Owner `type:"structure"`
+
+	// If present, indicates that the requester was successfully charged for the
+	// request.
+	RequestCharged *string `location:"header" locationName:"x-amz-request-charged" type:"string" enum:"RequestCharged"`
+}
+
+// String returns the string representation
+func (s GetObjectAclOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetObjectAclOutput) GoString() string {
+	return s.String()
+}
+
+// SetGrants sets the Grants field's value.
+func (s *GetObjectAclOutput) SetGrants(v []*Grant) *GetObjectAclOutput {
+	s.Grants = v
+	return s
+}
+
+// SetOwner sets the Owner field's value.
+func (s *GetObjectAclOutput) SetOwner(v *Owner) *GetObjectAclOutput {
+	s.Owner = v
+	return s
+}
+
+// SetRequestCharged sets the RequestCharged field's value.
+func (s *GetObjectAclOutput) SetRequestCharged(v string) *GetObjectAclOutput {
+	s.RequestCharged = &v
+	return s
+}
+
+type GetObjectInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Return the object only if its entity tag (ETag) is the same as the one specified,
+	// otherwise return a 412 (precondition failed).
+	IfMatch *string `location:"header" locationName:"If-Match" type:"string"`
+
+	// Return the object only if it has been modified since the specified time,
+	// otherwise return a 304 (not modified).
+	IfModifiedSince *time.Time `location:"header" locationName:"If-Modified-Since" type:"timestamp"`
+
+	// Return the object only if its entity tag (ETag) is different from the one
+	// specified, otherwise return a 304 (not modified).
+	IfNoneMatch *string `location:"header" locationName:"If-None-Match" type:"string"`
+
+	// Return the object only if it has not been modified since the specified time,
+	// otherwise return a 412 (precondition failed).
+	IfUnmodifiedSince *time.Time `location:"header" locationName:"If-Unmodified-Since" type:"timestamp"`
+
+	// Key is a required field
+	Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"`
+
+	// Part number of the object being read. This is a positive integer between
+	// 1 and 10,000. Effectively performs a 'ranged' GET request for the part specified.
+	// Useful for downloading just a part of an object.
+	PartNumber *int64 `location:"querystring" locationName:"partNumber" type:"integer"`
+
+	// Downloads the specified range bytes of an object. For more information about
+	// the HTTP Range header, go to http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.
+	Range *string `location:"header" locationName:"Range" type:"string"`
+
+	// Confirms that the requester knows that she or he will be charged for the
+	// request. Bucket owners need not specify this parameter in their requests.
+	// Documentation on downloading objects from requester pays buckets can be found
+	// at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
+	RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"`
+
+	// Sets the Cache-Control header of the response.
+	ResponseCacheControl *string `location:"querystring" locationName:"response-cache-control" type:"string"`
+
+	// Sets the Content-Disposition header of the response
+	ResponseContentDisposition *string `location:"querystring" locationName:"response-content-disposition" type:"string"`
+
+	// Sets the Content-Encoding header of the response.
+	ResponseContentEncoding *string `location:"querystring" locationName:"response-content-encoding" type:"string"`
+
+	// Sets the Content-Language header of the response.
+	ResponseContentLanguage *string `location:"querystring" locationName:"response-content-language" type:"string"`
+
+	// Sets the Content-Type header of the response.
+	ResponseContentType *string `location:"querystring" locationName:"response-content-type" type:"string"`
+
+	// Sets the Expires header of the response.
+	ResponseExpires *time.Time `location:"querystring" locationName:"response-expires" type:"timestamp"`
+
+	// Specifies the algorithm to use to when encrypting the object (e.g., AES256).
+	SSECustomerAlgorithm *string `location:"header" locationName:"x-amz-server-side-encryption-customer-algorithm" type:"string"`
+
+	// Specifies the customer-provided encryption key for Amazon S3 to use in encrypting
+	// data. This value is used to store the object and then it is discarded; Amazon
+	// does not store the encryption key. The key must be appropriate for use with
+	// the algorithm specified in the x-amz-server-side​-encryption​-customer-algorithm
+	// header.
+	SSECustomerKey *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key" type:"string"`
+
+	// Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321.
+	// Amazon S3 uses this header for a message integrity check to ensure the encryption
+	// key was transmitted without error.
+	SSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key-MD5" type:"string"`
+
+	// VersionId used to reference a specific version of the object.
+	VersionId *string `location:"querystring" locationName:"versionId" type:"string"`
+}
+
+// String returns the string representation
+func (s GetObjectInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetObjectInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetObjectInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetObjectInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Key == nil {
+		invalidParams.Add(request.NewErrParamRequired("Key"))
+	}
+	if s.Key != nil && len(*s.Key) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *GetObjectInput) SetBucket(v string) *GetObjectInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *GetObjectInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetIfMatch sets the IfMatch field's value.
+func (s *GetObjectInput) SetIfMatch(v string) *GetObjectInput {
+	s.IfMatch = &v
+	return s
+}
+
+// SetIfModifiedSince sets the IfModifiedSince field's value.
+func (s *GetObjectInput) SetIfModifiedSince(v time.Time) *GetObjectInput {
+	s.IfModifiedSince = &v
+	return s
+}
+
+// SetIfNoneMatch sets the IfNoneMatch field's value.
+func (s *GetObjectInput) SetIfNoneMatch(v string) *GetObjectInput {
+	s.IfNoneMatch = &v
+	return s
+}
+
+// SetIfUnmodifiedSince sets the IfUnmodifiedSince field's value.
+func (s *GetObjectInput) SetIfUnmodifiedSince(v time.Time) *GetObjectInput {
+	s.IfUnmodifiedSince = &v
+	return s
+}
+
+// SetKey sets the Key field's value.
+func (s *GetObjectInput) SetKey(v string) *GetObjectInput {
+	s.Key = &v
+	return s
+}
+
+// SetPartNumber sets the PartNumber field's value.
+func (s *GetObjectInput) SetPartNumber(v int64) *GetObjectInput {
+	s.PartNumber = &v
+	return s
+}
+
+// SetRange sets the Range field's value.
+func (s *GetObjectInput) SetRange(v string) *GetObjectInput {
+	s.Range = &v
+	return s
+}
+
+// SetRequestPayer sets the RequestPayer field's value.
+func (s *GetObjectInput) SetRequestPayer(v string) *GetObjectInput {
+	s.RequestPayer = &v
+	return s
+}
+
+// SetResponseCacheControl sets the ResponseCacheControl field's value.
+func (s *GetObjectInput) SetResponseCacheControl(v string) *GetObjectInput {
+	s.ResponseCacheControl = &v
+	return s
+}
+
+// SetResponseContentDisposition sets the ResponseContentDisposition field's value.
+func (s *GetObjectInput) SetResponseContentDisposition(v string) *GetObjectInput {
+	s.ResponseContentDisposition = &v
+	return s
+}
+
+// SetResponseContentEncoding sets the ResponseContentEncoding field's value.
+func (s *GetObjectInput) SetResponseContentEncoding(v string) *GetObjectInput {
+	s.ResponseContentEncoding = &v
+	return s
+}
+
+// SetResponseContentLanguage sets the ResponseContentLanguage field's value.
+func (s *GetObjectInput) SetResponseContentLanguage(v string) *GetObjectInput {
+	s.ResponseContentLanguage = &v
+	return s
+}
+
+// SetResponseContentType sets the ResponseContentType field's value.
+func (s *GetObjectInput) SetResponseContentType(v string) *GetObjectInput {
+	s.ResponseContentType = &v
+	return s
+}
+
+// SetResponseExpires sets the ResponseExpires field's value.
+func (s *GetObjectInput) SetResponseExpires(v time.Time) *GetObjectInput {
+	s.ResponseExpires = &v
+	return s
+}
+
+// SetSSECustomerAlgorithm sets the SSECustomerAlgorithm field's value.
+func (s *GetObjectInput) SetSSECustomerAlgorithm(v string) *GetObjectInput {
+	s.SSECustomerAlgorithm = &v
+	return s
+}
+
+// SetSSECustomerKey sets the SSECustomerKey field's value.
+func (s *GetObjectInput) SetSSECustomerKey(v string) *GetObjectInput {
+	s.SSECustomerKey = &v
+	return s
+}
+
+func (s *GetObjectInput) getSSECustomerKey() (v string) {
+	if s.SSECustomerKey == nil {
+		return v
+	}
+	return *s.SSECustomerKey
+}
+
+// SetSSECustomerKeyMD5 sets the SSECustomerKeyMD5 field's value.
+func (s *GetObjectInput) SetSSECustomerKeyMD5(v string) *GetObjectInput {
+	s.SSECustomerKeyMD5 = &v
+	return s
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *GetObjectInput) SetVersionId(v string) *GetObjectInput {
+	s.VersionId = &v
+	return s
+}
+
+type GetObjectOutput struct {
+	_ struct{} `type:"structure" payload:"Body"`
+
+	AcceptRanges *string `location:"header" locationName:"accept-ranges" type:"string"`
+
+	// Object data.
+	Body io.ReadCloser `type:"blob"`
+
+	// Specifies caching behavior along the request/reply chain.
+	CacheControl *string `location:"header" locationName:"Cache-Control" type:"string"`
+
+	// Specifies presentational information for the object.
+	ContentDisposition *string `location:"header" locationName:"Content-Disposition" type:"string"`
+
+	// Specifies what content encodings have been applied to the object and thus
+	// what decoding mechanisms must be applied to obtain the media-type referenced
+	// by the Content-Type header field.
+	ContentEncoding *string `location:"header" locationName:"Content-Encoding" type:"string"`
+
+	// The language the content is in.
+	ContentLanguage *string `location:"header" locationName:"Content-Language" type:"string"`
+
+	// Size of the body in bytes.
+	ContentLength *int64 `location:"header" locationName:"Content-Length" type:"long"`
+
+	// The portion of the object returned in the response.
+	ContentRange *string `location:"header" locationName:"Content-Range" type:"string"`
+
+	// A standard MIME type describing the format of the object data.
+	ContentType *string `location:"header" locationName:"Content-Type" type:"string"`
+
+	// Specifies whether the object retrieved was (true) or was not (false) a Delete
+	// Marker. If false, this response header does not appear in the response.
+	DeleteMarker *bool `location:"header" locationName:"x-amz-delete-marker" type:"boolean"`
+
+	// An ETag is an opaque identifier assigned by a web server to a specific version
+	// of a resource found at a URL
+	ETag *string `location:"header" locationName:"ETag" type:"string"`
+
+	// If the object expiration is configured (see PUT Bucket lifecycle), the response
+	// includes this header. It includes the expiry-date and rule-id key value pairs
+	// providing object expiration information. The value of the rule-id is URL
+	// encoded.
+	Expiration *string `location:"header" locationName:"x-amz-expiration" type:"string"`
+
+	// The date and time at which the object is no longer cacheable.
+	Expires *string `location:"header" locationName:"Expires" type:"string"`
+
+	// Last modified date of the object
+	LastModified *time.Time `location:"header" locationName:"Last-Modified" type:"timestamp"`
+
+	// A map of metadata to store with the object in S3.
+	Metadata map[string]*string `location:"headers" locationName:"x-amz-meta-" type:"map"`
+
+	// This is set to the number of metadata entries not returned in x-amz-meta
+	// headers. This can happen if you create metadata using an API like SOAP that
+	// supports more flexible metadata than the REST API. For example, using SOAP,
+	// you can create metadata whose values are not legal HTTP headers.
+	MissingMeta *int64 `location:"header" locationName:"x-amz-missing-meta" type:"integer"`
+
+	// The count of parts this object has.
+	PartsCount *int64 `location:"header" locationName:"x-amz-mp-parts-count" type:"integer"`
+
+	ReplicationStatus *string `location:"header" locationName:"x-amz-replication-status" type:"string" enum:"ReplicationStatus"`
+
+	// If present, indicates that the requester was successfully charged for the
+	// request.
+	RequestCharged *string `location:"header" locationName:"x-amz-request-charged" type:"string" enum:"RequestCharged"`
+
+	// Provides information about object restoration operation and expiration time
+	// of the restored object copy.
+	Restore *string `location:"header" locationName:"x-amz-restore" type:"string"`
+
+	// If server-side encryption with a customer-provided encryption key was requested,
+	// the response will include this header confirming the encryption algorithm
+	// used.
+	SSECustomerAlgorithm *string `location:"header" locationName:"x-amz-server-side-encryption-customer-algorithm" type:"string"`
+
+	// If server-side encryption with a customer-provided encryption key was requested,
+	// the response will include this header to provide round trip message integrity
+	// verification of the customer-provided encryption key.
+	SSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key-MD5" type:"string"`
+
+	// If present, specifies the ID of the AWS Key Management Service (KMS) master
+	// encryption key that was used for the object.
+	SSEKMSKeyId *string `location:"header" locationName:"x-amz-server-side-encryption-aws-kms-key-id" type:"string"`
+
+	// The Server-side encryption algorithm used when storing this object in S3
+	// (e.g., AES256, aws:kms).
+	ServerSideEncryption *string `location:"header" locationName:"x-amz-server-side-encryption" type:"string" enum:"ServerSideEncryption"`
+
+	StorageClass *string `location:"header" locationName:"x-amz-storage-class" type:"string" enum:"StorageClass"`
+
+	// The number of tags, if any, on the object.
+	TagCount *int64 `location:"header" locationName:"x-amz-tagging-count" type:"integer"`
+
+	// Version of the object.
+	VersionId *string `location:"header" locationName:"x-amz-version-id" type:"string"`
+
+	// If the bucket is configured as a website, redirects requests for this object
+	// to another object in the same bucket or to an external URL. Amazon S3 stores
+	// the value of this header in the object metadata.
+	WebsiteRedirectLocation *string `location:"header" locationName:"x-amz-website-redirect-location" type:"string"`
+}
+
+// String returns the string representation
+func (s GetObjectOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetObjectOutput) GoString() string {
+	return s.String()
+}
+
+// SetAcceptRanges sets the AcceptRanges field's value.
+func (s *GetObjectOutput) SetAcceptRanges(v string) *GetObjectOutput {
+	s.AcceptRanges = &v
+	return s
+}
+
+// SetBody sets the Body field's value.
+func (s *GetObjectOutput) SetBody(v io.ReadCloser) *GetObjectOutput {
+	s.Body = v
+	return s
+}
+
+// SetCacheControl sets the CacheControl field's value.
+func (s *GetObjectOutput) SetCacheControl(v string) *GetObjectOutput {
+	s.CacheControl = &v
+	return s
+}
+
+// SetContentDisposition sets the ContentDisposition field's value.
+func (s *GetObjectOutput) SetContentDisposition(v string) *GetObjectOutput {
+	s.ContentDisposition = &v
+	return s
+}
+
+// SetContentEncoding sets the ContentEncoding field's value.
+func (s *GetObjectOutput) SetContentEncoding(v string) *GetObjectOutput {
+	s.ContentEncoding = &v
+	return s
+}
+
+// SetContentLanguage sets the ContentLanguage field's value.
+func (s *GetObjectOutput) SetContentLanguage(v string) *GetObjectOutput {
+	s.ContentLanguage = &v
+	return s
+}
+
+// SetContentLength sets the ContentLength field's value.
+func (s *GetObjectOutput) SetContentLength(v int64) *GetObjectOutput {
+	s.ContentLength = &v
+	return s
+}
+
+// SetContentRange sets the ContentRange field's value.
+func (s *GetObjectOutput) SetContentRange(v string) *GetObjectOutput {
+	s.ContentRange = &v
+	return s
+}
+
+// SetContentType sets the ContentType field's value.
+func (s *GetObjectOutput) SetContentType(v string) *GetObjectOutput {
+	s.ContentType = &v
+	return s
+}
+
+// SetDeleteMarker sets the DeleteMarker field's value.
+func (s *GetObjectOutput) SetDeleteMarker(v bool) *GetObjectOutput {
+	s.DeleteMarker = &v
+	return s
+}
+
+// SetETag sets the ETag field's value.
+func (s *GetObjectOutput) SetETag(v string) *GetObjectOutput {
+	s.ETag = &v
+	return s
+}
+
+// SetExpiration sets the Expiration field's value.
+func (s *GetObjectOutput) SetExpiration(v string) *GetObjectOutput {
+	s.Expiration = &v
+	return s
+}
+
+// SetExpires sets the Expires field's value.
+func (s *GetObjectOutput) SetExpires(v string) *GetObjectOutput {
+	s.Expires = &v
+	return s
+}
+
+// SetLastModified sets the LastModified field's value.
+func (s *GetObjectOutput) SetLastModified(v time.Time) *GetObjectOutput {
+	s.LastModified = &v
+	return s
+}
+
+// SetMetadata sets the Metadata field's value.
+func (s *GetObjectOutput) SetMetadata(v map[string]*string) *GetObjectOutput {
+	s.Metadata = v
+	return s
+}
+
+// SetMissingMeta sets the MissingMeta field's value.
+func (s *GetObjectOutput) SetMissingMeta(v int64) *GetObjectOutput {
+	s.MissingMeta = &v
+	return s
+}
+
+// SetPartsCount sets the PartsCount field's value.
+func (s *GetObjectOutput) SetPartsCount(v int64) *GetObjectOutput {
+	s.PartsCount = &v
+	return s
+}
+
+// SetReplicationStatus sets the ReplicationStatus field's value.
+func (s *GetObjectOutput) SetReplicationStatus(v string) *GetObjectOutput {
+	s.ReplicationStatus = &v
+	return s
+}
+
+// SetRequestCharged sets the RequestCharged field's value.
+func (s *GetObjectOutput) SetRequestCharged(v string) *GetObjectOutput {
+	s.RequestCharged = &v
+	return s
+}
+
+// SetRestore sets the Restore field's value.
+func (s *GetObjectOutput) SetRestore(v string) *GetObjectOutput {
+	s.Restore = &v
+	return s
+}
+
+// SetSSECustomerAlgorithm sets the SSECustomerAlgorithm field's value.
+func (s *GetObjectOutput) SetSSECustomerAlgorithm(v string) *GetObjectOutput {
+	s.SSECustomerAlgorithm = &v
+	return s
+}
+
+// SetSSECustomerKeyMD5 sets the SSECustomerKeyMD5 field's value.
+func (s *GetObjectOutput) SetSSECustomerKeyMD5(v string) *GetObjectOutput {
+	s.SSECustomerKeyMD5 = &v
+	return s
+}
+
+// SetSSEKMSKeyId sets the SSEKMSKeyId field's value.
+func (s *GetObjectOutput) SetSSEKMSKeyId(v string) *GetObjectOutput {
+	s.SSEKMSKeyId = &v
+	return s
+}
+
+// SetServerSideEncryption sets the ServerSideEncryption field's value.
+func (s *GetObjectOutput) SetServerSideEncryption(v string) *GetObjectOutput {
+	s.ServerSideEncryption = &v
+	return s
+}
+
+// SetStorageClass sets the StorageClass field's value.
+func (s *GetObjectOutput) SetStorageClass(v string) *GetObjectOutput {
+	s.StorageClass = &v
+	return s
+}
+
+// SetTagCount sets the TagCount field's value.
+func (s *GetObjectOutput) SetTagCount(v int64) *GetObjectOutput {
+	s.TagCount = &v
+	return s
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *GetObjectOutput) SetVersionId(v string) *GetObjectOutput {
+	s.VersionId = &v
+	return s
+}
+
+// SetWebsiteRedirectLocation sets the WebsiteRedirectLocation field's value.
+func (s *GetObjectOutput) SetWebsiteRedirectLocation(v string) *GetObjectOutput {
+	s.WebsiteRedirectLocation = &v
+	return s
+}
+
+type GetObjectTaggingInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Key is a required field
+	Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"`
+
+	VersionId *string `location:"querystring" locationName:"versionId" type:"string"`
+}
+
+// String returns the string representation
+func (s GetObjectTaggingInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetObjectTaggingInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetObjectTaggingInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetObjectTaggingInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Key == nil {
+		invalidParams.Add(request.NewErrParamRequired("Key"))
+	}
+	if s.Key != nil && len(*s.Key) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *GetObjectTaggingInput) SetBucket(v string) *GetObjectTaggingInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *GetObjectTaggingInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetKey sets the Key field's value.
+func (s *GetObjectTaggingInput) SetKey(v string) *GetObjectTaggingInput {
+	s.Key = &v
+	return s
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *GetObjectTaggingInput) SetVersionId(v string) *GetObjectTaggingInput {
+	s.VersionId = &v
+	return s
+}
+
+type GetObjectTaggingOutput struct {
+	_ struct{} `type:"structure"`
+
+	// TagSet is a required field
+	TagSet []*Tag `locationNameList:"Tag" type:"list" required:"true"`
+
+	VersionId *string `location:"header" locationName:"x-amz-version-id" type:"string"`
+}
+
+// String returns the string representation
+func (s GetObjectTaggingOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetObjectTaggingOutput) GoString() string {
+	return s.String()
+}
+
+// SetTagSet sets the TagSet field's value.
+func (s *GetObjectTaggingOutput) SetTagSet(v []*Tag) *GetObjectTaggingOutput {
+	s.TagSet = v
+	return s
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *GetObjectTaggingOutput) SetVersionId(v string) *GetObjectTaggingOutput {
+	s.VersionId = &v
+	return s
+}
+
+type GetObjectTorrentInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Key is a required field
+	Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"`
+
+	// Confirms that the requester knows that she or he will be charged for the
+	// request. Bucket owners need not specify this parameter in their requests.
+	// Documentation on downloading objects from requester pays buckets can be found
+	// at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
+	RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"`
+}
+
+// String returns the string representation
+func (s GetObjectTorrentInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetObjectTorrentInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetObjectTorrentInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetObjectTorrentInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Key == nil {
+		invalidParams.Add(request.NewErrParamRequired("Key"))
+	}
+	if s.Key != nil && len(*s.Key) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *GetObjectTorrentInput) SetBucket(v string) *GetObjectTorrentInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *GetObjectTorrentInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetKey sets the Key field's value.
+func (s *GetObjectTorrentInput) SetKey(v string) *GetObjectTorrentInput {
+	s.Key = &v
+	return s
+}
+
+// SetRequestPayer sets the RequestPayer field's value.
+func (s *GetObjectTorrentInput) SetRequestPayer(v string) *GetObjectTorrentInput {
+	s.RequestPayer = &v
+	return s
+}
+
+type GetObjectTorrentOutput struct {
+	_ struct{} `type:"structure" payload:"Body"`
+
+	Body io.ReadCloser `type:"blob"`
+
+	// If present, indicates that the requester was successfully charged for the
+	// request.
+	RequestCharged *string `location:"header" locationName:"x-amz-request-charged" type:"string" enum:"RequestCharged"`
+}
+
+// String returns the string representation
+func (s GetObjectTorrentOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetObjectTorrentOutput) GoString() string {
+	return s.String()
+}
+
+// SetBody sets the Body field's value.
+func (s *GetObjectTorrentOutput) SetBody(v io.ReadCloser) *GetObjectTorrentOutput {
+	s.Body = v
+	return s
+}
+
+// SetRequestCharged sets the RequestCharged field's value.
+func (s *GetObjectTorrentOutput) SetRequestCharged(v string) *GetObjectTorrentOutput {
+	s.RequestCharged = &v
+	return s
+}
+
+type GlacierJobParameters struct {
+	_ struct{} `type:"structure"`
+
+	// Glacier retrieval tier at which the restore will be processed.
+	//
+	// Tier is a required field
+	Tier *string `type:"string" required:"true" enum:"Tier"`
+}
+
+// String returns the string representation
+func (s GlacierJobParameters) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GlacierJobParameters) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GlacierJobParameters) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GlacierJobParameters"}
+	if s.Tier == nil {
+		invalidParams.Add(request.NewErrParamRequired("Tier"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetTier sets the Tier field's value.
+func (s *GlacierJobParameters) SetTier(v string) *GlacierJobParameters {
+	s.Tier = &v
+	return s
+}
+
+type Grant struct {
+	_ struct{} `type:"structure"`
+
+	Grantee *Grantee `type:"structure" xmlPrefix:"xsi" xmlURI:"http://www.w3.org/2001/XMLSchema-instance"`
+
+	// Specifies the permission given to the grantee.
+	Permission *string `type:"string" enum:"Permission"`
+}
+
+// String returns the string representation
+func (s Grant) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s Grant) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *Grant) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "Grant"}
+	if s.Grantee != nil {
+		if err := s.Grantee.Validate(); err != nil {
+			invalidParams.AddNested("Grantee", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetGrantee sets the Grantee field's value.
+func (s *Grant) SetGrantee(v *Grantee) *Grant {
+	s.Grantee = v
+	return s
+}
+
+// SetPermission sets the Permission field's value.
+func (s *Grant) SetPermission(v string) *Grant {
+	s.Permission = &v
+	return s
+}
+
+type Grantee struct {
+	_ struct{} `type:"structure" xmlPrefix:"xsi" xmlURI:"http://www.w3.org/2001/XMLSchema-instance"`
+
+	// Screen name of the grantee.
+	DisplayName *string `type:"string"`
+
+	// Email address of the grantee.
+	EmailAddress *string `type:"string"`
+
+	// The canonical user ID of the grantee.
+	ID *string `type:"string"`
+
+	// Type of grantee
+	//
+	// Type is a required field
+	Type *string `locationName:"xsi:type" type:"string" xmlAttribute:"true" required:"true" enum:"Type"`
+
+	// URI of the grantee group.
+	URI *string `type:"string"`
+}
+
+// String returns the string representation
+func (s Grantee) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s Grantee) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *Grantee) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "Grantee"}
+	if s.Type == nil {
+		invalidParams.Add(request.NewErrParamRequired("Type"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetDisplayName sets the DisplayName field's value.
+func (s *Grantee) SetDisplayName(v string) *Grantee {
+	s.DisplayName = &v
+	return s
+}
+
+// SetEmailAddress sets the EmailAddress field's value.
+func (s *Grantee) SetEmailAddress(v string) *Grantee {
+	s.EmailAddress = &v
+	return s
+}
+
+// SetID sets the ID field's value.
+func (s *Grantee) SetID(v string) *Grantee {
+	s.ID = &v
+	return s
+}
+
+// SetType sets the Type field's value.
+func (s *Grantee) SetType(v string) *Grantee {
+	s.Type = &v
+	return s
+}
+
+// SetURI sets the URI field's value.
+func (s *Grantee) SetURI(v string) *Grantee {
+	s.URI = &v
+	return s
+}
+
+type HeadBucketInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s HeadBucketInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s HeadBucketInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *HeadBucketInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "HeadBucketInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *HeadBucketInput) SetBucket(v string) *HeadBucketInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *HeadBucketInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type HeadBucketOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s HeadBucketOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s HeadBucketOutput) GoString() string {
+	return s.String()
+}
+
+type HeadObjectInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Return the object only if its entity tag (ETag) is the same as the one specified,
+	// otherwise return a 412 (precondition failed).
+	IfMatch *string `location:"header" locationName:"If-Match" type:"string"`
+
+	// Return the object only if it has been modified since the specified time,
+	// otherwise return a 304 (not modified).
+	IfModifiedSince *time.Time `location:"header" locationName:"If-Modified-Since" type:"timestamp"`
+
+	// Return the object only if its entity tag (ETag) is different from the one
+	// specified, otherwise return a 304 (not modified).
+	IfNoneMatch *string `location:"header" locationName:"If-None-Match" type:"string"`
+
+	// Return the object only if it has not been modified since the specified time,
+	// otherwise return a 412 (precondition failed).
+	IfUnmodifiedSince *time.Time `location:"header" locationName:"If-Unmodified-Since" type:"timestamp"`
+
+	// Key is a required field
+	Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"`
+
+	// Part number of the object being read. This is a positive integer between
+	// 1 and 10,000. Effectively performs a 'ranged' HEAD request for the part specified.
+	// Useful querying about the size of the part and the number of parts in this
+	// object.
+	PartNumber *int64 `location:"querystring" locationName:"partNumber" type:"integer"`
+
+	// Downloads the specified range bytes of an object. For more information about
+	// the HTTP Range header, go to http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.
+	Range *string `location:"header" locationName:"Range" type:"string"`
+
+	// Confirms that the requester knows that she or he will be charged for the
+	// request. Bucket owners need not specify this parameter in their requests.
+	// Documentation on downloading objects from requester pays buckets can be found
+	// at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
+	RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"`
+
+	// Specifies the algorithm to use to when encrypting the object (e.g., AES256).
+	SSECustomerAlgorithm *string `location:"header" locationName:"x-amz-server-side-encryption-customer-algorithm" type:"string"`
+
+	// Specifies the customer-provided encryption key for Amazon S3 to use in encrypting
+	// data. This value is used to store the object and then it is discarded; Amazon
+	// does not store the encryption key. The key must be appropriate for use with
+	// the algorithm specified in the x-amz-server-side​-encryption​-customer-algorithm
+	// header.
+	SSECustomerKey *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key" type:"string"`
+
+	// Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321.
+	// Amazon S3 uses this header for a message integrity check to ensure the encryption
+	// key was transmitted without error.
+	SSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key-MD5" type:"string"`
+
+	// VersionId used to reference a specific version of the object.
+	VersionId *string `location:"querystring" locationName:"versionId" type:"string"`
+}
+
+// String returns the string representation
+func (s HeadObjectInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s HeadObjectInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *HeadObjectInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "HeadObjectInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Key == nil {
+		invalidParams.Add(request.NewErrParamRequired("Key"))
+	}
+	if s.Key != nil && len(*s.Key) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *HeadObjectInput) SetBucket(v string) *HeadObjectInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *HeadObjectInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetIfMatch sets the IfMatch field's value.
+func (s *HeadObjectInput) SetIfMatch(v string) *HeadObjectInput {
+	s.IfMatch = &v
+	return s
+}
+
+// SetIfModifiedSince sets the IfModifiedSince field's value.
+func (s *HeadObjectInput) SetIfModifiedSince(v time.Time) *HeadObjectInput {
+	s.IfModifiedSince = &v
+	return s
+}
+
+// SetIfNoneMatch sets the IfNoneMatch field's value.
+func (s *HeadObjectInput) SetIfNoneMatch(v string) *HeadObjectInput {
+	s.IfNoneMatch = &v
+	return s
+}
+
+// SetIfUnmodifiedSince sets the IfUnmodifiedSince field's value.
+func (s *HeadObjectInput) SetIfUnmodifiedSince(v time.Time) *HeadObjectInput {
+	s.IfUnmodifiedSince = &v
+	return s
+}
+
+// SetKey sets the Key field's value.
+func (s *HeadObjectInput) SetKey(v string) *HeadObjectInput {
+	s.Key = &v
+	return s
+}
+
+// SetPartNumber sets the PartNumber field's value.
+func (s *HeadObjectInput) SetPartNumber(v int64) *HeadObjectInput {
+	s.PartNumber = &v
+	return s
+}
+
+// SetRange sets the Range field's value.
+func (s *HeadObjectInput) SetRange(v string) *HeadObjectInput {
+	s.Range = &v
+	return s
+}
+
+// SetRequestPayer sets the RequestPayer field's value.
+func (s *HeadObjectInput) SetRequestPayer(v string) *HeadObjectInput {
+	s.RequestPayer = &v
+	return s
+}
+
+// SetSSECustomerAlgorithm sets the SSECustomerAlgorithm field's value.
+func (s *HeadObjectInput) SetSSECustomerAlgorithm(v string) *HeadObjectInput {
+	s.SSECustomerAlgorithm = &v
+	return s
+}
+
+// SetSSECustomerKey sets the SSECustomerKey field's value.
+func (s *HeadObjectInput) SetSSECustomerKey(v string) *HeadObjectInput {
+	s.SSECustomerKey = &v
+	return s
+}
+
+func (s *HeadObjectInput) getSSECustomerKey() (v string) {
+	if s.SSECustomerKey == nil {
+		return v
+	}
+	return *s.SSECustomerKey
+}
+
+// SetSSECustomerKeyMD5 sets the SSECustomerKeyMD5 field's value.
+func (s *HeadObjectInput) SetSSECustomerKeyMD5(v string) *HeadObjectInput {
+	s.SSECustomerKeyMD5 = &v
+	return s
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *HeadObjectInput) SetVersionId(v string) *HeadObjectInput {
+	s.VersionId = &v
+	return s
+}
+
+type HeadObjectOutput struct {
+	_ struct{} `type:"structure"`
+
+	AcceptRanges *string `location:"header" locationName:"accept-ranges" type:"string"`
+
+	// Specifies caching behavior along the request/reply chain.
+	CacheControl *string `location:"header" locationName:"Cache-Control" type:"string"`
+
+	// Specifies presentational information for the object.
+	ContentDisposition *string `location:"header" locationName:"Content-Disposition" type:"string"`
+
+	// Specifies what content encodings have been applied to the object and thus
+	// what decoding mechanisms must be applied to obtain the media-type referenced
+	// by the Content-Type header field.
+	ContentEncoding *string `location:"header" locationName:"Content-Encoding" type:"string"`
+
+	// The language the content is in.
+	ContentLanguage *string `location:"header" locationName:"Content-Language" type:"string"`
+
+	// Size of the body in bytes.
+	ContentLength *int64 `location:"header" locationName:"Content-Length" type:"long"`
+
+	// A standard MIME type describing the format of the object data.
+	ContentType *string `location:"header" locationName:"Content-Type" type:"string"`
+
+	// Specifies whether the object retrieved was (true) or was not (false) a Delete
+	// Marker. If false, this response header does not appear in the response.
+	DeleteMarker *bool `location:"header" locationName:"x-amz-delete-marker" type:"boolean"`
+
+	// An ETag is an opaque identifier assigned by a web server to a specific version
+	// of a resource found at a URL
+	ETag *string `location:"header" locationName:"ETag" type:"string"`
+
+	// If the object expiration is configured (see PUT Bucket lifecycle), the response
+	// includes this header. It includes the expiry-date and rule-id key value pairs
+	// providing object expiration information. The value of the rule-id is URL
+	// encoded.
+	Expiration *string `location:"header" locationName:"x-amz-expiration" type:"string"`
+
+	// The date and time at which the object is no longer cacheable.
+	Expires *string `location:"header" locationName:"Expires" type:"string"`
+
+	// Last modified date of the object
+	LastModified *time.Time `location:"header" locationName:"Last-Modified" type:"timestamp"`
+
+	// A map of metadata to store with the object in S3.
+	Metadata map[string]*string `location:"headers" locationName:"x-amz-meta-" type:"map"`
+
+	// This is set to the number of metadata entries not returned in x-amz-meta
+	// headers. This can happen if you create metadata using an API like SOAP that
+	// supports more flexible metadata than the REST API. For example, using SOAP,
+	// you can create metadata whose values are not legal HTTP headers.
+	MissingMeta *int64 `location:"header" locationName:"x-amz-missing-meta" type:"integer"`
+
+	// The count of parts this object has.
+	PartsCount *int64 `location:"header" locationName:"x-amz-mp-parts-count" type:"integer"`
+
+	ReplicationStatus *string `location:"header" locationName:"x-amz-replication-status" type:"string" enum:"ReplicationStatus"`
+
+	// If present, indicates that the requester was successfully charged for the
+	// request.
+	RequestCharged *string `location:"header" locationName:"x-amz-request-charged" type:"string" enum:"RequestCharged"`
+
+	// Provides information about object restoration operation and expiration time
+	// of the restored object copy.
+	Restore *string `location:"header" locationName:"x-amz-restore" type:"string"`
+
+	// If server-side encryption with a customer-provided encryption key was requested,
+	// the response will include this header confirming the encryption algorithm
+	// used.
+	SSECustomerAlgorithm *string `location:"header" locationName:"x-amz-server-side-encryption-customer-algorithm" type:"string"`
+
+	// If server-side encryption with a customer-provided encryption key was requested,
+	// the response will include this header to provide round trip message integrity
+	// verification of the customer-provided encryption key.
+	SSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key-MD5" type:"string"`
+
+	// If present, specifies the ID of the AWS Key Management Service (KMS) master
+	// encryption key that was used for the object.
+	SSEKMSKeyId *string `location:"header" locationName:"x-amz-server-side-encryption-aws-kms-key-id" type:"string"`
+
+	// The Server-side encryption algorithm used when storing this object in S3
+	// (e.g., AES256, aws:kms).
+	ServerSideEncryption *string `location:"header" locationName:"x-amz-server-side-encryption" type:"string" enum:"ServerSideEncryption"`
+
+	StorageClass *string `location:"header" locationName:"x-amz-storage-class" type:"string" enum:"StorageClass"`
+
+	// Version of the object.
+	VersionId *string `location:"header" locationName:"x-amz-version-id" type:"string"`
+
+	// If the bucket is configured as a website, redirects requests for this object
+	// to another object in the same bucket or to an external URL. Amazon S3 stores
+	// the value of this header in the object metadata.
+	WebsiteRedirectLocation *string `location:"header" locationName:"x-amz-website-redirect-location" type:"string"`
+}
+
+// String returns the string representation
+func (s HeadObjectOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s HeadObjectOutput) GoString() string {
+	return s.String()
+}
+
+// SetAcceptRanges sets the AcceptRanges field's value.
+func (s *HeadObjectOutput) SetAcceptRanges(v string) *HeadObjectOutput {
+	s.AcceptRanges = &v
+	return s
+}
+
+// SetCacheControl sets the CacheControl field's value.
+func (s *HeadObjectOutput) SetCacheControl(v string) *HeadObjectOutput {
+	s.CacheControl = &v
+	return s
+}
+
+// SetContentDisposition sets the ContentDisposition field's value.
+func (s *HeadObjectOutput) SetContentDisposition(v string) *HeadObjectOutput {
+	s.ContentDisposition = &v
+	return s
+}
+
+// SetContentEncoding sets the ContentEncoding field's value.
+func (s *HeadObjectOutput) SetContentEncoding(v string) *HeadObjectOutput {
+	s.ContentEncoding = &v
+	return s
+}
+
+// SetContentLanguage sets the ContentLanguage field's value.
+func (s *HeadObjectOutput) SetContentLanguage(v string) *HeadObjectOutput {
+	s.ContentLanguage = &v
+	return s
+}
+
+// SetContentLength sets the ContentLength field's value.
+func (s *HeadObjectOutput) SetContentLength(v int64) *HeadObjectOutput {
+	s.ContentLength = &v
+	return s
+}
+
+// SetContentType sets the ContentType field's value.
+func (s *HeadObjectOutput) SetContentType(v string) *HeadObjectOutput {
+	s.ContentType = &v
+	return s
+}
+
+// SetDeleteMarker sets the DeleteMarker field's value.
+func (s *HeadObjectOutput) SetDeleteMarker(v bool) *HeadObjectOutput {
+	s.DeleteMarker = &v
+	return s
+}
+
+// SetETag sets the ETag field's value.
+func (s *HeadObjectOutput) SetETag(v string) *HeadObjectOutput {
+	s.ETag = &v
+	return s
+}
+
+// SetExpiration sets the Expiration field's value.
+func (s *HeadObjectOutput) SetExpiration(v string) *HeadObjectOutput {
+	s.Expiration = &v
+	return s
+}
+
+// SetExpires sets the Expires field's value.
+func (s *HeadObjectOutput) SetExpires(v string) *HeadObjectOutput {
+	s.Expires = &v
+	return s
+}
+
+// SetLastModified sets the LastModified field's value.
+func (s *HeadObjectOutput) SetLastModified(v time.Time) *HeadObjectOutput {
+	s.LastModified = &v
+	return s
+}
+
+// SetMetadata sets the Metadata field's value.
+func (s *HeadObjectOutput) SetMetadata(v map[string]*string) *HeadObjectOutput {
+	s.Metadata = v
+	return s
+}
+
+// SetMissingMeta sets the MissingMeta field's value.
+func (s *HeadObjectOutput) SetMissingMeta(v int64) *HeadObjectOutput {
+	s.MissingMeta = &v
+	return s
+}
+
+// SetPartsCount sets the PartsCount field's value.
+func (s *HeadObjectOutput) SetPartsCount(v int64) *HeadObjectOutput {
+	s.PartsCount = &v
+	return s
+}
+
+// SetReplicationStatus sets the ReplicationStatus field's value.
+func (s *HeadObjectOutput) SetReplicationStatus(v string) *HeadObjectOutput {
+	s.ReplicationStatus = &v
+	return s
+}
+
+// SetRequestCharged sets the RequestCharged field's value.
+func (s *HeadObjectOutput) SetRequestCharged(v string) *HeadObjectOutput {
+	s.RequestCharged = &v
+	return s
+}
+
+// SetRestore sets the Restore field's value.
+func (s *HeadObjectOutput) SetRestore(v string) *HeadObjectOutput {
+	s.Restore = &v
+	return s
+}
+
+// SetSSECustomerAlgorithm sets the SSECustomerAlgorithm field's value.
+func (s *HeadObjectOutput) SetSSECustomerAlgorithm(v string) *HeadObjectOutput {
+	s.SSECustomerAlgorithm = &v
+	return s
+}
+
+// SetSSECustomerKeyMD5 sets the SSECustomerKeyMD5 field's value.
+func (s *HeadObjectOutput) SetSSECustomerKeyMD5(v string) *HeadObjectOutput {
+	s.SSECustomerKeyMD5 = &v
+	return s
+}
+
+// SetSSEKMSKeyId sets the SSEKMSKeyId field's value.
+func (s *HeadObjectOutput) SetSSEKMSKeyId(v string) *HeadObjectOutput {
+	s.SSEKMSKeyId = &v
+	return s
+}
+
+// SetServerSideEncryption sets the ServerSideEncryption field's value.
+func (s *HeadObjectOutput) SetServerSideEncryption(v string) *HeadObjectOutput {
+	s.ServerSideEncryption = &v
+	return s
+}
+
+// SetStorageClass sets the StorageClass field's value.
+func (s *HeadObjectOutput) SetStorageClass(v string) *HeadObjectOutput {
+	s.StorageClass = &v
+	return s
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *HeadObjectOutput) SetVersionId(v string) *HeadObjectOutput {
+	s.VersionId = &v
+	return s
+}
+
+// SetWebsiteRedirectLocation sets the WebsiteRedirectLocation field's value.
+func (s *HeadObjectOutput) SetWebsiteRedirectLocation(v string) *HeadObjectOutput {
+	s.WebsiteRedirectLocation = &v
+	return s
+}
+
+type IndexDocument struct {
+	_ struct{} `type:"structure"`
+
+	// A suffix that is appended to a request that is for a directory on the website
+	// endpoint (e.g. if the suffix is index.html and you make a request to samplebucket/images/
+	// the data that is returned will be for the object with the key name images/index.html)
+	// The suffix must not be empty and must not include a slash character.
+	//
+	// Suffix is a required field
+	Suffix *string `type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s IndexDocument) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s IndexDocument) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *IndexDocument) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "IndexDocument"}
+	if s.Suffix == nil {
+		invalidParams.Add(request.NewErrParamRequired("Suffix"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetSuffix sets the Suffix field's value.
+func (s *IndexDocument) SetSuffix(v string) *IndexDocument {
+	s.Suffix = &v
+	return s
+}
+
+type Initiator struct {
+	_ struct{} `type:"structure"`
+
+	// Name of the Principal.
+	DisplayName *string `type:"string"`
+
+	// If the principal is an AWS account, it provides the Canonical User ID. If
+	// the principal is an IAM User, it provides a user ARN value.
+	ID *string `type:"string"`
+}
+
+// String returns the string representation
+func (s Initiator) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s Initiator) GoString() string {
+	return s.String()
+}
+
+// SetDisplayName sets the DisplayName field's value.
+func (s *Initiator) SetDisplayName(v string) *Initiator {
+	s.DisplayName = &v
+	return s
+}
+
+// SetID sets the ID field's value.
+func (s *Initiator) SetID(v string) *Initiator {
+	s.ID = &v
+	return s
+}
+
+// Describes the serialization format of the object.
+type InputSerialization struct {
+	_ struct{} `type:"structure"`
+
+	// Describes the serialization of a CSV-encoded object.
+	CSV *CSVInput `type:"structure"`
+
+	// Specifies object's compression format. Valid values: NONE, GZIP, BZIP2. Default
+	// Value: NONE.
+	CompressionType *string `type:"string" enum:"CompressionType"`
+
+	// Specifies JSON as object's input serialization format.
+	JSON *JSONInput `type:"structure"`
+}
+
+// String returns the string representation
+func (s InputSerialization) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s InputSerialization) GoString() string {
+	return s.String()
+}
+
+// SetCSV sets the CSV field's value.
+func (s *InputSerialization) SetCSV(v *CSVInput) *InputSerialization {
+	s.CSV = v
+	return s
+}
+
+// SetCompressionType sets the CompressionType field's value.
+func (s *InputSerialization) SetCompressionType(v string) *InputSerialization {
+	s.CompressionType = &v
+	return s
+}
+
+// SetJSON sets the JSON field's value.
+func (s *InputSerialization) SetJSON(v *JSONInput) *InputSerialization {
+	s.JSON = v
+	return s
+}
+
+type InventoryConfiguration struct {
+	_ struct{} `type:"structure"`
+
+	// Contains information about where to publish the inventory results.
+	//
+	// Destination is a required field
+	Destination *InventoryDestination `type:"structure" required:"true"`
+
+	// Specifies an inventory filter. The inventory only includes objects that meet
+	// the filter's criteria.
+	Filter *InventoryFilter `type:"structure"`
+
+	// The ID used to identify the inventory configuration.
+	//
+	// Id is a required field
+	Id *string `type:"string" required:"true"`
+
+	// Specifies which object version(s) to included in the inventory results.
+	//
+	// IncludedObjectVersions is a required field
+	IncludedObjectVersions *string `type:"string" required:"true" enum:"InventoryIncludedObjectVersions"`
+
+	// Specifies whether the inventory is enabled or disabled.
+	//
+	// IsEnabled is a required field
+	IsEnabled *bool `type:"boolean" required:"true"`
+
+	// Contains the optional fields that are included in the inventory results.
+	OptionalFields []*string `locationNameList:"Field" type:"list"`
+
+	// Specifies the schedule for generating inventory results.
+	//
+	// Schedule is a required field
+	Schedule *InventorySchedule `type:"structure" required:"true"`
+}
+
+// String returns the string representation
+func (s InventoryConfiguration) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s InventoryConfiguration) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *InventoryConfiguration) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "InventoryConfiguration"}
+	if s.Destination == nil {
+		invalidParams.Add(request.NewErrParamRequired("Destination"))
+	}
+	if s.Id == nil {
+		invalidParams.Add(request.NewErrParamRequired("Id"))
+	}
+	if s.IncludedObjectVersions == nil {
+		invalidParams.Add(request.NewErrParamRequired("IncludedObjectVersions"))
+	}
+	if s.IsEnabled == nil {
+		invalidParams.Add(request.NewErrParamRequired("IsEnabled"))
+	}
+	if s.Schedule == nil {
+		invalidParams.Add(request.NewErrParamRequired("Schedule"))
+	}
+	if s.Destination != nil {
+		if err := s.Destination.Validate(); err != nil {
+			invalidParams.AddNested("Destination", err.(request.ErrInvalidParams))
+		}
+	}
+	if s.Filter != nil {
+		if err := s.Filter.Validate(); err != nil {
+			invalidParams.AddNested("Filter", err.(request.ErrInvalidParams))
+		}
+	}
+	if s.Schedule != nil {
+		if err := s.Schedule.Validate(); err != nil {
+			invalidParams.AddNested("Schedule", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetDestination sets the Destination field's value.
+func (s *InventoryConfiguration) SetDestination(v *InventoryDestination) *InventoryConfiguration {
+	s.Destination = v
+	return s
+}
+
+// SetFilter sets the Filter field's value.
+func (s *InventoryConfiguration) SetFilter(v *InventoryFilter) *InventoryConfiguration {
+	s.Filter = v
+	return s
+}
+
+// SetId sets the Id field's value.
+func (s *InventoryConfiguration) SetId(v string) *InventoryConfiguration {
+	s.Id = &v
+	return s
+}
+
+// SetIncludedObjectVersions sets the IncludedObjectVersions field's value.
+func (s *InventoryConfiguration) SetIncludedObjectVersions(v string) *InventoryConfiguration {
+	s.IncludedObjectVersions = &v
+	return s
+}
+
+// SetIsEnabled sets the IsEnabled field's value.
+func (s *InventoryConfiguration) SetIsEnabled(v bool) *InventoryConfiguration {
+	s.IsEnabled = &v
+	return s
+}
+
+// SetOptionalFields sets the OptionalFields field's value.
+func (s *InventoryConfiguration) SetOptionalFields(v []*string) *InventoryConfiguration {
+	s.OptionalFields = v
+	return s
+}
+
+// SetSchedule sets the Schedule field's value.
+func (s *InventoryConfiguration) SetSchedule(v *InventorySchedule) *InventoryConfiguration {
+	s.Schedule = v
+	return s
+}
+
+type InventoryDestination struct {
+	_ struct{} `type:"structure"`
+
+	// Contains the bucket name, file format, bucket owner (optional), and prefix
+	// (optional) where inventory results are published.
+	//
+	// S3BucketDestination is a required field
+	S3BucketDestination *InventoryS3BucketDestination `type:"structure" required:"true"`
+}
+
+// String returns the string representation
+func (s InventoryDestination) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s InventoryDestination) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *InventoryDestination) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "InventoryDestination"}
+	if s.S3BucketDestination == nil {
+		invalidParams.Add(request.NewErrParamRequired("S3BucketDestination"))
+	}
+	if s.S3BucketDestination != nil {
+		if err := s.S3BucketDestination.Validate(); err != nil {
+			invalidParams.AddNested("S3BucketDestination", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetS3BucketDestination sets the S3BucketDestination field's value.
+func (s *InventoryDestination) SetS3BucketDestination(v *InventoryS3BucketDestination) *InventoryDestination {
+	s.S3BucketDestination = v
+	return s
+}
+
+// Contains the type of server-side encryption used to encrypt the inventory
+// results.
+type InventoryEncryption struct {
+	_ struct{} `type:"structure"`
+
+	// Specifies the use of SSE-KMS to encrypt delievered Inventory reports.
+	SSEKMS *SSEKMS `locationName:"SSE-KMS" type:"structure"`
+
+	// Specifies the use of SSE-S3 to encrypt delievered Inventory reports.
+	SSES3 *SSES3 `locationName:"SSE-S3" type:"structure"`
+}
+
+// String returns the string representation
+func (s InventoryEncryption) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s InventoryEncryption) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *InventoryEncryption) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "InventoryEncryption"}
+	if s.SSEKMS != nil {
+		if err := s.SSEKMS.Validate(); err != nil {
+			invalidParams.AddNested("SSEKMS", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetSSEKMS sets the SSEKMS field's value.
+func (s *InventoryEncryption) SetSSEKMS(v *SSEKMS) *InventoryEncryption {
+	s.SSEKMS = v
+	return s
+}
+
+// SetSSES3 sets the SSES3 field's value.
+func (s *InventoryEncryption) SetSSES3(v *SSES3) *InventoryEncryption {
+	s.SSES3 = v
+	return s
+}
+
+type InventoryFilter struct {
+	_ struct{} `type:"structure"`
+
+	// The prefix that an object must have to be included in the inventory results.
+	//
+	// Prefix is a required field
+	Prefix *string `type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s InventoryFilter) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s InventoryFilter) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *InventoryFilter) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "InventoryFilter"}
+	if s.Prefix == nil {
+		invalidParams.Add(request.NewErrParamRequired("Prefix"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetPrefix sets the Prefix field's value.
+func (s *InventoryFilter) SetPrefix(v string) *InventoryFilter {
+	s.Prefix = &v
+	return s
+}
+
+type InventoryS3BucketDestination struct {
+	_ struct{} `type:"structure"`
+
+	// The ID of the account that owns the destination bucket.
+	AccountId *string `type:"string"`
+
+	// The Amazon resource name (ARN) of the bucket where inventory results will
+	// be published.
+	//
+	// Bucket is a required field
+	Bucket *string `type:"string" required:"true"`
+
+	// Contains the type of server-side encryption used to encrypt the inventory
+	// results.
+	Encryption *InventoryEncryption `type:"structure"`
+
+	// Specifies the output format of the inventory results.
+	//
+	// Format is a required field
+	Format *string `type:"string" required:"true" enum:"InventoryFormat"`
+
+	// The prefix that is prepended to all inventory results.
+	Prefix *string `type:"string"`
+}
+
+// String returns the string representation
+func (s InventoryS3BucketDestination) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s InventoryS3BucketDestination) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *InventoryS3BucketDestination) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "InventoryS3BucketDestination"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Format == nil {
+		invalidParams.Add(request.NewErrParamRequired("Format"))
+	}
+	if s.Encryption != nil {
+		if err := s.Encryption.Validate(); err != nil {
+			invalidParams.AddNested("Encryption", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetAccountId sets the AccountId field's value.
+func (s *InventoryS3BucketDestination) SetAccountId(v string) *InventoryS3BucketDestination {
+	s.AccountId = &v
+	return s
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *InventoryS3BucketDestination) SetBucket(v string) *InventoryS3BucketDestination {
+	s.Bucket = &v
+	return s
+}
+
+func (s *InventoryS3BucketDestination) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetEncryption sets the Encryption field's value.
+func (s *InventoryS3BucketDestination) SetEncryption(v *InventoryEncryption) *InventoryS3BucketDestination {
+	s.Encryption = v
+	return s
+}
+
+// SetFormat sets the Format field's value.
+func (s *InventoryS3BucketDestination) SetFormat(v string) *InventoryS3BucketDestination {
+	s.Format = &v
+	return s
+}
+
+// SetPrefix sets the Prefix field's value.
+func (s *InventoryS3BucketDestination) SetPrefix(v string) *InventoryS3BucketDestination {
+	s.Prefix = &v
+	return s
+}
+
+type InventorySchedule struct {
+	_ struct{} `type:"structure"`
+
+	// Specifies how frequently inventory results are produced.
+	//
+	// Frequency is a required field
+	Frequency *string `type:"string" required:"true" enum:"InventoryFrequency"`
+}
+
+// String returns the string representation
+func (s InventorySchedule) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s InventorySchedule) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *InventorySchedule) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "InventorySchedule"}
+	if s.Frequency == nil {
+		invalidParams.Add(request.NewErrParamRequired("Frequency"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetFrequency sets the Frequency field's value.
+func (s *InventorySchedule) SetFrequency(v string) *InventorySchedule {
+	s.Frequency = &v
+	return s
+}
+
+type JSONInput struct {
+	_ struct{} `type:"structure"`
+
+	// The type of JSON. Valid values: Document, Lines.
+	Type *string `type:"string" enum:"JSONType"`
+}
+
+// String returns the string representation
+func (s JSONInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s JSONInput) GoString() string {
+	return s.String()
+}
+
+// SetType sets the Type field's value.
+func (s *JSONInput) SetType(v string) *JSONInput {
+	s.Type = &v
+	return s
+}
+
+type JSONOutput struct {
+	_ struct{} `type:"structure"`
+
+	// The value used to separate individual records in the output.
+	RecordDelimiter *string `type:"string"`
+}
+
+// String returns the string representation
+func (s JSONOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s JSONOutput) GoString() string {
+	return s.String()
+}
+
+// SetRecordDelimiter sets the RecordDelimiter field's value.
+func (s *JSONOutput) SetRecordDelimiter(v string) *JSONOutput {
+	s.RecordDelimiter = &v
+	return s
+}
+
+// Container for object key name prefix and suffix filtering rules.
+type KeyFilter struct {
+	_ struct{} `type:"structure"`
+
+	// A list of containers for key value pair that defines the criteria for the
+	// filter rule.
+	FilterRules []*FilterRule `locationName:"FilterRule" type:"list" flattened:"true"`
+}
+
+// String returns the string representation
+func (s KeyFilter) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s KeyFilter) GoString() string {
+	return s.String()
+}
+
+// SetFilterRules sets the FilterRules field's value.
+func (s *KeyFilter) SetFilterRules(v []*FilterRule) *KeyFilter {
+	s.FilterRules = v
+	return s
+}
+
+// Container for specifying the AWS Lambda notification configuration.
+type LambdaFunctionConfiguration struct {
+	_ struct{} `type:"structure"`
+
+	// Events is a required field
+	Events []*string `locationName:"Event" type:"list" flattened:"true" required:"true"`
+
+	// Container for object key name filtering rules. For information about key
+	// name filtering, go to Configuring Event Notifications (http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html)
+	// in the Amazon Simple Storage Service Developer Guide.
+	Filter *NotificationConfigurationFilter `type:"structure"`
+
+	// Optional unique identifier for configurations in a notification configuration.
+	// If you don't provide one, Amazon S3 will assign an ID.
+	Id *string `type:"string"`
+
+	// Lambda cloud function ARN that Amazon S3 can invoke when it detects events
+	// of the specified type.
+	//
+	// LambdaFunctionArn is a required field
+	LambdaFunctionArn *string `locationName:"CloudFunction" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s LambdaFunctionConfiguration) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s LambdaFunctionConfiguration) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *LambdaFunctionConfiguration) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "LambdaFunctionConfiguration"}
+	if s.Events == nil {
+		invalidParams.Add(request.NewErrParamRequired("Events"))
+	}
+	if s.LambdaFunctionArn == nil {
+		invalidParams.Add(request.NewErrParamRequired("LambdaFunctionArn"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetEvents sets the Events field's value.
+func (s *LambdaFunctionConfiguration) SetEvents(v []*string) *LambdaFunctionConfiguration {
+	s.Events = v
+	return s
+}
+
+// SetFilter sets the Filter field's value.
+func (s *LambdaFunctionConfiguration) SetFilter(v *NotificationConfigurationFilter) *LambdaFunctionConfiguration {
+	s.Filter = v
+	return s
+}
+
+// SetId sets the Id field's value.
+func (s *LambdaFunctionConfiguration) SetId(v string) *LambdaFunctionConfiguration {
+	s.Id = &v
+	return s
+}
+
+// SetLambdaFunctionArn sets the LambdaFunctionArn field's value.
+func (s *LambdaFunctionConfiguration) SetLambdaFunctionArn(v string) *LambdaFunctionConfiguration {
+	s.LambdaFunctionArn = &v
+	return s
+}
+
+type LifecycleConfiguration struct {
+	_ struct{} `type:"structure"`
+
+	// Rules is a required field
+	Rules []*Rule `locationName:"Rule" type:"list" flattened:"true" required:"true"`
+}
+
+// String returns the string representation
+func (s LifecycleConfiguration) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s LifecycleConfiguration) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *LifecycleConfiguration) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "LifecycleConfiguration"}
+	if s.Rules == nil {
+		invalidParams.Add(request.NewErrParamRequired("Rules"))
+	}
+	if s.Rules != nil {
+		for i, v := range s.Rules {
+			if v == nil {
+				continue
+			}
+			if err := v.Validate(); err != nil {
+				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Rules", i), err.(request.ErrInvalidParams))
+			}
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetRules sets the Rules field's value.
+func (s *LifecycleConfiguration) SetRules(v []*Rule) *LifecycleConfiguration {
+	s.Rules = v
+	return s
+}
+
+type LifecycleExpiration struct {
+	_ struct{} `type:"structure"`
+
+	// Indicates at what date the object is to be moved or deleted. Should be in
+	// GMT ISO 8601 Format.
+	Date *time.Time `type:"timestamp" timestampFormat:"iso8601"`
+
+	// Indicates the lifetime, in days, of the objects that are subject to the rule.
+	// The value must be a non-zero positive integer.
+	Days *int64 `type:"integer"`
+
+	// Indicates whether Amazon S3 will remove a delete marker with no noncurrent
+	// versions. If set to true, the delete marker will be expired; if set to false
+	// the policy takes no action. This cannot be specified with Days or Date in
+	// a Lifecycle Expiration Policy.
+	ExpiredObjectDeleteMarker *bool `type:"boolean"`
+}
+
+// String returns the string representation
+func (s LifecycleExpiration) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s LifecycleExpiration) GoString() string {
+	return s.String()
+}
+
+// SetDate sets the Date field's value.
+func (s *LifecycleExpiration) SetDate(v time.Time) *LifecycleExpiration {
+	s.Date = &v
+	return s
+}
+
+// SetDays sets the Days field's value.
+func (s *LifecycleExpiration) SetDays(v int64) *LifecycleExpiration {
+	s.Days = &v
+	return s
+}
+
+// SetExpiredObjectDeleteMarker sets the ExpiredObjectDeleteMarker field's value.
+func (s *LifecycleExpiration) SetExpiredObjectDeleteMarker(v bool) *LifecycleExpiration {
+	s.ExpiredObjectDeleteMarker = &v
+	return s
+}
+
+type LifecycleRule struct {
+	_ struct{} `type:"structure"`
+
+	// Specifies the days since the initiation of an Incomplete Multipart Upload
+	// that Lifecycle will wait before permanently removing all parts of the upload.
+	AbortIncompleteMultipartUpload *AbortIncompleteMultipartUpload `type:"structure"`
+
+	Expiration *LifecycleExpiration `type:"structure"`
+
+	// The Filter is used to identify objects that a Lifecycle Rule applies to.
+	// A Filter must have exactly one of Prefix, Tag, or And specified.
+	Filter *LifecycleRuleFilter `type:"structure"`
+
+	// Unique identifier for the rule. The value cannot be longer than 255 characters.
+	ID *string `type:"string"`
+
+	// Specifies when noncurrent object versions expire. Upon expiration, Amazon
+	// S3 permanently deletes the noncurrent object versions. You set this lifecycle
+	// configuration action on a bucket that has versioning enabled (or suspended)
+	// to request that Amazon S3 delete noncurrent object versions at a specific
+	// period in the object's lifetime.
+	NoncurrentVersionExpiration *NoncurrentVersionExpiration `type:"structure"`
+
+	NoncurrentVersionTransitions []*NoncurrentVersionTransition `locationName:"NoncurrentVersionTransition" type:"list" flattened:"true"`
+
+	// Prefix identifying one or more objects to which the rule applies. This is
+	// deprecated; use Filter instead.
+	Prefix *string `deprecated:"true" type:"string"`
+
+	// If 'Enabled', the rule is currently being applied. If 'Disabled', the rule
+	// is not currently being applied.
+	//
+	// Status is a required field
+	Status *string `type:"string" required:"true" enum:"ExpirationStatus"`
+
+	Transitions []*Transition `locationName:"Transition" type:"list" flattened:"true"`
+}
+
+// String returns the string representation
+func (s LifecycleRule) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s LifecycleRule) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *LifecycleRule) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "LifecycleRule"}
+	if s.Status == nil {
+		invalidParams.Add(request.NewErrParamRequired("Status"))
+	}
+	if s.Filter != nil {
+		if err := s.Filter.Validate(); err != nil {
+			invalidParams.AddNested("Filter", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetAbortIncompleteMultipartUpload sets the AbortIncompleteMultipartUpload field's value.
+func (s *LifecycleRule) SetAbortIncompleteMultipartUpload(v *AbortIncompleteMultipartUpload) *LifecycleRule {
+	s.AbortIncompleteMultipartUpload = v
+	return s
+}
+
+// SetExpiration sets the Expiration field's value.
+func (s *LifecycleRule) SetExpiration(v *LifecycleExpiration) *LifecycleRule {
+	s.Expiration = v
+	return s
+}
+
+// SetFilter sets the Filter field's value.
+func (s *LifecycleRule) SetFilter(v *LifecycleRuleFilter) *LifecycleRule {
+	s.Filter = v
+	return s
+}
+
+// SetID sets the ID field's value.
+func (s *LifecycleRule) SetID(v string) *LifecycleRule {
+	s.ID = &v
+	return s
+}
+
+// SetNoncurrentVersionExpiration sets the NoncurrentVersionExpiration field's value.
+func (s *LifecycleRule) SetNoncurrentVersionExpiration(v *NoncurrentVersionExpiration) *LifecycleRule {
+	s.NoncurrentVersionExpiration = v
+	return s
+}
+
+// SetNoncurrentVersionTransitions sets the NoncurrentVersionTransitions field's value.
+func (s *LifecycleRule) SetNoncurrentVersionTransitions(v []*NoncurrentVersionTransition) *LifecycleRule {
+	s.NoncurrentVersionTransitions = v
+	return s
+}
+
+// SetPrefix sets the Prefix field's value.
+func (s *LifecycleRule) SetPrefix(v string) *LifecycleRule {
+	s.Prefix = &v
+	return s
+}
+
+// SetStatus sets the Status field's value.
+func (s *LifecycleRule) SetStatus(v string) *LifecycleRule {
+	s.Status = &v
+	return s
+}
+
+// SetTransitions sets the Transitions field's value.
+func (s *LifecycleRule) SetTransitions(v []*Transition) *LifecycleRule {
+	s.Transitions = v
+	return s
+}
+
+// This is used in a Lifecycle Rule Filter to apply a logical AND to two or
+// more predicates. The Lifecycle Rule will apply to any object matching all
+// of the predicates configured inside the And operator.
+type LifecycleRuleAndOperator struct {
+	_ struct{} `type:"structure"`
+
+	Prefix *string `type:"string"`
+
+	// All of these tags must exist in the object's tag set in order for the rule
+	// to apply.
+	Tags []*Tag `locationName:"Tag" locationNameList:"Tag" type:"list" flattened:"true"`
+}
+
+// String returns the string representation
+func (s LifecycleRuleAndOperator) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s LifecycleRuleAndOperator) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *LifecycleRuleAndOperator) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "LifecycleRuleAndOperator"}
+	if s.Tags != nil {
+		for i, v := range s.Tags {
+			if v == nil {
+				continue
+			}
+			if err := v.Validate(); err != nil {
+				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Tags", i), err.(request.ErrInvalidParams))
+			}
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetPrefix sets the Prefix field's value.
+func (s *LifecycleRuleAndOperator) SetPrefix(v string) *LifecycleRuleAndOperator {
+	s.Prefix = &v
+	return s
+}
+
+// SetTags sets the Tags field's value.
+func (s *LifecycleRuleAndOperator) SetTags(v []*Tag) *LifecycleRuleAndOperator {
+	s.Tags = v
+	return s
+}
+
+// The Filter is used to identify objects that a Lifecycle Rule applies to.
+// A Filter must have exactly one of Prefix, Tag, or And specified.
+type LifecycleRuleFilter struct {
+	_ struct{} `type:"structure"`
+
+	// This is used in a Lifecycle Rule Filter to apply a logical AND to two or
+	// more predicates. The Lifecycle Rule will apply to any object matching all
+	// of the predicates configured inside the And operator.
+	And *LifecycleRuleAndOperator `type:"structure"`
+
+	// Prefix identifying one or more objects to which the rule applies.
+	Prefix *string `type:"string"`
+
+	// This tag must exist in the object's tag set in order for the rule to apply.
+	Tag *Tag `type:"structure"`
+}
+
+// String returns the string representation
+func (s LifecycleRuleFilter) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s LifecycleRuleFilter) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *LifecycleRuleFilter) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "LifecycleRuleFilter"}
+	if s.And != nil {
+		if err := s.And.Validate(); err != nil {
+			invalidParams.AddNested("And", err.(request.ErrInvalidParams))
+		}
+	}
+	if s.Tag != nil {
+		if err := s.Tag.Validate(); err != nil {
+			invalidParams.AddNested("Tag", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetAnd sets the And field's value.
+func (s *LifecycleRuleFilter) SetAnd(v *LifecycleRuleAndOperator) *LifecycleRuleFilter {
+	s.And = v
+	return s
+}
+
+// SetPrefix sets the Prefix field's value.
+func (s *LifecycleRuleFilter) SetPrefix(v string) *LifecycleRuleFilter {
+	s.Prefix = &v
+	return s
+}
+
+// SetTag sets the Tag field's value.
+func (s *LifecycleRuleFilter) SetTag(v *Tag) *LifecycleRuleFilter {
+	s.Tag = v
+	return s
+}
+
+type ListBucketAnalyticsConfigurationsInput struct {
+	_ struct{} `type:"structure"`
+
+	// The name of the bucket from which analytics configurations are retrieved.
+	//
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// The ContinuationToken that represents a placeholder from where this request
+	// should begin.
+	ContinuationToken *string `location:"querystring" locationName:"continuation-token" type:"string"`
+}
+
+// String returns the string representation
+func (s ListBucketAnalyticsConfigurationsInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ListBucketAnalyticsConfigurationsInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *ListBucketAnalyticsConfigurationsInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "ListBucketAnalyticsConfigurationsInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *ListBucketAnalyticsConfigurationsInput) SetBucket(v string) *ListBucketAnalyticsConfigurationsInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *ListBucketAnalyticsConfigurationsInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetContinuationToken sets the ContinuationToken field's value.
+func (s *ListBucketAnalyticsConfigurationsInput) SetContinuationToken(v string) *ListBucketAnalyticsConfigurationsInput {
+	s.ContinuationToken = &v
+	return s
+}
+
+type ListBucketAnalyticsConfigurationsOutput struct {
+	_ struct{} `type:"structure"`
+
+	// The list of analytics configurations for a bucket.
+	AnalyticsConfigurationList []*AnalyticsConfiguration `locationName:"AnalyticsConfiguration" type:"list" flattened:"true"`
+
+	// The ContinuationToken that represents where this request began.
+	ContinuationToken *string `type:"string"`
+
+	// Indicates whether the returned list of analytics configurations is complete.
+	// A value of true indicates that the list is not complete and the NextContinuationToken
+	// will be provided for a subsequent request.
+	IsTruncated *bool `type:"boolean"`
+
+	// NextContinuationToken is sent when isTruncated is true, which indicates that
+	// there are more analytics configurations to list. The next request must include
+	// this NextContinuationToken. The token is obfuscated and is not a usable value.
+	NextContinuationToken *string `type:"string"`
+}
+
+// String returns the string representation
+func (s ListBucketAnalyticsConfigurationsOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ListBucketAnalyticsConfigurationsOutput) GoString() string {
+	return s.String()
+}
+
+// SetAnalyticsConfigurationList sets the AnalyticsConfigurationList field's value.
+func (s *ListBucketAnalyticsConfigurationsOutput) SetAnalyticsConfigurationList(v []*AnalyticsConfiguration) *ListBucketAnalyticsConfigurationsOutput {
+	s.AnalyticsConfigurationList = v
+	return s
+}
+
+// SetContinuationToken sets the ContinuationToken field's value.
+func (s *ListBucketAnalyticsConfigurationsOutput) SetContinuationToken(v string) *ListBucketAnalyticsConfigurationsOutput {
+	s.ContinuationToken = &v
+	return s
+}
+
+// SetIsTruncated sets the IsTruncated field's value.
+func (s *ListBucketAnalyticsConfigurationsOutput) SetIsTruncated(v bool) *ListBucketAnalyticsConfigurationsOutput {
+	s.IsTruncated = &v
+	return s
+}
+
+// SetNextContinuationToken sets the NextContinuationToken field's value.
+func (s *ListBucketAnalyticsConfigurationsOutput) SetNextContinuationToken(v string) *ListBucketAnalyticsConfigurationsOutput {
+	s.NextContinuationToken = &v
+	return s
+}
+
+type ListBucketInventoryConfigurationsInput struct {
+	_ struct{} `type:"structure"`
+
+	// The name of the bucket containing the inventory configurations to retrieve.
+	//
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// The marker used to continue an inventory configuration listing that has been
+	// truncated. Use the NextContinuationToken from a previously truncated list
+	// response to continue the listing. The continuation token is an opaque value
+	// that Amazon S3 understands.
+	ContinuationToken *string `location:"querystring" locationName:"continuation-token" type:"string"`
+}
+
+// String returns the string representation
+func (s ListBucketInventoryConfigurationsInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ListBucketInventoryConfigurationsInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *ListBucketInventoryConfigurationsInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "ListBucketInventoryConfigurationsInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *ListBucketInventoryConfigurationsInput) SetBucket(v string) *ListBucketInventoryConfigurationsInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *ListBucketInventoryConfigurationsInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetContinuationToken sets the ContinuationToken field's value.
+func (s *ListBucketInventoryConfigurationsInput) SetContinuationToken(v string) *ListBucketInventoryConfigurationsInput {
+	s.ContinuationToken = &v
+	return s
+}
+
+type ListBucketInventoryConfigurationsOutput struct {
+	_ struct{} `type:"structure"`
+
+	// If sent in the request, the marker that is used as a starting point for this
+	// inventory configuration list response.
+	ContinuationToken *string `type:"string"`
+
+	// The list of inventory configurations for a bucket.
+	InventoryConfigurationList []*InventoryConfiguration `locationName:"InventoryConfiguration" type:"list" flattened:"true"`
+
+	// Indicates whether the returned list of inventory configurations is truncated
+	// in this response. A value of true indicates that the list is truncated.
+	IsTruncated *bool `type:"boolean"`
+
+	// The marker used to continue this inventory configuration listing. Use the
+	// NextContinuationToken from this response to continue the listing in a subsequent
+	// request. The continuation token is an opaque value that Amazon S3 understands.
+	NextContinuationToken *string `type:"string"`
+}
+
+// String returns the string representation
+func (s ListBucketInventoryConfigurationsOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ListBucketInventoryConfigurationsOutput) GoString() string {
+	return s.String()
+}
+
+// SetContinuationToken sets the ContinuationToken field's value.
+func (s *ListBucketInventoryConfigurationsOutput) SetContinuationToken(v string) *ListBucketInventoryConfigurationsOutput {
+	s.ContinuationToken = &v
+	return s
+}
+
+// SetInventoryConfigurationList sets the InventoryConfigurationList field's value.
+func (s *ListBucketInventoryConfigurationsOutput) SetInventoryConfigurationList(v []*InventoryConfiguration) *ListBucketInventoryConfigurationsOutput {
+	s.InventoryConfigurationList = v
+	return s
+}
+
+// SetIsTruncated sets the IsTruncated field's value.
+func (s *ListBucketInventoryConfigurationsOutput) SetIsTruncated(v bool) *ListBucketInventoryConfigurationsOutput {
+	s.IsTruncated = &v
+	return s
+}
+
+// SetNextContinuationToken sets the NextContinuationToken field's value.
+func (s *ListBucketInventoryConfigurationsOutput) SetNextContinuationToken(v string) *ListBucketInventoryConfigurationsOutput {
+	s.NextContinuationToken = &v
+	return s
+}
+
+type ListBucketMetricsConfigurationsInput struct {
+	_ struct{} `type:"structure"`
+
+	// The name of the bucket containing the metrics configurations to retrieve.
+	//
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// The marker that is used to continue a metrics configuration listing that
+	// has been truncated. Use the NextContinuationToken from a previously truncated
+	// list response to continue the listing. The continuation token is an opaque
+	// value that Amazon S3 understands.
+	ContinuationToken *string `location:"querystring" locationName:"continuation-token" type:"string"`
+}
+
+// String returns the string representation
+func (s ListBucketMetricsConfigurationsInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ListBucketMetricsConfigurationsInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *ListBucketMetricsConfigurationsInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "ListBucketMetricsConfigurationsInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *ListBucketMetricsConfigurationsInput) SetBucket(v string) *ListBucketMetricsConfigurationsInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *ListBucketMetricsConfigurationsInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetContinuationToken sets the ContinuationToken field's value.
+func (s *ListBucketMetricsConfigurationsInput) SetContinuationToken(v string) *ListBucketMetricsConfigurationsInput {
+	s.ContinuationToken = &v
+	return s
+}
+
+type ListBucketMetricsConfigurationsOutput struct {
+	_ struct{} `type:"structure"`
+
+	// The marker that is used as a starting point for this metrics configuration
+	// list response. This value is present if it was sent in the request.
+	ContinuationToken *string `type:"string"`
+
+	// Indicates whether the returned list of metrics configurations is complete.
+	// A value of true indicates that the list is not complete and the NextContinuationToken
+	// will be provided for a subsequent request.
+	IsTruncated *bool `type:"boolean"`
+
+	// The list of metrics configurations for a bucket.
+	MetricsConfigurationList []*MetricsConfiguration `locationName:"MetricsConfiguration" type:"list" flattened:"true"`
+
+	// The marker used to continue a metrics configuration listing that has been
+	// truncated. Use the NextContinuationToken from a previously truncated list
+	// response to continue the listing. The continuation token is an opaque value
+	// that Amazon S3 understands.
+	NextContinuationToken *string `type:"string"`
+}
+
+// String returns the string representation
+func (s ListBucketMetricsConfigurationsOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ListBucketMetricsConfigurationsOutput) GoString() string {
+	return s.String()
+}
+
+// SetContinuationToken sets the ContinuationToken field's value.
+func (s *ListBucketMetricsConfigurationsOutput) SetContinuationToken(v string) *ListBucketMetricsConfigurationsOutput {
+	s.ContinuationToken = &v
+	return s
+}
+
+// SetIsTruncated sets the IsTruncated field's value.
+func (s *ListBucketMetricsConfigurationsOutput) SetIsTruncated(v bool) *ListBucketMetricsConfigurationsOutput {
+	s.IsTruncated = &v
+	return s
+}
+
+// SetMetricsConfigurationList sets the MetricsConfigurationList field's value.
+func (s *ListBucketMetricsConfigurationsOutput) SetMetricsConfigurationList(v []*MetricsConfiguration) *ListBucketMetricsConfigurationsOutput {
+	s.MetricsConfigurationList = v
+	return s
+}
+
+// SetNextContinuationToken sets the NextContinuationToken field's value.
+func (s *ListBucketMetricsConfigurationsOutput) SetNextContinuationToken(v string) *ListBucketMetricsConfigurationsOutput {
+	s.NextContinuationToken = &v
+	return s
+}
+
+type ListBucketsInput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s ListBucketsInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ListBucketsInput) GoString() string {
+	return s.String()
+}
+
+type ListBucketsOutput struct {
+	_ struct{} `type:"structure"`
+
+	Buckets []*Bucket `locationNameList:"Bucket" type:"list"`
+
+	Owner *Owner `type:"structure"`
+}
+
+// String returns the string representation
+func (s ListBucketsOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ListBucketsOutput) GoString() string {
+	return s.String()
+}
+
+// SetBuckets sets the Buckets field's value.
+func (s *ListBucketsOutput) SetBuckets(v []*Bucket) *ListBucketsOutput {
+	s.Buckets = v
+	return s
+}
+
+// SetOwner sets the Owner field's value.
+func (s *ListBucketsOutput) SetOwner(v *Owner) *ListBucketsOutput {
+	s.Owner = v
+	return s
+}
+
+type ListMultipartUploadsInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Character you use to group keys.
+	Delimiter *string `location:"querystring" locationName:"delimiter" type:"string"`
+
+	// Requests Amazon S3 to encode the object keys in the response and specifies
+	// the encoding method to use. An object key may contain any Unicode character;
+	// however, XML 1.0 parser cannot parse some characters, such as characters
+	// with an ASCII value from 0 to 10. For characters that are not supported in
+	// XML 1.0, you can add this parameter to request that Amazon S3 encode the
+	// keys in the response.
+	EncodingType *string `location:"querystring" locationName:"encoding-type" type:"string" enum:"EncodingType"`
+
+	// Together with upload-id-marker, this parameter specifies the multipart upload
+	// after which listing should begin.
+	KeyMarker *string `location:"querystring" locationName:"key-marker" type:"string"`
+
+	// Sets the maximum number of multipart uploads, from 1 to 1,000, to return
+	// in the response body. 1,000 is the maximum number of uploads that can be
+	// returned in a response.
+	MaxUploads *int64 `location:"querystring" locationName:"max-uploads" type:"integer"`
+
+	// Lists in-progress uploads only for those keys that begin with the specified
+	// prefix.
+	Prefix *string `location:"querystring" locationName:"prefix" type:"string"`
+
+	// Together with key-marker, specifies the multipart upload after which listing
+	// should begin. If key-marker is not specified, the upload-id-marker parameter
+	// is ignored.
+	UploadIdMarker *string `location:"querystring" locationName:"upload-id-marker" type:"string"`
+}
+
+// String returns the string representation
+func (s ListMultipartUploadsInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ListMultipartUploadsInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *ListMultipartUploadsInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "ListMultipartUploadsInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *ListMultipartUploadsInput) SetBucket(v string) *ListMultipartUploadsInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *ListMultipartUploadsInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetDelimiter sets the Delimiter field's value.
+func (s *ListMultipartUploadsInput) SetDelimiter(v string) *ListMultipartUploadsInput {
+	s.Delimiter = &v
+	return s
+}
+
+// SetEncodingType sets the EncodingType field's value.
+func (s *ListMultipartUploadsInput) SetEncodingType(v string) *ListMultipartUploadsInput {
+	s.EncodingType = &v
+	return s
+}
+
+// SetKeyMarker sets the KeyMarker field's value.
+func (s *ListMultipartUploadsInput) SetKeyMarker(v string) *ListMultipartUploadsInput {
+	s.KeyMarker = &v
+	return s
+}
+
+// SetMaxUploads sets the MaxUploads field's value.
+func (s *ListMultipartUploadsInput) SetMaxUploads(v int64) *ListMultipartUploadsInput {
+	s.MaxUploads = &v
+	return s
+}
+
+// SetPrefix sets the Prefix field's value.
+func (s *ListMultipartUploadsInput) SetPrefix(v string) *ListMultipartUploadsInput {
+	s.Prefix = &v
+	return s
+}
+
+// SetUploadIdMarker sets the UploadIdMarker field's value.
+func (s *ListMultipartUploadsInput) SetUploadIdMarker(v string) *ListMultipartUploadsInput {
+	s.UploadIdMarker = &v
+	return s
+}
+
+type ListMultipartUploadsOutput struct {
+	_ struct{} `type:"structure"`
+
+	// Name of the bucket to which the multipart upload was initiated.
+	Bucket *string `type:"string"`
+
+	CommonPrefixes []*CommonPrefix `type:"list" flattened:"true"`
+
+	Delimiter *string `type:"string"`
+
+	// Encoding type used by Amazon S3 to encode object keys in the response.
+	EncodingType *string `type:"string" enum:"EncodingType"`
+
+	// Indicates whether the returned list of multipart uploads is truncated. A
+	// value of true indicates that the list was truncated. The list can be truncated
+	// if the number of multipart uploads exceeds the limit allowed or specified
+	// by max uploads.
+	IsTruncated *bool `type:"boolean"`
+
+	// The key at or after which the listing began.
+	KeyMarker *string `type:"string"`
+
+	// Maximum number of multipart uploads that could have been included in the
+	// response.
+	MaxUploads *int64 `type:"integer"`
+
+	// When a list is truncated, this element specifies the value that should be
+	// used for the key-marker request parameter in a subsequent request.
+	NextKeyMarker *string `type:"string"`
+
+	// When a list is truncated, this element specifies the value that should be
+	// used for the upload-id-marker request parameter in a subsequent request.
+	NextUploadIdMarker *string `type:"string"`
+
+	// When a prefix is provided in the request, this field contains the specified
+	// prefix. The result contains only keys starting with the specified prefix.
+	Prefix *string `type:"string"`
+
+	// Upload ID after which listing began.
+	UploadIdMarker *string `type:"string"`
+
+	Uploads []*MultipartUpload `locationName:"Upload" type:"list" flattened:"true"`
+}
+
+// String returns the string representation
+func (s ListMultipartUploadsOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ListMultipartUploadsOutput) GoString() string {
+	return s.String()
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *ListMultipartUploadsOutput) SetBucket(v string) *ListMultipartUploadsOutput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *ListMultipartUploadsOutput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetCommonPrefixes sets the CommonPrefixes field's value.
+func (s *ListMultipartUploadsOutput) SetCommonPrefixes(v []*CommonPrefix) *ListMultipartUploadsOutput {
+	s.CommonPrefixes = v
+	return s
+}
+
+// SetDelimiter sets the Delimiter field's value.
+func (s *ListMultipartUploadsOutput) SetDelimiter(v string) *ListMultipartUploadsOutput {
+	s.Delimiter = &v
+	return s
+}
+
+// SetEncodingType sets the EncodingType field's value.
+func (s *ListMultipartUploadsOutput) SetEncodingType(v string) *ListMultipartUploadsOutput {
+	s.EncodingType = &v
+	return s
+}
+
+// SetIsTruncated sets the IsTruncated field's value.
+func (s *ListMultipartUploadsOutput) SetIsTruncated(v bool) *ListMultipartUploadsOutput {
+	s.IsTruncated = &v
+	return s
+}
+
+// SetKeyMarker sets the KeyMarker field's value.
+func (s *ListMultipartUploadsOutput) SetKeyMarker(v string) *ListMultipartUploadsOutput {
+	s.KeyMarker = &v
+	return s
+}
+
+// SetMaxUploads sets the MaxUploads field's value.
+func (s *ListMultipartUploadsOutput) SetMaxUploads(v int64) *ListMultipartUploadsOutput {
+	s.MaxUploads = &v
+	return s
+}
+
+// SetNextKeyMarker sets the NextKeyMarker field's value.
+func (s *ListMultipartUploadsOutput) SetNextKeyMarker(v string) *ListMultipartUploadsOutput {
+	s.NextKeyMarker = &v
+	return s
+}
+
+// SetNextUploadIdMarker sets the NextUploadIdMarker field's value.
+func (s *ListMultipartUploadsOutput) SetNextUploadIdMarker(v string) *ListMultipartUploadsOutput {
+	s.NextUploadIdMarker = &v
+	return s
+}
+
+// SetPrefix sets the Prefix field's value.
+func (s *ListMultipartUploadsOutput) SetPrefix(v string) *ListMultipartUploadsOutput {
+	s.Prefix = &v
+	return s
+}
+
+// SetUploadIdMarker sets the UploadIdMarker field's value.
+func (s *ListMultipartUploadsOutput) SetUploadIdMarker(v string) *ListMultipartUploadsOutput {
+	s.UploadIdMarker = &v
+	return s
+}
+
+// SetUploads sets the Uploads field's value.
+func (s *ListMultipartUploadsOutput) SetUploads(v []*MultipartUpload) *ListMultipartUploadsOutput {
+	s.Uploads = v
+	return s
+}
+
+type ListObjectVersionsInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// A delimiter is a character you use to group keys.
+	Delimiter *string `location:"querystring" locationName:"delimiter" type:"string"`
+
+	// Requests Amazon S3 to encode the object keys in the response and specifies
+	// the encoding method to use. An object key may contain any Unicode character;
+	// however, XML 1.0 parser cannot parse some characters, such as characters
+	// with an ASCII value from 0 to 10. For characters that are not supported in
+	// XML 1.0, you can add this parameter to request that Amazon S3 encode the
+	// keys in the response.
+	EncodingType *string `location:"querystring" locationName:"encoding-type" type:"string" enum:"EncodingType"`
+
+	// Specifies the key to start with when listing objects in a bucket.
+	KeyMarker *string `location:"querystring" locationName:"key-marker" type:"string"`
+
+	// Sets the maximum number of keys returned in the response. The response might
+	// contain fewer keys but will never contain more.
+	MaxKeys *int64 `location:"querystring" locationName:"max-keys" type:"integer"`
+
+	// Limits the response to keys that begin with the specified prefix.
+	Prefix *string `location:"querystring" locationName:"prefix" type:"string"`
+
+	// Specifies the object version you want to start listing from.
+	VersionIdMarker *string `location:"querystring" locationName:"version-id-marker" type:"string"`
+}
+
+// String returns the string representation
+func (s ListObjectVersionsInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ListObjectVersionsInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *ListObjectVersionsInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "ListObjectVersionsInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *ListObjectVersionsInput) SetBucket(v string) *ListObjectVersionsInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *ListObjectVersionsInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetDelimiter sets the Delimiter field's value.
+func (s *ListObjectVersionsInput) SetDelimiter(v string) *ListObjectVersionsInput {
+	s.Delimiter = &v
+	return s
+}
+
+// SetEncodingType sets the EncodingType field's value.
+func (s *ListObjectVersionsInput) SetEncodingType(v string) *ListObjectVersionsInput {
+	s.EncodingType = &v
+	return s
+}
+
+// SetKeyMarker sets the KeyMarker field's value.
+func (s *ListObjectVersionsInput) SetKeyMarker(v string) *ListObjectVersionsInput {
+	s.KeyMarker = &v
+	return s
+}
+
+// SetMaxKeys sets the MaxKeys field's value.
+func (s *ListObjectVersionsInput) SetMaxKeys(v int64) *ListObjectVersionsInput {
+	s.MaxKeys = &v
+	return s
+}
+
+// SetPrefix sets the Prefix field's value.
+func (s *ListObjectVersionsInput) SetPrefix(v string) *ListObjectVersionsInput {
+	s.Prefix = &v
+	return s
+}
+
+// SetVersionIdMarker sets the VersionIdMarker field's value.
+func (s *ListObjectVersionsInput) SetVersionIdMarker(v string) *ListObjectVersionsInput {
+	s.VersionIdMarker = &v
+	return s
+}
+
+type ListObjectVersionsOutput struct {
+	_ struct{} `type:"structure"`
+
+	CommonPrefixes []*CommonPrefix `type:"list" flattened:"true"`
+
+	DeleteMarkers []*DeleteMarkerEntry `locationName:"DeleteMarker" type:"list" flattened:"true"`
+
+	Delimiter *string `type:"string"`
+
+	// Encoding type used by Amazon S3 to encode object keys in the response.
+	EncodingType *string `type:"string" enum:"EncodingType"`
+
+	// A flag that indicates whether or not Amazon S3 returned all of the results
+	// that satisfied the search criteria. If your results were truncated, you can
+	// make a follow-up paginated request using the NextKeyMarker and NextVersionIdMarker
+	// response parameters as a starting place in another request to return the
+	// rest of the results.
+	IsTruncated *bool `type:"boolean"`
+
+	// Marks the last Key returned in a truncated response.
+	KeyMarker *string `type:"string"`
+
+	MaxKeys *int64 `type:"integer"`
+
+	Name *string `type:"string"`
+
+	// Use this value for the key marker request parameter in a subsequent request.
+	NextKeyMarker *string `type:"string"`
+
+	// Use this value for the next version id marker parameter in a subsequent request.
+	NextVersionIdMarker *string `type:"string"`
+
+	Prefix *string `type:"string"`
+
+	VersionIdMarker *string `type:"string"`
+
+	Versions []*ObjectVersion `locationName:"Version" type:"list" flattened:"true"`
+}
+
+// String returns the string representation
+func (s ListObjectVersionsOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ListObjectVersionsOutput) GoString() string {
+	return s.String()
+}
+
+// SetCommonPrefixes sets the CommonPrefixes field's value.
+func (s *ListObjectVersionsOutput) SetCommonPrefixes(v []*CommonPrefix) *ListObjectVersionsOutput {
+	s.CommonPrefixes = v
+	return s
+}
+
+// SetDeleteMarkers sets the DeleteMarkers field's value.
+func (s *ListObjectVersionsOutput) SetDeleteMarkers(v []*DeleteMarkerEntry) *ListObjectVersionsOutput {
+	s.DeleteMarkers = v
+	return s
+}
+
+// SetDelimiter sets the Delimiter field's value.
+func (s *ListObjectVersionsOutput) SetDelimiter(v string) *ListObjectVersionsOutput {
+	s.Delimiter = &v
+	return s
+}
+
+// SetEncodingType sets the EncodingType field's value.
+func (s *ListObjectVersionsOutput) SetEncodingType(v string) *ListObjectVersionsOutput {
+	s.EncodingType = &v
+	return s
+}
+
+// SetIsTruncated sets the IsTruncated field's value.
+func (s *ListObjectVersionsOutput) SetIsTruncated(v bool) *ListObjectVersionsOutput {
+	s.IsTruncated = &v
+	return s
+}
+
+// SetKeyMarker sets the KeyMarker field's value.
+func (s *ListObjectVersionsOutput) SetKeyMarker(v string) *ListObjectVersionsOutput {
+	s.KeyMarker = &v
+	return s
+}
+
+// SetMaxKeys sets the MaxKeys field's value.
+func (s *ListObjectVersionsOutput) SetMaxKeys(v int64) *ListObjectVersionsOutput {
+	s.MaxKeys = &v
+	return s
+}
+
+// SetName sets the Name field's value.
+func (s *ListObjectVersionsOutput) SetName(v string) *ListObjectVersionsOutput {
+	s.Name = &v
+	return s
+}
+
+// SetNextKeyMarker sets the NextKeyMarker field's value.
+func (s *ListObjectVersionsOutput) SetNextKeyMarker(v string) *ListObjectVersionsOutput {
+	s.NextKeyMarker = &v
+	return s
+}
+
+// SetNextVersionIdMarker sets the NextVersionIdMarker field's value.
+func (s *ListObjectVersionsOutput) SetNextVersionIdMarker(v string) *ListObjectVersionsOutput {
+	s.NextVersionIdMarker = &v
+	return s
+}
+
+// SetPrefix sets the Prefix field's value.
+func (s *ListObjectVersionsOutput) SetPrefix(v string) *ListObjectVersionsOutput {
+	s.Prefix = &v
+	return s
+}
+
+// SetVersionIdMarker sets the VersionIdMarker field's value.
+func (s *ListObjectVersionsOutput) SetVersionIdMarker(v string) *ListObjectVersionsOutput {
+	s.VersionIdMarker = &v
+	return s
+}
+
+// SetVersions sets the Versions field's value.
+func (s *ListObjectVersionsOutput) SetVersions(v []*ObjectVersion) *ListObjectVersionsOutput {
+	s.Versions = v
+	return s
+}
+
+type ListObjectsInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// A delimiter is a character you use to group keys.
+	Delimiter *string `location:"querystring" locationName:"delimiter" type:"string"`
+
+	// Requests Amazon S3 to encode the object keys in the response and specifies
+	// the encoding method to use. An object key may contain any Unicode character;
+	// however, XML 1.0 parser cannot parse some characters, such as characters
+	// with an ASCII value from 0 to 10. For characters that are not supported in
+	// XML 1.0, you can add this parameter to request that Amazon S3 encode the
+	// keys in the response.
+	EncodingType *string `location:"querystring" locationName:"encoding-type" type:"string" enum:"EncodingType"`
+
+	// Specifies the key to start with when listing objects in a bucket.
+	Marker *string `location:"querystring" locationName:"marker" type:"string"`
+
+	// Sets the maximum number of keys returned in the response. The response might
+	// contain fewer keys but will never contain more.
+	MaxKeys *int64 `location:"querystring" locationName:"max-keys" type:"integer"`
+
+	// Limits the response to keys that begin with the specified prefix.
+	Prefix *string `location:"querystring" locationName:"prefix" type:"string"`
+
+	// Confirms that the requester knows that she or he will be charged for the
+	// list objects request. Bucket owners need not specify this parameter in their
+	// requests.
+	RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"`
+}
+
+// String returns the string representation
+func (s ListObjectsInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ListObjectsInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *ListObjectsInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "ListObjectsInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *ListObjectsInput) SetBucket(v string) *ListObjectsInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *ListObjectsInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetDelimiter sets the Delimiter field's value.
+func (s *ListObjectsInput) SetDelimiter(v string) *ListObjectsInput {
+	s.Delimiter = &v
+	return s
+}
+
+// SetEncodingType sets the EncodingType field's value.
+func (s *ListObjectsInput) SetEncodingType(v string) *ListObjectsInput {
+	s.EncodingType = &v
+	return s
+}
+
+// SetMarker sets the Marker field's value.
+func (s *ListObjectsInput) SetMarker(v string) *ListObjectsInput {
+	s.Marker = &v
+	return s
+}
+
+// SetMaxKeys sets the MaxKeys field's value.
+func (s *ListObjectsInput) SetMaxKeys(v int64) *ListObjectsInput {
+	s.MaxKeys = &v
+	return s
+}
+
+// SetPrefix sets the Prefix field's value.
+func (s *ListObjectsInput) SetPrefix(v string) *ListObjectsInput {
+	s.Prefix = &v
+	return s
+}
+
+// SetRequestPayer sets the RequestPayer field's value.
+func (s *ListObjectsInput) SetRequestPayer(v string) *ListObjectsInput {
+	s.RequestPayer = &v
+	return s
+}
+
+type ListObjectsOutput struct {
+	_ struct{} `type:"structure"`
+
+	CommonPrefixes []*CommonPrefix `type:"list" flattened:"true"`
+
+	Contents []*Object `type:"list" flattened:"true"`
+
+	Delimiter *string `type:"string"`
+
+	// Encoding type used by Amazon S3 to encode object keys in the response.
+	EncodingType *string `type:"string" enum:"EncodingType"`
+
+	// A flag that indicates whether or not Amazon S3 returned all of the results
+	// that satisfied the search criteria.
+	IsTruncated *bool `type:"boolean"`
+
+	Marker *string `type:"string"`
+
+	MaxKeys *int64 `type:"integer"`
+
+	Name *string `type:"string"`
+
+	// When response is truncated (the IsTruncated element value in the response
+	// is true), you can use the key name in this field as marker in the subsequent
+	// request to get next set of objects. Amazon S3 lists objects in alphabetical
+	// order Note: This element is returned only if you have delimiter request parameter
+	// specified. If response does not include the NextMaker and it is truncated,
+	// you can use the value of the last Key in the response as the marker in the
+	// subsequent request to get the next set of object keys.
+	NextMarker *string `type:"string"`
+
+	Prefix *string `type:"string"`
+}
+
+// String returns the string representation
+func (s ListObjectsOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ListObjectsOutput) GoString() string {
+	return s.String()
+}
+
+// SetCommonPrefixes sets the CommonPrefixes field's value.
+func (s *ListObjectsOutput) SetCommonPrefixes(v []*CommonPrefix) *ListObjectsOutput {
+	s.CommonPrefixes = v
+	return s
+}
+
+// SetContents sets the Contents field's value.
+func (s *ListObjectsOutput) SetContents(v []*Object) *ListObjectsOutput {
+	s.Contents = v
+	return s
+}
+
+// SetDelimiter sets the Delimiter field's value.
+func (s *ListObjectsOutput) SetDelimiter(v string) *ListObjectsOutput {
+	s.Delimiter = &v
+	return s
+}
+
+// SetEncodingType sets the EncodingType field's value.
+func (s *ListObjectsOutput) SetEncodingType(v string) *ListObjectsOutput {
+	s.EncodingType = &v
+	return s
+}
+
+// SetIsTruncated sets the IsTruncated field's value.
+func (s *ListObjectsOutput) SetIsTruncated(v bool) *ListObjectsOutput {
+	s.IsTruncated = &v
+	return s
+}
+
+// SetMarker sets the Marker field's value.
+func (s *ListObjectsOutput) SetMarker(v string) *ListObjectsOutput {
+	s.Marker = &v
+	return s
+}
+
+// SetMaxKeys sets the MaxKeys field's value.
+func (s *ListObjectsOutput) SetMaxKeys(v int64) *ListObjectsOutput {
+	s.MaxKeys = &v
+	return s
+}
+
+// SetName sets the Name field's value.
+func (s *ListObjectsOutput) SetName(v string) *ListObjectsOutput {
+	s.Name = &v
+	return s
+}
+
+// SetNextMarker sets the NextMarker field's value.
+func (s *ListObjectsOutput) SetNextMarker(v string) *ListObjectsOutput {
+	s.NextMarker = &v
+	return s
+}
+
+// SetPrefix sets the Prefix field's value.
+func (s *ListObjectsOutput) SetPrefix(v string) *ListObjectsOutput {
+	s.Prefix = &v
+	return s
+}
+
+type ListObjectsV2Input struct {
+	_ struct{} `type:"structure"`
+
+	// Name of the bucket to list.
+	//
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// ContinuationToken indicates Amazon S3 that the list is being continued on
+	// this bucket with a token. ContinuationToken is obfuscated and is not a real
+	// key
+	ContinuationToken *string `location:"querystring" locationName:"continuation-token" type:"string"`
+
+	// A delimiter is a character you use to group keys.
+	Delimiter *string `location:"querystring" locationName:"delimiter" type:"string"`
+
+	// Encoding type used by Amazon S3 to encode object keys in the response.
+	EncodingType *string `location:"querystring" locationName:"encoding-type" type:"string" enum:"EncodingType"`
+
+	// The owner field is not present in listV2 by default, if you want to return
+	// owner field with each key in the result then set the fetch owner field to
+	// true
+	FetchOwner *bool `location:"querystring" locationName:"fetch-owner" type:"boolean"`
+
+	// Sets the maximum number of keys returned in the response. The response might
+	// contain fewer keys but will never contain more.
+	MaxKeys *int64 `location:"querystring" locationName:"max-keys" type:"integer"`
+
+	// Limits the response to keys that begin with the specified prefix.
+	Prefix *string `location:"querystring" locationName:"prefix" type:"string"`
+
+	// Confirms that the requester knows that she or he will be charged for the
+	// list objects request in V2 style. Bucket owners need not specify this parameter
+	// in their requests.
+	RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"`
+
+	// StartAfter is where you want Amazon S3 to start listing from. Amazon S3 starts
+	// listing after this specified key. StartAfter can be any key in the bucket
+	StartAfter *string `location:"querystring" locationName:"start-after" type:"string"`
+}
+
+// String returns the string representation
+func (s ListObjectsV2Input) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ListObjectsV2Input) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *ListObjectsV2Input) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "ListObjectsV2Input"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *ListObjectsV2Input) SetBucket(v string) *ListObjectsV2Input {
+	s.Bucket = &v
+	return s
+}
+
+func (s *ListObjectsV2Input) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetContinuationToken sets the ContinuationToken field's value.
+func (s *ListObjectsV2Input) SetContinuationToken(v string) *ListObjectsV2Input {
+	s.ContinuationToken = &v
+	return s
+}
+
+// SetDelimiter sets the Delimiter field's value.
+func (s *ListObjectsV2Input) SetDelimiter(v string) *ListObjectsV2Input {
+	s.Delimiter = &v
+	return s
+}
+
+// SetEncodingType sets the EncodingType field's value.
+func (s *ListObjectsV2Input) SetEncodingType(v string) *ListObjectsV2Input {
+	s.EncodingType = &v
+	return s
+}
+
+// SetFetchOwner sets the FetchOwner field's value.
+func (s *ListObjectsV2Input) SetFetchOwner(v bool) *ListObjectsV2Input {
+	s.FetchOwner = &v
+	return s
+}
+
+// SetMaxKeys sets the MaxKeys field's value.
+func (s *ListObjectsV2Input) SetMaxKeys(v int64) *ListObjectsV2Input {
+	s.MaxKeys = &v
+	return s
+}
+
+// SetPrefix sets the Prefix field's value.
+func (s *ListObjectsV2Input) SetPrefix(v string) *ListObjectsV2Input {
+	s.Prefix = &v
+	return s
+}
+
+// SetRequestPayer sets the RequestPayer field's value.
+func (s *ListObjectsV2Input) SetRequestPayer(v string) *ListObjectsV2Input {
+	s.RequestPayer = &v
+	return s
+}
+
+// SetStartAfter sets the StartAfter field's value.
+func (s *ListObjectsV2Input) SetStartAfter(v string) *ListObjectsV2Input {
+	s.StartAfter = &v
+	return s
+}
+
+type ListObjectsV2Output struct {
+	_ struct{} `type:"structure"`
+
+	// CommonPrefixes contains all (if there are any) keys between Prefix and the
+	// next occurrence of the string specified by delimiter
+	CommonPrefixes []*CommonPrefix `type:"list" flattened:"true"`
+
+	// Metadata about each object returned.
+	Contents []*Object `type:"list" flattened:"true"`
+
+	// ContinuationToken indicates Amazon S3 that the list is being continued on
+	// this bucket with a token. ContinuationToken is obfuscated and is not a real
+	// key
+	ContinuationToken *string `type:"string"`
+
+	// A delimiter is a character you use to group keys.
+	Delimiter *string `type:"string"`
+
+	// Encoding type used by Amazon S3 to encode object keys in the response.
+	EncodingType *string `type:"string" enum:"EncodingType"`
+
+	// A flag that indicates whether or not Amazon S3 returned all of the results
+	// that satisfied the search criteria.
+	IsTruncated *bool `type:"boolean"`
+
+	// KeyCount is the number of keys returned with this request. KeyCount will
+	// always be less than equals to MaxKeys field. Say you ask for 50 keys, your
+	// result will include less than equals 50 keys
+	KeyCount *int64 `type:"integer"`
+
+	// Sets the maximum number of keys returned in the response. The response might
+	// contain fewer keys but will never contain more.
+	MaxKeys *int64 `type:"integer"`
+
+	// Name of the bucket to list.
+	Name *string `type:"string"`
+
+	// NextContinuationToken is sent when isTruncated is true which means there
+	// are more keys in the bucket that can be listed. The next list requests to
+	// Amazon S3 can be continued with this NextContinuationToken. NextContinuationToken
+	// is obfuscated and is not a real key
+	NextContinuationToken *string `type:"string"`
+
+	// Limits the response to keys that begin with the specified prefix.
+	Prefix *string `type:"string"`
+
+	// StartAfter is where you want Amazon S3 to start listing from. Amazon S3 starts
+	// listing after this specified key. StartAfter can be any key in the bucket
+	StartAfter *string `type:"string"`
+}
+
+// String returns the string representation
+func (s ListObjectsV2Output) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ListObjectsV2Output) GoString() string {
+	return s.String()
+}
+
+// SetCommonPrefixes sets the CommonPrefixes field's value.
+func (s *ListObjectsV2Output) SetCommonPrefixes(v []*CommonPrefix) *ListObjectsV2Output {
+	s.CommonPrefixes = v
+	return s
+}
+
+// SetContents sets the Contents field's value.
+func (s *ListObjectsV2Output) SetContents(v []*Object) *ListObjectsV2Output {
+	s.Contents = v
+	return s
+}
+
+// SetContinuationToken sets the ContinuationToken field's value.
+func (s *ListObjectsV2Output) SetContinuationToken(v string) *ListObjectsV2Output {
+	s.ContinuationToken = &v
+	return s
+}
+
+// SetDelimiter sets the Delimiter field's value.
+func (s *ListObjectsV2Output) SetDelimiter(v string) *ListObjectsV2Output {
+	s.Delimiter = &v
+	return s
+}
+
+// SetEncodingType sets the EncodingType field's value.
+func (s *ListObjectsV2Output) SetEncodingType(v string) *ListObjectsV2Output {
+	s.EncodingType = &v
+	return s
+}
+
+// SetIsTruncated sets the IsTruncated field's value.
+func (s *ListObjectsV2Output) SetIsTruncated(v bool) *ListObjectsV2Output {
+	s.IsTruncated = &v
+	return s
+}
+
+// SetKeyCount sets the KeyCount field's value.
+func (s *ListObjectsV2Output) SetKeyCount(v int64) *ListObjectsV2Output {
+	s.KeyCount = &v
+	return s
+}
+
+// SetMaxKeys sets the MaxKeys field's value.
+func (s *ListObjectsV2Output) SetMaxKeys(v int64) *ListObjectsV2Output {
+	s.MaxKeys = &v
+	return s
+}
+
+// SetName sets the Name field's value.
+func (s *ListObjectsV2Output) SetName(v string) *ListObjectsV2Output {
+	s.Name = &v
+	return s
+}
+
+// SetNextContinuationToken sets the NextContinuationToken field's value.
+func (s *ListObjectsV2Output) SetNextContinuationToken(v string) *ListObjectsV2Output {
+	s.NextContinuationToken = &v
+	return s
+}
+
+// SetPrefix sets the Prefix field's value.
+func (s *ListObjectsV2Output) SetPrefix(v string) *ListObjectsV2Output {
+	s.Prefix = &v
+	return s
+}
+
+// SetStartAfter sets the StartAfter field's value.
+func (s *ListObjectsV2Output) SetStartAfter(v string) *ListObjectsV2Output {
+	s.StartAfter = &v
+	return s
+}
+
+type ListPartsInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Key is a required field
+	Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"`
+
+	// Sets the maximum number of parts to return.
+	MaxParts *int64 `location:"querystring" locationName:"max-parts" type:"integer"`
+
+	// Specifies the part after which listing should begin. Only parts with higher
+	// part numbers will be listed.
+	PartNumberMarker *int64 `location:"querystring" locationName:"part-number-marker" type:"integer"`
+
+	// Confirms that the requester knows that she or he will be charged for the
+	// request. Bucket owners need not specify this parameter in their requests.
+	// Documentation on downloading objects from requester pays buckets can be found
+	// at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
+	RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"`
+
+	// Upload ID identifying the multipart upload whose parts are being listed.
+	//
+	// UploadId is a required field
+	UploadId *string `location:"querystring" locationName:"uploadId" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s ListPartsInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ListPartsInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *ListPartsInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "ListPartsInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Key == nil {
+		invalidParams.Add(request.NewErrParamRequired("Key"))
+	}
+	if s.Key != nil && len(*s.Key) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
+	}
+	if s.UploadId == nil {
+		invalidParams.Add(request.NewErrParamRequired("UploadId"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *ListPartsInput) SetBucket(v string) *ListPartsInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *ListPartsInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetKey sets the Key field's value.
+func (s *ListPartsInput) SetKey(v string) *ListPartsInput {
+	s.Key = &v
+	return s
+}
+
+// SetMaxParts sets the MaxParts field's value.
+func (s *ListPartsInput) SetMaxParts(v int64) *ListPartsInput {
+	s.MaxParts = &v
+	return s
+}
+
+// SetPartNumberMarker sets the PartNumberMarker field's value.
+func (s *ListPartsInput) SetPartNumberMarker(v int64) *ListPartsInput {
+	s.PartNumberMarker = &v
+	return s
+}
+
+// SetRequestPayer sets the RequestPayer field's value.
+func (s *ListPartsInput) SetRequestPayer(v string) *ListPartsInput {
+	s.RequestPayer = &v
+	return s
+}
+
+// SetUploadId sets the UploadId field's value.
+func (s *ListPartsInput) SetUploadId(v string) *ListPartsInput {
+	s.UploadId = &v
+	return s
+}
+
+type ListPartsOutput struct {
+	_ struct{} `type:"structure"`
+
+	// Date when multipart upload will become eligible for abort operation by lifecycle.
+	AbortDate *time.Time `location:"header" locationName:"x-amz-abort-date" type:"timestamp"`
+
+	// Id of the lifecycle rule that makes a multipart upload eligible for abort
+	// operation.
+	AbortRuleId *string `location:"header" locationName:"x-amz-abort-rule-id" type:"string"`
+
+	// Name of the bucket to which the multipart upload was initiated.
+	Bucket *string `type:"string"`
+
+	// Identifies who initiated the multipart upload.
+	Initiator *Initiator `type:"structure"`
+
+	// Indicates whether the returned list of parts is truncated.
+	IsTruncated *bool `type:"boolean"`
+
+	// Object key for which the multipart upload was initiated.
+	Key *string `min:"1" type:"string"`
+
+	// Maximum number of parts that were allowed in the response.
+	MaxParts *int64 `type:"integer"`
+
+	// When a list is truncated, this element specifies the last part in the list,
+	// as well as the value to use for the part-number-marker request parameter
+	// in a subsequent request.
+	NextPartNumberMarker *int64 `type:"integer"`
+
+	Owner *Owner `type:"structure"`
+
+	// Part number after which listing begins.
+	PartNumberMarker *int64 `type:"integer"`
+
+	Parts []*Part `locationName:"Part" type:"list" flattened:"true"`
+
+	// If present, indicates that the requester was successfully charged for the
+	// request.
+	RequestCharged *string `location:"header" locationName:"x-amz-request-charged" type:"string" enum:"RequestCharged"`
+
+	// The class of storage used to store the object.
+	StorageClass *string `type:"string" enum:"StorageClass"`
+
+	// Upload ID identifying the multipart upload whose parts are being listed.
+	UploadId *string `type:"string"`
+}
+
+// String returns the string representation
+func (s ListPartsOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ListPartsOutput) GoString() string {
+	return s.String()
+}
+
+// SetAbortDate sets the AbortDate field's value.
+func (s *ListPartsOutput) SetAbortDate(v time.Time) *ListPartsOutput {
+	s.AbortDate = &v
+	return s
+}
+
+// SetAbortRuleId sets the AbortRuleId field's value.
+func (s *ListPartsOutput) SetAbortRuleId(v string) *ListPartsOutput {
+	s.AbortRuleId = &v
+	return s
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *ListPartsOutput) SetBucket(v string) *ListPartsOutput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *ListPartsOutput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetInitiator sets the Initiator field's value.
+func (s *ListPartsOutput) SetInitiator(v *Initiator) *ListPartsOutput {
+	s.Initiator = v
+	return s
+}
+
+// SetIsTruncated sets the IsTruncated field's value.
+func (s *ListPartsOutput) SetIsTruncated(v bool) *ListPartsOutput {
+	s.IsTruncated = &v
+	return s
+}
+
+// SetKey sets the Key field's value.
+func (s *ListPartsOutput) SetKey(v string) *ListPartsOutput {
+	s.Key = &v
+	return s
+}
+
+// SetMaxParts sets the MaxParts field's value.
+func (s *ListPartsOutput) SetMaxParts(v int64) *ListPartsOutput {
+	s.MaxParts = &v
+	return s
+}
+
+// SetNextPartNumberMarker sets the NextPartNumberMarker field's value.
+func (s *ListPartsOutput) SetNextPartNumberMarker(v int64) *ListPartsOutput {
+	s.NextPartNumberMarker = &v
+	return s
+}
+
+// SetOwner sets the Owner field's value.
+func (s *ListPartsOutput) SetOwner(v *Owner) *ListPartsOutput {
+	s.Owner = v
+	return s
+}
+
+// SetPartNumberMarker sets the PartNumberMarker field's value.
+func (s *ListPartsOutput) SetPartNumberMarker(v int64) *ListPartsOutput {
+	s.PartNumberMarker = &v
+	return s
+}
+
+// SetParts sets the Parts field's value.
+func (s *ListPartsOutput) SetParts(v []*Part) *ListPartsOutput {
+	s.Parts = v
+	return s
+}
+
+// SetRequestCharged sets the RequestCharged field's value.
+func (s *ListPartsOutput) SetRequestCharged(v string) *ListPartsOutput {
+	s.RequestCharged = &v
+	return s
+}
+
+// SetStorageClass sets the StorageClass field's value.
+func (s *ListPartsOutput) SetStorageClass(v string) *ListPartsOutput {
+	s.StorageClass = &v
+	return s
+}
+
+// SetUploadId sets the UploadId field's value.
+func (s *ListPartsOutput) SetUploadId(v string) *ListPartsOutput {
+	s.UploadId = &v
+	return s
+}
+
+// Describes an S3 location that will receive the results of the restore request.
+type Location struct {
+	_ struct{} `type:"structure"`
+
+	// A list of grants that control access to the staged results.
+	AccessControlList []*Grant `locationNameList:"Grant" type:"list"`
+
+	// The name of the bucket where the restore results will be placed.
+	//
+	// BucketName is a required field
+	BucketName *string `type:"string" required:"true"`
+
+	// The canned ACL to apply to the restore results.
+	CannedACL *string `type:"string" enum:"ObjectCannedACL"`
+
+	// Describes the server-side encryption that will be applied to the restore
+	// results.
+	Encryption *Encryption `type:"structure"`
+
+	// The prefix that is prepended to the restore results for this request.
+	//
+	// Prefix is a required field
+	Prefix *string `type:"string" required:"true"`
+
+	// The class of storage used to store the restore results.
+	StorageClass *string `type:"string" enum:"StorageClass"`
+
+	// The tag-set that is applied to the restore results.
+	Tagging *Tagging `type:"structure"`
+
+	// A list of metadata to store with the restore results in S3.
+	UserMetadata []*MetadataEntry `locationNameList:"MetadataEntry" type:"list"`
+}
+
+// String returns the string representation
+func (s Location) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s Location) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *Location) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "Location"}
+	if s.BucketName == nil {
+		invalidParams.Add(request.NewErrParamRequired("BucketName"))
+	}
+	if s.Prefix == nil {
+		invalidParams.Add(request.NewErrParamRequired("Prefix"))
+	}
+	if s.AccessControlList != nil {
+		for i, v := range s.AccessControlList {
+			if v == nil {
+				continue
+			}
+			if err := v.Validate(); err != nil {
+				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "AccessControlList", i), err.(request.ErrInvalidParams))
+			}
+		}
+	}
+	if s.Encryption != nil {
+		if err := s.Encryption.Validate(); err != nil {
+			invalidParams.AddNested("Encryption", err.(request.ErrInvalidParams))
+		}
+	}
+	if s.Tagging != nil {
+		if err := s.Tagging.Validate(); err != nil {
+			invalidParams.AddNested("Tagging", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetAccessControlList sets the AccessControlList field's value.
+func (s *Location) SetAccessControlList(v []*Grant) *Location {
+	s.AccessControlList = v
+	return s
+}
+
+// SetBucketName sets the BucketName field's value.
+func (s *Location) SetBucketName(v string) *Location {
+	s.BucketName = &v
+	return s
+}
+
+// SetCannedACL sets the CannedACL field's value.
+func (s *Location) SetCannedACL(v string) *Location {
+	s.CannedACL = &v
+	return s
+}
+
+// SetEncryption sets the Encryption field's value.
+func (s *Location) SetEncryption(v *Encryption) *Location {
+	s.Encryption = v
+	return s
+}
+
+// SetPrefix sets the Prefix field's value.
+func (s *Location) SetPrefix(v string) *Location {
+	s.Prefix = &v
+	return s
+}
+
+// SetStorageClass sets the StorageClass field's value.
+func (s *Location) SetStorageClass(v string) *Location {
+	s.StorageClass = &v
+	return s
+}
+
+// SetTagging sets the Tagging field's value.
+func (s *Location) SetTagging(v *Tagging) *Location {
+	s.Tagging = v
+	return s
+}
+
+// SetUserMetadata sets the UserMetadata field's value.
+func (s *Location) SetUserMetadata(v []*MetadataEntry) *Location {
+	s.UserMetadata = v
+	return s
+}
+
+// Container for logging information. Presence of this element indicates that
+// logging is enabled. Parameters TargetBucket and TargetPrefix are required
+// in this case.
+type LoggingEnabled struct {
+	_ struct{} `type:"structure"`
+
+	// Specifies the bucket where you want Amazon S3 to store server access logs.
+	// You can have your logs delivered to any bucket that you own, including the
+	// same bucket that is being logged. You can also configure multiple buckets
+	// to deliver their logs to the same target bucket. In this case you should
+	// choose a different TargetPrefix for each source bucket so that the delivered
+	// log files can be distinguished by key.
+	//
+	// TargetBucket is a required field
+	TargetBucket *string `type:"string" required:"true"`
+
+	TargetGrants []*TargetGrant `locationNameList:"Grant" type:"list"`
+
+	// This element lets you specify a prefix for the keys that the log files will
+	// be stored under.
+	//
+	// TargetPrefix is a required field
+	TargetPrefix *string `type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s LoggingEnabled) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s LoggingEnabled) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *LoggingEnabled) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "LoggingEnabled"}
+	if s.TargetBucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("TargetBucket"))
+	}
+	if s.TargetPrefix == nil {
+		invalidParams.Add(request.NewErrParamRequired("TargetPrefix"))
+	}
+	if s.TargetGrants != nil {
+		for i, v := range s.TargetGrants {
+			if v == nil {
+				continue
+			}
+			if err := v.Validate(); err != nil {
+				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "TargetGrants", i), err.(request.ErrInvalidParams))
+			}
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetTargetBucket sets the TargetBucket field's value.
+func (s *LoggingEnabled) SetTargetBucket(v string) *LoggingEnabled {
+	s.TargetBucket = &v
+	return s
+}
+
+// SetTargetGrants sets the TargetGrants field's value.
+func (s *LoggingEnabled) SetTargetGrants(v []*TargetGrant) *LoggingEnabled {
+	s.TargetGrants = v
+	return s
+}
+
+// SetTargetPrefix sets the TargetPrefix field's value.
+func (s *LoggingEnabled) SetTargetPrefix(v string) *LoggingEnabled {
+	s.TargetPrefix = &v
+	return s
+}
+
+// A metadata key-value pair to store with an object.
+type MetadataEntry struct {
+	_ struct{} `type:"structure"`
+
+	Name *string `type:"string"`
+
+	Value *string `type:"string"`
+}
+
+// String returns the string representation
+func (s MetadataEntry) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s MetadataEntry) GoString() string {
+	return s.String()
+}
+
+// SetName sets the Name field's value.
+func (s *MetadataEntry) SetName(v string) *MetadataEntry {
+	s.Name = &v
+	return s
+}
+
+// SetValue sets the Value field's value.
+func (s *MetadataEntry) SetValue(v string) *MetadataEntry {
+	s.Value = &v
+	return s
+}
+
+type MetricsAndOperator struct {
+	_ struct{} `type:"structure"`
+
+	// The prefix used when evaluating an AND predicate.
+	Prefix *string `type:"string"`
+
+	// The list of tags used when evaluating an AND predicate.
+	Tags []*Tag `locationName:"Tag" locationNameList:"Tag" type:"list" flattened:"true"`
+}
+
+// String returns the string representation
+func (s MetricsAndOperator) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s MetricsAndOperator) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *MetricsAndOperator) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "MetricsAndOperator"}
+	if s.Tags != nil {
+		for i, v := range s.Tags {
+			if v == nil {
+				continue
+			}
+			if err := v.Validate(); err != nil {
+				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Tags", i), err.(request.ErrInvalidParams))
+			}
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetPrefix sets the Prefix field's value.
+func (s *MetricsAndOperator) SetPrefix(v string) *MetricsAndOperator {
+	s.Prefix = &v
+	return s
+}
+
+// SetTags sets the Tags field's value.
+func (s *MetricsAndOperator) SetTags(v []*Tag) *MetricsAndOperator {
+	s.Tags = v
+	return s
+}
+
+type MetricsConfiguration struct {
+	_ struct{} `type:"structure"`
+
+	// Specifies a metrics configuration filter. The metrics configuration will
+	// only include objects that meet the filter's criteria. A filter must be a
+	// prefix, a tag, or a conjunction (MetricsAndOperator).
+	Filter *MetricsFilter `type:"structure"`
+
+	// The ID used to identify the metrics configuration.
+	//
+	// Id is a required field
+	Id *string `type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s MetricsConfiguration) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s MetricsConfiguration) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *MetricsConfiguration) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "MetricsConfiguration"}
+	if s.Id == nil {
+		invalidParams.Add(request.NewErrParamRequired("Id"))
+	}
+	if s.Filter != nil {
+		if err := s.Filter.Validate(); err != nil {
+			invalidParams.AddNested("Filter", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetFilter sets the Filter field's value.
+func (s *MetricsConfiguration) SetFilter(v *MetricsFilter) *MetricsConfiguration {
+	s.Filter = v
+	return s
+}
+
+// SetId sets the Id field's value.
+func (s *MetricsConfiguration) SetId(v string) *MetricsConfiguration {
+	s.Id = &v
+	return s
+}
+
+type MetricsFilter struct {
+	_ struct{} `type:"structure"`
+
+	// A conjunction (logical AND) of predicates, which is used in evaluating a
+	// metrics filter. The operator must have at least two predicates, and an object
+	// must match all of the predicates in order for the filter to apply.
+	And *MetricsAndOperator `type:"structure"`
+
+	// The prefix used when evaluating a metrics filter.
+	Prefix *string `type:"string"`
+
+	// The tag used when evaluating a metrics filter.
+	Tag *Tag `type:"structure"`
+}
+
+// String returns the string representation
+func (s MetricsFilter) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s MetricsFilter) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *MetricsFilter) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "MetricsFilter"}
+	if s.And != nil {
+		if err := s.And.Validate(); err != nil {
+			invalidParams.AddNested("And", err.(request.ErrInvalidParams))
+		}
+	}
+	if s.Tag != nil {
+		if err := s.Tag.Validate(); err != nil {
+			invalidParams.AddNested("Tag", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetAnd sets the And field's value.
+func (s *MetricsFilter) SetAnd(v *MetricsAndOperator) *MetricsFilter {
+	s.And = v
+	return s
+}
+
+// SetPrefix sets the Prefix field's value.
+func (s *MetricsFilter) SetPrefix(v string) *MetricsFilter {
+	s.Prefix = &v
+	return s
+}
+
+// SetTag sets the Tag field's value.
+func (s *MetricsFilter) SetTag(v *Tag) *MetricsFilter {
+	s.Tag = v
+	return s
+}
+
+type MultipartUpload struct {
+	_ struct{} `type:"structure"`
+
+	// Date and time at which the multipart upload was initiated.
+	Initiated *time.Time `type:"timestamp"`
+
+	// Identifies who initiated the multipart upload.
+	Initiator *Initiator `type:"structure"`
+
+	// Key of the object for which the multipart upload was initiated.
+	Key *string `min:"1" type:"string"`
+
+	Owner *Owner `type:"structure"`
+
+	// The class of storage used to store the object.
+	StorageClass *string `type:"string" enum:"StorageClass"`
+
+	// Upload ID that identifies the multipart upload.
+	UploadId *string `type:"string"`
+}
+
+// String returns the string representation
+func (s MultipartUpload) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s MultipartUpload) GoString() string {
+	return s.String()
+}
+
+// SetInitiated sets the Initiated field's value.
+func (s *MultipartUpload) SetInitiated(v time.Time) *MultipartUpload {
+	s.Initiated = &v
+	return s
+}
+
+// SetInitiator sets the Initiator field's value.
+func (s *MultipartUpload) SetInitiator(v *Initiator) *MultipartUpload {
+	s.Initiator = v
+	return s
+}
+
+// SetKey sets the Key field's value.
+func (s *MultipartUpload) SetKey(v string) *MultipartUpload {
+	s.Key = &v
+	return s
+}
+
+// SetOwner sets the Owner field's value.
+func (s *MultipartUpload) SetOwner(v *Owner) *MultipartUpload {
+	s.Owner = v
+	return s
+}
+
+// SetStorageClass sets the StorageClass field's value.
+func (s *MultipartUpload) SetStorageClass(v string) *MultipartUpload {
+	s.StorageClass = &v
+	return s
+}
+
+// SetUploadId sets the UploadId field's value.
+func (s *MultipartUpload) SetUploadId(v string) *MultipartUpload {
+	s.UploadId = &v
+	return s
+}
+
+// Specifies when noncurrent object versions expire. Upon expiration, Amazon
+// S3 permanently deletes the noncurrent object versions. You set this lifecycle
+// configuration action on a bucket that has versioning enabled (or suspended)
+// to request that Amazon S3 delete noncurrent object versions at a specific
+// period in the object's lifetime.
+type NoncurrentVersionExpiration struct {
+	_ struct{} `type:"structure"`
+
+	// Specifies the number of days an object is noncurrent before Amazon S3 can
+	// perform the associated action. For information about the noncurrent days
+	// calculations, see How Amazon S3 Calculates When an Object Became Noncurrent
+	// (http://docs.aws.amazon.com/AmazonS3/latest/dev/s3-access-control.html) in
+	// the Amazon Simple Storage Service Developer Guide.
+	NoncurrentDays *int64 `type:"integer"`
+}
+
+// String returns the string representation
+func (s NoncurrentVersionExpiration) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s NoncurrentVersionExpiration) GoString() string {
+	return s.String()
+}
+
+// SetNoncurrentDays sets the NoncurrentDays field's value.
+func (s *NoncurrentVersionExpiration) SetNoncurrentDays(v int64) *NoncurrentVersionExpiration {
+	s.NoncurrentDays = &v
+	return s
+}
+
+// Container for the transition rule that describes when noncurrent objects
+// transition to the STANDARD_IA, ONEZONE_IA or GLACIER storage class. If your
+// bucket is versioning-enabled (or versioning is suspended), you can set this
+// action to request that Amazon S3 transition noncurrent object versions to
+// the STANDARD_IA, ONEZONE_IA or GLACIER storage class at a specific period
+// in the object's lifetime.
+type NoncurrentVersionTransition struct {
+	_ struct{} `type:"structure"`
+
+	// Specifies the number of days an object is noncurrent before Amazon S3 can
+	// perform the associated action. For information about the noncurrent days
+	// calculations, see How Amazon S3 Calculates When an Object Became Noncurrent
+	// (http://docs.aws.amazon.com/AmazonS3/latest/dev/s3-access-control.html) in
+	// the Amazon Simple Storage Service Developer Guide.
+	NoncurrentDays *int64 `type:"integer"`
+
+	// The class of storage used to store the object.
+	StorageClass *string `type:"string" enum:"TransitionStorageClass"`
+}
+
+// String returns the string representation
+func (s NoncurrentVersionTransition) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s NoncurrentVersionTransition) GoString() string {
+	return s.String()
+}
+
+// SetNoncurrentDays sets the NoncurrentDays field's value.
+func (s *NoncurrentVersionTransition) SetNoncurrentDays(v int64) *NoncurrentVersionTransition {
+	s.NoncurrentDays = &v
+	return s
+}
+
+// SetStorageClass sets the StorageClass field's value.
+func (s *NoncurrentVersionTransition) SetStorageClass(v string) *NoncurrentVersionTransition {
+	s.StorageClass = &v
+	return s
+}
+
+// Container for specifying the notification configuration of the bucket. If
+// this element is empty, notifications are turned off on the bucket.
+type NotificationConfiguration struct {
+	_ struct{} `type:"structure"`
+
+	LambdaFunctionConfigurations []*LambdaFunctionConfiguration `locationName:"CloudFunctionConfiguration" type:"list" flattened:"true"`
+
+	QueueConfigurations []*QueueConfiguration `locationName:"QueueConfiguration" type:"list" flattened:"true"`
+
+	TopicConfigurations []*TopicConfiguration `locationName:"TopicConfiguration" type:"list" flattened:"true"`
+}
+
+// String returns the string representation
+func (s NotificationConfiguration) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s NotificationConfiguration) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *NotificationConfiguration) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "NotificationConfiguration"}
+	if s.LambdaFunctionConfigurations != nil {
+		for i, v := range s.LambdaFunctionConfigurations {
+			if v == nil {
+				continue
+			}
+			if err := v.Validate(); err != nil {
+				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "LambdaFunctionConfigurations", i), err.(request.ErrInvalidParams))
+			}
+		}
+	}
+	if s.QueueConfigurations != nil {
+		for i, v := range s.QueueConfigurations {
+			if v == nil {
+				continue
+			}
+			if err := v.Validate(); err != nil {
+				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "QueueConfigurations", i), err.(request.ErrInvalidParams))
+			}
+		}
+	}
+	if s.TopicConfigurations != nil {
+		for i, v := range s.TopicConfigurations {
+			if v == nil {
+				continue
+			}
+			if err := v.Validate(); err != nil {
+				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "TopicConfigurations", i), err.(request.ErrInvalidParams))
+			}
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetLambdaFunctionConfigurations sets the LambdaFunctionConfigurations field's value.
+func (s *NotificationConfiguration) SetLambdaFunctionConfigurations(v []*LambdaFunctionConfiguration) *NotificationConfiguration {
+	s.LambdaFunctionConfigurations = v
+	return s
+}
+
+// SetQueueConfigurations sets the QueueConfigurations field's value.
+func (s *NotificationConfiguration) SetQueueConfigurations(v []*QueueConfiguration) *NotificationConfiguration {
+	s.QueueConfigurations = v
+	return s
+}
+
+// SetTopicConfigurations sets the TopicConfigurations field's value.
+func (s *NotificationConfiguration) SetTopicConfigurations(v []*TopicConfiguration) *NotificationConfiguration {
+	s.TopicConfigurations = v
+	return s
+}
+
+type NotificationConfigurationDeprecated struct {
+	_ struct{} `type:"structure"`
+
+	CloudFunctionConfiguration *CloudFunctionConfiguration `type:"structure"`
+
+	QueueConfiguration *QueueConfigurationDeprecated `type:"structure"`
+
+	TopicConfiguration *TopicConfigurationDeprecated `type:"structure"`
+}
+
+// String returns the string representation
+func (s NotificationConfigurationDeprecated) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s NotificationConfigurationDeprecated) GoString() string {
+	return s.String()
+}
+
+// SetCloudFunctionConfiguration sets the CloudFunctionConfiguration field's value.
+func (s *NotificationConfigurationDeprecated) SetCloudFunctionConfiguration(v *CloudFunctionConfiguration) *NotificationConfigurationDeprecated {
+	s.CloudFunctionConfiguration = v
+	return s
+}
+
+// SetQueueConfiguration sets the QueueConfiguration field's value.
+func (s *NotificationConfigurationDeprecated) SetQueueConfiguration(v *QueueConfigurationDeprecated) *NotificationConfigurationDeprecated {
+	s.QueueConfiguration = v
+	return s
+}
+
+// SetTopicConfiguration sets the TopicConfiguration field's value.
+func (s *NotificationConfigurationDeprecated) SetTopicConfiguration(v *TopicConfigurationDeprecated) *NotificationConfigurationDeprecated {
+	s.TopicConfiguration = v
+	return s
+}
+
+// Container for object key name filtering rules. For information about key
+// name filtering, go to Configuring Event Notifications (http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html)
+// in the Amazon Simple Storage Service Developer Guide.
+type NotificationConfigurationFilter struct {
+	_ struct{} `type:"structure"`
+
+	// Container for object key name prefix and suffix filtering rules.
+	Key *KeyFilter `locationName:"S3Key" type:"structure"`
+}
+
+// String returns the string representation
+func (s NotificationConfigurationFilter) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s NotificationConfigurationFilter) GoString() string {
+	return s.String()
+}
+
+// SetKey sets the Key field's value.
+func (s *NotificationConfigurationFilter) SetKey(v *KeyFilter) *NotificationConfigurationFilter {
+	s.Key = v
+	return s
+}
+
+type Object struct {
+	_ struct{} `type:"structure"`
+
+	ETag *string `type:"string"`
+
+	Key *string `min:"1" type:"string"`
+
+	LastModified *time.Time `type:"timestamp"`
+
+	Owner *Owner `type:"structure"`
+
+	Size *int64 `type:"integer"`
+
+	// The class of storage used to store the object.
+	StorageClass *string `type:"string" enum:"ObjectStorageClass"`
+}
+
+// String returns the string representation
+func (s Object) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s Object) GoString() string {
+	return s.String()
+}
+
+// SetETag sets the ETag field's value.
+func (s *Object) SetETag(v string) *Object {
+	s.ETag = &v
+	return s
+}
+
+// SetKey sets the Key field's value.
+func (s *Object) SetKey(v string) *Object {
+	s.Key = &v
+	return s
+}
+
+// SetLastModified sets the LastModified field's value.
+func (s *Object) SetLastModified(v time.Time) *Object {
+	s.LastModified = &v
+	return s
+}
+
+// SetOwner sets the Owner field's value.
+func (s *Object) SetOwner(v *Owner) *Object {
+	s.Owner = v
+	return s
+}
+
+// SetSize sets the Size field's value.
+func (s *Object) SetSize(v int64) *Object {
+	s.Size = &v
+	return s
+}
+
+// SetStorageClass sets the StorageClass field's value.
+func (s *Object) SetStorageClass(v string) *Object {
+	s.StorageClass = &v
+	return s
+}
+
+type ObjectIdentifier struct {
+	_ struct{} `type:"structure"`
+
+	// Key name of the object to delete.
+	//
+	// Key is a required field
+	Key *string `min:"1" type:"string" required:"true"`
+
+	// VersionId for the specific version of the object to delete.
+	VersionId *string `type:"string"`
+}
+
+// String returns the string representation
+func (s ObjectIdentifier) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ObjectIdentifier) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *ObjectIdentifier) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "ObjectIdentifier"}
+	if s.Key == nil {
+		invalidParams.Add(request.NewErrParamRequired("Key"))
+	}
+	if s.Key != nil && len(*s.Key) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetKey sets the Key field's value.
+func (s *ObjectIdentifier) SetKey(v string) *ObjectIdentifier {
+	s.Key = &v
+	return s
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *ObjectIdentifier) SetVersionId(v string) *ObjectIdentifier {
+	s.VersionId = &v
+	return s
+}
+
+type ObjectVersion struct {
+	_ struct{} `type:"structure"`
+
+	ETag *string `type:"string"`
+
+	// Specifies whether the object is (true) or is not (false) the latest version
+	// of an object.
+	IsLatest *bool `type:"boolean"`
+
+	// The object key.
+	Key *string `min:"1" type:"string"`
+
+	// Date and time the object was last modified.
+	LastModified *time.Time `type:"timestamp"`
+
+	Owner *Owner `type:"structure"`
+
+	// Size in bytes of the object.
+	Size *int64 `type:"integer"`
+
+	// The class of storage used to store the object.
+	StorageClass *string `type:"string" enum:"ObjectVersionStorageClass"`
+
+	// Version ID of an object.
+	VersionId *string `type:"string"`
+}
+
+// String returns the string representation
+func (s ObjectVersion) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ObjectVersion) GoString() string {
+	return s.String()
+}
+
+// SetETag sets the ETag field's value.
+func (s *ObjectVersion) SetETag(v string) *ObjectVersion {
+	s.ETag = &v
+	return s
+}
+
+// SetIsLatest sets the IsLatest field's value.
+func (s *ObjectVersion) SetIsLatest(v bool) *ObjectVersion {
+	s.IsLatest = &v
+	return s
+}
+
+// SetKey sets the Key field's value.
+func (s *ObjectVersion) SetKey(v string) *ObjectVersion {
+	s.Key = &v
+	return s
+}
+
+// SetLastModified sets the LastModified field's value.
+func (s *ObjectVersion) SetLastModified(v time.Time) *ObjectVersion {
+	s.LastModified = &v
+	return s
+}
+
+// SetOwner sets the Owner field's value.
+func (s *ObjectVersion) SetOwner(v *Owner) *ObjectVersion {
+	s.Owner = v
+	return s
+}
+
+// SetSize sets the Size field's value.
+func (s *ObjectVersion) SetSize(v int64) *ObjectVersion {
+	s.Size = &v
+	return s
+}
+
+// SetStorageClass sets the StorageClass field's value.
+func (s *ObjectVersion) SetStorageClass(v string) *ObjectVersion {
+	s.StorageClass = &v
+	return s
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *ObjectVersion) SetVersionId(v string) *ObjectVersion {
+	s.VersionId = &v
+	return s
+}
+
+// Describes the location where the restore job's output is stored.
+type OutputLocation struct {
+	_ struct{} `type:"structure"`
+
+	// Describes an S3 location that will receive the results of the restore request.
+	S3 *Location `type:"structure"`
+}
+
+// String returns the string representation
+func (s OutputLocation) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s OutputLocation) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *OutputLocation) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "OutputLocation"}
+	if s.S3 != nil {
+		if err := s.S3.Validate(); err != nil {
+			invalidParams.AddNested("S3", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetS3 sets the S3 field's value.
+func (s *OutputLocation) SetS3(v *Location) *OutputLocation {
+	s.S3 = v
+	return s
+}
+
+// Describes how results of the Select job are serialized.
+type OutputSerialization struct {
+	_ struct{} `type:"structure"`
+
+	// Describes the serialization of CSV-encoded Select results.
+	CSV *CSVOutput `type:"structure"`
+
+	// Specifies JSON as request's output serialization format.
+	JSON *JSONOutput `type:"structure"`
+}
+
+// String returns the string representation
+func (s OutputSerialization) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s OutputSerialization) GoString() string {
+	return s.String()
+}
+
+// SetCSV sets the CSV field's value.
+func (s *OutputSerialization) SetCSV(v *CSVOutput) *OutputSerialization {
+	s.CSV = v
+	return s
+}
+
+// SetJSON sets the JSON field's value.
+func (s *OutputSerialization) SetJSON(v *JSONOutput) *OutputSerialization {
+	s.JSON = v
+	return s
+}
+
+type Owner struct {
+	_ struct{} `type:"structure"`
+
+	DisplayName *string `type:"string"`
+
+	ID *string `type:"string"`
+}
+
+// String returns the string representation
+func (s Owner) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s Owner) GoString() string {
+	return s.String()
+}
+
+// SetDisplayName sets the DisplayName field's value.
+func (s *Owner) SetDisplayName(v string) *Owner {
+	s.DisplayName = &v
+	return s
+}
+
+// SetID sets the ID field's value.
+func (s *Owner) SetID(v string) *Owner {
+	s.ID = &v
+	return s
+}
+
+type Part struct {
+	_ struct{} `type:"structure"`
+
+	// Entity tag returned when the part was uploaded.
+	ETag *string `type:"string"`
+
+	// Date and time at which the part was uploaded.
+	LastModified *time.Time `type:"timestamp"`
+
+	// Part number identifying the part. This is a positive integer between 1 and
+	// 10,000.
+	PartNumber *int64 `type:"integer"`
+
+	// Size of the uploaded part data.
+	Size *int64 `type:"integer"`
+}
+
+// String returns the string representation
+func (s Part) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s Part) GoString() string {
+	return s.String()
+}
+
+// SetETag sets the ETag field's value.
+func (s *Part) SetETag(v string) *Part {
+	s.ETag = &v
+	return s
+}
+
+// SetLastModified sets the LastModified field's value.
+func (s *Part) SetLastModified(v time.Time) *Part {
+	s.LastModified = &v
+	return s
+}
+
+// SetPartNumber sets the PartNumber field's value.
+func (s *Part) SetPartNumber(v int64) *Part {
+	s.PartNumber = &v
+	return s
+}
+
+// SetSize sets the Size field's value.
+func (s *Part) SetSize(v int64) *Part {
+	s.Size = &v
+	return s
+}
+
+type Progress struct {
+	_ struct{} `type:"structure"`
+
+	// Current number of uncompressed object bytes processed.
+	BytesProcessed *int64 `type:"long"`
+
+	// Current number of bytes of records payload data returned.
+	BytesReturned *int64 `type:"long"`
+
+	// Current number of object bytes scanned.
+	BytesScanned *int64 `type:"long"`
+}
+
+// String returns the string representation
+func (s Progress) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s Progress) GoString() string {
+	return s.String()
+}
+
+// SetBytesProcessed sets the BytesProcessed field's value.
+func (s *Progress) SetBytesProcessed(v int64) *Progress {
+	s.BytesProcessed = &v
+	return s
+}
+
+// SetBytesReturned sets the BytesReturned field's value.
+func (s *Progress) SetBytesReturned(v int64) *Progress {
+	s.BytesReturned = &v
+	return s
+}
+
+// SetBytesScanned sets the BytesScanned field's value.
+func (s *Progress) SetBytesScanned(v int64) *Progress {
+	s.BytesScanned = &v
+	return s
+}
+
+type ProgressEvent struct {
+	_ struct{} `locationName:"ProgressEvent" type:"structure" payload:"Details"`
+
+	// The Progress event details.
+	Details *Progress `locationName:"Details" type:"structure"`
+}
+
+// String returns the string representation
+func (s ProgressEvent) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ProgressEvent) GoString() string {
+	return s.String()
+}
+
+// SetDetails sets the Details field's value.
+func (s *ProgressEvent) SetDetails(v *Progress) *ProgressEvent {
+	s.Details = v
+	return s
+}
+
+// The ProgressEvent is and event in the SelectObjectContentEventStream group of events.
+func (s *ProgressEvent) eventSelectObjectContentEventStream() {}
+
+// UnmarshalEvent unmarshals the EventStream Message into the ProgressEvent value.
+// This method is only used internally within the SDK's EventStream handling.
+func (s *ProgressEvent) UnmarshalEvent(
+	payloadUnmarshaler protocol.PayloadUnmarshaler,
+	msg eventstream.Message,
+) error {
+	if err := payloadUnmarshaler.UnmarshalPayload(
+		bytes.NewReader(msg.Payload), s,
+	); err != nil {
+		return err
+	}
+	return nil
+}
+
+type PutBucketAccelerateConfigurationInput struct {
+	_ struct{} `type:"structure" payload:"AccelerateConfiguration"`
+
+	// Specifies the Accelerate Configuration you want to set for the bucket.
+	//
+	// AccelerateConfiguration is a required field
+	AccelerateConfiguration *AccelerateConfiguration `locationName:"AccelerateConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+
+	// Name of the bucket for which the accelerate configuration is set.
+	//
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s PutBucketAccelerateConfigurationInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketAccelerateConfigurationInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *PutBucketAccelerateConfigurationInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "PutBucketAccelerateConfigurationInput"}
+	if s.AccelerateConfiguration == nil {
+		invalidParams.Add(request.NewErrParamRequired("AccelerateConfiguration"))
+	}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetAccelerateConfiguration sets the AccelerateConfiguration field's value.
+func (s *PutBucketAccelerateConfigurationInput) SetAccelerateConfiguration(v *AccelerateConfiguration) *PutBucketAccelerateConfigurationInput {
+	s.AccelerateConfiguration = v
+	return s
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *PutBucketAccelerateConfigurationInput) SetBucket(v string) *PutBucketAccelerateConfigurationInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *PutBucketAccelerateConfigurationInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+type PutBucketAccelerateConfigurationOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s PutBucketAccelerateConfigurationOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketAccelerateConfigurationOutput) GoString() string {
+	return s.String()
+}
+
+type PutBucketAclInput struct {
+	_ struct{} `type:"structure" payload:"AccessControlPolicy"`
+
+	// The canned ACL to apply to the bucket.
+	ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"BucketCannedACL"`
+
+	AccessControlPolicy *AccessControlPolicy `locationName:"AccessControlPolicy" type:"structure" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Allows grantee the read, write, read ACP, and write ACP permissions on the
+	// bucket.
+	GrantFullControl *string `location:"header" locationName:"x-amz-grant-full-control" type:"string"`
+
+	// Allows grantee to list the objects in the bucket.
+	GrantRead *string `location:"header" locationName:"x-amz-grant-read" type:"string"`
+
+	// Allows grantee to read the bucket ACL.
+	GrantReadACP *string `location:"header" locationName:"x-amz-grant-read-acp" type:"string"`
+
+	// Allows grantee to create, overwrite, and delete any object in the bucket.
+	GrantWrite *string `location:"header" locationName:"x-amz-grant-write" type:"string"`
+
+	// Allows grantee to write the ACL for the applicable bucket.
+	GrantWriteACP *string `location:"header" locationName:"x-amz-grant-write-acp" type:"string"`
+}
+
+// String returns the string representation
+func (s PutBucketAclInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketAclInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *PutBucketAclInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "PutBucketAclInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.AccessControlPolicy != nil {
+		if err := s.AccessControlPolicy.Validate(); err != nil {
+			invalidParams.AddNested("AccessControlPolicy", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetACL sets the ACL field's value.
+func (s *PutBucketAclInput) SetACL(v string) *PutBucketAclInput {
+	s.ACL = &v
+	return s
+}
+
+// SetAccessControlPolicy sets the AccessControlPolicy field's value.
+func (s *PutBucketAclInput) SetAccessControlPolicy(v *AccessControlPolicy) *PutBucketAclInput {
+	s.AccessControlPolicy = v
+	return s
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *PutBucketAclInput) SetBucket(v string) *PutBucketAclInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *PutBucketAclInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetGrantFullControl sets the GrantFullControl field's value.
+func (s *PutBucketAclInput) SetGrantFullControl(v string) *PutBucketAclInput {
+	s.GrantFullControl = &v
+	return s
+}
+
+// SetGrantRead sets the GrantRead field's value.
+func (s *PutBucketAclInput) SetGrantRead(v string) *PutBucketAclInput {
+	s.GrantRead = &v
+	return s
+}
+
+// SetGrantReadACP sets the GrantReadACP field's value.
+func (s *PutBucketAclInput) SetGrantReadACP(v string) *PutBucketAclInput {
+	s.GrantReadACP = &v
+	return s
+}
+
+// SetGrantWrite sets the GrantWrite field's value.
+func (s *PutBucketAclInput) SetGrantWrite(v string) *PutBucketAclInput {
+	s.GrantWrite = &v
+	return s
+}
+
+// SetGrantWriteACP sets the GrantWriteACP field's value.
+func (s *PutBucketAclInput) SetGrantWriteACP(v string) *PutBucketAclInput {
+	s.GrantWriteACP = &v
+	return s
+}
+
+type PutBucketAclOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s PutBucketAclOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketAclOutput) GoString() string {
+	return s.String()
+}
+
+type PutBucketAnalyticsConfigurationInput struct {
+	_ struct{} `type:"structure" payload:"AnalyticsConfiguration"`
+
+	// The configuration and any analyses for the analytics filter.
+	//
+	// AnalyticsConfiguration is a required field
+	AnalyticsConfiguration *AnalyticsConfiguration `locationName:"AnalyticsConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+
+	// The name of the bucket to which an analytics configuration is stored.
+	//
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// The identifier used to represent an analytics configuration.
+	//
+	// Id is a required field
+	Id *string `location:"querystring" locationName:"id" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s PutBucketAnalyticsConfigurationInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketAnalyticsConfigurationInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *PutBucketAnalyticsConfigurationInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "PutBucketAnalyticsConfigurationInput"}
+	if s.AnalyticsConfiguration == nil {
+		invalidParams.Add(request.NewErrParamRequired("AnalyticsConfiguration"))
+	}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Id == nil {
+		invalidParams.Add(request.NewErrParamRequired("Id"))
+	}
+	if s.AnalyticsConfiguration != nil {
+		if err := s.AnalyticsConfiguration.Validate(); err != nil {
+			invalidParams.AddNested("AnalyticsConfiguration", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetAnalyticsConfiguration sets the AnalyticsConfiguration field's value.
+func (s *PutBucketAnalyticsConfigurationInput) SetAnalyticsConfiguration(v *AnalyticsConfiguration) *PutBucketAnalyticsConfigurationInput {
+	s.AnalyticsConfiguration = v
+	return s
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *PutBucketAnalyticsConfigurationInput) SetBucket(v string) *PutBucketAnalyticsConfigurationInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *PutBucketAnalyticsConfigurationInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetId sets the Id field's value.
+func (s *PutBucketAnalyticsConfigurationInput) SetId(v string) *PutBucketAnalyticsConfigurationInput {
+	s.Id = &v
+	return s
+}
+
+type PutBucketAnalyticsConfigurationOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s PutBucketAnalyticsConfigurationOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketAnalyticsConfigurationOutput) GoString() string {
+	return s.String()
+}
+
+type PutBucketCorsInput struct {
+	_ struct{} `type:"structure" payload:"CORSConfiguration"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// CORSConfiguration is a required field
+	CORSConfiguration *CORSConfiguration `locationName:"CORSConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+}
+
+// String returns the string representation
+func (s PutBucketCorsInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketCorsInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *PutBucketCorsInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "PutBucketCorsInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.CORSConfiguration == nil {
+		invalidParams.Add(request.NewErrParamRequired("CORSConfiguration"))
+	}
+	if s.CORSConfiguration != nil {
+		if err := s.CORSConfiguration.Validate(); err != nil {
+			invalidParams.AddNested("CORSConfiguration", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *PutBucketCorsInput) SetBucket(v string) *PutBucketCorsInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *PutBucketCorsInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetCORSConfiguration sets the CORSConfiguration field's value.
+func (s *PutBucketCorsInput) SetCORSConfiguration(v *CORSConfiguration) *PutBucketCorsInput {
+	s.CORSConfiguration = v
+	return s
+}
+
+type PutBucketCorsOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s PutBucketCorsOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketCorsOutput) GoString() string {
+	return s.String()
+}
+
+type PutBucketEncryptionInput struct {
+	_ struct{} `type:"structure" payload:"ServerSideEncryptionConfiguration"`
+
+	// The name of the bucket for which the server-side encryption configuration
+	// is set.
+	//
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Container for server-side encryption configuration rules. Currently S3 supports
+	// one rule only.
+	//
+	// ServerSideEncryptionConfiguration is a required field
+	ServerSideEncryptionConfiguration *ServerSideEncryptionConfiguration `locationName:"ServerSideEncryptionConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+}
+
+// String returns the string representation
+func (s PutBucketEncryptionInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketEncryptionInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *PutBucketEncryptionInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "PutBucketEncryptionInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.ServerSideEncryptionConfiguration == nil {
+		invalidParams.Add(request.NewErrParamRequired("ServerSideEncryptionConfiguration"))
+	}
+	if s.ServerSideEncryptionConfiguration != nil {
+		if err := s.ServerSideEncryptionConfiguration.Validate(); err != nil {
+			invalidParams.AddNested("ServerSideEncryptionConfiguration", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *PutBucketEncryptionInput) SetBucket(v string) *PutBucketEncryptionInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *PutBucketEncryptionInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetServerSideEncryptionConfiguration sets the ServerSideEncryptionConfiguration field's value.
+func (s *PutBucketEncryptionInput) SetServerSideEncryptionConfiguration(v *ServerSideEncryptionConfiguration) *PutBucketEncryptionInput {
+	s.ServerSideEncryptionConfiguration = v
+	return s
+}
+
+type PutBucketEncryptionOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s PutBucketEncryptionOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketEncryptionOutput) GoString() string {
+	return s.String()
+}
+
+type PutBucketInventoryConfigurationInput struct {
+	_ struct{} `type:"structure" payload:"InventoryConfiguration"`
+
+	// The name of the bucket where the inventory configuration will be stored.
+	//
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// The ID used to identify the inventory configuration.
+	//
+	// Id is a required field
+	Id *string `location:"querystring" locationName:"id" type:"string" required:"true"`
+
+	// Specifies the inventory configuration.
+	//
+	// InventoryConfiguration is a required field
+	InventoryConfiguration *InventoryConfiguration `locationName:"InventoryConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+}
+
+// String returns the string representation
+func (s PutBucketInventoryConfigurationInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketInventoryConfigurationInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *PutBucketInventoryConfigurationInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "PutBucketInventoryConfigurationInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Id == nil {
+		invalidParams.Add(request.NewErrParamRequired("Id"))
+	}
+	if s.InventoryConfiguration == nil {
+		invalidParams.Add(request.NewErrParamRequired("InventoryConfiguration"))
+	}
+	if s.InventoryConfiguration != nil {
+		if err := s.InventoryConfiguration.Validate(); err != nil {
+			invalidParams.AddNested("InventoryConfiguration", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *PutBucketInventoryConfigurationInput) SetBucket(v string) *PutBucketInventoryConfigurationInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *PutBucketInventoryConfigurationInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetId sets the Id field's value.
+func (s *PutBucketInventoryConfigurationInput) SetId(v string) *PutBucketInventoryConfigurationInput {
+	s.Id = &v
+	return s
+}
+
+// SetInventoryConfiguration sets the InventoryConfiguration field's value.
+func (s *PutBucketInventoryConfigurationInput) SetInventoryConfiguration(v *InventoryConfiguration) *PutBucketInventoryConfigurationInput {
+	s.InventoryConfiguration = v
+	return s
+}
+
+type PutBucketInventoryConfigurationOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s PutBucketInventoryConfigurationOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketInventoryConfigurationOutput) GoString() string {
+	return s.String()
+}
+
+type PutBucketLifecycleConfigurationInput struct {
+	_ struct{} `type:"structure" payload:"LifecycleConfiguration"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	LifecycleConfiguration *BucketLifecycleConfiguration `locationName:"LifecycleConfiguration" type:"structure" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+}
+
+// String returns the string representation
+func (s PutBucketLifecycleConfigurationInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketLifecycleConfigurationInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *PutBucketLifecycleConfigurationInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "PutBucketLifecycleConfigurationInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.LifecycleConfiguration != nil {
+		if err := s.LifecycleConfiguration.Validate(); err != nil {
+			invalidParams.AddNested("LifecycleConfiguration", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *PutBucketLifecycleConfigurationInput) SetBucket(v string) *PutBucketLifecycleConfigurationInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *PutBucketLifecycleConfigurationInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetLifecycleConfiguration sets the LifecycleConfiguration field's value.
+func (s *PutBucketLifecycleConfigurationInput) SetLifecycleConfiguration(v *BucketLifecycleConfiguration) *PutBucketLifecycleConfigurationInput {
+	s.LifecycleConfiguration = v
+	return s
+}
+
+type PutBucketLifecycleConfigurationOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s PutBucketLifecycleConfigurationOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketLifecycleConfigurationOutput) GoString() string {
+	return s.String()
+}
+
+type PutBucketLifecycleInput struct {
+	_ struct{} `type:"structure" payload:"LifecycleConfiguration"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	LifecycleConfiguration *LifecycleConfiguration `locationName:"LifecycleConfiguration" type:"structure" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+}
+
+// String returns the string representation
+func (s PutBucketLifecycleInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketLifecycleInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *PutBucketLifecycleInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "PutBucketLifecycleInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.LifecycleConfiguration != nil {
+		if err := s.LifecycleConfiguration.Validate(); err != nil {
+			invalidParams.AddNested("LifecycleConfiguration", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *PutBucketLifecycleInput) SetBucket(v string) *PutBucketLifecycleInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *PutBucketLifecycleInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetLifecycleConfiguration sets the LifecycleConfiguration field's value.
+func (s *PutBucketLifecycleInput) SetLifecycleConfiguration(v *LifecycleConfiguration) *PutBucketLifecycleInput {
+	s.LifecycleConfiguration = v
+	return s
+}
+
+type PutBucketLifecycleOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s PutBucketLifecycleOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketLifecycleOutput) GoString() string {
+	return s.String()
+}
+
+type PutBucketLoggingInput struct {
+	_ struct{} `type:"structure" payload:"BucketLoggingStatus"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// BucketLoggingStatus is a required field
+	BucketLoggingStatus *BucketLoggingStatus `locationName:"BucketLoggingStatus" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+}
+
+// String returns the string representation
+func (s PutBucketLoggingInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketLoggingInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *PutBucketLoggingInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "PutBucketLoggingInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.BucketLoggingStatus == nil {
+		invalidParams.Add(request.NewErrParamRequired("BucketLoggingStatus"))
+	}
+	if s.BucketLoggingStatus != nil {
+		if err := s.BucketLoggingStatus.Validate(); err != nil {
+			invalidParams.AddNested("BucketLoggingStatus", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *PutBucketLoggingInput) SetBucket(v string) *PutBucketLoggingInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *PutBucketLoggingInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetBucketLoggingStatus sets the BucketLoggingStatus field's value.
+func (s *PutBucketLoggingInput) SetBucketLoggingStatus(v *BucketLoggingStatus) *PutBucketLoggingInput {
+	s.BucketLoggingStatus = v
+	return s
+}
+
+type PutBucketLoggingOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s PutBucketLoggingOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketLoggingOutput) GoString() string {
+	return s.String()
+}
+
+type PutBucketMetricsConfigurationInput struct {
+	_ struct{} `type:"structure" payload:"MetricsConfiguration"`
+
+	// The name of the bucket for which the metrics configuration is set.
+	//
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// The ID used to identify the metrics configuration.
+	//
+	// Id is a required field
+	Id *string `location:"querystring" locationName:"id" type:"string" required:"true"`
+
+	// Specifies the metrics configuration.
+	//
+	// MetricsConfiguration is a required field
+	MetricsConfiguration *MetricsConfiguration `locationName:"MetricsConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+}
+
+// String returns the string representation
+func (s PutBucketMetricsConfigurationInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketMetricsConfigurationInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *PutBucketMetricsConfigurationInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "PutBucketMetricsConfigurationInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Id == nil {
+		invalidParams.Add(request.NewErrParamRequired("Id"))
+	}
+	if s.MetricsConfiguration == nil {
+		invalidParams.Add(request.NewErrParamRequired("MetricsConfiguration"))
+	}
+	if s.MetricsConfiguration != nil {
+		if err := s.MetricsConfiguration.Validate(); err != nil {
+			invalidParams.AddNested("MetricsConfiguration", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *PutBucketMetricsConfigurationInput) SetBucket(v string) *PutBucketMetricsConfigurationInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *PutBucketMetricsConfigurationInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetId sets the Id field's value.
+func (s *PutBucketMetricsConfigurationInput) SetId(v string) *PutBucketMetricsConfigurationInput {
+	s.Id = &v
+	return s
+}
+
+// SetMetricsConfiguration sets the MetricsConfiguration field's value.
+func (s *PutBucketMetricsConfigurationInput) SetMetricsConfiguration(v *MetricsConfiguration) *PutBucketMetricsConfigurationInput {
+	s.MetricsConfiguration = v
+	return s
+}
+
+type PutBucketMetricsConfigurationOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s PutBucketMetricsConfigurationOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketMetricsConfigurationOutput) GoString() string {
+	return s.String()
+}
+
+type PutBucketNotificationConfigurationInput struct {
+	_ struct{} `type:"structure" payload:"NotificationConfiguration"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Container for specifying the notification configuration of the bucket. If
+	// this element is empty, notifications are turned off on the bucket.
+	//
+	// NotificationConfiguration is a required field
+	NotificationConfiguration *NotificationConfiguration `locationName:"NotificationConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+}
+
+// String returns the string representation
+func (s PutBucketNotificationConfigurationInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketNotificationConfigurationInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *PutBucketNotificationConfigurationInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "PutBucketNotificationConfigurationInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.NotificationConfiguration == nil {
+		invalidParams.Add(request.NewErrParamRequired("NotificationConfiguration"))
+	}
+	if s.NotificationConfiguration != nil {
+		if err := s.NotificationConfiguration.Validate(); err != nil {
+			invalidParams.AddNested("NotificationConfiguration", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *PutBucketNotificationConfigurationInput) SetBucket(v string) *PutBucketNotificationConfigurationInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *PutBucketNotificationConfigurationInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetNotificationConfiguration sets the NotificationConfiguration field's value.
+func (s *PutBucketNotificationConfigurationInput) SetNotificationConfiguration(v *NotificationConfiguration) *PutBucketNotificationConfigurationInput {
+	s.NotificationConfiguration = v
+	return s
+}
+
+type PutBucketNotificationConfigurationOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s PutBucketNotificationConfigurationOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketNotificationConfigurationOutput) GoString() string {
+	return s.String()
+}
+
+type PutBucketNotificationInput struct {
+	_ struct{} `type:"structure" payload:"NotificationConfiguration"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// NotificationConfiguration is a required field
+	NotificationConfiguration *NotificationConfigurationDeprecated `locationName:"NotificationConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+}
+
+// String returns the string representation
+func (s PutBucketNotificationInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketNotificationInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *PutBucketNotificationInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "PutBucketNotificationInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.NotificationConfiguration == nil {
+		invalidParams.Add(request.NewErrParamRequired("NotificationConfiguration"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *PutBucketNotificationInput) SetBucket(v string) *PutBucketNotificationInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *PutBucketNotificationInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetNotificationConfiguration sets the NotificationConfiguration field's value.
+func (s *PutBucketNotificationInput) SetNotificationConfiguration(v *NotificationConfigurationDeprecated) *PutBucketNotificationInput {
+	s.NotificationConfiguration = v
+	return s
+}
+
+type PutBucketNotificationOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s PutBucketNotificationOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketNotificationOutput) GoString() string {
+	return s.String()
+}
+
+type PutBucketPolicyInput struct {
+	_ struct{} `type:"structure" payload:"Policy"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Set this parameter to true to confirm that you want to remove your permissions
+	// to change this bucket policy in the future.
+	ConfirmRemoveSelfBucketAccess *bool `location:"header" locationName:"x-amz-confirm-remove-self-bucket-access" type:"boolean"`
+
+	// The bucket policy as a JSON document.
+	//
+	// Policy is a required field
+	Policy *string `type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s PutBucketPolicyInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketPolicyInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *PutBucketPolicyInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "PutBucketPolicyInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Policy == nil {
+		invalidParams.Add(request.NewErrParamRequired("Policy"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *PutBucketPolicyInput) SetBucket(v string) *PutBucketPolicyInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *PutBucketPolicyInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetConfirmRemoveSelfBucketAccess sets the ConfirmRemoveSelfBucketAccess field's value.
+func (s *PutBucketPolicyInput) SetConfirmRemoveSelfBucketAccess(v bool) *PutBucketPolicyInput {
+	s.ConfirmRemoveSelfBucketAccess = &v
+	return s
+}
+
+// SetPolicy sets the Policy field's value.
+func (s *PutBucketPolicyInput) SetPolicy(v string) *PutBucketPolicyInput {
+	s.Policy = &v
+	return s
+}
+
+type PutBucketPolicyOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s PutBucketPolicyOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketPolicyOutput) GoString() string {
+	return s.String()
+}
+
+type PutBucketReplicationInput struct {
+	_ struct{} `type:"structure" payload:"ReplicationConfiguration"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Container for replication rules. You can add as many as 1,000 rules. Total
+	// replication configuration size can be up to 2 MB.
+	//
+	// ReplicationConfiguration is a required field
+	ReplicationConfiguration *ReplicationConfiguration `locationName:"ReplicationConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+}
+
+// String returns the string representation
+func (s PutBucketReplicationInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketReplicationInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *PutBucketReplicationInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "PutBucketReplicationInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.ReplicationConfiguration == nil {
+		invalidParams.Add(request.NewErrParamRequired("ReplicationConfiguration"))
+	}
+	if s.ReplicationConfiguration != nil {
+		if err := s.ReplicationConfiguration.Validate(); err != nil {
+			invalidParams.AddNested("ReplicationConfiguration", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *PutBucketReplicationInput) SetBucket(v string) *PutBucketReplicationInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *PutBucketReplicationInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetReplicationConfiguration sets the ReplicationConfiguration field's value.
+func (s *PutBucketReplicationInput) SetReplicationConfiguration(v *ReplicationConfiguration) *PutBucketReplicationInput {
+	s.ReplicationConfiguration = v
+	return s
+}
+
+type PutBucketReplicationOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s PutBucketReplicationOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketReplicationOutput) GoString() string {
+	return s.String()
+}
+
+type PutBucketRequestPaymentInput struct {
+	_ struct{} `type:"structure" payload:"RequestPaymentConfiguration"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// RequestPaymentConfiguration is a required field
+	RequestPaymentConfiguration *RequestPaymentConfiguration `locationName:"RequestPaymentConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+}
+
+// String returns the string representation
+func (s PutBucketRequestPaymentInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketRequestPaymentInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *PutBucketRequestPaymentInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "PutBucketRequestPaymentInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.RequestPaymentConfiguration == nil {
+		invalidParams.Add(request.NewErrParamRequired("RequestPaymentConfiguration"))
+	}
+	if s.RequestPaymentConfiguration != nil {
+		if err := s.RequestPaymentConfiguration.Validate(); err != nil {
+			invalidParams.AddNested("RequestPaymentConfiguration", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *PutBucketRequestPaymentInput) SetBucket(v string) *PutBucketRequestPaymentInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *PutBucketRequestPaymentInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetRequestPaymentConfiguration sets the RequestPaymentConfiguration field's value.
+func (s *PutBucketRequestPaymentInput) SetRequestPaymentConfiguration(v *RequestPaymentConfiguration) *PutBucketRequestPaymentInput {
+	s.RequestPaymentConfiguration = v
+	return s
+}
+
+type PutBucketRequestPaymentOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s PutBucketRequestPaymentOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketRequestPaymentOutput) GoString() string {
+	return s.String()
+}
+
+type PutBucketTaggingInput struct {
+	_ struct{} `type:"structure" payload:"Tagging"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Tagging is a required field
+	Tagging *Tagging `locationName:"Tagging" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+}
+
+// String returns the string representation
+func (s PutBucketTaggingInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketTaggingInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *PutBucketTaggingInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "PutBucketTaggingInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Tagging == nil {
+		invalidParams.Add(request.NewErrParamRequired("Tagging"))
+	}
+	if s.Tagging != nil {
+		if err := s.Tagging.Validate(); err != nil {
+			invalidParams.AddNested("Tagging", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *PutBucketTaggingInput) SetBucket(v string) *PutBucketTaggingInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *PutBucketTaggingInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetTagging sets the Tagging field's value.
+func (s *PutBucketTaggingInput) SetTagging(v *Tagging) *PutBucketTaggingInput {
+	s.Tagging = v
+	return s
+}
+
+type PutBucketTaggingOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s PutBucketTaggingOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketTaggingOutput) GoString() string {
+	return s.String()
+}
+
+type PutBucketVersioningInput struct {
+	_ struct{} `type:"structure" payload:"VersioningConfiguration"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// The concatenation of the authentication device's serial number, a space,
+	// and the value that is displayed on your authentication device.
+	MFA *string `location:"header" locationName:"x-amz-mfa" type:"string"`
+
+	// VersioningConfiguration is a required field
+	VersioningConfiguration *VersioningConfiguration `locationName:"VersioningConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+}
+
+// String returns the string representation
+func (s PutBucketVersioningInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketVersioningInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *PutBucketVersioningInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "PutBucketVersioningInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.VersioningConfiguration == nil {
+		invalidParams.Add(request.NewErrParamRequired("VersioningConfiguration"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *PutBucketVersioningInput) SetBucket(v string) *PutBucketVersioningInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *PutBucketVersioningInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetMFA sets the MFA field's value.
+func (s *PutBucketVersioningInput) SetMFA(v string) *PutBucketVersioningInput {
+	s.MFA = &v
+	return s
+}
+
+// SetVersioningConfiguration sets the VersioningConfiguration field's value.
+func (s *PutBucketVersioningInput) SetVersioningConfiguration(v *VersioningConfiguration) *PutBucketVersioningInput {
+	s.VersioningConfiguration = v
+	return s
+}
+
+type PutBucketVersioningOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s PutBucketVersioningOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketVersioningOutput) GoString() string {
+	return s.String()
+}
+
+type PutBucketWebsiteInput struct {
+	_ struct{} `type:"structure" payload:"WebsiteConfiguration"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// WebsiteConfiguration is a required field
+	WebsiteConfiguration *WebsiteConfiguration `locationName:"WebsiteConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+}
+
+// String returns the string representation
+func (s PutBucketWebsiteInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketWebsiteInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *PutBucketWebsiteInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "PutBucketWebsiteInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.WebsiteConfiguration == nil {
+		invalidParams.Add(request.NewErrParamRequired("WebsiteConfiguration"))
+	}
+	if s.WebsiteConfiguration != nil {
+		if err := s.WebsiteConfiguration.Validate(); err != nil {
+			invalidParams.AddNested("WebsiteConfiguration", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *PutBucketWebsiteInput) SetBucket(v string) *PutBucketWebsiteInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *PutBucketWebsiteInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetWebsiteConfiguration sets the WebsiteConfiguration field's value.
+func (s *PutBucketWebsiteInput) SetWebsiteConfiguration(v *WebsiteConfiguration) *PutBucketWebsiteInput {
+	s.WebsiteConfiguration = v
+	return s
+}
+
+type PutBucketWebsiteOutput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s PutBucketWebsiteOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutBucketWebsiteOutput) GoString() string {
+	return s.String()
+}
+
+type PutObjectAclInput struct {
+	_ struct{} `type:"structure" payload:"AccessControlPolicy"`
+
+	// The canned ACL to apply to the object.
+	ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"ObjectCannedACL"`
+
+	AccessControlPolicy *AccessControlPolicy `locationName:"AccessControlPolicy" type:"structure" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Allows grantee the read, write, read ACP, and write ACP permissions on the
+	// bucket.
+	GrantFullControl *string `location:"header" locationName:"x-amz-grant-full-control" type:"string"`
+
+	// Allows grantee to list the objects in the bucket.
+	GrantRead *string `location:"header" locationName:"x-amz-grant-read" type:"string"`
+
+	// Allows grantee to read the bucket ACL.
+	GrantReadACP *string `location:"header" locationName:"x-amz-grant-read-acp" type:"string"`
+
+	// Allows grantee to create, overwrite, and delete any object in the bucket.
+	GrantWrite *string `location:"header" locationName:"x-amz-grant-write" type:"string"`
+
+	// Allows grantee to write the ACL for the applicable bucket.
+	GrantWriteACP *string `location:"header" locationName:"x-amz-grant-write-acp" type:"string"`
+
+	// Key is a required field
+	Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"`
+
+	// Confirms that the requester knows that she or he will be charged for the
+	// request. Bucket owners need not specify this parameter in their requests.
+	// Documentation on downloading objects from requester pays buckets can be found
+	// at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
+	RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"`
+
+	// VersionId used to reference a specific version of the object.
+	VersionId *string `location:"querystring" locationName:"versionId" type:"string"`
+}
+
+// String returns the string representation
+func (s PutObjectAclInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutObjectAclInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *PutObjectAclInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "PutObjectAclInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Key == nil {
+		invalidParams.Add(request.NewErrParamRequired("Key"))
+	}
+	if s.Key != nil && len(*s.Key) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
+	}
+	if s.AccessControlPolicy != nil {
+		if err := s.AccessControlPolicy.Validate(); err != nil {
+			invalidParams.AddNested("AccessControlPolicy", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetACL sets the ACL field's value.
+func (s *PutObjectAclInput) SetACL(v string) *PutObjectAclInput {
+	s.ACL = &v
+	return s
+}
+
+// SetAccessControlPolicy sets the AccessControlPolicy field's value.
+func (s *PutObjectAclInput) SetAccessControlPolicy(v *AccessControlPolicy) *PutObjectAclInput {
+	s.AccessControlPolicy = v
+	return s
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *PutObjectAclInput) SetBucket(v string) *PutObjectAclInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *PutObjectAclInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetGrantFullControl sets the GrantFullControl field's value.
+func (s *PutObjectAclInput) SetGrantFullControl(v string) *PutObjectAclInput {
+	s.GrantFullControl = &v
+	return s
+}
+
+// SetGrantRead sets the GrantRead field's value.
+func (s *PutObjectAclInput) SetGrantRead(v string) *PutObjectAclInput {
+	s.GrantRead = &v
+	return s
+}
+
+// SetGrantReadACP sets the GrantReadACP field's value.
+func (s *PutObjectAclInput) SetGrantReadACP(v string) *PutObjectAclInput {
+	s.GrantReadACP = &v
+	return s
+}
+
+// SetGrantWrite sets the GrantWrite field's value.
+func (s *PutObjectAclInput) SetGrantWrite(v string) *PutObjectAclInput {
+	s.GrantWrite = &v
+	return s
+}
+
+// SetGrantWriteACP sets the GrantWriteACP field's value.
+func (s *PutObjectAclInput) SetGrantWriteACP(v string) *PutObjectAclInput {
+	s.GrantWriteACP = &v
+	return s
+}
+
+// SetKey sets the Key field's value.
+func (s *PutObjectAclInput) SetKey(v string) *PutObjectAclInput {
+	s.Key = &v
+	return s
+}
+
+// SetRequestPayer sets the RequestPayer field's value.
+func (s *PutObjectAclInput) SetRequestPayer(v string) *PutObjectAclInput {
+	s.RequestPayer = &v
+	return s
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *PutObjectAclInput) SetVersionId(v string) *PutObjectAclInput {
+	s.VersionId = &v
+	return s
+}
+
+type PutObjectAclOutput struct {
+	_ struct{} `type:"structure"`
+
+	// If present, indicates that the requester was successfully charged for the
+	// request.
+	RequestCharged *string `location:"header" locationName:"x-amz-request-charged" type:"string" enum:"RequestCharged"`
+}
+
+// String returns the string representation
+func (s PutObjectAclOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutObjectAclOutput) GoString() string {
+	return s.String()
+}
+
+// SetRequestCharged sets the RequestCharged field's value.
+func (s *PutObjectAclOutput) SetRequestCharged(v string) *PutObjectAclOutput {
+	s.RequestCharged = &v
+	return s
+}
+
+type PutObjectInput struct {
+	_ struct{} `type:"structure" payload:"Body"`
+
+	// The canned ACL to apply to the object.
+	ACL *string `location:"header" locationName:"x-amz-acl" type:"string" enum:"ObjectCannedACL"`
+
+	// Object data.
+	Body io.ReadSeeker `type:"blob"`
+
+	// Name of the bucket to which the PUT operation was initiated.
+	//
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Specifies caching behavior along the request/reply chain.
+	CacheControl *string `location:"header" locationName:"Cache-Control" type:"string"`
+
+	// Specifies presentational information for the object.
+	ContentDisposition *string `location:"header" locationName:"Content-Disposition" type:"string"`
+
+	// Specifies what content encodings have been applied to the object and thus
+	// what decoding mechanisms must be applied to obtain the media-type referenced
+	// by the Content-Type header field.
+	ContentEncoding *string `location:"header" locationName:"Content-Encoding" type:"string"`
+
+	// The language the content is in.
+	ContentLanguage *string `location:"header" locationName:"Content-Language" type:"string"`
+
+	// Size of the body in bytes. This parameter is useful when the size of the
+	// body cannot be determined automatically.
+	ContentLength *int64 `location:"header" locationName:"Content-Length" type:"long"`
+
+	// The base64-encoded 128-bit MD5 digest of the part data.
+	ContentMD5 *string `location:"header" locationName:"Content-MD5" type:"string"`
+
+	// A standard MIME type describing the format of the object data.
+	ContentType *string `location:"header" locationName:"Content-Type" type:"string"`
+
+	// The date and time at which the object is no longer cacheable.
+	Expires *time.Time `location:"header" locationName:"Expires" type:"timestamp"`
+
+	// Gives the grantee READ, READ_ACP, and WRITE_ACP permissions on the object.
+	GrantFullControl *string `location:"header" locationName:"x-amz-grant-full-control" type:"string"`
+
+	// Allows grantee to read the object data and its metadata.
+	GrantRead *string `location:"header" locationName:"x-amz-grant-read" type:"string"`
+
+	// Allows grantee to read the object ACL.
+	GrantReadACP *string `location:"header" locationName:"x-amz-grant-read-acp" type:"string"`
+
+	// Allows grantee to write the ACL for the applicable object.
+	GrantWriteACP *string `location:"header" locationName:"x-amz-grant-write-acp" type:"string"`
+
+	// Object key for which the PUT operation was initiated.
+	//
+	// Key is a required field
+	Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"`
+
+	// A map of metadata to store with the object in S3.
+	Metadata map[string]*string `location:"headers" locationName:"x-amz-meta-" type:"map"`
+
+	// Confirms that the requester knows that she or he will be charged for the
+	// request. Bucket owners need not specify this parameter in their requests.
+	// Documentation on downloading objects from requester pays buckets can be found
+	// at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
+	RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"`
+
+	// Specifies the algorithm to use to when encrypting the object (e.g., AES256).
+	SSECustomerAlgorithm *string `location:"header" locationName:"x-amz-server-side-encryption-customer-algorithm" type:"string"`
+
+	// Specifies the customer-provided encryption key for Amazon S3 to use in encrypting
+	// data. This value is used to store the object and then it is discarded; Amazon
+	// does not store the encryption key. The key must be appropriate for use with
+	// the algorithm specified in the x-amz-server-side​-encryption​-customer-algorithm
+	// header.
+	SSECustomerKey *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key" type:"string"`
+
+	// Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321.
+	// Amazon S3 uses this header for a message integrity check to ensure the encryption
+	// key was transmitted without error.
+	SSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key-MD5" type:"string"`
+
+	// Specifies the AWS KMS key ID to use for object encryption. All GET and PUT
+	// requests for an object protected by AWS KMS will fail if not made via SSL
+	// or using SigV4. Documentation on configuring any of the officially supported
+	// AWS SDKs and CLI can be found at http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingAWSSDK.html#specify-signature-version
+	SSEKMSKeyId *string `location:"header" locationName:"x-amz-server-side-encryption-aws-kms-key-id" type:"string"`
+
+	// The Server-side encryption algorithm used when storing this object in S3
+	// (e.g., AES256, aws:kms).
+	ServerSideEncryption *string `location:"header" locationName:"x-amz-server-side-encryption" type:"string" enum:"ServerSideEncryption"`
+
+	// The type of storage to use for the object. Defaults to 'STANDARD'.
+	StorageClass *string `location:"header" locationName:"x-amz-storage-class" type:"string" enum:"StorageClass"`
+
+	// The tag-set for the object. The tag-set must be encoded as URL Query parameters
+	Tagging *string `location:"header" locationName:"x-amz-tagging" type:"string"`
+
+	// If the bucket is configured as a website, redirects requests for this object
+	// to another object in the same bucket or to an external URL. Amazon S3 stores
+	// the value of this header in the object metadata.
+	WebsiteRedirectLocation *string `location:"header" locationName:"x-amz-website-redirect-location" type:"string"`
+}
+
+// String returns the string representation
+func (s PutObjectInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutObjectInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *PutObjectInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "PutObjectInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Key == nil {
+		invalidParams.Add(request.NewErrParamRequired("Key"))
+	}
+	if s.Key != nil && len(*s.Key) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetACL sets the ACL field's value.
+func (s *PutObjectInput) SetACL(v string) *PutObjectInput {
+	s.ACL = &v
+	return s
+}
+
+// SetBody sets the Body field's value.
+func (s *PutObjectInput) SetBody(v io.ReadSeeker) *PutObjectInput {
+	s.Body = v
+	return s
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *PutObjectInput) SetBucket(v string) *PutObjectInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *PutObjectInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetCacheControl sets the CacheControl field's value.
+func (s *PutObjectInput) SetCacheControl(v string) *PutObjectInput {
+	s.CacheControl = &v
+	return s
+}
+
+// SetContentDisposition sets the ContentDisposition field's value.
+func (s *PutObjectInput) SetContentDisposition(v string) *PutObjectInput {
+	s.ContentDisposition = &v
+	return s
+}
+
+// SetContentEncoding sets the ContentEncoding field's value.
+func (s *PutObjectInput) SetContentEncoding(v string) *PutObjectInput {
+	s.ContentEncoding = &v
+	return s
+}
+
+// SetContentLanguage sets the ContentLanguage field's value.
+func (s *PutObjectInput) SetContentLanguage(v string) *PutObjectInput {
+	s.ContentLanguage = &v
+	return s
+}
+
+// SetContentLength sets the ContentLength field's value.
+func (s *PutObjectInput) SetContentLength(v int64) *PutObjectInput {
+	s.ContentLength = &v
+	return s
+}
+
+// SetContentMD5 sets the ContentMD5 field's value.
+func (s *PutObjectInput) SetContentMD5(v string) *PutObjectInput {
+	s.ContentMD5 = &v
+	return s
+}
+
+// SetContentType sets the ContentType field's value.
+func (s *PutObjectInput) SetContentType(v string) *PutObjectInput {
+	s.ContentType = &v
+	return s
+}
+
+// SetExpires sets the Expires field's value.
+func (s *PutObjectInput) SetExpires(v time.Time) *PutObjectInput {
+	s.Expires = &v
+	return s
+}
+
+// SetGrantFullControl sets the GrantFullControl field's value.
+func (s *PutObjectInput) SetGrantFullControl(v string) *PutObjectInput {
+	s.GrantFullControl = &v
+	return s
+}
+
+// SetGrantRead sets the GrantRead field's value.
+func (s *PutObjectInput) SetGrantRead(v string) *PutObjectInput {
+	s.GrantRead = &v
+	return s
+}
+
+// SetGrantReadACP sets the GrantReadACP field's value.
+func (s *PutObjectInput) SetGrantReadACP(v string) *PutObjectInput {
+	s.GrantReadACP = &v
+	return s
+}
+
+// SetGrantWriteACP sets the GrantWriteACP field's value.
+func (s *PutObjectInput) SetGrantWriteACP(v string) *PutObjectInput {
+	s.GrantWriteACP = &v
+	return s
+}
+
+// SetKey sets the Key field's value.
+func (s *PutObjectInput) SetKey(v string) *PutObjectInput {
+	s.Key = &v
+	return s
+}
+
+// SetMetadata sets the Metadata field's value.
+func (s *PutObjectInput) SetMetadata(v map[string]*string) *PutObjectInput {
+	s.Metadata = v
+	return s
+}
+
+// SetRequestPayer sets the RequestPayer field's value.
+func (s *PutObjectInput) SetRequestPayer(v string) *PutObjectInput {
+	s.RequestPayer = &v
+	return s
+}
+
+// SetSSECustomerAlgorithm sets the SSECustomerAlgorithm field's value.
+func (s *PutObjectInput) SetSSECustomerAlgorithm(v string) *PutObjectInput {
+	s.SSECustomerAlgorithm = &v
+	return s
+}
+
+// SetSSECustomerKey sets the SSECustomerKey field's value.
+func (s *PutObjectInput) SetSSECustomerKey(v string) *PutObjectInput {
+	s.SSECustomerKey = &v
+	return s
+}
+
+func (s *PutObjectInput) getSSECustomerKey() (v string) {
+	if s.SSECustomerKey == nil {
+		return v
+	}
+	return *s.SSECustomerKey
+}
+
+// SetSSECustomerKeyMD5 sets the SSECustomerKeyMD5 field's value.
+func (s *PutObjectInput) SetSSECustomerKeyMD5(v string) *PutObjectInput {
+	s.SSECustomerKeyMD5 = &v
+	return s
+}
+
+// SetSSEKMSKeyId sets the SSEKMSKeyId field's value.
+func (s *PutObjectInput) SetSSEKMSKeyId(v string) *PutObjectInput {
+	s.SSEKMSKeyId = &v
+	return s
+}
+
+// SetServerSideEncryption sets the ServerSideEncryption field's value.
+func (s *PutObjectInput) SetServerSideEncryption(v string) *PutObjectInput {
+	s.ServerSideEncryption = &v
+	return s
+}
+
+// SetStorageClass sets the StorageClass field's value.
+func (s *PutObjectInput) SetStorageClass(v string) *PutObjectInput {
+	s.StorageClass = &v
+	return s
+}
+
+// SetTagging sets the Tagging field's value.
+func (s *PutObjectInput) SetTagging(v string) *PutObjectInput {
+	s.Tagging = &v
+	return s
+}
+
+// SetWebsiteRedirectLocation sets the WebsiteRedirectLocation field's value.
+func (s *PutObjectInput) SetWebsiteRedirectLocation(v string) *PutObjectInput {
+	s.WebsiteRedirectLocation = &v
+	return s
+}
+
+type PutObjectOutput struct {
+	_ struct{} `type:"structure"`
+
+	// Entity tag for the uploaded object.
+	ETag *string `location:"header" locationName:"ETag" type:"string"`
+
+	// If the object expiration is configured, this will contain the expiration
+	// date (expiry-date) and rule ID (rule-id). The value of rule-id is URL encoded.
+	Expiration *string `location:"header" locationName:"x-amz-expiration" type:"string"`
+
+	// If present, indicates that the requester was successfully charged for the
+	// request.
+	RequestCharged *string `location:"header" locationName:"x-amz-request-charged" type:"string" enum:"RequestCharged"`
+
+	// If server-side encryption with a customer-provided encryption key was requested,
+	// the response will include this header confirming the encryption algorithm
+	// used.
+	SSECustomerAlgorithm *string `location:"header" locationName:"x-amz-server-side-encryption-customer-algorithm" type:"string"`
+
+	// If server-side encryption with a customer-provided encryption key was requested,
+	// the response will include this header to provide round trip message integrity
+	// verification of the customer-provided encryption key.
+	SSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key-MD5" type:"string"`
+
+	// If present, specifies the ID of the AWS Key Management Service (KMS) master
+	// encryption key that was used for the object.
+	SSEKMSKeyId *string `location:"header" locationName:"x-amz-server-side-encryption-aws-kms-key-id" type:"string"`
+
+	// The Server-side encryption algorithm used when storing this object in S3
+	// (e.g., AES256, aws:kms).
+	ServerSideEncryption *string `location:"header" locationName:"x-amz-server-side-encryption" type:"string" enum:"ServerSideEncryption"`
+
+	// Version of the object.
+	VersionId *string `location:"header" locationName:"x-amz-version-id" type:"string"`
+}
+
+// String returns the string representation
+func (s PutObjectOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutObjectOutput) GoString() string {
+	return s.String()
+}
+
+// SetETag sets the ETag field's value.
+func (s *PutObjectOutput) SetETag(v string) *PutObjectOutput {
+	s.ETag = &v
+	return s
+}
+
+// SetExpiration sets the Expiration field's value.
+func (s *PutObjectOutput) SetExpiration(v string) *PutObjectOutput {
+	s.Expiration = &v
+	return s
+}
+
+// SetRequestCharged sets the RequestCharged field's value.
+func (s *PutObjectOutput) SetRequestCharged(v string) *PutObjectOutput {
+	s.RequestCharged = &v
+	return s
+}
+
+// SetSSECustomerAlgorithm sets the SSECustomerAlgorithm field's value.
+func (s *PutObjectOutput) SetSSECustomerAlgorithm(v string) *PutObjectOutput {
+	s.SSECustomerAlgorithm = &v
+	return s
+}
+
+// SetSSECustomerKeyMD5 sets the SSECustomerKeyMD5 field's value.
+func (s *PutObjectOutput) SetSSECustomerKeyMD5(v string) *PutObjectOutput {
+	s.SSECustomerKeyMD5 = &v
+	return s
+}
+
+// SetSSEKMSKeyId sets the SSEKMSKeyId field's value.
+func (s *PutObjectOutput) SetSSEKMSKeyId(v string) *PutObjectOutput {
+	s.SSEKMSKeyId = &v
+	return s
+}
+
+// SetServerSideEncryption sets the ServerSideEncryption field's value.
+func (s *PutObjectOutput) SetServerSideEncryption(v string) *PutObjectOutput {
+	s.ServerSideEncryption = &v
+	return s
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *PutObjectOutput) SetVersionId(v string) *PutObjectOutput {
+	s.VersionId = &v
+	return s
+}
+
+type PutObjectTaggingInput struct {
+	_ struct{} `type:"structure" payload:"Tagging"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Key is a required field
+	Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"`
+
+	// Tagging is a required field
+	Tagging *Tagging `locationName:"Tagging" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+
+	VersionId *string `location:"querystring" locationName:"versionId" type:"string"`
+}
+
+// String returns the string representation
+func (s PutObjectTaggingInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutObjectTaggingInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *PutObjectTaggingInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "PutObjectTaggingInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Key == nil {
+		invalidParams.Add(request.NewErrParamRequired("Key"))
+	}
+	if s.Key != nil && len(*s.Key) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
+	}
+	if s.Tagging == nil {
+		invalidParams.Add(request.NewErrParamRequired("Tagging"))
+	}
+	if s.Tagging != nil {
+		if err := s.Tagging.Validate(); err != nil {
+			invalidParams.AddNested("Tagging", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *PutObjectTaggingInput) SetBucket(v string) *PutObjectTaggingInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *PutObjectTaggingInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetKey sets the Key field's value.
+func (s *PutObjectTaggingInput) SetKey(v string) *PutObjectTaggingInput {
+	s.Key = &v
+	return s
+}
+
+// SetTagging sets the Tagging field's value.
+func (s *PutObjectTaggingInput) SetTagging(v *Tagging) *PutObjectTaggingInput {
+	s.Tagging = v
+	return s
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *PutObjectTaggingInput) SetVersionId(v string) *PutObjectTaggingInput {
+	s.VersionId = &v
+	return s
+}
+
+type PutObjectTaggingOutput struct {
+	_ struct{} `type:"structure"`
+
+	VersionId *string `location:"header" locationName:"x-amz-version-id" type:"string"`
+}
+
+// String returns the string representation
+func (s PutObjectTaggingOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s PutObjectTaggingOutput) GoString() string {
+	return s.String()
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *PutObjectTaggingOutput) SetVersionId(v string) *PutObjectTaggingOutput {
+	s.VersionId = &v
+	return s
+}
+
+// Container for specifying an configuration when you want Amazon S3 to publish
+// events to an Amazon Simple Queue Service (Amazon SQS) queue.
+type QueueConfiguration struct {
+	_ struct{} `type:"structure"`
+
+	// Events is a required field
+	Events []*string `locationName:"Event" type:"list" flattened:"true" required:"true"`
+
+	// Container for object key name filtering rules. For information about key
+	// name filtering, go to Configuring Event Notifications (http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html)
+	// in the Amazon Simple Storage Service Developer Guide.
+	Filter *NotificationConfigurationFilter `type:"structure"`
+
+	// Optional unique identifier for configurations in a notification configuration.
+	// If you don't provide one, Amazon S3 will assign an ID.
+	Id *string `type:"string"`
+
+	// Amazon SQS queue ARN to which Amazon S3 will publish a message when it detects
+	// events of specified type.
+	//
+	// QueueArn is a required field
+	QueueArn *string `locationName:"Queue" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s QueueConfiguration) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s QueueConfiguration) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *QueueConfiguration) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "QueueConfiguration"}
+	if s.Events == nil {
+		invalidParams.Add(request.NewErrParamRequired("Events"))
+	}
+	if s.QueueArn == nil {
+		invalidParams.Add(request.NewErrParamRequired("QueueArn"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetEvents sets the Events field's value.
+func (s *QueueConfiguration) SetEvents(v []*string) *QueueConfiguration {
+	s.Events = v
+	return s
+}
+
+// SetFilter sets the Filter field's value.
+func (s *QueueConfiguration) SetFilter(v *NotificationConfigurationFilter) *QueueConfiguration {
+	s.Filter = v
+	return s
+}
+
+// SetId sets the Id field's value.
+func (s *QueueConfiguration) SetId(v string) *QueueConfiguration {
+	s.Id = &v
+	return s
+}
+
+// SetQueueArn sets the QueueArn field's value.
+func (s *QueueConfiguration) SetQueueArn(v string) *QueueConfiguration {
+	s.QueueArn = &v
+	return s
+}
+
+type QueueConfigurationDeprecated struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket event for which to send notifications.
+	Event *string `deprecated:"true" type:"string" enum:"Event"`
+
+	Events []*string `locationName:"Event" type:"list" flattened:"true"`
+
+	// Optional unique identifier for configurations in a notification configuration.
+	// If you don't provide one, Amazon S3 will assign an ID.
+	Id *string `type:"string"`
+
+	Queue *string `type:"string"`
+}
+
+// String returns the string representation
+func (s QueueConfigurationDeprecated) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s QueueConfigurationDeprecated) GoString() string {
+	return s.String()
+}
+
+// SetEvent sets the Event field's value.
+func (s *QueueConfigurationDeprecated) SetEvent(v string) *QueueConfigurationDeprecated {
+	s.Event = &v
+	return s
+}
+
+// SetEvents sets the Events field's value.
+func (s *QueueConfigurationDeprecated) SetEvents(v []*string) *QueueConfigurationDeprecated {
+	s.Events = v
+	return s
+}
+
+// SetId sets the Id field's value.
+func (s *QueueConfigurationDeprecated) SetId(v string) *QueueConfigurationDeprecated {
+	s.Id = &v
+	return s
+}
+
+// SetQueue sets the Queue field's value.
+func (s *QueueConfigurationDeprecated) SetQueue(v string) *QueueConfigurationDeprecated {
+	s.Queue = &v
+	return s
+}
+
+type RecordsEvent struct {
+	_ struct{} `locationName:"RecordsEvent" type:"structure" payload:"Payload"`
+
+	// The byte array of partial, one or more result records.
+	//
+	// Payload is automatically base64 encoded/decoded by the SDK.
+	Payload []byte `type:"blob"`
+}
+
+// String returns the string representation
+func (s RecordsEvent) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s RecordsEvent) GoString() string {
+	return s.String()
+}
+
+// SetPayload sets the Payload field's value.
+func (s *RecordsEvent) SetPayload(v []byte) *RecordsEvent {
+	s.Payload = v
+	return s
+}
+
+// The RecordsEvent is and event in the SelectObjectContentEventStream group of events.
+func (s *RecordsEvent) eventSelectObjectContentEventStream() {}
+
+// UnmarshalEvent unmarshals the EventStream Message into the RecordsEvent value.
+// This method is only used internally within the SDK's EventStream handling.
+func (s *RecordsEvent) UnmarshalEvent(
+	payloadUnmarshaler protocol.PayloadUnmarshaler,
+	msg eventstream.Message,
+) error {
+	s.Payload = make([]byte, len(msg.Payload))
+	copy(s.Payload, msg.Payload)
+	return nil
+}
+
+type Redirect struct {
+	_ struct{} `type:"structure"`
+
+	// The host name to use in the redirect request.
+	HostName *string `type:"string"`
+
+	// The HTTP redirect code to use on the response. Not required if one of the
+	// siblings is present.
+	HttpRedirectCode *string `type:"string"`
+
+	// Protocol to use (http, https) when redirecting requests. The default is the
+	// protocol that is used in the original request.
+	Protocol *string `type:"string" enum:"Protocol"`
+
+	// The object key prefix to use in the redirect request. For example, to redirect
+	// requests for all pages with prefix docs/ (objects in the docs/ folder) to
+	// documents/, you can set a condition block with KeyPrefixEquals set to docs/
+	// and in the Redirect set ReplaceKeyPrefixWith to /documents. Not required
+	// if one of the siblings is present. Can be present only if ReplaceKeyWith
+	// is not provided.
+	ReplaceKeyPrefixWith *string `type:"string"`
+
+	// The specific object key to use in the redirect request. For example, redirect
+	// request to error.html. Not required if one of the sibling is present. Can
+	// be present only if ReplaceKeyPrefixWith is not provided.
+	ReplaceKeyWith *string `type:"string"`
+}
+
+// String returns the string representation
+func (s Redirect) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s Redirect) GoString() string {
+	return s.String()
+}
+
+// SetHostName sets the HostName field's value.
+func (s *Redirect) SetHostName(v string) *Redirect {
+	s.HostName = &v
+	return s
+}
+
+// SetHttpRedirectCode sets the HttpRedirectCode field's value.
+func (s *Redirect) SetHttpRedirectCode(v string) *Redirect {
+	s.HttpRedirectCode = &v
+	return s
+}
+
+// SetProtocol sets the Protocol field's value.
+func (s *Redirect) SetProtocol(v string) *Redirect {
+	s.Protocol = &v
+	return s
+}
+
+// SetReplaceKeyPrefixWith sets the ReplaceKeyPrefixWith field's value.
+func (s *Redirect) SetReplaceKeyPrefixWith(v string) *Redirect {
+	s.ReplaceKeyPrefixWith = &v
+	return s
+}
+
+// SetReplaceKeyWith sets the ReplaceKeyWith field's value.
+func (s *Redirect) SetReplaceKeyWith(v string) *Redirect {
+	s.ReplaceKeyWith = &v
+	return s
+}
+
+type RedirectAllRequestsTo struct {
+	_ struct{} `type:"structure"`
+
+	// Name of the host where requests will be redirected.
+	//
+	// HostName is a required field
+	HostName *string `type:"string" required:"true"`
+
+	// Protocol to use (http, https) when redirecting requests. The default is the
+	// protocol that is used in the original request.
+	Protocol *string `type:"string" enum:"Protocol"`
+}
+
+// String returns the string representation
+func (s RedirectAllRequestsTo) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s RedirectAllRequestsTo) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *RedirectAllRequestsTo) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "RedirectAllRequestsTo"}
+	if s.HostName == nil {
+		invalidParams.Add(request.NewErrParamRequired("HostName"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetHostName sets the HostName field's value.
+func (s *RedirectAllRequestsTo) SetHostName(v string) *RedirectAllRequestsTo {
+	s.HostName = &v
+	return s
+}
+
+// SetProtocol sets the Protocol field's value.
+func (s *RedirectAllRequestsTo) SetProtocol(v string) *RedirectAllRequestsTo {
+	s.Protocol = &v
+	return s
+}
+
+// Container for replication rules. You can add as many as 1,000 rules. Total
+// replication configuration size can be up to 2 MB.
+type ReplicationConfiguration struct {
+	_ struct{} `type:"structure"`
+
+	// Amazon Resource Name (ARN) of an IAM role for Amazon S3 to assume when replicating
+	// the objects.
+	//
+	// Role is a required field
+	Role *string `type:"string" required:"true"`
+
+	// Container for information about a particular replication rule. Replication
+	// configuration must have at least one rule and can contain up to 1,000 rules.
+	//
+	// Rules is a required field
+	Rules []*ReplicationRule `locationName:"Rule" type:"list" flattened:"true" required:"true"`
+}
+
+// String returns the string representation
+func (s ReplicationConfiguration) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ReplicationConfiguration) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *ReplicationConfiguration) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "ReplicationConfiguration"}
+	if s.Role == nil {
+		invalidParams.Add(request.NewErrParamRequired("Role"))
+	}
+	if s.Rules == nil {
+		invalidParams.Add(request.NewErrParamRequired("Rules"))
+	}
+	if s.Rules != nil {
+		for i, v := range s.Rules {
+			if v == nil {
+				continue
+			}
+			if err := v.Validate(); err != nil {
+				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Rules", i), err.(request.ErrInvalidParams))
+			}
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetRole sets the Role field's value.
+func (s *ReplicationConfiguration) SetRole(v string) *ReplicationConfiguration {
+	s.Role = &v
+	return s
+}
+
+// SetRules sets the Rules field's value.
+func (s *ReplicationConfiguration) SetRules(v []*ReplicationRule) *ReplicationConfiguration {
+	s.Rules = v
+	return s
+}
+
+// Container for information about a particular replication rule.
+type ReplicationRule struct {
+	_ struct{} `type:"structure"`
+
+	// Container for replication destination information.
+	//
+	// Destination is a required field
+	Destination *Destination `type:"structure" required:"true"`
+
+	// Unique identifier for the rule. The value cannot be longer than 255 characters.
+	ID *string `type:"string"`
+
+	// Object keyname prefix identifying one or more objects to which the rule applies.
+	// Maximum prefix length can be up to 1,024 characters. Overlapping prefixes
+	// are not supported.
+	//
+	// Prefix is a required field
+	Prefix *string `type:"string" required:"true"`
+
+	// Container for filters that define which source objects should be replicated.
+	SourceSelectionCriteria *SourceSelectionCriteria `type:"structure"`
+
+	// The rule is ignored if status is not Enabled.
+	//
+	// Status is a required field
+	Status *string `type:"string" required:"true" enum:"ReplicationRuleStatus"`
+}
+
+// String returns the string representation
+func (s ReplicationRule) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ReplicationRule) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *ReplicationRule) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "ReplicationRule"}
+	if s.Destination == nil {
+		invalidParams.Add(request.NewErrParamRequired("Destination"))
+	}
+	if s.Prefix == nil {
+		invalidParams.Add(request.NewErrParamRequired("Prefix"))
+	}
+	if s.Status == nil {
+		invalidParams.Add(request.NewErrParamRequired("Status"))
+	}
+	if s.Destination != nil {
+		if err := s.Destination.Validate(); err != nil {
+			invalidParams.AddNested("Destination", err.(request.ErrInvalidParams))
+		}
+	}
+	if s.SourceSelectionCriteria != nil {
+		if err := s.SourceSelectionCriteria.Validate(); err != nil {
+			invalidParams.AddNested("SourceSelectionCriteria", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetDestination sets the Destination field's value.
+func (s *ReplicationRule) SetDestination(v *Destination) *ReplicationRule {
+	s.Destination = v
+	return s
+}
+
+// SetID sets the ID field's value.
+func (s *ReplicationRule) SetID(v string) *ReplicationRule {
+	s.ID = &v
+	return s
+}
+
+// SetPrefix sets the Prefix field's value.
+func (s *ReplicationRule) SetPrefix(v string) *ReplicationRule {
+	s.Prefix = &v
+	return s
+}
+
+// SetSourceSelectionCriteria sets the SourceSelectionCriteria field's value.
+func (s *ReplicationRule) SetSourceSelectionCriteria(v *SourceSelectionCriteria) *ReplicationRule {
+	s.SourceSelectionCriteria = v
+	return s
+}
+
+// SetStatus sets the Status field's value.
+func (s *ReplicationRule) SetStatus(v string) *ReplicationRule {
+	s.Status = &v
+	return s
+}
+
+type RequestPaymentConfiguration struct {
+	_ struct{} `type:"structure"`
+
+	// Specifies who pays for the download and request fees.
+	//
+	// Payer is a required field
+	Payer *string `type:"string" required:"true" enum:"Payer"`
+}
+
+// String returns the string representation
+func (s RequestPaymentConfiguration) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s RequestPaymentConfiguration) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *RequestPaymentConfiguration) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "RequestPaymentConfiguration"}
+	if s.Payer == nil {
+		invalidParams.Add(request.NewErrParamRequired("Payer"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetPayer sets the Payer field's value.
+func (s *RequestPaymentConfiguration) SetPayer(v string) *RequestPaymentConfiguration {
+	s.Payer = &v
+	return s
+}
+
+type RequestProgress struct {
+	_ struct{} `type:"structure"`
+
+	// Specifies whether periodic QueryProgress frames should be sent. Valid values:
+	// TRUE, FALSE. Default value: FALSE.
+	Enabled *bool `type:"boolean"`
+}
+
+// String returns the string representation
+func (s RequestProgress) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s RequestProgress) GoString() string {
+	return s.String()
+}
+
+// SetEnabled sets the Enabled field's value.
+func (s *RequestProgress) SetEnabled(v bool) *RequestProgress {
+	s.Enabled = &v
+	return s
+}
+
+type RestoreObjectInput struct {
+	_ struct{} `type:"structure" payload:"RestoreRequest"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Key is a required field
+	Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"`
+
+	// Confirms that the requester knows that she or he will be charged for the
+	// request. Bucket owners need not specify this parameter in their requests.
+	// Documentation on downloading objects from requester pays buckets can be found
+	// at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
+	RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"`
+
+	// Container for restore job parameters.
+	RestoreRequest *RestoreRequest `locationName:"RestoreRequest" type:"structure" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+
+	VersionId *string `location:"querystring" locationName:"versionId" type:"string"`
+}
+
+// String returns the string representation
+func (s RestoreObjectInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s RestoreObjectInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *RestoreObjectInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "RestoreObjectInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Key == nil {
+		invalidParams.Add(request.NewErrParamRequired("Key"))
+	}
+	if s.Key != nil && len(*s.Key) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
+	}
+	if s.RestoreRequest != nil {
+		if err := s.RestoreRequest.Validate(); err != nil {
+			invalidParams.AddNested("RestoreRequest", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *RestoreObjectInput) SetBucket(v string) *RestoreObjectInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *RestoreObjectInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetKey sets the Key field's value.
+func (s *RestoreObjectInput) SetKey(v string) *RestoreObjectInput {
+	s.Key = &v
+	return s
+}
+
+// SetRequestPayer sets the RequestPayer field's value.
+func (s *RestoreObjectInput) SetRequestPayer(v string) *RestoreObjectInput {
+	s.RequestPayer = &v
+	return s
+}
+
+// SetRestoreRequest sets the RestoreRequest field's value.
+func (s *RestoreObjectInput) SetRestoreRequest(v *RestoreRequest) *RestoreObjectInput {
+	s.RestoreRequest = v
+	return s
+}
+
+// SetVersionId sets the VersionId field's value.
+func (s *RestoreObjectInput) SetVersionId(v string) *RestoreObjectInput {
+	s.VersionId = &v
+	return s
+}
+
+type RestoreObjectOutput struct {
+	_ struct{} `type:"structure"`
+
+	// If present, indicates that the requester was successfully charged for the
+	// request.
+	RequestCharged *string `location:"header" locationName:"x-amz-request-charged" type:"string" enum:"RequestCharged"`
+
+	// Indicates the path in the provided S3 output location where Select results
+	// will be restored to.
+	RestoreOutputPath *string `location:"header" locationName:"x-amz-restore-output-path" type:"string"`
+}
+
+// String returns the string representation
+func (s RestoreObjectOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s RestoreObjectOutput) GoString() string {
+	return s.String()
+}
+
+// SetRequestCharged sets the RequestCharged field's value.
+func (s *RestoreObjectOutput) SetRequestCharged(v string) *RestoreObjectOutput {
+	s.RequestCharged = &v
+	return s
+}
+
+// SetRestoreOutputPath sets the RestoreOutputPath field's value.
+func (s *RestoreObjectOutput) SetRestoreOutputPath(v string) *RestoreObjectOutput {
+	s.RestoreOutputPath = &v
+	return s
+}
+
+// Container for restore job parameters.
+type RestoreRequest struct {
+	_ struct{} `type:"structure"`
+
+	// Lifetime of the active copy in days. Do not use with restores that specify
+	// OutputLocation.
+	Days *int64 `type:"integer"`
+
+	// The optional description for the job.
+	Description *string `type:"string"`
+
+	// Glacier related parameters pertaining to this job. Do not use with restores
+	// that specify OutputLocation.
+	GlacierJobParameters *GlacierJobParameters `type:"structure"`
+
+	// Describes the location where the restore job's output is stored.
+	OutputLocation *OutputLocation `type:"structure"`
+
+	// Describes the parameters for Select job types.
+	SelectParameters *SelectParameters `type:"structure"`
+
+	// Glacier retrieval tier at which the restore will be processed.
+	Tier *string `type:"string" enum:"Tier"`
+
+	// Type of restore request.
+	Type *string `type:"string" enum:"RestoreRequestType"`
+}
+
+// String returns the string representation
+func (s RestoreRequest) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s RestoreRequest) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *RestoreRequest) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "RestoreRequest"}
+	if s.GlacierJobParameters != nil {
+		if err := s.GlacierJobParameters.Validate(); err != nil {
+			invalidParams.AddNested("GlacierJobParameters", err.(request.ErrInvalidParams))
+		}
+	}
+	if s.OutputLocation != nil {
+		if err := s.OutputLocation.Validate(); err != nil {
+			invalidParams.AddNested("OutputLocation", err.(request.ErrInvalidParams))
+		}
+	}
+	if s.SelectParameters != nil {
+		if err := s.SelectParameters.Validate(); err != nil {
+			invalidParams.AddNested("SelectParameters", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetDays sets the Days field's value.
+func (s *RestoreRequest) SetDays(v int64) *RestoreRequest {
+	s.Days = &v
+	return s
+}
+
+// SetDescription sets the Description field's value.
+func (s *RestoreRequest) SetDescription(v string) *RestoreRequest {
+	s.Description = &v
+	return s
+}
+
+// SetGlacierJobParameters sets the GlacierJobParameters field's value.
+func (s *RestoreRequest) SetGlacierJobParameters(v *GlacierJobParameters) *RestoreRequest {
+	s.GlacierJobParameters = v
+	return s
+}
+
+// SetOutputLocation sets the OutputLocation field's value.
+func (s *RestoreRequest) SetOutputLocation(v *OutputLocation) *RestoreRequest {
+	s.OutputLocation = v
+	return s
+}
+
+// SetSelectParameters sets the SelectParameters field's value.
+func (s *RestoreRequest) SetSelectParameters(v *SelectParameters) *RestoreRequest {
+	s.SelectParameters = v
+	return s
+}
+
+// SetTier sets the Tier field's value.
+func (s *RestoreRequest) SetTier(v string) *RestoreRequest {
+	s.Tier = &v
+	return s
+}
+
+// SetType sets the Type field's value.
+func (s *RestoreRequest) SetType(v string) *RestoreRequest {
+	s.Type = &v
+	return s
+}
+
+type RoutingRule struct {
+	_ struct{} `type:"structure"`
+
+	// A container for describing a condition that must be met for the specified
+	// redirect to apply. For example, 1. If request is for pages in the /docs folder,
+	// redirect to the /documents folder. 2. If request results in HTTP error 4xx,
+	// redirect request to another host where you might process the error.
+	Condition *Condition `type:"structure"`
+
+	// Container for redirect information. You can redirect requests to another
+	// host, to another page, or with another protocol. In the event of an error,
+	// you can can specify a different error code to return.
+	//
+	// Redirect is a required field
+	Redirect *Redirect `type:"structure" required:"true"`
+}
+
+// String returns the string representation
+func (s RoutingRule) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s RoutingRule) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *RoutingRule) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "RoutingRule"}
+	if s.Redirect == nil {
+		invalidParams.Add(request.NewErrParamRequired("Redirect"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetCondition sets the Condition field's value.
+func (s *RoutingRule) SetCondition(v *Condition) *RoutingRule {
+	s.Condition = v
+	return s
+}
+
+// SetRedirect sets the Redirect field's value.
+func (s *RoutingRule) SetRedirect(v *Redirect) *RoutingRule {
+	s.Redirect = v
+	return s
+}
+
+type Rule struct {
+	_ struct{} `type:"structure"`
+
+	// Specifies the days since the initiation of an Incomplete Multipart Upload
+	// that Lifecycle will wait before permanently removing all parts of the upload.
+	AbortIncompleteMultipartUpload *AbortIncompleteMultipartUpload `type:"structure"`
+
+	Expiration *LifecycleExpiration `type:"structure"`
+
+	// Unique identifier for the rule. The value cannot be longer than 255 characters.
+	ID *string `type:"string"`
+
+	// Specifies when noncurrent object versions expire. Upon expiration, Amazon
+	// S3 permanently deletes the noncurrent object versions. You set this lifecycle
+	// configuration action on a bucket that has versioning enabled (or suspended)
+	// to request that Amazon S3 delete noncurrent object versions at a specific
+	// period in the object's lifetime.
+	NoncurrentVersionExpiration *NoncurrentVersionExpiration `type:"structure"`
+
+	// Container for the transition rule that describes when noncurrent objects
+	// transition to the STANDARD_IA, ONEZONE_IA or GLACIER storage class. If your
+	// bucket is versioning-enabled (or versioning is suspended), you can set this
+	// action to request that Amazon S3 transition noncurrent object versions to
+	// the STANDARD_IA, ONEZONE_IA or GLACIER storage class at a specific period
+	// in the object's lifetime.
+	NoncurrentVersionTransition *NoncurrentVersionTransition `type:"structure"`
+
+	// Prefix identifying one or more objects to which the rule applies.
+	//
+	// Prefix is a required field
+	Prefix *string `type:"string" required:"true"`
+
+	// If 'Enabled', the rule is currently being applied. If 'Disabled', the rule
+	// is not currently being applied.
+	//
+	// Status is a required field
+	Status *string `type:"string" required:"true" enum:"ExpirationStatus"`
+
+	Transition *Transition `type:"structure"`
+}
+
+// String returns the string representation
+func (s Rule) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s Rule) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *Rule) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "Rule"}
+	if s.Prefix == nil {
+		invalidParams.Add(request.NewErrParamRequired("Prefix"))
+	}
+	if s.Status == nil {
+		invalidParams.Add(request.NewErrParamRequired("Status"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetAbortIncompleteMultipartUpload sets the AbortIncompleteMultipartUpload field's value.
+func (s *Rule) SetAbortIncompleteMultipartUpload(v *AbortIncompleteMultipartUpload) *Rule {
+	s.AbortIncompleteMultipartUpload = v
+	return s
+}
+
+// SetExpiration sets the Expiration field's value.
+func (s *Rule) SetExpiration(v *LifecycleExpiration) *Rule {
+	s.Expiration = v
+	return s
+}
+
+// SetID sets the ID field's value.
+func (s *Rule) SetID(v string) *Rule {
+	s.ID = &v
+	return s
+}
+
+// SetNoncurrentVersionExpiration sets the NoncurrentVersionExpiration field's value.
+func (s *Rule) SetNoncurrentVersionExpiration(v *NoncurrentVersionExpiration) *Rule {
+	s.NoncurrentVersionExpiration = v
+	return s
+}
+
+// SetNoncurrentVersionTransition sets the NoncurrentVersionTransition field's value.
+func (s *Rule) SetNoncurrentVersionTransition(v *NoncurrentVersionTransition) *Rule {
+	s.NoncurrentVersionTransition = v
+	return s
+}
+
+// SetPrefix sets the Prefix field's value.
+func (s *Rule) SetPrefix(v string) *Rule {
+	s.Prefix = &v
+	return s
+}
+
+// SetStatus sets the Status field's value.
+func (s *Rule) SetStatus(v string) *Rule {
+	s.Status = &v
+	return s
+}
+
+// SetTransition sets the Transition field's value.
+func (s *Rule) SetTransition(v *Transition) *Rule {
+	s.Transition = v
+	return s
+}
+
+// Specifies the use of SSE-KMS to encrypt delievered Inventory reports.
+type SSEKMS struct {
+	_ struct{} `locationName:"SSE-KMS" type:"structure"`
+
+	// Specifies the ID of the AWS Key Management Service (KMS) master encryption
+	// key to use for encrypting Inventory reports.
+	//
+	// KeyId is a required field
+	KeyId *string `type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s SSEKMS) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s SSEKMS) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *SSEKMS) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "SSEKMS"}
+	if s.KeyId == nil {
+		invalidParams.Add(request.NewErrParamRequired("KeyId"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetKeyId sets the KeyId field's value.
+func (s *SSEKMS) SetKeyId(v string) *SSEKMS {
+	s.KeyId = &v
+	return s
+}
+
+// Specifies the use of SSE-S3 to encrypt delievered Inventory reports.
+type SSES3 struct {
+	_ struct{} `locationName:"SSE-S3" type:"structure"`
+}
+
+// String returns the string representation
+func (s SSES3) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s SSES3) GoString() string {
+	return s.String()
+}
+
+// SelectObjectContentEventStream provides handling of EventStreams for
+// the SelectObjectContent API.
+//
+// Use this type to receive SelectObjectContentEventStream events. The events
+// can be read from the Events channel member.
+//
+// The events that can be received are:
+//
+//     * ContinuationEvent
+//     * EndEvent
+//     * ProgressEvent
+//     * RecordsEvent
+//     * StatsEvent
+type SelectObjectContentEventStream struct {
+	// Reader is the EventStream reader for the SelectObjectContentEventStream
+	// events. This value is automatically set by the SDK when the API call is made
+	// Use this member when unit testing your code with the SDK to mock out the
+	// EventStream Reader.
+	//
+	// Must not be nil.
+	Reader SelectObjectContentEventStreamReader
+
+	// StreamCloser is the io.Closer for the EventStream connection. For HTTP
+	// EventStream this is the response Body. The stream will be closed when
+	// the Close method of the EventStream is called.
+	StreamCloser io.Closer
+}
+
+// Close closes the EventStream. This will also cause the Events channel to be
+// closed. You can use the closing of the Events channel to terminate your
+// application's read from the API's EventStream.
+//
+// Will close the underlying EventStream reader. For EventStream over HTTP
+// connection this will also close the HTTP connection.
+//
+// Close must be called when done using the EventStream API. Not calling Close
+// may result in resource leaks.
+func (es *SelectObjectContentEventStream) Close() (err error) {
+	es.Reader.Close()
+	return es.Err()
+}
+
+// Err returns any error that occurred while reading EventStream Events from
+// the service API's response. Returns nil if there were no errors.
+func (es *SelectObjectContentEventStream) Err() error {
+	if err := es.Reader.Err(); err != nil {
+		return err
+	}
+	es.StreamCloser.Close()
+
+	return nil
+}
+
+// Events returns a channel to read EventStream Events from the
+// SelectObjectContent API.
+//
+// These events are:
+//
+//     * ContinuationEvent
+//     * EndEvent
+//     * ProgressEvent
+//     * RecordsEvent
+//     * StatsEvent
+func (es *SelectObjectContentEventStream) Events() <-chan SelectObjectContentEventStreamEvent {
+	return es.Reader.Events()
+}
+
+// SelectObjectContentEventStreamEvent groups together all EventStream
+// events read from the SelectObjectContent API.
+//
+// These events are:
+//
+//     * ContinuationEvent
+//     * EndEvent
+//     * ProgressEvent
+//     * RecordsEvent
+//     * StatsEvent
+type SelectObjectContentEventStreamEvent interface {
+	eventSelectObjectContentEventStream()
+}
+
+// SelectObjectContentEventStreamReader provides the interface for reading EventStream
+// Events from the SelectObjectContent API. The
+// default implementation for this interface will be SelectObjectContentEventStream.
+//
+// The reader's Close method must allow multiple concurrent calls.
+//
+// These events are:
+//
+//     * ContinuationEvent
+//     * EndEvent
+//     * ProgressEvent
+//     * RecordsEvent
+//     * StatsEvent
+type SelectObjectContentEventStreamReader interface {
+	// Returns a channel of events as they are read from the event stream.
+	Events() <-chan SelectObjectContentEventStreamEvent
+
+	// Close will close the underlying event stream reader. For event stream over
+	// HTTP this will also close the HTTP connection.
+	Close() error
+
+	// Returns any error that has occured while reading from the event stream.
+	Err() error
+}
+
+type readSelectObjectContentEventStream struct {
+	eventReader *eventstreamapi.EventReader
+	stream      chan SelectObjectContentEventStreamEvent
+	errVal      atomic.Value
+
+	done      chan struct{}
+	closeOnce sync.Once
+}
+
+func newReadSelectObjectContentEventStream(
+	reader io.ReadCloser,
+	unmarshalers request.HandlerList,
+	logger aws.Logger,
+	logLevel aws.LogLevelType,
+) *readSelectObjectContentEventStream {
+	r := &readSelectObjectContentEventStream{
+		stream: make(chan SelectObjectContentEventStreamEvent),
+		done:   make(chan struct{}),
+	}
+
+	r.eventReader = eventstreamapi.NewEventReader(
+		reader,
+		protocol.HandlerPayloadUnmarshal{
+			Unmarshalers: unmarshalers,
+		},
+		r.unmarshalerForEventType,
+	)
+	r.eventReader.UseLogger(logger, logLevel)
+
+	return r
+}
+
+// Close will close the underlying event stream reader. For EventStream over
+// HTTP this will also close the HTTP connection.
+func (r *readSelectObjectContentEventStream) Close() error {
+	r.closeOnce.Do(r.safeClose)
+
+	return r.Err()
+}
+
+func (r *readSelectObjectContentEventStream) safeClose() {
+	close(r.done)
+	err := r.eventReader.Close()
+	if err != nil {
+		r.errVal.Store(err)
+	}
+}
+
+func (r *readSelectObjectContentEventStream) Err() error {
+	if v := r.errVal.Load(); v != nil {
+		return v.(error)
+	}
+
+	return nil
+}
+
+func (r *readSelectObjectContentEventStream) Events() <-chan SelectObjectContentEventStreamEvent {
+	return r.stream
+}
+
+func (r *readSelectObjectContentEventStream) readEventStream() {
+	defer close(r.stream)
+
+	for {
+		event, err := r.eventReader.ReadEvent()
+		if err != nil {
+			if err == io.EOF {
+				return
+			}
+			select {
+			case <-r.done:
+				// If closed already ignore the error
+				return
+			default:
+			}
+			r.errVal.Store(err)
+			return
+		}
+
+		select {
+		case r.stream <- event.(SelectObjectContentEventStreamEvent):
+		case <-r.done:
+			return
+		}
+	}
+}
+
+func (r *readSelectObjectContentEventStream) unmarshalerForEventType(
+	eventType string,
+) (eventstreamapi.Unmarshaler, error) {
+	switch eventType {
+	case "Cont":
+		return &ContinuationEvent{}, nil
+
+	case "End":
+		return &EndEvent{}, nil
+
+	case "Progress":
+		return &ProgressEvent{}, nil
+
+	case "Records":
+		return &RecordsEvent{}, nil
+
+	case "Stats":
+		return &StatsEvent{}, nil
+	default:
+		return nil, awserr.New(
+			request.ErrCodeSerialization,
+			fmt.Sprintf("unknown event type name, %s, for SelectObjectContentEventStream", eventType),
+			nil,
+		)
+	}
+}
+
+// Request to filter the contents of an Amazon S3 object based on a simple Structured
+// Query Language (SQL) statement. In the request, along with the SQL expression,
+// you must also specify a data serialization format (JSON or CSV) of the object.
+// Amazon S3 uses this to parse object data into records, and returns only records
+// that match the specified SQL expression. You must also specify the data serialization
+// format for the response. For more information, go to S3Select API Documentation
+// (http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectSELECTContent.html).
+type SelectObjectContentInput struct {
+	_ struct{} `locationName:"SelectObjectContentRequest" type:"structure" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+
+	// The S3 Bucket.
+	//
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// The expression that is used to query the object.
+	//
+	// Expression is a required field
+	Expression *string `type:"string" required:"true"`
+
+	// The type of the provided expression (e.g., SQL).
+	//
+	// ExpressionType is a required field
+	ExpressionType *string `type:"string" required:"true" enum:"ExpressionType"`
+
+	// Describes the format of the data in the object that is being queried.
+	//
+	// InputSerialization is a required field
+	InputSerialization *InputSerialization `type:"structure" required:"true"`
+
+	// The Object Key.
+	//
+	// Key is a required field
+	Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"`
+
+	// Describes the format of the data that you want Amazon S3 to return in response.
+	//
+	// OutputSerialization is a required field
+	OutputSerialization *OutputSerialization `type:"structure" required:"true"`
+
+	// Specifies if periodic request progress information should be enabled.
+	RequestProgress *RequestProgress `type:"structure"`
+
+	// The SSE Algorithm used to encrypt the object. For more information, go to
+	//  Server-Side Encryption (Using Customer-Provided Encryption Keys (http://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html).
+	SSECustomerAlgorithm *string `location:"header" locationName:"x-amz-server-side-encryption-customer-algorithm" type:"string"`
+
+	// The SSE Customer Key. For more information, go to  Server-Side Encryption
+	// (Using Customer-Provided Encryption Keys (http://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html).
+	SSECustomerKey *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key" type:"string"`
+
+	// The SSE Customer Key MD5. For more information, go to  Server-Side Encryption
+	// (Using Customer-Provided Encryption Keys (http://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html).
+	SSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key-MD5" type:"string"`
+}
+
+// String returns the string representation
+func (s SelectObjectContentInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s SelectObjectContentInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *SelectObjectContentInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "SelectObjectContentInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Expression == nil {
+		invalidParams.Add(request.NewErrParamRequired("Expression"))
+	}
+	if s.ExpressionType == nil {
+		invalidParams.Add(request.NewErrParamRequired("ExpressionType"))
+	}
+	if s.InputSerialization == nil {
+		invalidParams.Add(request.NewErrParamRequired("InputSerialization"))
+	}
+	if s.Key == nil {
+		invalidParams.Add(request.NewErrParamRequired("Key"))
+	}
+	if s.Key != nil && len(*s.Key) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
+	}
+	if s.OutputSerialization == nil {
+		invalidParams.Add(request.NewErrParamRequired("OutputSerialization"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *SelectObjectContentInput) SetBucket(v string) *SelectObjectContentInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *SelectObjectContentInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetExpression sets the Expression field's value.
+func (s *SelectObjectContentInput) SetExpression(v string) *SelectObjectContentInput {
+	s.Expression = &v
+	return s
+}
+
+// SetExpressionType sets the ExpressionType field's value.
+func (s *SelectObjectContentInput) SetExpressionType(v string) *SelectObjectContentInput {
+	s.ExpressionType = &v
+	return s
+}
+
+// SetInputSerialization sets the InputSerialization field's value.
+func (s *SelectObjectContentInput) SetInputSerialization(v *InputSerialization) *SelectObjectContentInput {
+	s.InputSerialization = v
+	return s
+}
+
+// SetKey sets the Key field's value.
+func (s *SelectObjectContentInput) SetKey(v string) *SelectObjectContentInput {
+	s.Key = &v
+	return s
+}
+
+// SetOutputSerialization sets the OutputSerialization field's value.
+func (s *SelectObjectContentInput) SetOutputSerialization(v *OutputSerialization) *SelectObjectContentInput {
+	s.OutputSerialization = v
+	return s
+}
+
+// SetRequestProgress sets the RequestProgress field's value.
+func (s *SelectObjectContentInput) SetRequestProgress(v *RequestProgress) *SelectObjectContentInput {
+	s.RequestProgress = v
+	return s
+}
+
+// SetSSECustomerAlgorithm sets the SSECustomerAlgorithm field's value.
+func (s *SelectObjectContentInput) SetSSECustomerAlgorithm(v string) *SelectObjectContentInput {
+	s.SSECustomerAlgorithm = &v
+	return s
+}
+
+// SetSSECustomerKey sets the SSECustomerKey field's value.
+func (s *SelectObjectContentInput) SetSSECustomerKey(v string) *SelectObjectContentInput {
+	s.SSECustomerKey = &v
+	return s
+}
+
+func (s *SelectObjectContentInput) getSSECustomerKey() (v string) {
+	if s.SSECustomerKey == nil {
+		return v
+	}
+	return *s.SSECustomerKey
+}
+
+// SetSSECustomerKeyMD5 sets the SSECustomerKeyMD5 field's value.
+func (s *SelectObjectContentInput) SetSSECustomerKeyMD5(v string) *SelectObjectContentInput {
+	s.SSECustomerKeyMD5 = &v
+	return s
+}
+
+type SelectObjectContentOutput struct {
+	_ struct{} `type:"structure" payload:"Payload"`
+
+	// Use EventStream to use the API's stream.
+	EventStream *SelectObjectContentEventStream `type:"structure"`
+}
+
+// String returns the string representation
+func (s SelectObjectContentOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s SelectObjectContentOutput) GoString() string {
+	return s.String()
+}
+
+// SetEventStream sets the EventStream field's value.
+func (s *SelectObjectContentOutput) SetEventStream(v *SelectObjectContentEventStream) *SelectObjectContentOutput {
+	s.EventStream = v
+	return s
+}
+
+func (s *SelectObjectContentOutput) runEventStreamLoop(r *request.Request) {
+	if r.Error != nil {
+		return
+	}
+	reader := newReadSelectObjectContentEventStream(
+		r.HTTPResponse.Body,
+		r.Handlers.UnmarshalStream,
+		r.Config.Logger,
+		r.Config.LogLevel.Value(),
+	)
+	go reader.readEventStream()
+
+	eventStream := &SelectObjectContentEventStream{
+		StreamCloser: r.HTTPResponse.Body,
+		Reader:       reader,
+	}
+	s.EventStream = eventStream
+}
+
+// Describes the parameters for Select job types.
+type SelectParameters struct {
+	_ struct{} `type:"structure"`
+
+	// The expression that is used to query the object.
+	//
+	// Expression is a required field
+	Expression *string `type:"string" required:"true"`
+
+	// The type of the provided expression (e.g., SQL).
+	//
+	// ExpressionType is a required field
+	ExpressionType *string `type:"string" required:"true" enum:"ExpressionType"`
+
+	// Describes the serialization format of the object.
+	//
+	// InputSerialization is a required field
+	InputSerialization *InputSerialization `type:"structure" required:"true"`
+
+	// Describes how the results of the Select job are serialized.
+	//
+	// OutputSerialization is a required field
+	OutputSerialization *OutputSerialization `type:"structure" required:"true"`
+}
+
+// String returns the string representation
+func (s SelectParameters) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s SelectParameters) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *SelectParameters) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "SelectParameters"}
+	if s.Expression == nil {
+		invalidParams.Add(request.NewErrParamRequired("Expression"))
+	}
+	if s.ExpressionType == nil {
+		invalidParams.Add(request.NewErrParamRequired("ExpressionType"))
+	}
+	if s.InputSerialization == nil {
+		invalidParams.Add(request.NewErrParamRequired("InputSerialization"))
+	}
+	if s.OutputSerialization == nil {
+		invalidParams.Add(request.NewErrParamRequired("OutputSerialization"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetExpression sets the Expression field's value.
+func (s *SelectParameters) SetExpression(v string) *SelectParameters {
+	s.Expression = &v
+	return s
+}
+
+// SetExpressionType sets the ExpressionType field's value.
+func (s *SelectParameters) SetExpressionType(v string) *SelectParameters {
+	s.ExpressionType = &v
+	return s
+}
+
+// SetInputSerialization sets the InputSerialization field's value.
+func (s *SelectParameters) SetInputSerialization(v *InputSerialization) *SelectParameters {
+	s.InputSerialization = v
+	return s
+}
+
+// SetOutputSerialization sets the OutputSerialization field's value.
+func (s *SelectParameters) SetOutputSerialization(v *OutputSerialization) *SelectParameters {
+	s.OutputSerialization = v
+	return s
+}
+
+// Describes the default server-side encryption to apply to new objects in the
+// bucket. If Put Object request does not specify any server-side encryption,
+// this default encryption will be applied.
+type ServerSideEncryptionByDefault struct {
+	_ struct{} `type:"structure"`
+
+	// KMS master key ID to use for the default encryption. This parameter is allowed
+	// if SSEAlgorithm is aws:kms.
+	KMSMasterKeyID *string `type:"string"`
+
+	// Server-side encryption algorithm to use for the default encryption.
+	//
+	// SSEAlgorithm is a required field
+	SSEAlgorithm *string `type:"string" required:"true" enum:"ServerSideEncryption"`
+}
+
+// String returns the string representation
+func (s ServerSideEncryptionByDefault) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ServerSideEncryptionByDefault) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *ServerSideEncryptionByDefault) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "ServerSideEncryptionByDefault"}
+	if s.SSEAlgorithm == nil {
+		invalidParams.Add(request.NewErrParamRequired("SSEAlgorithm"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetKMSMasterKeyID sets the KMSMasterKeyID field's value.
+func (s *ServerSideEncryptionByDefault) SetKMSMasterKeyID(v string) *ServerSideEncryptionByDefault {
+	s.KMSMasterKeyID = &v
+	return s
+}
+
+// SetSSEAlgorithm sets the SSEAlgorithm field's value.
+func (s *ServerSideEncryptionByDefault) SetSSEAlgorithm(v string) *ServerSideEncryptionByDefault {
+	s.SSEAlgorithm = &v
+	return s
+}
+
+// Container for server-side encryption configuration rules. Currently S3 supports
+// one rule only.
+type ServerSideEncryptionConfiguration struct {
+	_ struct{} `type:"structure"`
+
+	// Container for information about a particular server-side encryption configuration
+	// rule.
+	//
+	// Rules is a required field
+	Rules []*ServerSideEncryptionRule `locationName:"Rule" type:"list" flattened:"true" required:"true"`
+}
+
+// String returns the string representation
+func (s ServerSideEncryptionConfiguration) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ServerSideEncryptionConfiguration) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *ServerSideEncryptionConfiguration) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "ServerSideEncryptionConfiguration"}
+	if s.Rules == nil {
+		invalidParams.Add(request.NewErrParamRequired("Rules"))
+	}
+	if s.Rules != nil {
+		for i, v := range s.Rules {
+			if v == nil {
+				continue
+			}
+			if err := v.Validate(); err != nil {
+				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Rules", i), err.(request.ErrInvalidParams))
+			}
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetRules sets the Rules field's value.
+func (s *ServerSideEncryptionConfiguration) SetRules(v []*ServerSideEncryptionRule) *ServerSideEncryptionConfiguration {
+	s.Rules = v
+	return s
+}
+
+// Container for information about a particular server-side encryption configuration
+// rule.
+type ServerSideEncryptionRule struct {
+	_ struct{} `type:"structure"`
+
+	// Describes the default server-side encryption to apply to new objects in the
+	// bucket. If Put Object request does not specify any server-side encryption,
+	// this default encryption will be applied.
+	ApplyServerSideEncryptionByDefault *ServerSideEncryptionByDefault `type:"structure"`
+}
+
+// String returns the string representation
+func (s ServerSideEncryptionRule) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s ServerSideEncryptionRule) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *ServerSideEncryptionRule) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "ServerSideEncryptionRule"}
+	if s.ApplyServerSideEncryptionByDefault != nil {
+		if err := s.ApplyServerSideEncryptionByDefault.Validate(); err != nil {
+			invalidParams.AddNested("ApplyServerSideEncryptionByDefault", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetApplyServerSideEncryptionByDefault sets the ApplyServerSideEncryptionByDefault field's value.
+func (s *ServerSideEncryptionRule) SetApplyServerSideEncryptionByDefault(v *ServerSideEncryptionByDefault) *ServerSideEncryptionRule {
+	s.ApplyServerSideEncryptionByDefault = v
+	return s
+}
+
+// Container for filters that define which source objects should be replicated.
+type SourceSelectionCriteria struct {
+	_ struct{} `type:"structure"`
+
+	// Container for filter information of selection of KMS Encrypted S3 objects.
+	SseKmsEncryptedObjects *SseKmsEncryptedObjects `type:"structure"`
+}
+
+// String returns the string representation
+func (s SourceSelectionCriteria) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s SourceSelectionCriteria) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *SourceSelectionCriteria) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "SourceSelectionCriteria"}
+	if s.SseKmsEncryptedObjects != nil {
+		if err := s.SseKmsEncryptedObjects.Validate(); err != nil {
+			invalidParams.AddNested("SseKmsEncryptedObjects", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetSseKmsEncryptedObjects sets the SseKmsEncryptedObjects field's value.
+func (s *SourceSelectionCriteria) SetSseKmsEncryptedObjects(v *SseKmsEncryptedObjects) *SourceSelectionCriteria {
+	s.SseKmsEncryptedObjects = v
+	return s
+}
+
+// Container for filter information of selection of KMS Encrypted S3 objects.
+type SseKmsEncryptedObjects struct {
+	_ struct{} `type:"structure"`
+
+	// The replication for KMS encrypted S3 objects is disabled if status is not
+	// Enabled.
+	//
+	// Status is a required field
+	Status *string `type:"string" required:"true" enum:"SseKmsEncryptedObjectsStatus"`
+}
+
+// String returns the string representation
+func (s SseKmsEncryptedObjects) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s SseKmsEncryptedObjects) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *SseKmsEncryptedObjects) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "SseKmsEncryptedObjects"}
+	if s.Status == nil {
+		invalidParams.Add(request.NewErrParamRequired("Status"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetStatus sets the Status field's value.
+func (s *SseKmsEncryptedObjects) SetStatus(v string) *SseKmsEncryptedObjects {
+	s.Status = &v
+	return s
+}
+
+type Stats struct {
+	_ struct{} `type:"structure"`
+
+	// Total number of uncompressed object bytes processed.
+	BytesProcessed *int64 `type:"long"`
+
+	// Total number of bytes of records payload data returned.
+	BytesReturned *int64 `type:"long"`
+
+	// Total number of object bytes scanned.
+	BytesScanned *int64 `type:"long"`
+}
+
+// String returns the string representation
+func (s Stats) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s Stats) GoString() string {
+	return s.String()
+}
+
+// SetBytesProcessed sets the BytesProcessed field's value.
+func (s *Stats) SetBytesProcessed(v int64) *Stats {
+	s.BytesProcessed = &v
+	return s
+}
+
+// SetBytesReturned sets the BytesReturned field's value.
+func (s *Stats) SetBytesReturned(v int64) *Stats {
+	s.BytesReturned = &v
+	return s
+}
+
+// SetBytesScanned sets the BytesScanned field's value.
+func (s *Stats) SetBytesScanned(v int64) *Stats {
+	s.BytesScanned = &v
+	return s
+}
+
+type StatsEvent struct {
+	_ struct{} `locationName:"StatsEvent" type:"structure" payload:"Details"`
+
+	// The Stats event details.
+	Details *Stats `locationName:"Details" type:"structure"`
+}
+
+// String returns the string representation
+func (s StatsEvent) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s StatsEvent) GoString() string {
+	return s.String()
+}
+
+// SetDetails sets the Details field's value.
+func (s *StatsEvent) SetDetails(v *Stats) *StatsEvent {
+	s.Details = v
+	return s
+}
+
+// The StatsEvent is and event in the SelectObjectContentEventStream group of events.
+func (s *StatsEvent) eventSelectObjectContentEventStream() {}
+
+// UnmarshalEvent unmarshals the EventStream Message into the StatsEvent value.
+// This method is only used internally within the SDK's EventStream handling.
+func (s *StatsEvent) UnmarshalEvent(
+	payloadUnmarshaler protocol.PayloadUnmarshaler,
+	msg eventstream.Message,
+) error {
+	if err := payloadUnmarshaler.UnmarshalPayload(
+		bytes.NewReader(msg.Payload), s,
+	); err != nil {
+		return err
+	}
+	return nil
+}
+
+type StorageClassAnalysis struct {
+	_ struct{} `type:"structure"`
+
+	// A container used to describe how data related to the storage class analysis
+	// should be exported.
+	DataExport *StorageClassAnalysisDataExport `type:"structure"`
+}
+
+// String returns the string representation
+func (s StorageClassAnalysis) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s StorageClassAnalysis) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *StorageClassAnalysis) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "StorageClassAnalysis"}
+	if s.DataExport != nil {
+		if err := s.DataExport.Validate(); err != nil {
+			invalidParams.AddNested("DataExport", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetDataExport sets the DataExport field's value.
+func (s *StorageClassAnalysis) SetDataExport(v *StorageClassAnalysisDataExport) *StorageClassAnalysis {
+	s.DataExport = v
+	return s
+}
+
+type StorageClassAnalysisDataExport struct {
+	_ struct{} `type:"structure"`
+
+	// The place to store the data for an analysis.
+	//
+	// Destination is a required field
+	Destination *AnalyticsExportDestination `type:"structure" required:"true"`
+
+	// The version of the output schema to use when exporting data. Must be V_1.
+	//
+	// OutputSchemaVersion is a required field
+	OutputSchemaVersion *string `type:"string" required:"true" enum:"StorageClassAnalysisSchemaVersion"`
+}
+
+// String returns the string representation
+func (s StorageClassAnalysisDataExport) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s StorageClassAnalysisDataExport) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *StorageClassAnalysisDataExport) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "StorageClassAnalysisDataExport"}
+	if s.Destination == nil {
+		invalidParams.Add(request.NewErrParamRequired("Destination"))
+	}
+	if s.OutputSchemaVersion == nil {
+		invalidParams.Add(request.NewErrParamRequired("OutputSchemaVersion"))
+	}
+	if s.Destination != nil {
+		if err := s.Destination.Validate(); err != nil {
+			invalidParams.AddNested("Destination", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetDestination sets the Destination field's value.
+func (s *StorageClassAnalysisDataExport) SetDestination(v *AnalyticsExportDestination) *StorageClassAnalysisDataExport {
+	s.Destination = v
+	return s
+}
+
+// SetOutputSchemaVersion sets the OutputSchemaVersion field's value.
+func (s *StorageClassAnalysisDataExport) SetOutputSchemaVersion(v string) *StorageClassAnalysisDataExport {
+	s.OutputSchemaVersion = &v
+	return s
+}
+
+type Tag struct {
+	_ struct{} `type:"structure"`
+
+	// Name of the tag.
+	//
+	// Key is a required field
+	Key *string `min:"1" type:"string" required:"true"`
+
+	// Value of the tag.
+	//
+	// Value is a required field
+	Value *string `type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s Tag) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s Tag) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *Tag) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "Tag"}
+	if s.Key == nil {
+		invalidParams.Add(request.NewErrParamRequired("Key"))
+	}
+	if s.Key != nil && len(*s.Key) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
+	}
+	if s.Value == nil {
+		invalidParams.Add(request.NewErrParamRequired("Value"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetKey sets the Key field's value.
+func (s *Tag) SetKey(v string) *Tag {
+	s.Key = &v
+	return s
+}
+
+// SetValue sets the Value field's value.
+func (s *Tag) SetValue(v string) *Tag {
+	s.Value = &v
+	return s
+}
+
+type Tagging struct {
+	_ struct{} `type:"structure"`
+
+	// TagSet is a required field
+	TagSet []*Tag `locationNameList:"Tag" type:"list" required:"true"`
+}
+
+// String returns the string representation
+func (s Tagging) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s Tagging) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *Tagging) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "Tagging"}
+	if s.TagSet == nil {
+		invalidParams.Add(request.NewErrParamRequired("TagSet"))
+	}
+	if s.TagSet != nil {
+		for i, v := range s.TagSet {
+			if v == nil {
+				continue
+			}
+			if err := v.Validate(); err != nil {
+				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "TagSet", i), err.(request.ErrInvalidParams))
+			}
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetTagSet sets the TagSet field's value.
+func (s *Tagging) SetTagSet(v []*Tag) *Tagging {
+	s.TagSet = v
+	return s
+}
+
+type TargetGrant struct {
+	_ struct{} `type:"structure"`
+
+	Grantee *Grantee `type:"structure" xmlPrefix:"xsi" xmlURI:"http://www.w3.org/2001/XMLSchema-instance"`
+
+	// Logging permissions assigned to the Grantee for the bucket.
+	Permission *string `type:"string" enum:"BucketLogsPermission"`
+}
+
+// String returns the string representation
+func (s TargetGrant) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s TargetGrant) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *TargetGrant) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "TargetGrant"}
+	if s.Grantee != nil {
+		if err := s.Grantee.Validate(); err != nil {
+			invalidParams.AddNested("Grantee", err.(request.ErrInvalidParams))
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetGrantee sets the Grantee field's value.
+func (s *TargetGrant) SetGrantee(v *Grantee) *TargetGrant {
+	s.Grantee = v
+	return s
+}
+
+// SetPermission sets the Permission field's value.
+func (s *TargetGrant) SetPermission(v string) *TargetGrant {
+	s.Permission = &v
+	return s
+}
+
+// Container for specifying the configuration when you want Amazon S3 to publish
+// events to an Amazon Simple Notification Service (Amazon SNS) topic.
+type TopicConfiguration struct {
+	_ struct{} `type:"structure"`
+
+	// Events is a required field
+	Events []*string `locationName:"Event" type:"list" flattened:"true" required:"true"`
+
+	// Container for object key name filtering rules. For information about key
+	// name filtering, go to Configuring Event Notifications (http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html)
+	// in the Amazon Simple Storage Service Developer Guide.
+	Filter *NotificationConfigurationFilter `type:"structure"`
+
+	// Optional unique identifier for configurations in a notification configuration.
+	// If you don't provide one, Amazon S3 will assign an ID.
+	Id *string `type:"string"`
+
+	// Amazon SNS topic ARN to which Amazon S3 will publish a message when it detects
+	// events of specified type.
+	//
+	// TopicArn is a required field
+	TopicArn *string `locationName:"Topic" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s TopicConfiguration) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s TopicConfiguration) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *TopicConfiguration) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "TopicConfiguration"}
+	if s.Events == nil {
+		invalidParams.Add(request.NewErrParamRequired("Events"))
+	}
+	if s.TopicArn == nil {
+		invalidParams.Add(request.NewErrParamRequired("TopicArn"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetEvents sets the Events field's value.
+func (s *TopicConfiguration) SetEvents(v []*string) *TopicConfiguration {
+	s.Events = v
+	return s
+}
+
+// SetFilter sets the Filter field's value.
+func (s *TopicConfiguration) SetFilter(v *NotificationConfigurationFilter) *TopicConfiguration {
+	s.Filter = v
+	return s
+}
+
+// SetId sets the Id field's value.
+func (s *TopicConfiguration) SetId(v string) *TopicConfiguration {
+	s.Id = &v
+	return s
+}
+
+// SetTopicArn sets the TopicArn field's value.
+func (s *TopicConfiguration) SetTopicArn(v string) *TopicConfiguration {
+	s.TopicArn = &v
+	return s
+}
+
+type TopicConfigurationDeprecated struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket event for which to send notifications.
+	Event *string `deprecated:"true" type:"string" enum:"Event"`
+
+	Events []*string `locationName:"Event" type:"list" flattened:"true"`
+
+	// Optional unique identifier for configurations in a notification configuration.
+	// If you don't provide one, Amazon S3 will assign an ID.
+	Id *string `type:"string"`
+
+	// Amazon SNS topic to which Amazon S3 will publish a message to report the
+	// specified events for the bucket.
+	Topic *string `type:"string"`
+}
+
+// String returns the string representation
+func (s TopicConfigurationDeprecated) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s TopicConfigurationDeprecated) GoString() string {
+	return s.String()
+}
+
+// SetEvent sets the Event field's value.
+func (s *TopicConfigurationDeprecated) SetEvent(v string) *TopicConfigurationDeprecated {
+	s.Event = &v
+	return s
+}
+
+// SetEvents sets the Events field's value.
+func (s *TopicConfigurationDeprecated) SetEvents(v []*string) *TopicConfigurationDeprecated {
+	s.Events = v
+	return s
+}
+
+// SetId sets the Id field's value.
+func (s *TopicConfigurationDeprecated) SetId(v string) *TopicConfigurationDeprecated {
+	s.Id = &v
+	return s
+}
+
+// SetTopic sets the Topic field's value.
+func (s *TopicConfigurationDeprecated) SetTopic(v string) *TopicConfigurationDeprecated {
+	s.Topic = &v
+	return s
+}
+
+type Transition struct {
+	_ struct{} `type:"structure"`
+
+	// Indicates at what date the object is to be moved or deleted. Should be in
+	// GMT ISO 8601 Format.
+	Date *time.Time `type:"timestamp" timestampFormat:"iso8601"`
+
+	// Indicates the lifetime, in days, of the objects that are subject to the rule.
+	// The value must be a non-zero positive integer.
+	Days *int64 `type:"integer"`
+
+	// The class of storage used to store the object.
+	StorageClass *string `type:"string" enum:"TransitionStorageClass"`
+}
+
+// String returns the string representation
+func (s Transition) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s Transition) GoString() string {
+	return s.String()
+}
+
+// SetDate sets the Date field's value.
+func (s *Transition) SetDate(v time.Time) *Transition {
+	s.Date = &v
+	return s
+}
+
+// SetDays sets the Days field's value.
+func (s *Transition) SetDays(v int64) *Transition {
+	s.Days = &v
+	return s
+}
+
+// SetStorageClass sets the StorageClass field's value.
+func (s *Transition) SetStorageClass(v string) *Transition {
+	s.StorageClass = &v
+	return s
+}
+
+type UploadPartCopyInput struct {
+	_ struct{} `type:"structure"`
+
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// The name of the source bucket and key name of the source object, separated
+	// by a slash (/). Must be URL-encoded.
+	//
+	// CopySource is a required field
+	CopySource *string `location:"header" locationName:"x-amz-copy-source" type:"string" required:"true"`
+
+	// Copies the object if its entity tag (ETag) matches the specified tag.
+	CopySourceIfMatch *string `location:"header" locationName:"x-amz-copy-source-if-match" type:"string"`
+
+	// Copies the object if it has been modified since the specified time.
+	CopySourceIfModifiedSince *time.Time `location:"header" locationName:"x-amz-copy-source-if-modified-since" type:"timestamp"`
+
+	// Copies the object if its entity tag (ETag) is different than the specified
+	// ETag.
+	CopySourceIfNoneMatch *string `location:"header" locationName:"x-amz-copy-source-if-none-match" type:"string"`
+
+	// Copies the object if it hasn't been modified since the specified time.
+	CopySourceIfUnmodifiedSince *time.Time `location:"header" locationName:"x-amz-copy-source-if-unmodified-since" type:"timestamp"`
+
+	// The range of bytes to copy from the source object. The range value must use
+	// the form bytes=first-last, where the first and last are the zero-based byte
+	// offsets to copy. For example, bytes=0-9 indicates that you want to copy the
+	// first ten bytes of the source. You can copy a range only if the source object
+	// is greater than 5 GB.
+	CopySourceRange *string `location:"header" locationName:"x-amz-copy-source-range" type:"string"`
+
+	// Specifies the algorithm to use when decrypting the source object (e.g., AES256).
+	CopySourceSSECustomerAlgorithm *string `location:"header" locationName:"x-amz-copy-source-server-side-encryption-customer-algorithm" type:"string"`
+
+	// Specifies the customer-provided encryption key for Amazon S3 to use to decrypt
+	// the source object. The encryption key provided in this header must be one
+	// that was used when the source object was created.
+	CopySourceSSECustomerKey *string `location:"header" locationName:"x-amz-copy-source-server-side-encryption-customer-key" type:"string"`
+
+	// Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321.
+	// Amazon S3 uses this header for a message integrity check to ensure the encryption
+	// key was transmitted without error.
+	CopySourceSSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-copy-source-server-side-encryption-customer-key-MD5" type:"string"`
+
+	// Key is a required field
+	Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"`
+
+	// Part number of part being copied. This is a positive integer between 1 and
+	// 10,000.
+	//
+	// PartNumber is a required field
+	PartNumber *int64 `location:"querystring" locationName:"partNumber" type:"integer" required:"true"`
+
+	// Confirms that the requester knows that she or he will be charged for the
+	// request. Bucket owners need not specify this parameter in their requests.
+	// Documentation on downloading objects from requester pays buckets can be found
+	// at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
+	RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"`
+
+	// Specifies the algorithm to use to when encrypting the object (e.g., AES256).
+	SSECustomerAlgorithm *string `location:"header" locationName:"x-amz-server-side-encryption-customer-algorithm" type:"string"`
+
+	// Specifies the customer-provided encryption key for Amazon S3 to use in encrypting
+	// data. This value is used to store the object and then it is discarded; Amazon
+	// does not store the encryption key. The key must be appropriate for use with
+	// the algorithm specified in the x-amz-server-side​-encryption​-customer-algorithm
+	// header. This must be the same encryption key specified in the initiate multipart
+	// upload request.
+	SSECustomerKey *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key" type:"string"`
+
+	// Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321.
+	// Amazon S3 uses this header for a message integrity check to ensure the encryption
+	// key was transmitted without error.
+	SSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key-MD5" type:"string"`
+
+	// Upload ID identifying the multipart upload whose part is being copied.
+	//
+	// UploadId is a required field
+	UploadId *string `location:"querystring" locationName:"uploadId" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s UploadPartCopyInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s UploadPartCopyInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *UploadPartCopyInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "UploadPartCopyInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.CopySource == nil {
+		invalidParams.Add(request.NewErrParamRequired("CopySource"))
+	}
+	if s.Key == nil {
+		invalidParams.Add(request.NewErrParamRequired("Key"))
+	}
+	if s.Key != nil && len(*s.Key) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
+	}
+	if s.PartNumber == nil {
+		invalidParams.Add(request.NewErrParamRequired("PartNumber"))
+	}
+	if s.UploadId == nil {
+		invalidParams.Add(request.NewErrParamRequired("UploadId"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *UploadPartCopyInput) SetBucket(v string) *UploadPartCopyInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *UploadPartCopyInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetCopySource sets the CopySource field's value.
+func (s *UploadPartCopyInput) SetCopySource(v string) *UploadPartCopyInput {
+	s.CopySource = &v
+	return s
+}
+
+// SetCopySourceIfMatch sets the CopySourceIfMatch field's value.
+func (s *UploadPartCopyInput) SetCopySourceIfMatch(v string) *UploadPartCopyInput {
+	s.CopySourceIfMatch = &v
+	return s
+}
+
+// SetCopySourceIfModifiedSince sets the CopySourceIfModifiedSince field's value.
+func (s *UploadPartCopyInput) SetCopySourceIfModifiedSince(v time.Time) *UploadPartCopyInput {
+	s.CopySourceIfModifiedSince = &v
+	return s
+}
+
+// SetCopySourceIfNoneMatch sets the CopySourceIfNoneMatch field's value.
+func (s *UploadPartCopyInput) SetCopySourceIfNoneMatch(v string) *UploadPartCopyInput {
+	s.CopySourceIfNoneMatch = &v
+	return s
+}
+
+// SetCopySourceIfUnmodifiedSince sets the CopySourceIfUnmodifiedSince field's value.
+func (s *UploadPartCopyInput) SetCopySourceIfUnmodifiedSince(v time.Time) *UploadPartCopyInput {
+	s.CopySourceIfUnmodifiedSince = &v
+	return s
+}
+
+// SetCopySourceRange sets the CopySourceRange field's value.
+func (s *UploadPartCopyInput) SetCopySourceRange(v string) *UploadPartCopyInput {
+	s.CopySourceRange = &v
+	return s
+}
+
+// SetCopySourceSSECustomerAlgorithm sets the CopySourceSSECustomerAlgorithm field's value.
+func (s *UploadPartCopyInput) SetCopySourceSSECustomerAlgorithm(v string) *UploadPartCopyInput {
+	s.CopySourceSSECustomerAlgorithm = &v
+	return s
+}
+
+// SetCopySourceSSECustomerKey sets the CopySourceSSECustomerKey field's value.
+func (s *UploadPartCopyInput) SetCopySourceSSECustomerKey(v string) *UploadPartCopyInput {
+	s.CopySourceSSECustomerKey = &v
+	return s
+}
+
+func (s *UploadPartCopyInput) getCopySourceSSECustomerKey() (v string) {
+	if s.CopySourceSSECustomerKey == nil {
+		return v
+	}
+	return *s.CopySourceSSECustomerKey
+}
+
+// SetCopySourceSSECustomerKeyMD5 sets the CopySourceSSECustomerKeyMD5 field's value.
+func (s *UploadPartCopyInput) SetCopySourceSSECustomerKeyMD5(v string) *UploadPartCopyInput {
+	s.CopySourceSSECustomerKeyMD5 = &v
+	return s
+}
+
+// SetKey sets the Key field's value.
+func (s *UploadPartCopyInput) SetKey(v string) *UploadPartCopyInput {
+	s.Key = &v
+	return s
+}
+
+// SetPartNumber sets the PartNumber field's value.
+func (s *UploadPartCopyInput) SetPartNumber(v int64) *UploadPartCopyInput {
+	s.PartNumber = &v
+	return s
+}
+
+// SetRequestPayer sets the RequestPayer field's value.
+func (s *UploadPartCopyInput) SetRequestPayer(v string) *UploadPartCopyInput {
+	s.RequestPayer = &v
+	return s
+}
+
+// SetSSECustomerAlgorithm sets the SSECustomerAlgorithm field's value.
+func (s *UploadPartCopyInput) SetSSECustomerAlgorithm(v string) *UploadPartCopyInput {
+	s.SSECustomerAlgorithm = &v
+	return s
+}
+
+// SetSSECustomerKey sets the SSECustomerKey field's value.
+func (s *UploadPartCopyInput) SetSSECustomerKey(v string) *UploadPartCopyInput {
+	s.SSECustomerKey = &v
+	return s
+}
+
+func (s *UploadPartCopyInput) getSSECustomerKey() (v string) {
+	if s.SSECustomerKey == nil {
+		return v
+	}
+	return *s.SSECustomerKey
+}
+
+// SetSSECustomerKeyMD5 sets the SSECustomerKeyMD5 field's value.
+func (s *UploadPartCopyInput) SetSSECustomerKeyMD5(v string) *UploadPartCopyInput {
+	s.SSECustomerKeyMD5 = &v
+	return s
+}
+
+// SetUploadId sets the UploadId field's value.
+func (s *UploadPartCopyInput) SetUploadId(v string) *UploadPartCopyInput {
+	s.UploadId = &v
+	return s
+}
+
+type UploadPartCopyOutput struct {
+	_ struct{} `type:"structure" payload:"CopyPartResult"`
+
+	CopyPartResult *CopyPartResult `type:"structure"`
+
+	// The version of the source object that was copied, if you have enabled versioning
+	// on the source bucket.
+	CopySourceVersionId *string `location:"header" locationName:"x-amz-copy-source-version-id" type:"string"`
+
+	// If present, indicates that the requester was successfully charged for the
+	// request.
+	RequestCharged *string `location:"header" locationName:"x-amz-request-charged" type:"string" enum:"RequestCharged"`
+
+	// If server-side encryption with a customer-provided encryption key was requested,
+	// the response will include this header confirming the encryption algorithm
+	// used.
+	SSECustomerAlgorithm *string `location:"header" locationName:"x-amz-server-side-encryption-customer-algorithm" type:"string"`
+
+	// If server-side encryption with a customer-provided encryption key was requested,
+	// the response will include this header to provide round trip message integrity
+	// verification of the customer-provided encryption key.
+	SSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key-MD5" type:"string"`
+
+	// If present, specifies the ID of the AWS Key Management Service (KMS) master
+	// encryption key that was used for the object.
+	SSEKMSKeyId *string `location:"header" locationName:"x-amz-server-side-encryption-aws-kms-key-id" type:"string"`
+
+	// The Server-side encryption algorithm used when storing this object in S3
+	// (e.g., AES256, aws:kms).
+	ServerSideEncryption *string `location:"header" locationName:"x-amz-server-side-encryption" type:"string" enum:"ServerSideEncryption"`
+}
+
+// String returns the string representation
+func (s UploadPartCopyOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s UploadPartCopyOutput) GoString() string {
+	return s.String()
+}
+
+// SetCopyPartResult sets the CopyPartResult field's value.
+func (s *UploadPartCopyOutput) SetCopyPartResult(v *CopyPartResult) *UploadPartCopyOutput {
+	s.CopyPartResult = v
+	return s
+}
+
+// SetCopySourceVersionId sets the CopySourceVersionId field's value.
+func (s *UploadPartCopyOutput) SetCopySourceVersionId(v string) *UploadPartCopyOutput {
+	s.CopySourceVersionId = &v
+	return s
+}
+
+// SetRequestCharged sets the RequestCharged field's value.
+func (s *UploadPartCopyOutput) SetRequestCharged(v string) *UploadPartCopyOutput {
+	s.RequestCharged = &v
+	return s
+}
+
+// SetSSECustomerAlgorithm sets the SSECustomerAlgorithm field's value.
+func (s *UploadPartCopyOutput) SetSSECustomerAlgorithm(v string) *UploadPartCopyOutput {
+	s.SSECustomerAlgorithm = &v
+	return s
+}
+
+// SetSSECustomerKeyMD5 sets the SSECustomerKeyMD5 field's value.
+func (s *UploadPartCopyOutput) SetSSECustomerKeyMD5(v string) *UploadPartCopyOutput {
+	s.SSECustomerKeyMD5 = &v
+	return s
+}
+
+// SetSSEKMSKeyId sets the SSEKMSKeyId field's value.
+func (s *UploadPartCopyOutput) SetSSEKMSKeyId(v string) *UploadPartCopyOutput {
+	s.SSEKMSKeyId = &v
+	return s
+}
+
+// SetServerSideEncryption sets the ServerSideEncryption field's value.
+func (s *UploadPartCopyOutput) SetServerSideEncryption(v string) *UploadPartCopyOutput {
+	s.ServerSideEncryption = &v
+	return s
+}
+
+type UploadPartInput struct {
+	_ struct{} `type:"structure" payload:"Body"`
+
+	// Object data.
+	Body io.ReadSeeker `type:"blob"`
+
+	// Name of the bucket to which the multipart upload was initiated.
+	//
+	// Bucket is a required field
+	Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`
+
+	// Size of the body in bytes. This parameter is useful when the size of the
+	// body cannot be determined automatically.
+	ContentLength *int64 `location:"header" locationName:"Content-Length" type:"long"`
+
+	// The base64-encoded 128-bit MD5 digest of the part data.
+	ContentMD5 *string `location:"header" locationName:"Content-MD5" type:"string"`
+
+	// Object key for which the multipart upload was initiated.
+	//
+	// Key is a required field
+	Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"`
+
+	// Part number of part being uploaded. This is a positive integer between 1
+	// and 10,000.
+	//
+	// PartNumber is a required field
+	PartNumber *int64 `location:"querystring" locationName:"partNumber" type:"integer" required:"true"`
+
+	// Confirms that the requester knows that she or he will be charged for the
+	// request. Bucket owners need not specify this parameter in their requests.
+	// Documentation on downloading objects from requester pays buckets can be found
+	// at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
+	RequestPayer *string `location:"header" locationName:"x-amz-request-payer" type:"string" enum:"RequestPayer"`
+
+	// Specifies the algorithm to use to when encrypting the object (e.g., AES256).
+	SSECustomerAlgorithm *string `location:"header" locationName:"x-amz-server-side-encryption-customer-algorithm" type:"string"`
+
+	// Specifies the customer-provided encryption key for Amazon S3 to use in encrypting
+	// data. This value is used to store the object and then it is discarded; Amazon
+	// does not store the encryption key. The key must be appropriate for use with
+	// the algorithm specified in the x-amz-server-side​-encryption​-customer-algorithm
+	// header. This must be the same encryption key specified in the initiate multipart
+	// upload request.
+	SSECustomerKey *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key" type:"string"`
+
+	// Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321.
+	// Amazon S3 uses this header for a message integrity check to ensure the encryption
+	// key was transmitted without error.
+	SSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key-MD5" type:"string"`
+
+	// Upload ID identifying the multipart upload whose part is being uploaded.
+	//
+	// UploadId is a required field
+	UploadId *string `location:"querystring" locationName:"uploadId" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s UploadPartInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s UploadPartInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *UploadPartInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "UploadPartInput"}
+	if s.Bucket == nil {
+		invalidParams.Add(request.NewErrParamRequired("Bucket"))
+	}
+	if s.Key == nil {
+		invalidParams.Add(request.NewErrParamRequired("Key"))
+	}
+	if s.Key != nil && len(*s.Key) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
+	}
+	if s.PartNumber == nil {
+		invalidParams.Add(request.NewErrParamRequired("PartNumber"))
+	}
+	if s.UploadId == nil {
+		invalidParams.Add(request.NewErrParamRequired("UploadId"))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetBody sets the Body field's value.
+func (s *UploadPartInput) SetBody(v io.ReadSeeker) *UploadPartInput {
+	s.Body = v
+	return s
+}
+
+// SetBucket sets the Bucket field's value.
+func (s *UploadPartInput) SetBucket(v string) *UploadPartInput {
+	s.Bucket = &v
+	return s
+}
+
+func (s *UploadPartInput) getBucket() (v string) {
+	if s.Bucket == nil {
+		return v
+	}
+	return *s.Bucket
+}
+
+// SetContentLength sets the ContentLength field's value.
+func (s *UploadPartInput) SetContentLength(v int64) *UploadPartInput {
+	s.ContentLength = &v
+	return s
+}
+
+// SetContentMD5 sets the ContentMD5 field's value.
+func (s *UploadPartInput) SetContentMD5(v string) *UploadPartInput {
+	s.ContentMD5 = &v
+	return s
+}
+
+// SetKey sets the Key field's value.
+func (s *UploadPartInput) SetKey(v string) *UploadPartInput {
+	s.Key = &v
+	return s
+}
+
+// SetPartNumber sets the PartNumber field's value.
+func (s *UploadPartInput) SetPartNumber(v int64) *UploadPartInput {
+	s.PartNumber = &v
+	return s
+}
+
+// SetRequestPayer sets the RequestPayer field's value.
+func (s *UploadPartInput) SetRequestPayer(v string) *UploadPartInput {
+	s.RequestPayer = &v
+	return s
+}
+
+// SetSSECustomerAlgorithm sets the SSECustomerAlgorithm field's value.
+func (s *UploadPartInput) SetSSECustomerAlgorithm(v string) *UploadPartInput {
+	s.SSECustomerAlgorithm = &v
+	return s
+}
+
+// SetSSECustomerKey sets the SSECustomerKey field's value.
+func (s *UploadPartInput) SetSSECustomerKey(v string) *UploadPartInput {
+	s.SSECustomerKey = &v
+	return s
+}
+
+func (s *UploadPartInput) getSSECustomerKey() (v string) {
+	if s.SSECustomerKey == nil {
+		return v
+	}
+	return *s.SSECustomerKey
+}
+
+// SetSSECustomerKeyMD5 sets the SSECustomerKeyMD5 field's value.
+func (s *UploadPartInput) SetSSECustomerKeyMD5(v string) *UploadPartInput {
+	s.SSECustomerKeyMD5 = &v
+	return s
+}
+
+// SetUploadId sets the UploadId field's value.
+func (s *UploadPartInput) SetUploadId(v string) *UploadPartInput {
+	s.UploadId = &v
+	return s
+}
+
+type UploadPartOutput struct {
+	_ struct{} `type:"structure"`
+
+	// Entity tag for the uploaded object.
+	ETag *string `location:"header" locationName:"ETag" type:"string"`
+
+	// If present, indicates that the requester was successfully charged for the
+	// request.
+	RequestCharged *string `location:"header" locationName:"x-amz-request-charged" type:"string" enum:"RequestCharged"`
+
+	// If server-side encryption with a customer-provided encryption key was requested,
+	// the response will include this header confirming the encryption algorithm
+	// used.
+	SSECustomerAlgorithm *string `location:"header" locationName:"x-amz-server-side-encryption-customer-algorithm" type:"string"`
+
+	// If server-side encryption with a customer-provided encryption key was requested,
+	// the response will include this header to provide round trip message integrity
+	// verification of the customer-provided encryption key.
+	SSECustomerKeyMD5 *string `location:"header" locationName:"x-amz-server-side-encryption-customer-key-MD5" type:"string"`
+
+	// If present, specifies the ID of the AWS Key Management Service (KMS) master
+	// encryption key that was used for the object.
+	SSEKMSKeyId *string `location:"header" locationName:"x-amz-server-side-encryption-aws-kms-key-id" type:"string"`
+
+	// The Server-side encryption algorithm used when storing this object in S3
+	// (e.g., AES256, aws:kms).
+	ServerSideEncryption *string `location:"header" locationName:"x-amz-server-side-encryption" type:"string" enum:"ServerSideEncryption"`
+}
+
+// String returns the string representation
+func (s UploadPartOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s UploadPartOutput) GoString() string {
+	return s.String()
+}
+
+// SetETag sets the ETag field's value.
+func (s *UploadPartOutput) SetETag(v string) *UploadPartOutput {
+	s.ETag = &v
+	return s
+}
+
+// SetRequestCharged sets the RequestCharged field's value.
+func (s *UploadPartOutput) SetRequestCharged(v string) *UploadPartOutput {
+	s.RequestCharged = &v
+	return s
+}
+
+// SetSSECustomerAlgorithm sets the SSECustomerAlgorithm field's value.
+func (s *UploadPartOutput) SetSSECustomerAlgorithm(v string) *UploadPartOutput {
+	s.SSECustomerAlgorithm = &v
+	return s
+}
+
+// SetSSECustomerKeyMD5 sets the SSECustomerKeyMD5 field's value.
+func (s *UploadPartOutput) SetSSECustomerKeyMD5(v string) *UploadPartOutput {
+	s.SSECustomerKeyMD5 = &v
+	return s
+}
+
+// SetSSEKMSKeyId sets the SSEKMSKeyId field's value.
+func (s *UploadPartOutput) SetSSEKMSKeyId(v string) *UploadPartOutput {
+	s.SSEKMSKeyId = &v
+	return s
+}
+
+// SetServerSideEncryption sets the ServerSideEncryption field's value.
+func (s *UploadPartOutput) SetServerSideEncryption(v string) *UploadPartOutput {
+	s.ServerSideEncryption = &v
+	return s
+}
+
+type VersioningConfiguration struct {
+	_ struct{} `type:"structure"`
+
+	// Specifies whether MFA delete is enabled in the bucket versioning configuration.
+	// This element is only returned if the bucket has been configured with MFA
+	// delete. If the bucket has never been so configured, this element is not returned.
+	MFADelete *string `locationName:"MfaDelete" type:"string" enum:"MFADelete"`
+
+	// The versioning state of the bucket.
+	Status *string `type:"string" enum:"BucketVersioningStatus"`
+}
+
+// String returns the string representation
+func (s VersioningConfiguration) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s VersioningConfiguration) GoString() string {
+	return s.String()
+}
+
+// SetMFADelete sets the MFADelete field's value.
+func (s *VersioningConfiguration) SetMFADelete(v string) *VersioningConfiguration {
+	s.MFADelete = &v
+	return s
+}
+
+// SetStatus sets the Status field's value.
+func (s *VersioningConfiguration) SetStatus(v string) *VersioningConfiguration {
+	s.Status = &v
+	return s
+}
+
+type WebsiteConfiguration struct {
+	_ struct{} `type:"structure"`
+
+	ErrorDocument *ErrorDocument `type:"structure"`
+
+	IndexDocument *IndexDocument `type:"structure"`
+
+	RedirectAllRequestsTo *RedirectAllRequestsTo `type:"structure"`
+
+	RoutingRules []*RoutingRule `locationNameList:"RoutingRule" type:"list"`
+}
+
+// String returns the string representation
+func (s WebsiteConfiguration) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s WebsiteConfiguration) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *WebsiteConfiguration) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "WebsiteConfiguration"}
+	if s.ErrorDocument != nil {
+		if err := s.ErrorDocument.Validate(); err != nil {
+			invalidParams.AddNested("ErrorDocument", err.(request.ErrInvalidParams))
+		}
+	}
+	if s.IndexDocument != nil {
+		if err := s.IndexDocument.Validate(); err != nil {
+			invalidParams.AddNested("IndexDocument", err.(request.ErrInvalidParams))
+		}
+	}
+	if s.RedirectAllRequestsTo != nil {
+		if err := s.RedirectAllRequestsTo.Validate(); err != nil {
+			invalidParams.AddNested("RedirectAllRequestsTo", err.(request.ErrInvalidParams))
+		}
+	}
+	if s.RoutingRules != nil {
+		for i, v := range s.RoutingRules {
+			if v == nil {
+				continue
+			}
+			if err := v.Validate(); err != nil {
+				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "RoutingRules", i), err.(request.ErrInvalidParams))
+			}
+		}
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetErrorDocument sets the ErrorDocument field's value.
+func (s *WebsiteConfiguration) SetErrorDocument(v *ErrorDocument) *WebsiteConfiguration {
+	s.ErrorDocument = v
+	return s
+}
+
+// SetIndexDocument sets the IndexDocument field's value.
+func (s *WebsiteConfiguration) SetIndexDocument(v *IndexDocument) *WebsiteConfiguration {
+	s.IndexDocument = v
+	return s
+}
+
+// SetRedirectAllRequestsTo sets the RedirectAllRequestsTo field's value.
+func (s *WebsiteConfiguration) SetRedirectAllRequestsTo(v *RedirectAllRequestsTo) *WebsiteConfiguration {
+	s.RedirectAllRequestsTo = v
+	return s
+}
+
+// SetRoutingRules sets the RoutingRules field's value.
+func (s *WebsiteConfiguration) SetRoutingRules(v []*RoutingRule) *WebsiteConfiguration {
+	s.RoutingRules = v
+	return s
+}
+
+const (
+	// AnalyticsS3ExportFileFormatCsv is a AnalyticsS3ExportFileFormat enum value
+	AnalyticsS3ExportFileFormatCsv = "CSV"
+)
+
+const (
+	// BucketAccelerateStatusEnabled is a BucketAccelerateStatus enum value
+	BucketAccelerateStatusEnabled = "Enabled"
+
+	// BucketAccelerateStatusSuspended is a BucketAccelerateStatus enum value
+	BucketAccelerateStatusSuspended = "Suspended"
+)
+
+const (
+	// BucketCannedACLPrivate is a BucketCannedACL enum value
+	BucketCannedACLPrivate = "private"
+
+	// BucketCannedACLPublicRead is a BucketCannedACL enum value
+	BucketCannedACLPublicRead = "public-read"
+
+	// BucketCannedACLPublicReadWrite is a BucketCannedACL enum value
+	BucketCannedACLPublicReadWrite = "public-read-write"
+
+	// BucketCannedACLAuthenticatedRead is a BucketCannedACL enum value
+	BucketCannedACLAuthenticatedRead = "authenticated-read"
+)
+
+const (
+	// BucketLocationConstraintEu is a BucketLocationConstraint enum value
+	BucketLocationConstraintEu = "EU"
+
+	// BucketLocationConstraintEuWest1 is a BucketLocationConstraint enum value
+	BucketLocationConstraintEuWest1 = "eu-west-1"
+
+	// BucketLocationConstraintUsWest1 is a BucketLocationConstraint enum value
+	BucketLocationConstraintUsWest1 = "us-west-1"
+
+	// BucketLocationConstraintUsWest2 is a BucketLocationConstraint enum value
+	BucketLocationConstraintUsWest2 = "us-west-2"
+
+	// BucketLocationConstraintApSouth1 is a BucketLocationConstraint enum value
+	BucketLocationConstraintApSouth1 = "ap-south-1"
+
+	// BucketLocationConstraintApSoutheast1 is a BucketLocationConstraint enum value
+	BucketLocationConstraintApSoutheast1 = "ap-southeast-1"
+
+	// BucketLocationConstraintApSoutheast2 is a BucketLocationConstraint enum value
+	BucketLocationConstraintApSoutheast2 = "ap-southeast-2"
+
+	// BucketLocationConstraintApNortheast1 is a BucketLocationConstraint enum value
+	BucketLocationConstraintApNortheast1 = "ap-northeast-1"
+
+	// BucketLocationConstraintSaEast1 is a BucketLocationConstraint enum value
+	BucketLocationConstraintSaEast1 = "sa-east-1"
+
+	// BucketLocationConstraintCnNorth1 is a BucketLocationConstraint enum value
+	BucketLocationConstraintCnNorth1 = "cn-north-1"
+
+	// BucketLocationConstraintEuCentral1 is a BucketLocationConstraint enum value
+	BucketLocationConstraintEuCentral1 = "eu-central-1"
+)
+
+const (
+	// BucketLogsPermissionFullControl is a BucketLogsPermission enum value
+	BucketLogsPermissionFullControl = "FULL_CONTROL"
+
+	// BucketLogsPermissionRead is a BucketLogsPermission enum value
+	BucketLogsPermissionRead = "READ"
+
+	// BucketLogsPermissionWrite is a BucketLogsPermission enum value
+	BucketLogsPermissionWrite = "WRITE"
+)
+
+const (
+	// BucketVersioningStatusEnabled is a BucketVersioningStatus enum value
+	BucketVersioningStatusEnabled = "Enabled"
+
+	// BucketVersioningStatusSuspended is a BucketVersioningStatus enum value
+	BucketVersioningStatusSuspended = "Suspended"
+)
+
+const (
+	// CompressionTypeNone is a CompressionType enum value
+	CompressionTypeNone = "NONE"
+
+	// CompressionTypeGzip is a CompressionType enum value
+	CompressionTypeGzip = "GZIP"
+
+	// CompressionTypeBzip2 is a CompressionType enum value
+	CompressionTypeBzip2 = "BZIP2"
+)
+
+// Requests Amazon S3 to encode the object keys in the response and specifies
+// the encoding method to use. An object key may contain any Unicode character;
+// however, XML 1.0 parser cannot parse some characters, such as characters
+// with an ASCII value from 0 to 10. For characters that are not supported in
+// XML 1.0, you can add this parameter to request that Amazon S3 encode the
+// keys in the response.
+const (
+	// EncodingTypeUrl is a EncodingType enum value
+	EncodingTypeUrl = "url"
+)
+
+// Bucket event for which to send notifications.
+const (
+	// EventS3ReducedRedundancyLostObject is a Event enum value
+	EventS3ReducedRedundancyLostObject = "s3:ReducedRedundancyLostObject"
+
+	// EventS3ObjectCreated is a Event enum value
+	EventS3ObjectCreated = "s3:ObjectCreated:*"
+
+	// EventS3ObjectCreatedPut is a Event enum value
+	EventS3ObjectCreatedPut = "s3:ObjectCreated:Put"
+
+	// EventS3ObjectCreatedPost is a Event enum value
+	EventS3ObjectCreatedPost = "s3:ObjectCreated:Post"
+
+	// EventS3ObjectCreatedCopy is a Event enum value
+	EventS3ObjectCreatedCopy = "s3:ObjectCreated:Copy"
+
+	// EventS3ObjectCreatedCompleteMultipartUpload is a Event enum value
+	EventS3ObjectCreatedCompleteMultipartUpload = "s3:ObjectCreated:CompleteMultipartUpload"
+
+	// EventS3ObjectRemoved is a Event enum value
+	EventS3ObjectRemoved = "s3:ObjectRemoved:*"
+
+	// EventS3ObjectRemovedDelete is a Event enum value
+	EventS3ObjectRemovedDelete = "s3:ObjectRemoved:Delete"
+
+	// EventS3ObjectRemovedDeleteMarkerCreated is a Event enum value
+	EventS3ObjectRemovedDeleteMarkerCreated = "s3:ObjectRemoved:DeleteMarkerCreated"
+)
+
+const (
+	// ExpirationStatusEnabled is a ExpirationStatus enum value
+	ExpirationStatusEnabled = "Enabled"
+
+	// ExpirationStatusDisabled is a ExpirationStatus enum value
+	ExpirationStatusDisabled = "Disabled"
+)
+
+const (
+	// ExpressionTypeSql is a ExpressionType enum value
+	ExpressionTypeSql = "SQL"
+)
+
+const (
+	// FileHeaderInfoUse is a FileHeaderInfo enum value
+	FileHeaderInfoUse = "USE"
+
+	// FileHeaderInfoIgnore is a FileHeaderInfo enum value
+	FileHeaderInfoIgnore = "IGNORE"
+
+	// FileHeaderInfoNone is a FileHeaderInfo enum value
+	FileHeaderInfoNone = "NONE"
+)
+
+const (
+	// FilterRuleNamePrefix is a FilterRuleName enum value
+	FilterRuleNamePrefix = "prefix"
+
+	// FilterRuleNameSuffix is a FilterRuleName enum value
+	FilterRuleNameSuffix = "suffix"
+)
+
+const (
+	// InventoryFormatCsv is a InventoryFormat enum value
+	InventoryFormatCsv = "CSV"
+
+	// InventoryFormatOrc is a InventoryFormat enum value
+	InventoryFormatOrc = "ORC"
+)
+
+const (
+	// InventoryFrequencyDaily is a InventoryFrequency enum value
+	InventoryFrequencyDaily = "Daily"
+
+	// InventoryFrequencyWeekly is a InventoryFrequency enum value
+	InventoryFrequencyWeekly = "Weekly"
+)
+
+const (
+	// InventoryIncludedObjectVersionsAll is a InventoryIncludedObjectVersions enum value
+	InventoryIncludedObjectVersionsAll = "All"
+
+	// InventoryIncludedObjectVersionsCurrent is a InventoryIncludedObjectVersions enum value
+	InventoryIncludedObjectVersionsCurrent = "Current"
+)
+
+const (
+	// InventoryOptionalFieldSize is a InventoryOptionalField enum value
+	InventoryOptionalFieldSize = "Size"
+
+	// InventoryOptionalFieldLastModifiedDate is a InventoryOptionalField enum value
+	InventoryOptionalFieldLastModifiedDate = "LastModifiedDate"
+
+	// InventoryOptionalFieldStorageClass is a InventoryOptionalField enum value
+	InventoryOptionalFieldStorageClass = "StorageClass"
+
+	// InventoryOptionalFieldEtag is a InventoryOptionalField enum value
+	InventoryOptionalFieldEtag = "ETag"
+
+	// InventoryOptionalFieldIsMultipartUploaded is a InventoryOptionalField enum value
+	InventoryOptionalFieldIsMultipartUploaded = "IsMultipartUploaded"
+
+	// InventoryOptionalFieldReplicationStatus is a InventoryOptionalField enum value
+	InventoryOptionalFieldReplicationStatus = "ReplicationStatus"
+
+	// InventoryOptionalFieldEncryptionStatus is a InventoryOptionalField enum value
+	InventoryOptionalFieldEncryptionStatus = "EncryptionStatus"
+)
+
+const (
+	// JSONTypeDocument is a JSONType enum value
+	JSONTypeDocument = "DOCUMENT"
+
+	// JSONTypeLines is a JSONType enum value
+	JSONTypeLines = "LINES"
+)
+
+const (
+	// MFADeleteEnabled is a MFADelete enum value
+	MFADeleteEnabled = "Enabled"
+
+	// MFADeleteDisabled is a MFADelete enum value
+	MFADeleteDisabled = "Disabled"
+)
+
+const (
+	// MFADeleteStatusEnabled is a MFADeleteStatus enum value
+	MFADeleteStatusEnabled = "Enabled"
+
+	// MFADeleteStatusDisabled is a MFADeleteStatus enum value
+	MFADeleteStatusDisabled = "Disabled"
+)
+
+const (
+	// MetadataDirectiveCopy is a MetadataDirective enum value
+	MetadataDirectiveCopy = "COPY"
+
+	// MetadataDirectiveReplace is a MetadataDirective enum value
+	MetadataDirectiveReplace = "REPLACE"
+)
+
+const (
+	// ObjectCannedACLPrivate is a ObjectCannedACL enum value
+	ObjectCannedACLPrivate = "private"
+
+	// ObjectCannedACLPublicRead is a ObjectCannedACL enum value
+	ObjectCannedACLPublicRead = "public-read"
+
+	// ObjectCannedACLPublicReadWrite is a ObjectCannedACL enum value
+	ObjectCannedACLPublicReadWrite = "public-read-write"
+
+	// ObjectCannedACLAuthenticatedRead is a ObjectCannedACL enum value
+	ObjectCannedACLAuthenticatedRead = "authenticated-read"
+
+	// ObjectCannedACLAwsExecRead is a ObjectCannedACL enum value
+	ObjectCannedACLAwsExecRead = "aws-exec-read"
+
+	// ObjectCannedACLBucketOwnerRead is a ObjectCannedACL enum value
+	ObjectCannedACLBucketOwnerRead = "bucket-owner-read"
+
+	// ObjectCannedACLBucketOwnerFullControl is a ObjectCannedACL enum value
+	ObjectCannedACLBucketOwnerFullControl = "bucket-owner-full-control"
+)
+
+const (
+	// ObjectStorageClassStandard is a ObjectStorageClass enum value
+	ObjectStorageClassStandard = "STANDARD"
+
+	// ObjectStorageClassReducedRedundancy is a ObjectStorageClass enum value
+	ObjectStorageClassReducedRedundancy = "REDUCED_REDUNDANCY"
+
+	// ObjectStorageClassGlacier is a ObjectStorageClass enum value
+	ObjectStorageClassGlacier = "GLACIER"
+
+	// ObjectStorageClassStandardIa is a ObjectStorageClass enum value
+	ObjectStorageClassStandardIa = "STANDARD_IA"
+
+	// ObjectStorageClassOnezoneIa is a ObjectStorageClass enum value
+	ObjectStorageClassOnezoneIa = "ONEZONE_IA"
+)
+
+const (
+	// ObjectVersionStorageClassStandard is a ObjectVersionStorageClass enum value
+	ObjectVersionStorageClassStandard = "STANDARD"
+)
+
+const (
+	// OwnerOverrideDestination is a OwnerOverride enum value
+	OwnerOverrideDestination = "Destination"
+)
+
+const (
+	// PayerRequester is a Payer enum value
+	PayerRequester = "Requester"
+
+	// PayerBucketOwner is a Payer enum value
+	PayerBucketOwner = "BucketOwner"
+)
+
+const (
+	// PermissionFullControl is a Permission enum value
+	PermissionFullControl = "FULL_CONTROL"
+
+	// PermissionWrite is a Permission enum value
+	PermissionWrite = "WRITE"
+
+	// PermissionWriteAcp is a Permission enum value
+	PermissionWriteAcp = "WRITE_ACP"
+
+	// PermissionRead is a Permission enum value
+	PermissionRead = "READ"
+
+	// PermissionReadAcp is a Permission enum value
+	PermissionReadAcp = "READ_ACP"
+)
+
+const (
+	// ProtocolHttp is a Protocol enum value
+	ProtocolHttp = "http"
+
+	// ProtocolHttps is a Protocol enum value
+	ProtocolHttps = "https"
+)
+
+const (
+	// QuoteFieldsAlways is a QuoteFields enum value
+	QuoteFieldsAlways = "ALWAYS"
+
+	// QuoteFieldsAsneeded is a QuoteFields enum value
+	QuoteFieldsAsneeded = "ASNEEDED"
+)
+
+const (
+	// ReplicationRuleStatusEnabled is a ReplicationRuleStatus enum value
+	ReplicationRuleStatusEnabled = "Enabled"
+
+	// ReplicationRuleStatusDisabled is a ReplicationRuleStatus enum value
+	ReplicationRuleStatusDisabled = "Disabled"
+)
+
+const (
+	// ReplicationStatusComplete is a ReplicationStatus enum value
+	ReplicationStatusComplete = "COMPLETE"
+
+	// ReplicationStatusPending is a ReplicationStatus enum value
+	ReplicationStatusPending = "PENDING"
+
+	// ReplicationStatusFailed is a ReplicationStatus enum value
+	ReplicationStatusFailed = "FAILED"
+
+	// ReplicationStatusReplica is a ReplicationStatus enum value
+	ReplicationStatusReplica = "REPLICA"
+)
+
+// If present, indicates that the requester was successfully charged for the
+// request.
+const (
+	// RequestChargedRequester is a RequestCharged enum value
+	RequestChargedRequester = "requester"
+)
+
+// Confirms that the requester knows that she or he will be charged for the
+// request. Bucket owners need not specify this parameter in their requests.
+// Documentation on downloading objects from requester pays buckets can be found
+// at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
+const (
+	// RequestPayerRequester is a RequestPayer enum value
+	RequestPayerRequester = "requester"
+)
+
+const (
+	// RestoreRequestTypeSelect is a RestoreRequestType enum value
+	RestoreRequestTypeSelect = "SELECT"
+)
+
+const (
+	// ServerSideEncryptionAes256 is a ServerSideEncryption enum value
+	ServerSideEncryptionAes256 = "AES256"
+
+	// ServerSideEncryptionAwsKms is a ServerSideEncryption enum value
+	ServerSideEncryptionAwsKms = "aws:kms"
+)
+
+const (
+	// SseKmsEncryptedObjectsStatusEnabled is a SseKmsEncryptedObjectsStatus enum value
+	SseKmsEncryptedObjectsStatusEnabled = "Enabled"
+
+	// SseKmsEncryptedObjectsStatusDisabled is a SseKmsEncryptedObjectsStatus enum value
+	SseKmsEncryptedObjectsStatusDisabled = "Disabled"
+)
+
+const (
+	// StorageClassStandard is a StorageClass enum value
+	StorageClassStandard = "STANDARD"
+
+	// StorageClassReducedRedundancy is a StorageClass enum value
+	StorageClassReducedRedundancy = "REDUCED_REDUNDANCY"
+
+	// StorageClassStandardIa is a StorageClass enum value
+	StorageClassStandardIa = "STANDARD_IA"
+
+	// StorageClassOnezoneIa is a StorageClass enum value
+	StorageClassOnezoneIa = "ONEZONE_IA"
+)
+
+const (
+	// StorageClassAnalysisSchemaVersionV1 is a StorageClassAnalysisSchemaVersion enum value
+	StorageClassAnalysisSchemaVersionV1 = "V_1"
+)
+
+const (
+	// TaggingDirectiveCopy is a TaggingDirective enum value
+	TaggingDirectiveCopy = "COPY"
+
+	// TaggingDirectiveReplace is a TaggingDirective enum value
+	TaggingDirectiveReplace = "REPLACE"
+)
+
+const (
+	// TierStandard is a Tier enum value
+	TierStandard = "Standard"
+
+	// TierBulk is a Tier enum value
+	TierBulk = "Bulk"
+
+	// TierExpedited is a Tier enum value
+	TierExpedited = "Expedited"
+)
+
+const (
+	// TransitionStorageClassGlacier is a TransitionStorageClass enum value
+	TransitionStorageClassGlacier = "GLACIER"
+
+	// TransitionStorageClassStandardIa is a TransitionStorageClass enum value
+	TransitionStorageClassStandardIa = "STANDARD_IA"
+
+	// TransitionStorageClassOnezoneIa is a TransitionStorageClass enum value
+	TransitionStorageClassOnezoneIa = "ONEZONE_IA"
+)
+
+const (
+	// TypeCanonicalUser is a Type enum value
+	TypeCanonicalUser = "CanonicalUser"
+
+	// TypeAmazonCustomerByEmail is a Type enum value
+	TypeAmazonCustomerByEmail = "AmazonCustomerByEmail"
+
+	// TypeGroup is a Type enum value
+	TypeGroup = "Group"
+)
diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/body_hash.go b/vendor/github.com/aws/aws-sdk-go/service/s3/body_hash.go
new file mode 100644
index 000000000..5c8ce5cc8
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/service/s3/body_hash.go
@@ -0,0 +1,249 @@
+package s3
+
+import (
+	"bytes"
+	"crypto/md5"
+	"crypto/sha256"
+	"encoding/base64"
+	"encoding/hex"
+	"fmt"
+	"hash"
+	"io"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/request"
+	"github.com/aws/aws-sdk-go/internal/sdkio"
+)
+
+const (
+	contentMD5Header    = "Content-Md5"
+	contentSha256Header = "X-Amz-Content-Sha256"
+	amzTeHeader         = "X-Amz-Te"
+	amzTxEncodingHeader = "X-Amz-Transfer-Encoding"
+
+	appendMD5TxEncoding = "append-md5"
+)
+
+// contentMD5 computes and sets the HTTP Content-MD5 header for requests that
+// require it.
+func contentMD5(r *request.Request) {
+	h := md5.New()
+
+	if !aws.IsReaderSeekable(r.Body) {
+		if r.Config.Logger != nil {
+			r.Config.Logger.Log(fmt.Sprintf(
+				"Unable to compute Content-MD5 for unseekable body, S3.%s",
+				r.Operation.Name))
+		}
+		return
+	}
+
+	if _, err := copySeekableBody(h, r.Body); err != nil {
+		r.Error = awserr.New("ContentMD5", "failed to compute body MD5", err)
+		return
+	}
+
+	// encode the md5 checksum in base64 and set the request header.
+	v := base64.StdEncoding.EncodeToString(h.Sum(nil))
+	r.HTTPRequest.Header.Set(contentMD5Header, v)
+}
+
+// computeBodyHashes will add Content MD5 and Content Sha256 hashes to the
+// request. If the body is not seekable or S3DisableContentMD5Validation set
+// this handler will be ignored.
+func computeBodyHashes(r *request.Request) {
+	if aws.BoolValue(r.Config.S3DisableContentMD5Validation) {
+		return
+	}
+	if r.IsPresigned() {
+		return
+	}
+	if r.Error != nil || !aws.IsReaderSeekable(r.Body) {
+		return
+	}
+
+	var md5Hash, sha256Hash hash.Hash
+	hashers := make([]io.Writer, 0, 2)
+
+	// Determine upfront which hashes can be set without overriding user
+	// provide header data.
+	if v := r.HTTPRequest.Header.Get(contentMD5Header); len(v) == 0 {
+		md5Hash = md5.New()
+		hashers = append(hashers, md5Hash)
+	}
+
+	if v := r.HTTPRequest.Header.Get(contentSha256Header); len(v) == 0 {
+		sha256Hash = sha256.New()
+		hashers = append(hashers, sha256Hash)
+	}
+
+	// Create the destination writer based on the hashes that are not already
+	// provided by the user.
+	var dst io.Writer
+	switch len(hashers) {
+	case 0:
+		return
+	case 1:
+		dst = hashers[0]
+	default:
+		dst = io.MultiWriter(hashers...)
+	}
+
+	if _, err := copySeekableBody(dst, r.Body); err != nil {
+		r.Error = awserr.New("BodyHashError", "failed to compute body hashes", err)
+		return
+	}
+
+	// For the hashes created, set the associated headers that the user did not
+	// already provide.
+	if md5Hash != nil {
+		sum := make([]byte, md5.Size)
+		encoded := make([]byte, md5Base64EncLen)
+
+		base64.StdEncoding.Encode(encoded, md5Hash.Sum(sum[0:0]))
+		r.HTTPRequest.Header[contentMD5Header] = []string{string(encoded)}
+	}
+
+	if sha256Hash != nil {
+		encoded := make([]byte, sha256HexEncLen)
+		sum := make([]byte, sha256.Size)
+
+		hex.Encode(encoded, sha256Hash.Sum(sum[0:0]))
+		r.HTTPRequest.Header[contentSha256Header] = []string{string(encoded)}
+	}
+}
+
+const (
+	md5Base64EncLen = (md5.Size + 2) / 3 * 4 // base64.StdEncoding.EncodedLen
+	sha256HexEncLen = sha256.Size * 2        // hex.EncodedLen
+)
+
+func copySeekableBody(dst io.Writer, src io.ReadSeeker) (int64, error) {
+	curPos, err := src.Seek(0, sdkio.SeekCurrent)
+	if err != nil {
+		return 0, err
+	}
+
+	// hash the body.  seek back to the first position after reading to reset
+	// the body for transmission.  copy errors may be assumed to be from the
+	// body.
+	n, err := io.Copy(dst, src)
+	if err != nil {
+		return n, err
+	}
+
+	_, err = src.Seek(curPos, sdkio.SeekStart)
+	if err != nil {
+		return n, err
+	}
+
+	return n, nil
+}
+
+// Adds the x-amz-te: append_md5 header to the request. This requests the service
+// responds with a trailing MD5 checksum.
+//
+// Will not ask for append MD5 if disabled, the request is presigned or,
+// or the API operation does not support content MD5 validation.
+func askForTxEncodingAppendMD5(r *request.Request) {
+	if aws.BoolValue(r.Config.S3DisableContentMD5Validation) {
+		return
+	}
+	if r.IsPresigned() {
+		return
+	}
+	r.HTTPRequest.Header.Set(amzTeHeader, appendMD5TxEncoding)
+}
+
+func useMD5ValidationReader(r *request.Request) {
+	if r.Error != nil {
+		return
+	}
+
+	if v := r.HTTPResponse.Header.Get(amzTxEncodingHeader); v != appendMD5TxEncoding {
+		return
+	}
+
+	var bodyReader *io.ReadCloser
+	var contentLen int64
+	switch tv := r.Data.(type) {
+	case *GetObjectOutput:
+		bodyReader = &tv.Body
+		contentLen = aws.Int64Value(tv.ContentLength)
+		// Update ContentLength hiden the trailing MD5 checksum.
+		tv.ContentLength = aws.Int64(contentLen - md5.Size)
+		tv.ContentRange = aws.String(r.HTTPResponse.Header.Get("X-Amz-Content-Range"))
+	default:
+		r.Error = awserr.New("ChecksumValidationError",
+			fmt.Sprintf("%s: %s header received on unsupported API, %s",
+				amzTxEncodingHeader, appendMD5TxEncoding, r.Operation.Name,
+			), nil)
+		return
+	}
+
+	if contentLen < md5.Size {
+		r.Error = awserr.New("ChecksumValidationError",
+			fmt.Sprintf("invalid Content-Length %d for %s %s",
+				contentLen, appendMD5TxEncoding, amzTxEncodingHeader,
+			), nil)
+		return
+	}
+
+	// Wrap and swap the response body reader with the validation reader.
+	*bodyReader = newMD5ValidationReader(*bodyReader, contentLen-md5.Size)
+}
+
+type md5ValidationReader struct {
+	rawReader io.ReadCloser
+	payload   io.Reader
+	hash      hash.Hash
+
+	payloadLen int64
+	read       int64
+}
+
+func newMD5ValidationReader(reader io.ReadCloser, payloadLen int64) *md5ValidationReader {
+	h := md5.New()
+	return &md5ValidationReader{
+		rawReader:  reader,
+		payload:    io.TeeReader(&io.LimitedReader{R: reader, N: payloadLen}, h),
+		hash:       h,
+		payloadLen: payloadLen,
+	}
+}
+
+func (v *md5ValidationReader) Read(p []byte) (n int, err error) {
+	n, err = v.payload.Read(p)
+	if err != nil && err != io.EOF {
+		return n, err
+	}
+
+	v.read += int64(n)
+
+	if err == io.EOF {
+		if v.read != v.payloadLen {
+			return n, io.ErrUnexpectedEOF
+		}
+		expectSum := make([]byte, md5.Size)
+		actualSum := make([]byte, md5.Size)
+		if _, sumReadErr := io.ReadFull(v.rawReader, expectSum); sumReadErr != nil {
+			return n, sumReadErr
+		}
+		actualSum = v.hash.Sum(actualSum[0:0])
+		if !bytes.Equal(expectSum, actualSum) {
+			return n, awserr.New("InvalidChecksum",
+				fmt.Sprintf("expected MD5 checksum %s, got %s",
+					hex.EncodeToString(expectSum),
+					hex.EncodeToString(actualSum),
+				),
+				nil)
+		}
+	}
+
+	return n, err
+}
+
+func (v *md5ValidationReader) Close() error {
+	return v.rawReader.Close()
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/bucket_location.go b/vendor/github.com/aws/aws-sdk-go/service/s3/bucket_location.go
new file mode 100644
index 000000000..bc68a46ac
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/service/s3/bucket_location.go
@@ -0,0 +1,106 @@
+package s3
+
+import (
+	"io/ioutil"
+	"regexp"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/awsutil"
+	"github.com/aws/aws-sdk-go/aws/request"
+)
+
+var reBucketLocation = regexp.MustCompile(`>([^<>]+)<\/Location`)
+
+// NormalizeBucketLocation is a utility function which will update the
+// passed in value to always be a region ID. Generally this would be used
+// with GetBucketLocation API operation.
+//
+// Replaces empty string with "us-east-1", and "EU" with "eu-west-1".
+//
+// See http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlocation.html
+// for more information on the values that can be returned.
+func NormalizeBucketLocation(loc string) string {
+	switch loc {
+	case "":
+		loc = "us-east-1"
+	case "EU":
+		loc = "eu-west-1"
+	}
+
+	return loc
+}
+
+// NormalizeBucketLocationHandler is a request handler which will update the
+// GetBucketLocation's result LocationConstraint value to always be a region ID.
+//
+// Replaces empty string with "us-east-1", and "EU" with "eu-west-1".
+//
+// See http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlocation.html
+// for more information on the values that can be returned.
+//
+//     req, result := svc.GetBucketLocationRequest(&s3.GetBucketLocationInput{
+//         Bucket: aws.String(bucket),
+//     })
+//     req.Handlers.Unmarshal.PushBackNamed(NormalizeBucketLocationHandler)
+//     err := req.Send()
+var NormalizeBucketLocationHandler = request.NamedHandler{
+	Name: "awssdk.s3.NormalizeBucketLocation",
+	Fn: func(req *request.Request) {
+		if req.Error != nil {
+			return
+		}
+
+		out := req.Data.(*GetBucketLocationOutput)
+		loc := NormalizeBucketLocation(aws.StringValue(out.LocationConstraint))
+		out.LocationConstraint = aws.String(loc)
+	},
+}
+
+// WithNormalizeBucketLocation is a request option which will update the
+// GetBucketLocation's result LocationConstraint value to always be a region ID.
+//
+// Replaces empty string with "us-east-1", and "EU" with "eu-west-1".
+//
+// See http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlocation.html
+// for more information on the values that can be returned.
+//
+//     result, err := svc.GetBucketLocationWithContext(ctx,
+//         &s3.GetBucketLocationInput{
+//             Bucket: aws.String(bucket),
+//         },
+//         s3.WithNormalizeBucketLocation,
+//     )
+func WithNormalizeBucketLocation(r *request.Request) {
+	r.Handlers.Unmarshal.PushBackNamed(NormalizeBucketLocationHandler)
+}
+
+func buildGetBucketLocation(r *request.Request) {
+	if r.DataFilled() {
+		out := r.Data.(*GetBucketLocationOutput)
+		b, err := ioutil.ReadAll(r.HTTPResponse.Body)
+		if err != nil {
+			r.Error = awserr.New("SerializationError", "failed reading response body", err)
+			return
+		}
+
+		match := reBucketLocation.FindSubmatch(b)
+		if len(match) > 1 {
+			loc := string(match[1])
+			out.LocationConstraint = aws.String(loc)
+		}
+	}
+}
+
+func populateLocationConstraint(r *request.Request) {
+	if r.ParamsFilled() && aws.StringValue(r.Config.Region) != "us-east-1" {
+		in := r.Params.(*CreateBucketInput)
+		if in.CreateBucketConfiguration == nil {
+			r.Params = awsutil.CopyOf(r.Params)
+			in = r.Params.(*CreateBucketInput)
+			in.CreateBucketConfiguration = &CreateBucketConfiguration{
+				LocationConstraint: r.Config.Region,
+			}
+		}
+	}
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/customizations.go b/vendor/github.com/aws/aws-sdk-go/service/s3/customizations.go
new file mode 100644
index 000000000..a55beab96
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/service/s3/customizations.go
@@ -0,0 +1,70 @@
+package s3
+
+import (
+	"github.com/aws/aws-sdk-go/aws/client"
+	"github.com/aws/aws-sdk-go/aws/request"
+)
+
+func init() {
+	initClient = defaultInitClientFn
+	initRequest = defaultInitRequestFn
+}
+
+func defaultInitClientFn(c *client.Client) {
+	// Support building custom endpoints based on config
+	c.Handlers.Build.PushFront(updateEndpointForS3Config)
+
+	// Require SSL when using SSE keys
+	c.Handlers.Validate.PushBack(validateSSERequiresSSL)
+	c.Handlers.Build.PushBack(computeSSEKeys)
+
+	// S3 uses custom error unmarshaling logic
+	c.Handlers.UnmarshalError.Clear()
+	c.Handlers.UnmarshalError.PushBack(unmarshalError)
+}
+
+func defaultInitRequestFn(r *request.Request) {
+	// Add reuest handlers for specific platforms.
+	// e.g. 100-continue support for PUT requests using Go 1.6
+	platformRequestHandlers(r)
+
+	switch r.Operation.Name {
+	case opPutBucketCors, opPutBucketLifecycle, opPutBucketPolicy,
+		opPutBucketTagging, opDeleteObjects, opPutBucketLifecycleConfiguration,
+		opPutBucketReplication:
+		// These S3 operations require Content-MD5 to be set
+		r.Handlers.Build.PushBack(contentMD5)
+	case opGetBucketLocation:
+		// GetBucketLocation has custom parsing logic
+		r.Handlers.Unmarshal.PushFront(buildGetBucketLocation)
+	case opCreateBucket:
+		// Auto-populate LocationConstraint with current region
+		r.Handlers.Validate.PushFront(populateLocationConstraint)
+	case opCopyObject, opUploadPartCopy, opCompleteMultipartUpload:
+		r.Handlers.Unmarshal.PushFront(copyMultipartStatusOKUnmarhsalError)
+	case opPutObject, opUploadPart:
+		r.Handlers.Build.PushBack(computeBodyHashes)
+		// Disabled until #1837 root issue is resolved.
+		//	case opGetObject:
+		//		r.Handlers.Build.PushBack(askForTxEncodingAppendMD5)
+		//		r.Handlers.Unmarshal.PushBack(useMD5ValidationReader)
+	}
+}
+
+// bucketGetter is an accessor interface to grab the "Bucket" field from
+// an S3 type.
+type bucketGetter interface {
+	getBucket() string
+}
+
+// sseCustomerKeyGetter is an accessor interface to grab the "SSECustomerKey"
+// field from an S3 type.
+type sseCustomerKeyGetter interface {
+	getSSECustomerKey() string
+}
+
+// copySourceSSECustomerKeyGetter is an accessor interface to grab the
+// "CopySourceSSECustomerKey" field from an S3 type.
+type copySourceSSECustomerKeyGetter interface {
+	getCopySourceSSECustomerKey() string
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/doc.go b/vendor/github.com/aws/aws-sdk-go/service/s3/doc.go
new file mode 100644
index 000000000..0def02255
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/service/s3/doc.go
@@ -0,0 +1,26 @@
+// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
+
+// Package s3 provides the client and types for making API
+// requests to Amazon Simple Storage Service.
+//
+// See https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01 for more information on this service.
+//
+// See s3 package documentation for more information.
+// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/
+//
+// Using the Client
+//
+// To contact Amazon Simple Storage Service with the SDK use the New function to create
+// a new service client. With that client you can make API requests to the service.
+// These clients are safe to use concurrently.
+//
+// See the SDK's documentation for more information on how to use the SDK.
+// https://docs.aws.amazon.com/sdk-for-go/api/
+//
+// See aws.Config documentation for more information on configuring SDK clients.
+// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config
+//
+// See the Amazon Simple Storage Service client S3 for more
+// information on creating client for this service.
+// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/#New
+package s3
diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/doc_custom.go b/vendor/github.com/aws/aws-sdk-go/service/s3/doc_custom.go
new file mode 100644
index 000000000..39b912c26
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/service/s3/doc_custom.go
@@ -0,0 +1,109 @@
+// Upload Managers
+//
+// The s3manager package's Uploader provides concurrent upload of content to S3
+// by taking advantage of S3's Multipart APIs. The Uploader also supports both
+// io.Reader for streaming uploads, and will also take advantage of io.ReadSeeker
+// for optimizations if the Body satisfies that type. Once the Uploader instance
+// is created you can call Upload concurrently from multiple goroutines safely.
+//
+//   // The session the S3 Uploader will use
+//   sess := session.Must(session.NewSession())
+//
+//   // Create an uploader with the session and default options
+//   uploader := s3manager.NewUploader(sess)
+//
+//   f, err  := os.Open(filename)
+//   if err != nil {
+//       return fmt.Errorf("failed to open file %q, %v", filename, err)
+//   }
+//
+//   // Upload the file to S3.
+//   result, err := uploader.Upload(&s3manager.UploadInput{
+//       Bucket: aws.String(myBucket),
+//       Key:    aws.String(myString),
+//       Body:   f,
+//   })
+//   if err != nil {
+//       return fmt.Errorf("failed to upload file, %v", err)
+//   }
+//   fmt.Printf("file uploaded to, %s\n", aws.StringValue(result.Location))
+//
+// See the s3manager package's Uploader type documentation for more information.
+// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3manager/#Uploader
+//
+// Download Manager
+//
+// The s3manager package's Downloader provides concurrently downloading of Objects
+// from S3. The Downloader will write S3 Object content with an io.WriterAt.
+// Once the Downloader instance is created you can call Download concurrently from
+// multiple goroutines safely.
+//
+//   // The session the S3 Downloader will use
+//   sess := session.Must(session.NewSession())
+//
+//   // Create a downloader with the session and default options
+//   downloader := s3manager.NewDownloader(sess)
+//
+//   // Create a file to write the S3 Object contents to.
+//   f, err := os.Create(filename)
+//   if err != nil {
+//       return fmt.Errorf("failed to create file %q, %v", filename, err)
+//   }
+//
+//   // Write the contents of S3 Object to the file
+//   n, err := downloader.Download(f, &s3.GetObjectInput{
+//       Bucket: aws.String(myBucket),
+//       Key:    aws.String(myString),
+//   })
+//   if err != nil {
+//       return fmt.Errorf("failed to download file, %v", err)
+//   }
+//   fmt.Printf("file downloaded, %d bytes\n", n)
+//
+// See the s3manager package's Downloader type documentation for more information.
+// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3manager/#Downloader
+//
+// Get Bucket Region
+//
+// GetBucketRegion will attempt to get the region for a bucket using a region
+// hint to determine which AWS partition to perform the query on. Use this utility
+// to determine the region a bucket is in.
+//
+//   sess := session.Must(session.NewSession())
+//
+//   bucket := "my-bucket"
+//   region, err := s3manager.GetBucketRegion(ctx, sess, bucket, "us-west-2")
+//   if err != nil {
+//       if aerr, ok := err.(awserr.Error); ok && aerr.Code() == "NotFound" {
+//            fmt.Fprintf(os.Stderr, "unable to find bucket %s's region not found\n", bucket)
+//       }
+//       return err
+//   }
+//   fmt.Printf("Bucket %s is in %s region\n", bucket, region)
+//
+// See the s3manager package's GetBucketRegion function documentation for more information
+// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3manager/#GetBucketRegion
+//
+// S3 Crypto Client
+//
+// The s3crypto package provides the tools to upload and download encrypted
+// content from S3. The Encryption and Decryption clients can be used concurrently
+// once the client is created.
+//
+//    sess := session.Must(session.NewSession())
+//
+//    // Create the decryption client.
+//    svc := s3crypto.NewDecryptionClient(sess)
+//
+//    // The object will be downloaded from S3 and decrypted locally. By metadata
+//    // about the object's encryption will instruct the decryption client how
+//    // decrypt the content of the object. By default KMS is used for keys.
+//    result, err := svc.GetObject(&s3.GetObjectInput {
+//        Bucket: aws.String(myBucket),
+//        Key: aws.String(myKey),
+//    })
+//
+// See the s3crypto package documentation for more information.
+// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3crypto/
+//
+package s3
diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/errors.go b/vendor/github.com/aws/aws-sdk-go/service/s3/errors.go
new file mode 100644
index 000000000..931cb17bb
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/service/s3/errors.go
@@ -0,0 +1,48 @@
+// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
+
+package s3
+
+const (
+
+	// ErrCodeBucketAlreadyExists for service response error code
+	// "BucketAlreadyExists".
+	//
+	// The requested bucket name is not available. The bucket namespace is shared
+	// by all users of the system. Please select a different name and try again.
+	ErrCodeBucketAlreadyExists = "BucketAlreadyExists"
+
+	// ErrCodeBucketAlreadyOwnedByYou for service response error code
+	// "BucketAlreadyOwnedByYou".
+	ErrCodeBucketAlreadyOwnedByYou = "BucketAlreadyOwnedByYou"
+
+	// ErrCodeNoSuchBucket for service response error code
+	// "NoSuchBucket".
+	//
+	// The specified bucket does not exist.
+	ErrCodeNoSuchBucket = "NoSuchBucket"
+
+	// ErrCodeNoSuchKey for service response error code
+	// "NoSuchKey".
+	//
+	// The specified key does not exist.
+	ErrCodeNoSuchKey = "NoSuchKey"
+
+	// ErrCodeNoSuchUpload for service response error code
+	// "NoSuchUpload".
+	//
+	// The specified multipart upload does not exist.
+	ErrCodeNoSuchUpload = "NoSuchUpload"
+
+	// ErrCodeObjectAlreadyInActiveTierError for service response error code
+	// "ObjectAlreadyInActiveTierError".
+	//
+	// This operation is not allowed against this storage tier
+	ErrCodeObjectAlreadyInActiveTierError = "ObjectAlreadyInActiveTierError"
+
+	// ErrCodeObjectNotInActiveTierError for service response error code
+	// "ObjectNotInActiveTierError".
+	//
+	// The source object of the COPY operation is not in the active tier and is
+	// only stored in Amazon Glacier.
+	ErrCodeObjectNotInActiveTierError = "ObjectNotInActiveTierError"
+)
diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/host_style_bucket.go b/vendor/github.com/aws/aws-sdk-go/service/s3/host_style_bucket.go
new file mode 100644
index 000000000..a7fbc2de2
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/service/s3/host_style_bucket.go
@@ -0,0 +1,155 @@
+package s3
+
+import (
+	"fmt"
+	"net/url"
+	"regexp"
+	"strings"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/request"
+)
+
+// an operationBlacklist is a list of operation names that should a
+// request handler should not be executed with.
+type operationBlacklist []string
+
+// Continue will return true of the Request's operation name is not
+// in the blacklist. False otherwise.
+func (b operationBlacklist) Continue(r *request.Request) bool {
+	for i := 0; i < len(b); i++ {
+		if b[i] == r.Operation.Name {
+			return false
+		}
+	}
+	return true
+}
+
+var accelerateOpBlacklist = operationBlacklist{
+	opListBuckets, opCreateBucket, opDeleteBucket,
+}
+
+// Request handler to automatically add the bucket name to the endpoint domain
+// if possible. This style of bucket is valid for all bucket names which are
+// DNS compatible and do not contain "."
+func updateEndpointForS3Config(r *request.Request) {
+	forceHostStyle := aws.BoolValue(r.Config.S3ForcePathStyle)
+	accelerate := aws.BoolValue(r.Config.S3UseAccelerate)
+
+	if accelerate && accelerateOpBlacklist.Continue(r) {
+		if forceHostStyle {
+			if r.Config.Logger != nil {
+				r.Config.Logger.Log("ERROR: aws.Config.S3UseAccelerate is not compatible with aws.Config.S3ForcePathStyle, ignoring S3ForcePathStyle.")
+			}
+		}
+		updateEndpointForAccelerate(r)
+	} else if !forceHostStyle && r.Operation.Name != opGetBucketLocation {
+		updateEndpointForHostStyle(r)
+	}
+}
+
+func updateEndpointForHostStyle(r *request.Request) {
+	bucket, ok := bucketNameFromReqParams(r.Params)
+	if !ok {
+		// Ignore operation requests if the bucketname was not provided
+		// if this is an input validation error the validation handler
+		// will report it.
+		return
+	}
+
+	if !hostCompatibleBucketName(r.HTTPRequest.URL, bucket) {
+		// bucket name must be valid to put into the host
+		return
+	}
+
+	moveBucketToHost(r.HTTPRequest.URL, bucket)
+}
+
+var (
+	accelElem = []byte("s3-accelerate.dualstack.")
+)
+
+func updateEndpointForAccelerate(r *request.Request) {
+	bucket, ok := bucketNameFromReqParams(r.Params)
+	if !ok {
+		// Ignore operation requests if the bucketname was not provided
+		// if this is an input validation error the validation handler
+		// will report it.
+		return
+	}
+
+	if !hostCompatibleBucketName(r.HTTPRequest.URL, bucket) {
+		r.Error = awserr.New("InvalidParameterException",
+			fmt.Sprintf("bucket name %s is not compatible with S3 Accelerate", bucket),
+			nil)
+		return
+	}
+
+	parts := strings.Split(r.HTTPRequest.URL.Host, ".")
+	if len(parts) < 3 {
+		r.Error = awserr.New("InvalidParameterExecption",
+			fmt.Sprintf("unable to update endpoint host for S3 accelerate, hostname invalid, %s",
+				r.HTTPRequest.URL.Host), nil)
+		return
+	}
+
+	if parts[0] == "s3" || strings.HasPrefix(parts[0], "s3-") {
+		parts[0] = "s3-accelerate"
+	}
+	for i := 1; i+1 < len(parts); i++ {
+		if parts[i] == aws.StringValue(r.Config.Region) {
+			parts = append(parts[:i], parts[i+1:]...)
+			break
+		}
+	}
+
+	r.HTTPRequest.URL.Host = strings.Join(parts, ".")
+
+	moveBucketToHost(r.HTTPRequest.URL, bucket)
+}
+
+// Attempts to retrieve the bucket name from the request input parameters.
+// If no bucket is found, or the field is empty "", false will be returned.
+func bucketNameFromReqParams(params interface{}) (string, bool) {
+	if iface, ok := params.(bucketGetter); ok {
+		b := iface.getBucket()
+		return b, len(b) > 0
+	}
+
+	return "", false
+}
+
+// hostCompatibleBucketName returns true if the request should
+// put the bucket in the host. This is false if S3ForcePathStyle is
+// explicitly set or if the bucket is not DNS compatible.
+func hostCompatibleBucketName(u *url.URL, bucket string) bool {
+	// Bucket might be DNS compatible but dots in the hostname will fail
+	// certificate validation, so do not use host-style.
+	if u.Scheme == "https" && strings.Contains(bucket, ".") {
+		return false
+	}
+
+	// if the bucket is DNS compatible
+	return dnsCompatibleBucketName(bucket)
+}
+
+var reDomain = regexp.MustCompile(`^[a-z0-9][a-z0-9\.\-]{1,61}[a-z0-9]$`)
+var reIPAddress = regexp.MustCompile(`^(\d+\.){3}\d+$`)
+
+// dnsCompatibleBucketName returns true if the bucket name is DNS compatible.
+// Buckets created outside of the classic region MUST be DNS compatible.
+func dnsCompatibleBucketName(bucket string) bool {
+	return reDomain.MatchString(bucket) &&
+		!reIPAddress.MatchString(bucket) &&
+		!strings.Contains(bucket, "..")
+}
+
+// moveBucketToHost moves the bucket name from the URI path to URL host.
+func moveBucketToHost(u *url.URL, bucket string) {
+	u.Host = bucket + "." + u.Host
+	u.Path = strings.Replace(u.Path, "/{Bucket}", "", -1)
+	if u.Path == "" {
+		u.Path = "/"
+	}
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/platform_handlers.go b/vendor/github.com/aws/aws-sdk-go/service/s3/platform_handlers.go
new file mode 100644
index 000000000..8e6f3307d
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/service/s3/platform_handlers.go
@@ -0,0 +1,8 @@
+// +build !go1.6
+
+package s3
+
+import "github.com/aws/aws-sdk-go/aws/request"
+
+func platformRequestHandlers(r *request.Request) {
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/platform_handlers_go1.6.go b/vendor/github.com/aws/aws-sdk-go/service/s3/platform_handlers_go1.6.go
new file mode 100644
index 000000000..14d05f7b7
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/service/s3/platform_handlers_go1.6.go
@@ -0,0 +1,28 @@
+// +build go1.6
+
+package s3
+
+import (
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/request"
+)
+
+func platformRequestHandlers(r *request.Request) {
+	if r.Operation.HTTPMethod == "PUT" {
+		// 100-Continue should only be used on put requests.
+		r.Handlers.Sign.PushBack(add100Continue)
+	}
+}
+
+func add100Continue(r *request.Request) {
+	if aws.BoolValue(r.Config.S3Disable100Continue) {
+		return
+	}
+	if r.HTTPRequest.ContentLength < 1024*1024*2 {
+		// Ignore requests smaller than 2MB. This helps prevent delaying
+		// requests unnecessarily.
+		return
+	}
+
+	r.HTTPRequest.Header.Set("Expect", "100-Continue")
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/service.go b/vendor/github.com/aws/aws-sdk-go/service/s3/service.go
new file mode 100644
index 000000000..20de53f29
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/service/s3/service.go
@@ -0,0 +1,97 @@
+// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
+
+package s3
+
+import (
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/client"
+	"github.com/aws/aws-sdk-go/aws/client/metadata"
+	"github.com/aws/aws-sdk-go/aws/request"
+	"github.com/aws/aws-sdk-go/aws/signer/v4"
+	"github.com/aws/aws-sdk-go/private/protocol/restxml"
+)
+
+// S3 provides the API operation methods for making requests to
+// Amazon Simple Storage Service. See this package's package overview docs
+// for details on the service.
+//
+// S3 methods are safe to use concurrently. It is not safe to
+// modify mutate any of the struct's properties though.
+type S3 struct {
+	*client.Client
+}
+
+// Used for custom client initialization logic
+var initClient func(*client.Client)
+
+// Used for custom request initialization logic
+var initRequest func(*request.Request)
+
+// Service information constants
+const (
+	ServiceName = "s3"        // Name of service.
+	EndpointsID = ServiceName // ID to lookup a service endpoint with.
+	ServiceID   = "S3"        // ServiceID is a unique identifer of a specific service.
+)
+
+// New creates a new instance of the S3 client with a session.
+// If additional configuration is needed for the client instance use the optional
+// aws.Config parameter to add your extra config.
+//
+// Example:
+//     // Create a S3 client from just a session.
+//     svc := s3.New(mySession)
+//
+//     // Create a S3 client with additional configuration
+//     svc := s3.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
+func New(p client.ConfigProvider, cfgs ...*aws.Config) *S3 {
+	c := p.ClientConfig(EndpointsID, cfgs...)
+	return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName)
+}
+
+// newClient creates, initializes and returns a new service client instance.
+func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *S3 {
+	svc := &S3{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName:   ServiceName,
+				ServiceID:     ServiceID,
+				SigningName:   signingName,
+				SigningRegion: signingRegion,
+				Endpoint:      endpoint,
+				APIVersion:    "2006-03-01",
+			},
+			handlers,
+		),
+	}
+
+	// Handlers
+	svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler)
+	svc.Handlers.Build.PushBackNamed(restxml.BuildHandler)
+	svc.Handlers.Unmarshal.PushBackNamed(restxml.UnmarshalHandler)
+	svc.Handlers.UnmarshalMeta.PushBackNamed(restxml.UnmarshalMetaHandler)
+	svc.Handlers.UnmarshalError.PushBackNamed(restxml.UnmarshalErrorHandler)
+
+	svc.Handlers.UnmarshalStream.PushBackNamed(restxml.UnmarshalHandler)
+
+	// Run custom client initialization if present
+	if initClient != nil {
+		initClient(svc.Client)
+	}
+
+	return svc
+}
+
+// newRequest creates a new request for a S3 operation and runs any
+// custom request initialization.
+func (c *S3) newRequest(op *request.Operation, params, data interface{}) *request.Request {
+	req := c.NewRequest(op, params, data)
+
+	// Run custom request initialization if present
+	if initRequest != nil {
+		initRequest(req)
+	}
+
+	return req
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/sse.go b/vendor/github.com/aws/aws-sdk-go/service/s3/sse.go
new file mode 100644
index 000000000..8010c4fa1
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/service/s3/sse.go
@@ -0,0 +1,54 @@
+package s3
+
+import (
+	"crypto/md5"
+	"encoding/base64"
+
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/request"
+)
+
+var errSSERequiresSSL = awserr.New("ConfigError", "cannot send SSE keys over HTTP.", nil)
+
+func validateSSERequiresSSL(r *request.Request) {
+	if r.HTTPRequest.URL.Scheme == "https" {
+		return
+	}
+
+	if iface, ok := r.Params.(sseCustomerKeyGetter); ok {
+		if len(iface.getSSECustomerKey()) > 0 {
+			r.Error = errSSERequiresSSL
+			return
+		}
+	}
+
+	if iface, ok := r.Params.(copySourceSSECustomerKeyGetter); ok {
+		if len(iface.getCopySourceSSECustomerKey()) > 0 {
+			r.Error = errSSERequiresSSL
+			return
+		}
+	}
+}
+
+func computeSSEKeys(r *request.Request) {
+	headers := []string{
+		"x-amz-server-side-encryption-customer-key",
+		"x-amz-copy-source-server-side-encryption-customer-key",
+	}
+
+	for _, h := range headers {
+		md5h := h + "-md5"
+		if key := r.HTTPRequest.Header.Get(h); key != "" {
+			// Base64-encode the value
+			b64v := base64.StdEncoding.EncodeToString([]byte(key))
+			r.HTTPRequest.Header.Set(h, b64v)
+
+			// Add MD5 if it wasn't computed
+			if r.HTTPRequest.Header.Get(md5h) == "" {
+				sum := md5.Sum([]byte(key))
+				b64sum := base64.StdEncoding.EncodeToString(sum[:])
+				r.HTTPRequest.Header.Set(md5h, b64sum)
+			}
+		}
+	}
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/statusok_error.go b/vendor/github.com/aws/aws-sdk-go/service/s3/statusok_error.go
new file mode 100644
index 000000000..9f33efc6c
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/service/s3/statusok_error.go
@@ -0,0 +1,36 @@
+package s3
+
+import (
+	"bytes"
+	"io/ioutil"
+	"net/http"
+
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/request"
+	"github.com/aws/aws-sdk-go/internal/sdkio"
+)
+
+func copyMultipartStatusOKUnmarhsalError(r *request.Request) {
+	b, err := ioutil.ReadAll(r.HTTPResponse.Body)
+	if err != nil {
+		r.Error = awserr.New("SerializationError", "unable to read response body", err)
+		return
+	}
+	body := bytes.NewReader(b)
+	r.HTTPResponse.Body = ioutil.NopCloser(body)
+	defer body.Seek(0, sdkio.SeekStart)
+
+	if body.Len() == 0 {
+		// If there is no body don't attempt to parse the body.
+		return
+	}
+
+	unmarshalError(r)
+	if err, ok := r.Error.(awserr.Error); ok && err != nil {
+		if err.Code() == "SerializationError" {
+			r.Error = nil
+			return
+		}
+		r.HTTPResponse.StatusCode = http.StatusServiceUnavailable
+	}
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/unmarshal_error.go b/vendor/github.com/aws/aws-sdk-go/service/s3/unmarshal_error.go
new file mode 100644
index 000000000..bcca8627a
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/service/s3/unmarshal_error.go
@@ -0,0 +1,103 @@
+package s3
+
+import (
+	"encoding/xml"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net/http"
+	"strings"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/request"
+)
+
+type xmlErrorResponse struct {
+	XMLName xml.Name `xml:"Error"`
+	Code    string   `xml:"Code"`
+	Message string   `xml:"Message"`
+}
+
+func unmarshalError(r *request.Request) {
+	defer r.HTTPResponse.Body.Close()
+	defer io.Copy(ioutil.Discard, r.HTTPResponse.Body)
+
+	hostID := r.HTTPResponse.Header.Get("X-Amz-Id-2")
+
+	// Bucket exists in a different region, and request needs
+	// to be made to the correct region.
+	if r.HTTPResponse.StatusCode == http.StatusMovedPermanently {
+		r.Error = requestFailure{
+			RequestFailure: awserr.NewRequestFailure(
+				awserr.New("BucketRegionError",
+					fmt.Sprintf("incorrect region, the bucket is not in '%s' region",
+						aws.StringValue(r.Config.Region)),
+					nil),
+				r.HTTPResponse.StatusCode,
+				r.RequestID,
+			),
+			hostID: hostID,
+		}
+		return
+	}
+
+	var errCode, errMsg string
+
+	// Attempt to parse error from body if it is known
+	resp := &xmlErrorResponse{}
+	err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp)
+	if err != nil && err != io.EOF {
+		errCode = "SerializationError"
+		errMsg = "failed to decode S3 XML error response"
+	} else {
+		errCode = resp.Code
+		errMsg = resp.Message
+		err = nil
+	}
+
+	// Fallback to status code converted to message if still no error code
+	if len(errCode) == 0 {
+		statusText := http.StatusText(r.HTTPResponse.StatusCode)
+		errCode = strings.Replace(statusText, " ", "", -1)
+		errMsg = statusText
+	}
+
+	r.Error = requestFailure{
+		RequestFailure: awserr.NewRequestFailure(
+			awserr.New(errCode, errMsg, err),
+			r.HTTPResponse.StatusCode,
+			r.RequestID,
+		),
+		hostID: hostID,
+	}
+}
+
+// A RequestFailure provides access to the S3 Request ID and Host ID values
+// returned from API operation errors. Getting the error as a string will
+// return the formated error with the same information as awserr.RequestFailure,
+// while also adding the HostID value from the response.
+type RequestFailure interface {
+	awserr.RequestFailure
+
+	// Host ID is the S3 Host ID needed for debug, and contacting support
+	HostID() string
+}
+
+type requestFailure struct {
+	awserr.RequestFailure
+
+	hostID string
+}
+
+func (r requestFailure) Error() string {
+	extra := fmt.Sprintf("status code: %d, request id: %s, host id: %s",
+		r.StatusCode(), r.RequestID(), r.hostID)
+	return awserr.SprintError(r.Code(), r.Message(), extra, r.OrigErr())
+}
+func (r requestFailure) String() string {
+	return r.Error()
+}
+func (r requestFailure) HostID() string {
+	return r.hostID
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/waiters.go b/vendor/github.com/aws/aws-sdk-go/service/s3/waiters.go
new file mode 100644
index 000000000..2596c694b
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/service/s3/waiters.go
@@ -0,0 +1,214 @@
+// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
+
+package s3
+
+import (
+	"time"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/request"
+)
+
+// WaitUntilBucketExists uses the Amazon S3 API operation
+// HeadBucket to wait for a condition to be met before returning.
+// If the condition is not met within the max attempt window, an error will
+// be returned.
+func (c *S3) WaitUntilBucketExists(input *HeadBucketInput) error {
+	return c.WaitUntilBucketExistsWithContext(aws.BackgroundContext(), input)
+}
+
+// WaitUntilBucketExistsWithContext is an extended version of WaitUntilBucketExists.
+// With the support for passing in a context and options to configure the
+// Waiter and the underlying request options.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) WaitUntilBucketExistsWithContext(ctx aws.Context, input *HeadBucketInput, opts ...request.WaiterOption) error {
+	w := request.Waiter{
+		Name:        "WaitUntilBucketExists",
+		MaxAttempts: 20,
+		Delay:       request.ConstantWaiterDelay(5 * time.Second),
+		Acceptors: []request.WaiterAcceptor{
+			{
+				State:    request.SuccessWaiterState,
+				Matcher:  request.StatusWaiterMatch,
+				Expected: 200,
+			},
+			{
+				State:    request.SuccessWaiterState,
+				Matcher:  request.StatusWaiterMatch,
+				Expected: 301,
+			},
+			{
+				State:    request.SuccessWaiterState,
+				Matcher:  request.StatusWaiterMatch,
+				Expected: 403,
+			},
+			{
+				State:    request.RetryWaiterState,
+				Matcher:  request.StatusWaiterMatch,
+				Expected: 404,
+			},
+		},
+		Logger: c.Config.Logger,
+		NewRequest: func(opts []request.Option) (*request.Request, error) {
+			var inCpy *HeadBucketInput
+			if input != nil {
+				tmp := *input
+				inCpy = &tmp
+			}
+			req, _ := c.HeadBucketRequest(inCpy)
+			req.SetContext(ctx)
+			req.ApplyOptions(opts...)
+			return req, nil
+		},
+	}
+	w.ApplyOptions(opts...)
+
+	return w.WaitWithContext(ctx)
+}
+
+// WaitUntilBucketNotExists uses the Amazon S3 API operation
+// HeadBucket to wait for a condition to be met before returning.
+// If the condition is not met within the max attempt window, an error will
+// be returned.
+func (c *S3) WaitUntilBucketNotExists(input *HeadBucketInput) error {
+	return c.WaitUntilBucketNotExistsWithContext(aws.BackgroundContext(), input)
+}
+
+// WaitUntilBucketNotExistsWithContext is an extended version of WaitUntilBucketNotExists.
+// With the support for passing in a context and options to configure the
+// Waiter and the underlying request options.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) WaitUntilBucketNotExistsWithContext(ctx aws.Context, input *HeadBucketInput, opts ...request.WaiterOption) error {
+	w := request.Waiter{
+		Name:        "WaitUntilBucketNotExists",
+		MaxAttempts: 20,
+		Delay:       request.ConstantWaiterDelay(5 * time.Second),
+		Acceptors: []request.WaiterAcceptor{
+			{
+				State:    request.SuccessWaiterState,
+				Matcher:  request.StatusWaiterMatch,
+				Expected: 404,
+			},
+		},
+		Logger: c.Config.Logger,
+		NewRequest: func(opts []request.Option) (*request.Request, error) {
+			var inCpy *HeadBucketInput
+			if input != nil {
+				tmp := *input
+				inCpy = &tmp
+			}
+			req, _ := c.HeadBucketRequest(inCpy)
+			req.SetContext(ctx)
+			req.ApplyOptions(opts...)
+			return req, nil
+		},
+	}
+	w.ApplyOptions(opts...)
+
+	return w.WaitWithContext(ctx)
+}
+
+// WaitUntilObjectExists uses the Amazon S3 API operation
+// HeadObject to wait for a condition to be met before returning.
+// If the condition is not met within the max attempt window, an error will
+// be returned.
+func (c *S3) WaitUntilObjectExists(input *HeadObjectInput) error {
+	return c.WaitUntilObjectExistsWithContext(aws.BackgroundContext(), input)
+}
+
+// WaitUntilObjectExistsWithContext is an extended version of WaitUntilObjectExists.
+// With the support for passing in a context and options to configure the
+// Waiter and the underlying request options.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) WaitUntilObjectExistsWithContext(ctx aws.Context, input *HeadObjectInput, opts ...request.WaiterOption) error {
+	w := request.Waiter{
+		Name:        "WaitUntilObjectExists",
+		MaxAttempts: 20,
+		Delay:       request.ConstantWaiterDelay(5 * time.Second),
+		Acceptors: []request.WaiterAcceptor{
+			{
+				State:    request.SuccessWaiterState,
+				Matcher:  request.StatusWaiterMatch,
+				Expected: 200,
+			},
+			{
+				State:    request.RetryWaiterState,
+				Matcher:  request.StatusWaiterMatch,
+				Expected: 404,
+			},
+		},
+		Logger: c.Config.Logger,
+		NewRequest: func(opts []request.Option) (*request.Request, error) {
+			var inCpy *HeadObjectInput
+			if input != nil {
+				tmp := *input
+				inCpy = &tmp
+			}
+			req, _ := c.HeadObjectRequest(inCpy)
+			req.SetContext(ctx)
+			req.ApplyOptions(opts...)
+			return req, nil
+		},
+	}
+	w.ApplyOptions(opts...)
+
+	return w.WaitWithContext(ctx)
+}
+
+// WaitUntilObjectNotExists uses the Amazon S3 API operation
+// HeadObject to wait for a condition to be met before returning.
+// If the condition is not met within the max attempt window, an error will
+// be returned.
+func (c *S3) WaitUntilObjectNotExists(input *HeadObjectInput) error {
+	return c.WaitUntilObjectNotExistsWithContext(aws.BackgroundContext(), input)
+}
+
+// WaitUntilObjectNotExistsWithContext is an extended version of WaitUntilObjectNotExists.
+// With the support for passing in a context and options to configure the
+// Waiter and the underlying request options.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *S3) WaitUntilObjectNotExistsWithContext(ctx aws.Context, input *HeadObjectInput, opts ...request.WaiterOption) error {
+	w := request.Waiter{
+		Name:        "WaitUntilObjectNotExists",
+		MaxAttempts: 20,
+		Delay:       request.ConstantWaiterDelay(5 * time.Second),
+		Acceptors: []request.WaiterAcceptor{
+			{
+				State:    request.SuccessWaiterState,
+				Matcher:  request.StatusWaiterMatch,
+				Expected: 404,
+			},
+		},
+		Logger: c.Config.Logger,
+		NewRequest: func(opts []request.Option) (*request.Request, error) {
+			var inCpy *HeadObjectInput
+			if input != nil {
+				tmp := *input
+				inCpy = &tmp
+			}
+			req, _ := c.HeadObjectRequest(inCpy)
+			req.SetContext(ctx)
+			req.ApplyOptions(opts...)
+			return req, nil
+		},
+	}
+	w.ApplyOptions(opts...)
+
+	return w.WaitWithContext(ctx)
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/api.go b/vendor/github.com/aws/aws-sdk-go/service/sts/api.go
new file mode 100644
index 000000000..6f89a796e
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/service/sts/api.go
@@ -0,0 +1,2398 @@
+// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
+
+package sts
+
+import (
+	"time"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/awsutil"
+	"github.com/aws/aws-sdk-go/aws/request"
+)
+
+const opAssumeRole = "AssumeRole"
+
+// AssumeRoleRequest generates a "aws/request.Request" representing the
+// client's request for the AssumeRole operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See AssumeRole for more information on using the AssumeRole
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the AssumeRoleRequest method.
+//    req, resp := client.AssumeRoleRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRole
+func (c *STS) AssumeRoleRequest(input *AssumeRoleInput) (req *request.Request, output *AssumeRoleOutput) {
+	op := &request.Operation{
+		Name:       opAssumeRole,
+		HTTPMethod: "POST",
+		HTTPPath:   "/",
+	}
+
+	if input == nil {
+		input = &AssumeRoleInput{}
+	}
+
+	output = &AssumeRoleOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// AssumeRole API operation for AWS Security Token Service.
+//
+// Returns a set of temporary security credentials (consisting of an access
+// key ID, a secret access key, and a security token) that you can use to access
+// AWS resources that you might not normally have access to. Typically, you
+// use AssumeRole for cross-account access or federation. For a comparison of
+// AssumeRole with the other APIs that produce temporary credentials, see Requesting
+// Temporary Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html)
+// and Comparing the AWS STS APIs (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison)
+// in the IAM User Guide.
+//
+// Important: You cannot call AssumeRole by using AWS root account credentials;
+// access is denied. You must use credentials for an IAM user or an IAM role
+// to call AssumeRole.
+//
+// For cross-account access, imagine that you own multiple accounts and need
+// to access resources in each account. You could create long-term credentials
+// in each account to access those resources. However, managing all those credentials
+// and remembering which one can access which account can be time consuming.
+// Instead, you can create one set of long-term credentials in one account and
+// then use temporary security credentials to access all the other accounts
+// by assuming roles in those accounts. For more information about roles, see
+// IAM Roles (Delegation and Federation) (http://docs.aws.amazon.com/IAM/latest/UserGuide/roles-toplevel.html)
+// in the IAM User Guide.
+//
+// For federation, you can, for example, grant single sign-on access to the
+// AWS Management Console. If you already have an identity and authentication
+// system in your corporate network, you don't have to recreate user identities
+// in AWS in order to grant those user identities access to AWS. Instead, after
+// a user has been authenticated, you call AssumeRole (and specify the role
+// with the appropriate permissions) to get temporary security credentials for
+// that user. With those temporary security credentials, you construct a sign-in
+// URL that users can use to access the console. For more information, see Common
+// Scenarios for Temporary Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html#sts-introduction)
+// in the IAM User Guide.
+//
+// By default, the temporary security credentials created by AssumeRole last
+// for one hour. However, you can use the optional DurationSeconds parameter
+// to specify the duration of your session. You can provide a value from 900
+// seconds (15 minutes) up to the maximum session duration setting for the role.
+// This setting can have a value from 1 hour to 12 hours. To learn how to view
+// the maximum value for your role, see View the Maximum Session Duration Setting
+// for a Role (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session)
+// in the IAM User Guide. The maximum session duration limit applies when you
+// use the AssumeRole* API operations or the assume-role* CLI operations but
+// does not apply when you use those operations to create a console URL. For
+// more information, see Using IAM Roles (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html)
+// in the IAM User Guide.
+//
+// The temporary security credentials created by AssumeRole can be used to make
+// API calls to any AWS service with the following exception: you cannot call
+// the STS service's GetFederationToken or GetSessionToken APIs.
+//
+// Optionally, you can pass an IAM access policy to this operation. If you choose
+// not to pass a policy, the temporary security credentials that are returned
+// by the operation have the permissions that are defined in the access policy
+// of the role that is being assumed. If you pass a policy to this operation,
+// the temporary security credentials that are returned by the operation have
+// the permissions that are allowed by both the access policy of the role that
+// is being assumed, and the policy that you pass. This gives you a way to further
+// restrict the permissions for the resulting temporary security credentials.
+// You cannot use the passed policy to grant permissions that are in excess
+// of those allowed by the access policy of the role that is being assumed.
+// For more information, see Permissions for AssumeRole, AssumeRoleWithSAML,
+// and AssumeRoleWithWebIdentity (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html)
+// in the IAM User Guide.
+//
+// To assume a role, your AWS account must be trusted by the role. The trust
+// relationship is defined in the role's trust policy when the role is created.
+// That trust policy states which accounts are allowed to delegate access to
+// this account's role.
+//
+// The user who wants to access the role must also have permissions delegated
+// from the role's administrator. If the user is in a different account than
+// the role, then the user's administrator must attach a policy that allows
+// the user to call AssumeRole on the ARN of the role in the other account.
+// If the user is in the same account as the role, then you can either attach
+// a policy to the user (identical to the previous different account user),
+// or you can add the user as a principal directly in the role's trust policy.
+// In this case, the trust policy acts as the only resource-based policy in
+// IAM, and users in the same account as the role do not need explicit permission
+// to assume the role. For more information about trust policies and resource-based
+// policies, see IAM Policies (http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html)
+// in the IAM User Guide.
+//
+// Using MFA with AssumeRole
+//
+// You can optionally include multi-factor authentication (MFA) information
+// when you call AssumeRole. This is useful for cross-account scenarios in which
+// you want to make sure that the user who is assuming the role has been authenticated
+// using an AWS MFA device. In that scenario, the trust policy of the role being
+// assumed includes a condition that tests for MFA authentication; if the caller
+// does not include valid MFA information, the request to assume the role is
+// denied. The condition in a trust policy that tests for MFA authentication
+// might look like the following example.
+//
+// "Condition": {"Bool": {"aws:MultiFactorAuthPresent": true}}
+//
+// For more information, see Configuring MFA-Protected API Access (http://docs.aws.amazon.com/IAM/latest/UserGuide/MFAProtectedAPI.html)
+// in the IAM User Guide guide.
+//
+// To use MFA with AssumeRole, you pass values for the SerialNumber and TokenCode
+// parameters. The SerialNumber value identifies the user's hardware or virtual
+// MFA device. The TokenCode is the time-based one-time password (TOTP) that
+// the MFA devices produces.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for AWS Security Token Service's
+// API operation AssumeRole for usage and error information.
+//
+// Returned Error Codes:
+//   * ErrCodeMalformedPolicyDocumentException "MalformedPolicyDocument"
+//   The request was rejected because the policy document was malformed. The error
+//   message describes the specific error.
+//
+//   * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge"
+//   The request was rejected because the policy document was too large. The error
+//   message describes how big the policy document is, in packed form, as a percentage
+//   of what the API allows.
+//
+//   * ErrCodeRegionDisabledException "RegionDisabledException"
+//   STS is not activated in the requested region for the account that is being
+//   asked to generate credentials. The account administrator must use the IAM
+//   console to activate STS in that region. For more information, see Activating
+//   and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
+//   in the IAM User Guide.
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRole
+func (c *STS) AssumeRole(input *AssumeRoleInput) (*AssumeRoleOutput, error) {
+	req, out := c.AssumeRoleRequest(input)
+	return out, req.Send()
+}
+
+// AssumeRoleWithContext is the same as AssumeRole with the addition of
+// the ability to pass a context and additional request options.
+//
+// See AssumeRole for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *STS) AssumeRoleWithContext(ctx aws.Context, input *AssumeRoleInput, opts ...request.Option) (*AssumeRoleOutput, error) {
+	req, out := c.AssumeRoleRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opAssumeRoleWithSAML = "AssumeRoleWithSAML"
+
+// AssumeRoleWithSAMLRequest generates a "aws/request.Request" representing the
+// client's request for the AssumeRoleWithSAML operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See AssumeRoleWithSAML for more information on using the AssumeRoleWithSAML
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the AssumeRoleWithSAMLRequest method.
+//    req, resp := client.AssumeRoleWithSAMLRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAML
+func (c *STS) AssumeRoleWithSAMLRequest(input *AssumeRoleWithSAMLInput) (req *request.Request, output *AssumeRoleWithSAMLOutput) {
+	op := &request.Operation{
+		Name:       opAssumeRoleWithSAML,
+		HTTPMethod: "POST",
+		HTTPPath:   "/",
+	}
+
+	if input == nil {
+		input = &AssumeRoleWithSAMLInput{}
+	}
+
+	output = &AssumeRoleWithSAMLOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// AssumeRoleWithSAML API operation for AWS Security Token Service.
+//
+// Returns a set of temporary security credentials for users who have been authenticated
+// via a SAML authentication response. This operation provides a mechanism for
+// tying an enterprise identity store or directory to role-based AWS access
+// without user-specific credentials or configuration. For a comparison of AssumeRoleWithSAML
+// with the other APIs that produce temporary credentials, see Requesting Temporary
+// Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html)
+// and Comparing the AWS STS APIs (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison)
+// in the IAM User Guide.
+//
+// The temporary security credentials returned by this operation consist of
+// an access key ID, a secret access key, and a security token. Applications
+// can use these temporary security credentials to sign calls to AWS services.
+//
+// By default, the temporary security credentials created by AssumeRoleWithSAML
+// last for one hour. However, you can use the optional DurationSeconds parameter
+// to specify the duration of your session. Your role session lasts for the
+// duration that you specify, or until the time specified in the SAML authentication
+// response's SessionNotOnOrAfter value, whichever is shorter. You can provide
+// a DurationSeconds value from 900 seconds (15 minutes) up to the maximum session
+// duration setting for the role. This setting can have a value from 1 hour
+// to 12 hours. To learn how to view the maximum value for your role, see View
+// the Maximum Session Duration Setting for a Role (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session)
+// in the IAM User Guide. The maximum session duration limit applies when you
+// use the AssumeRole* API operations or the assume-role* CLI operations but
+// does not apply when you use those operations to create a console URL. For
+// more information, see Using IAM Roles (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html)
+// in the IAM User Guide.
+//
+// The temporary security credentials created by AssumeRoleWithSAML can be used
+// to make API calls to any AWS service with the following exception: you cannot
+// call the STS service's GetFederationToken or GetSessionToken APIs.
+//
+// Optionally, you can pass an IAM access policy to this operation. If you choose
+// not to pass a policy, the temporary security credentials that are returned
+// by the operation have the permissions that are defined in the access policy
+// of the role that is being assumed. If you pass a policy to this operation,
+// the temporary security credentials that are returned by the operation have
+// the permissions that are allowed by the intersection of both the access policy
+// of the role that is being assumed, and the policy that you pass. This means
+// that both policies must grant the permission for the action to be allowed.
+// This gives you a way to further restrict the permissions for the resulting
+// temporary security credentials. You cannot use the passed policy to grant
+// permissions that are in excess of those allowed by the access policy of the
+// role that is being assumed. For more information, see Permissions for AssumeRole,
+// AssumeRoleWithSAML, and AssumeRoleWithWebIdentity (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html)
+// in the IAM User Guide.
+//
+// Before your application can call AssumeRoleWithSAML, you must configure your
+// SAML identity provider (IdP) to issue the claims required by AWS. Additionally,
+// you must use AWS Identity and Access Management (IAM) to create a SAML provider
+// entity in your AWS account that represents your identity provider, and create
+// an IAM role that specifies this SAML provider in its trust policy.
+//
+// Calling AssumeRoleWithSAML does not require the use of AWS security credentials.
+// The identity of the caller is validated by using keys in the metadata document
+// that is uploaded for the SAML provider entity for your identity provider.
+//
+// Calling AssumeRoleWithSAML can result in an entry in your AWS CloudTrail
+// logs. The entry includes the value in the NameID element of the SAML assertion.
+// We recommend that you use a NameIDType that is not associated with any personally
+// identifiable information (PII). For example, you could instead use the Persistent
+// Identifier (urn:oasis:names:tc:SAML:2.0:nameid-format:persistent).
+//
+// For more information, see the following resources:
+//
+//    * About SAML 2.0-based Federation (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_saml.html)
+//    in the IAM User Guide.
+//
+//    * Creating SAML Identity Providers (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml.html)
+//    in the IAM User Guide.
+//
+//    * Configuring a Relying Party and Claims (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml_relying-party.html)
+//    in the IAM User Guide.
+//
+//    * Creating a Role for SAML 2.0 Federation (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_saml.html)
+//    in the IAM User Guide.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for AWS Security Token Service's
+// API operation AssumeRoleWithSAML for usage and error information.
+//
+// Returned Error Codes:
+//   * ErrCodeMalformedPolicyDocumentException "MalformedPolicyDocument"
+//   The request was rejected because the policy document was malformed. The error
+//   message describes the specific error.
+//
+//   * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge"
+//   The request was rejected because the policy document was too large. The error
+//   message describes how big the policy document is, in packed form, as a percentage
+//   of what the API allows.
+//
+//   * ErrCodeIDPRejectedClaimException "IDPRejectedClaim"
+//   The identity provider (IdP) reported that authentication failed. This might
+//   be because the claim is invalid.
+//
+//   If this error is returned for the AssumeRoleWithWebIdentity operation, it
+//   can also mean that the claim has expired or has been explicitly revoked.
+//
+//   * ErrCodeInvalidIdentityTokenException "InvalidIdentityToken"
+//   The web identity token that was passed could not be validated by AWS. Get
+//   a new identity token from the identity provider and then retry the request.
+//
+//   * ErrCodeExpiredTokenException "ExpiredTokenException"
+//   The web identity token that was passed is expired or is not valid. Get a
+//   new identity token from the identity provider and then retry the request.
+//
+//   * ErrCodeRegionDisabledException "RegionDisabledException"
+//   STS is not activated in the requested region for the account that is being
+//   asked to generate credentials. The account administrator must use the IAM
+//   console to activate STS in that region. For more information, see Activating
+//   and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
+//   in the IAM User Guide.
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAML
+func (c *STS) AssumeRoleWithSAML(input *AssumeRoleWithSAMLInput) (*AssumeRoleWithSAMLOutput, error) {
+	req, out := c.AssumeRoleWithSAMLRequest(input)
+	return out, req.Send()
+}
+
+// AssumeRoleWithSAMLWithContext is the same as AssumeRoleWithSAML with the addition of
+// the ability to pass a context and additional request options.
+//
+// See AssumeRoleWithSAML for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *STS) AssumeRoleWithSAMLWithContext(ctx aws.Context, input *AssumeRoleWithSAMLInput, opts ...request.Option) (*AssumeRoleWithSAMLOutput, error) {
+	req, out := c.AssumeRoleWithSAMLRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opAssumeRoleWithWebIdentity = "AssumeRoleWithWebIdentity"
+
+// AssumeRoleWithWebIdentityRequest generates a "aws/request.Request" representing the
+// client's request for the AssumeRoleWithWebIdentity operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See AssumeRoleWithWebIdentity for more information on using the AssumeRoleWithWebIdentity
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the AssumeRoleWithWebIdentityRequest method.
+//    req, resp := client.AssumeRoleWithWebIdentityRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentity
+func (c *STS) AssumeRoleWithWebIdentityRequest(input *AssumeRoleWithWebIdentityInput) (req *request.Request, output *AssumeRoleWithWebIdentityOutput) {
+	op := &request.Operation{
+		Name:       opAssumeRoleWithWebIdentity,
+		HTTPMethod: "POST",
+		HTTPPath:   "/",
+	}
+
+	if input == nil {
+		input = &AssumeRoleWithWebIdentityInput{}
+	}
+
+	output = &AssumeRoleWithWebIdentityOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// AssumeRoleWithWebIdentity API operation for AWS Security Token Service.
+//
+// Returns a set of temporary security credentials for users who have been authenticated
+// in a mobile or web application with a web identity provider, such as Amazon
+// Cognito, Login with Amazon, Facebook, Google, or any OpenID Connect-compatible
+// identity provider.
+//
+// For mobile applications, we recommend that you use Amazon Cognito. You can
+// use Amazon Cognito with the AWS SDK for iOS (http://aws.amazon.com/sdkforios/)
+// and the AWS SDK for Android (http://aws.amazon.com/sdkforandroid/) to uniquely
+// identify a user and supply the user with a consistent identity throughout
+// the lifetime of an application.
+//
+// To learn more about Amazon Cognito, see Amazon Cognito Overview (http://docs.aws.amazon.com/mobile/sdkforandroid/developerguide/cognito-auth.html#d0e840)
+// in the AWS SDK for Android Developer Guide guide and Amazon Cognito Overview
+// (http://docs.aws.amazon.com/mobile/sdkforios/developerguide/cognito-auth.html#d0e664)
+// in the AWS SDK for iOS Developer Guide.
+//
+// Calling AssumeRoleWithWebIdentity does not require the use of AWS security
+// credentials. Therefore, you can distribute an application (for example, on
+// mobile devices) that requests temporary security credentials without including
+// long-term AWS credentials in the application, and without deploying server-based
+// proxy services that use long-term AWS credentials. Instead, the identity
+// of the caller is validated by using a token from the web identity provider.
+// For a comparison of AssumeRoleWithWebIdentity with the other APIs that produce
+// temporary credentials, see Requesting Temporary Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html)
+// and Comparing the AWS STS APIs (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison)
+// in the IAM User Guide.
+//
+// The temporary security credentials returned by this API consist of an access
+// key ID, a secret access key, and a security token. Applications can use these
+// temporary security credentials to sign calls to AWS service APIs.
+//
+// By default, the temporary security credentials created by AssumeRoleWithWebIdentity
+// last for one hour. However, you can use the optional DurationSeconds parameter
+// to specify the duration of your session. You can provide a value from 900
+// seconds (15 minutes) up to the maximum session duration setting for the role.
+// This setting can have a value from 1 hour to 12 hours. To learn how to view
+// the maximum value for your role, see View the Maximum Session Duration Setting
+// for a Role (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session)
+// in the IAM User Guide. The maximum session duration limit applies when you
+// use the AssumeRole* API operations or the assume-role* CLI operations but
+// does not apply when you use those operations to create a console URL. For
+// more information, see Using IAM Roles (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html)
+// in the IAM User Guide.
+//
+// The temporary security credentials created by AssumeRoleWithWebIdentity can
+// be used to make API calls to any AWS service with the following exception:
+// you cannot call the STS service's GetFederationToken or GetSessionToken APIs.
+//
+// Optionally, you can pass an IAM access policy to this operation. If you choose
+// not to pass a policy, the temporary security credentials that are returned
+// by the operation have the permissions that are defined in the access policy
+// of the role that is being assumed. If you pass a policy to this operation,
+// the temporary security credentials that are returned by the operation have
+// the permissions that are allowed by both the access policy of the role that
+// is being assumed, and the policy that you pass. This gives you a way to further
+// restrict the permissions for the resulting temporary security credentials.
+// You cannot use the passed policy to grant permissions that are in excess
+// of those allowed by the access policy of the role that is being assumed.
+// For more information, see Permissions for AssumeRole, AssumeRoleWithSAML,
+// and AssumeRoleWithWebIdentity (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html)
+// in the IAM User Guide.
+//
+// Before your application can call AssumeRoleWithWebIdentity, you must have
+// an identity token from a supported identity provider and create a role that
+// the application can assume. The role that your application assumes must trust
+// the identity provider that is associated with the identity token. In other
+// words, the identity provider must be specified in the role's trust policy.
+//
+// Calling AssumeRoleWithWebIdentity can result in an entry in your AWS CloudTrail
+// logs. The entry includes the Subject (http://openid.net/specs/openid-connect-core-1_0.html#Claims)
+// of the provided Web Identity Token. We recommend that you avoid using any
+// personally identifiable information (PII) in this field. For example, you
+// could instead use a GUID or a pairwise identifier, as suggested in the OIDC
+// specification (http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes).
+//
+// For more information about how to use web identity federation and the AssumeRoleWithWebIdentity
+// API, see the following resources:
+//
+//    * Using Web Identity Federation APIs for Mobile Apps (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc_manual.html)
+//    and Federation Through a Web-based Identity Provider (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity).
+//
+//
+//    *  Web Identity Federation Playground (https://web-identity-federation-playground.s3.amazonaws.com/index.html).
+//    This interactive website lets you walk through the process of authenticating
+//    via Login with Amazon, Facebook, or Google, getting temporary security
+//    credentials, and then using those credentials to make a request to AWS.
+//
+//
+//    * AWS SDK for iOS (http://aws.amazon.com/sdkforios/) and AWS SDK for Android
+//    (http://aws.amazon.com/sdkforandroid/). These toolkits contain sample
+//    apps that show how to invoke the identity providers, and then how to use
+//    the information from these providers to get and use temporary security
+//    credentials.
+//
+//    * Web Identity Federation with Mobile Applications (http://aws.amazon.com/articles/web-identity-federation-with-mobile-applications).
+//    This article discusses web identity federation and shows an example of
+//    how to use web identity federation to get access to content in Amazon
+//    S3.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for AWS Security Token Service's
+// API operation AssumeRoleWithWebIdentity for usage and error information.
+//
+// Returned Error Codes:
+//   * ErrCodeMalformedPolicyDocumentException "MalformedPolicyDocument"
+//   The request was rejected because the policy document was malformed. The error
+//   message describes the specific error.
+//
+//   * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge"
+//   The request was rejected because the policy document was too large. The error
+//   message describes how big the policy document is, in packed form, as a percentage
+//   of what the API allows.
+//
+//   * ErrCodeIDPRejectedClaimException "IDPRejectedClaim"
+//   The identity provider (IdP) reported that authentication failed. This might
+//   be because the claim is invalid.
+//
+//   If this error is returned for the AssumeRoleWithWebIdentity operation, it
+//   can also mean that the claim has expired or has been explicitly revoked.
+//
+//   * ErrCodeIDPCommunicationErrorException "IDPCommunicationError"
+//   The request could not be fulfilled because the non-AWS identity provider
+//   (IDP) that was asked to verify the incoming identity token could not be reached.
+//   This is often a transient error caused by network conditions. Retry the request
+//   a limited number of times so that you don't exceed the request rate. If the
+//   error persists, the non-AWS identity provider might be down or not responding.
+//
+//   * ErrCodeInvalidIdentityTokenException "InvalidIdentityToken"
+//   The web identity token that was passed could not be validated by AWS. Get
+//   a new identity token from the identity provider and then retry the request.
+//
+//   * ErrCodeExpiredTokenException "ExpiredTokenException"
+//   The web identity token that was passed is expired or is not valid. Get a
+//   new identity token from the identity provider and then retry the request.
+//
+//   * ErrCodeRegionDisabledException "RegionDisabledException"
+//   STS is not activated in the requested region for the account that is being
+//   asked to generate credentials. The account administrator must use the IAM
+//   console to activate STS in that region. For more information, see Activating
+//   and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
+//   in the IAM User Guide.
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentity
+func (c *STS) AssumeRoleWithWebIdentity(input *AssumeRoleWithWebIdentityInput) (*AssumeRoleWithWebIdentityOutput, error) {
+	req, out := c.AssumeRoleWithWebIdentityRequest(input)
+	return out, req.Send()
+}
+
+// AssumeRoleWithWebIdentityWithContext is the same as AssumeRoleWithWebIdentity with the addition of
+// the ability to pass a context and additional request options.
+//
+// See AssumeRoleWithWebIdentity for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *STS) AssumeRoleWithWebIdentityWithContext(ctx aws.Context, input *AssumeRoleWithWebIdentityInput, opts ...request.Option) (*AssumeRoleWithWebIdentityOutput, error) {
+	req, out := c.AssumeRoleWithWebIdentityRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opDecodeAuthorizationMessage = "DecodeAuthorizationMessage"
+
+// DecodeAuthorizationMessageRequest generates a "aws/request.Request" representing the
+// client's request for the DecodeAuthorizationMessage operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See DecodeAuthorizationMessage for more information on using the DecodeAuthorizationMessage
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the DecodeAuthorizationMessageRequest method.
+//    req, resp := client.DecodeAuthorizationMessageRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessage
+func (c *STS) DecodeAuthorizationMessageRequest(input *DecodeAuthorizationMessageInput) (req *request.Request, output *DecodeAuthorizationMessageOutput) {
+	op := &request.Operation{
+		Name:       opDecodeAuthorizationMessage,
+		HTTPMethod: "POST",
+		HTTPPath:   "/",
+	}
+
+	if input == nil {
+		input = &DecodeAuthorizationMessageInput{}
+	}
+
+	output = &DecodeAuthorizationMessageOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// DecodeAuthorizationMessage API operation for AWS Security Token Service.
+//
+// Decodes additional information about the authorization status of a request
+// from an encoded message returned in response to an AWS request.
+//
+// For example, if a user is not authorized to perform an action that he or
+// she has requested, the request returns a Client.UnauthorizedOperation response
+// (an HTTP 403 response). Some AWS actions additionally return an encoded message
+// that can provide details about this authorization failure.
+//
+// Only certain AWS actions return an encoded authorization message. The documentation
+// for an individual action indicates whether that action returns an encoded
+// message in addition to returning an HTTP code.
+//
+// The message is encoded because the details of the authorization status can
+// constitute privileged information that the user who requested the action
+// should not see. To decode an authorization status message, a user must be
+// granted permissions via an IAM policy to request the DecodeAuthorizationMessage
+// (sts:DecodeAuthorizationMessage) action.
+//
+// The decoded message includes the following type of information:
+//
+//    * Whether the request was denied due to an explicit deny or due to the
+//    absence of an explicit allow. For more information, see Determining Whether
+//    a Request is Allowed or Denied (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html#policy-eval-denyallow)
+//    in the IAM User Guide.
+//
+//    * The principal who made the request.
+//
+//    * The requested action.
+//
+//    * The requested resource.
+//
+//    * The values of condition keys in the context of the user's request.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for AWS Security Token Service's
+// API operation DecodeAuthorizationMessage for usage and error information.
+//
+// Returned Error Codes:
+//   * ErrCodeInvalidAuthorizationMessageException "InvalidAuthorizationMessageException"
+//   The error returned if the message passed to DecodeAuthorizationMessage was
+//   invalid. This can happen if the token contains invalid characters, such as
+//   linebreaks.
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessage
+func (c *STS) DecodeAuthorizationMessage(input *DecodeAuthorizationMessageInput) (*DecodeAuthorizationMessageOutput, error) {
+	req, out := c.DecodeAuthorizationMessageRequest(input)
+	return out, req.Send()
+}
+
+// DecodeAuthorizationMessageWithContext is the same as DecodeAuthorizationMessage with the addition of
+// the ability to pass a context and additional request options.
+//
+// See DecodeAuthorizationMessage for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *STS) DecodeAuthorizationMessageWithContext(ctx aws.Context, input *DecodeAuthorizationMessageInput, opts ...request.Option) (*DecodeAuthorizationMessageOutput, error) {
+	req, out := c.DecodeAuthorizationMessageRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetCallerIdentity = "GetCallerIdentity"
+
+// GetCallerIdentityRequest generates a "aws/request.Request" representing the
+// client's request for the GetCallerIdentity operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetCallerIdentity for more information on using the GetCallerIdentity
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetCallerIdentityRequest method.
+//    req, resp := client.GetCallerIdentityRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentity
+func (c *STS) GetCallerIdentityRequest(input *GetCallerIdentityInput) (req *request.Request, output *GetCallerIdentityOutput) {
+	op := &request.Operation{
+		Name:       opGetCallerIdentity,
+		HTTPMethod: "POST",
+		HTTPPath:   "/",
+	}
+
+	if input == nil {
+		input = &GetCallerIdentityInput{}
+	}
+
+	output = &GetCallerIdentityOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetCallerIdentity API operation for AWS Security Token Service.
+//
+// Returns details about the IAM identity whose credentials are used to call
+// the API.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for AWS Security Token Service's
+// API operation GetCallerIdentity for usage and error information.
+// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentity
+func (c *STS) GetCallerIdentity(input *GetCallerIdentityInput) (*GetCallerIdentityOutput, error) {
+	req, out := c.GetCallerIdentityRequest(input)
+	return out, req.Send()
+}
+
+// GetCallerIdentityWithContext is the same as GetCallerIdentity with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetCallerIdentity for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *STS) GetCallerIdentityWithContext(ctx aws.Context, input *GetCallerIdentityInput, opts ...request.Option) (*GetCallerIdentityOutput, error) {
+	req, out := c.GetCallerIdentityRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetFederationToken = "GetFederationToken"
+
+// GetFederationTokenRequest generates a "aws/request.Request" representing the
+// client's request for the GetFederationToken operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetFederationToken for more information on using the GetFederationToken
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetFederationTokenRequest method.
+//    req, resp := client.GetFederationTokenRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationToken
+func (c *STS) GetFederationTokenRequest(input *GetFederationTokenInput) (req *request.Request, output *GetFederationTokenOutput) {
+	op := &request.Operation{
+		Name:       opGetFederationToken,
+		HTTPMethod: "POST",
+		HTTPPath:   "/",
+	}
+
+	if input == nil {
+		input = &GetFederationTokenInput{}
+	}
+
+	output = &GetFederationTokenOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetFederationToken API operation for AWS Security Token Service.
+//
+// Returns a set of temporary security credentials (consisting of an access
+// key ID, a secret access key, and a security token) for a federated user.
+// A typical use is in a proxy application that gets temporary security credentials
+// on behalf of distributed applications inside a corporate network. Because
+// you must call the GetFederationToken action using the long-term security
+// credentials of an IAM user, this call is appropriate in contexts where those
+// credentials can be safely stored, usually in a server-based application.
+// For a comparison of GetFederationToken with the other APIs that produce temporary
+// credentials, see Requesting Temporary Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html)
+// and Comparing the AWS STS APIs (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison)
+// in the IAM User Guide.
+//
+// If you are creating a mobile-based or browser-based app that can authenticate
+// users using a web identity provider like Login with Amazon, Facebook, Google,
+// or an OpenID Connect-compatible identity provider, we recommend that you
+// use Amazon Cognito (http://aws.amazon.com/cognito/) or AssumeRoleWithWebIdentity.
+// For more information, see Federation Through a Web-based Identity Provider
+// (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity).
+//
+// The GetFederationToken action must be called by using the long-term AWS security
+// credentials of an IAM user. You can also call GetFederationToken using the
+// security credentials of an AWS root account, but we do not recommended it.
+// Instead, we recommend that you create an IAM user for the purpose of the
+// proxy application and then attach a policy to the IAM user that limits federated
+// users to only the actions and resources that they need access to. For more
+// information, see IAM Best Practices (http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)
+// in the IAM User Guide.
+//
+// The temporary security credentials that are obtained by using the long-term
+// credentials of an IAM user are valid for the specified duration, from 900
+// seconds (15 minutes) up to a maximium of 129600 seconds (36 hours). The default
+// is 43200 seconds (12 hours). Temporary credentials that are obtained by using
+// AWS root account credentials have a maximum duration of 3600 seconds (1 hour).
+//
+// The temporary security credentials created by GetFederationToken can be used
+// to make API calls to any AWS service with the following exceptions:
+//
+//    * You cannot use these credentials to call any IAM APIs.
+//
+//    * You cannot call any STS APIs except GetCallerIdentity.
+//
+// Permissions
+//
+// The permissions for the temporary security credentials returned by GetFederationToken
+// are determined by a combination of the following:
+//
+//    * The policy or policies that are attached to the IAM user whose credentials
+//    are used to call GetFederationToken.
+//
+//    * The policy that is passed as a parameter in the call.
+//
+// The passed policy is attached to the temporary security credentials that
+// result from the GetFederationToken API call--that is, to the federated user.
+// When the federated user makes an AWS request, AWS evaluates the policy attached
+// to the federated user in combination with the policy or policies attached
+// to the IAM user whose credentials were used to call GetFederationToken. AWS
+// allows the federated user's request only when both the federated user and
+// the IAM user are explicitly allowed to perform the requested action. The
+// passed policy cannot grant more permissions than those that are defined in
+// the IAM user policy.
+//
+// A typical use case is that the permissions of the IAM user whose credentials
+// are used to call GetFederationToken are designed to allow access to all the
+// actions and resources that any federated user will need. Then, for individual
+// users, you pass a policy to the operation that scopes down the permissions
+// to a level that's appropriate to that individual user, using a policy that
+// allows only a subset of permissions that are granted to the IAM user.
+//
+// If you do not pass a policy, the resulting temporary security credentials
+// have no effective permissions. The only exception is when the temporary security
+// credentials are used to access a resource that has a resource-based policy
+// that specifically allows the federated user to access the resource.
+//
+// For more information about how permissions work, see Permissions for GetFederationToken
+// (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_getfederationtoken.html).
+// For information about using GetFederationToken to create temporary security
+// credentials, see GetFederationToken—Federation Through a Custom Identity
+// Broker (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_getfederationtoken).
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for AWS Security Token Service's
+// API operation GetFederationToken for usage and error information.
+//
+// Returned Error Codes:
+//   * ErrCodeMalformedPolicyDocumentException "MalformedPolicyDocument"
+//   The request was rejected because the policy document was malformed. The error
+//   message describes the specific error.
+//
+//   * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge"
+//   The request was rejected because the policy document was too large. The error
+//   message describes how big the policy document is, in packed form, as a percentage
+//   of what the API allows.
+//
+//   * ErrCodeRegionDisabledException "RegionDisabledException"
+//   STS is not activated in the requested region for the account that is being
+//   asked to generate credentials. The account administrator must use the IAM
+//   console to activate STS in that region. For more information, see Activating
+//   and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
+//   in the IAM User Guide.
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationToken
+func (c *STS) GetFederationToken(input *GetFederationTokenInput) (*GetFederationTokenOutput, error) {
+	req, out := c.GetFederationTokenRequest(input)
+	return out, req.Send()
+}
+
+// GetFederationTokenWithContext is the same as GetFederationToken with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetFederationToken for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *STS) GetFederationTokenWithContext(ctx aws.Context, input *GetFederationTokenInput, opts ...request.Option) (*GetFederationTokenOutput, error) {
+	req, out := c.GetFederationTokenRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+const opGetSessionToken = "GetSessionToken"
+
+// GetSessionTokenRequest generates a "aws/request.Request" representing the
+// client's request for the GetSessionToken operation. The "output" return
+// value will be populated with the request's response once the request completes
+// successfuly.
+//
+// Use "Send" method on the returned Request to send the API call to the service.
+// the "output" return value is not valid until after Send returns without error.
+//
+// See GetSessionToken for more information on using the GetSessionToken
+// API call, and error handling.
+//
+// This method is useful when you want to inject custom logic or configuration
+// into the SDK's request lifecycle. Such as custom headers, or retry logic.
+//
+//
+//    // Example sending a request using the GetSessionTokenRequest method.
+//    req, resp := client.GetSessionTokenRequest(params)
+//
+//    err := req.Send()
+//    if err == nil { // resp is now filled
+//        fmt.Println(resp)
+//    }
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionToken
+func (c *STS) GetSessionTokenRequest(input *GetSessionTokenInput) (req *request.Request, output *GetSessionTokenOutput) {
+	op := &request.Operation{
+		Name:       opGetSessionToken,
+		HTTPMethod: "POST",
+		HTTPPath:   "/",
+	}
+
+	if input == nil {
+		input = &GetSessionTokenInput{}
+	}
+
+	output = &GetSessionTokenOutput{}
+	req = c.newRequest(op, input, output)
+	return
+}
+
+// GetSessionToken API operation for AWS Security Token Service.
+//
+// Returns a set of temporary credentials for an AWS account or IAM user. The
+// credentials consist of an access key ID, a secret access key, and a security
+// token. Typically, you use GetSessionToken if you want to use MFA to protect
+// programmatic calls to specific AWS APIs like Amazon EC2 StopInstances. MFA-enabled
+// IAM users would need to call GetSessionToken and submit an MFA code that
+// is associated with their MFA device. Using the temporary security credentials
+// that are returned from the call, IAM users can then make programmatic calls
+// to APIs that require MFA authentication. If you do not supply a correct MFA
+// code, then the API returns an access denied error. For a comparison of GetSessionToken
+// with the other APIs that produce temporary credentials, see Requesting Temporary
+// Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html)
+// and Comparing the AWS STS APIs (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison)
+// in the IAM User Guide.
+//
+// The GetSessionToken action must be called by using the long-term AWS security
+// credentials of the AWS account or an IAM user. Credentials that are created
+// by IAM users are valid for the duration that you specify, from 900 seconds
+// (15 minutes) up to a maximum of 129600 seconds (36 hours), with a default
+// of 43200 seconds (12 hours); credentials that are created by using account
+// credentials can range from 900 seconds (15 minutes) up to a maximum of 3600
+// seconds (1 hour), with a default of 1 hour.
+//
+// The temporary security credentials created by GetSessionToken can be used
+// to make API calls to any AWS service with the following exceptions:
+//
+//    * You cannot call any IAM APIs unless MFA authentication information is
+//    included in the request.
+//
+//    * You cannot call any STS API exceptAssumeRole or GetCallerIdentity.
+//
+// We recommend that you do not call GetSessionToken with root account credentials.
+// Instead, follow our best practices (http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#create-iam-users)
+// by creating one or more IAM users, giving them the necessary permissions,
+// and using IAM users for everyday interaction with AWS.
+//
+// The permissions associated with the temporary security credentials returned
+// by GetSessionToken are based on the permissions associated with account or
+// IAM user whose credentials are used to call the action. If GetSessionToken
+// is called using root account credentials, the temporary credentials have
+// root account permissions. Similarly, if GetSessionToken is called using the
+// credentials of an IAM user, the temporary credentials have the same permissions
+// as the IAM user.
+//
+// For more information about using GetSessionToken to create temporary credentials,
+// go to Temporary Credentials for Users in Untrusted Environments (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_getsessiontoken)
+// in the IAM User Guide.
+//
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
+// with awserr.Error's Code and Message methods to get detailed information about
+// the error.
+//
+// See the AWS API reference guide for AWS Security Token Service's
+// API operation GetSessionToken for usage and error information.
+//
+// Returned Error Codes:
+//   * ErrCodeRegionDisabledException "RegionDisabledException"
+//   STS is not activated in the requested region for the account that is being
+//   asked to generate credentials. The account administrator must use the IAM
+//   console to activate STS in that region. For more information, see Activating
+//   and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
+//   in the IAM User Guide.
+//
+// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionToken
+func (c *STS) GetSessionToken(input *GetSessionTokenInput) (*GetSessionTokenOutput, error) {
+	req, out := c.GetSessionTokenRequest(input)
+	return out, req.Send()
+}
+
+// GetSessionTokenWithContext is the same as GetSessionToken with the addition of
+// the ability to pass a context and additional request options.
+//
+// See GetSessionToken for details on how to use this API operation.
+//
+// The context must be non-nil and will be used for request cancellation. If
+// the context is nil a panic will occur. In the future the SDK may create
+// sub-contexts for http.Requests. See https://golang.org/pkg/context/
+// for more information on using Contexts.
+func (c *STS) GetSessionTokenWithContext(ctx aws.Context, input *GetSessionTokenInput, opts ...request.Option) (*GetSessionTokenOutput, error) {
+	req, out := c.GetSessionTokenRequest(input)
+	req.SetContext(ctx)
+	req.ApplyOptions(opts...)
+	return out, req.Send()
+}
+
+type AssumeRoleInput struct {
+	_ struct{} `type:"structure"`
+
+	// The duration, in seconds, of the role session. The value can range from 900
+	// seconds (15 minutes) up to the maximum session duration setting for the role.
+	// This setting can have a value from 1 hour to 12 hours. If you specify a value
+	// higher than this setting, the operation fails. For example, if you specify
+	// a session duration of 12 hours, but your administrator set the maximum session
+	// duration to 6 hours, your operation fails. To learn how to view the maximum
+	// value for your role, see View the Maximum Session Duration Setting for a
+	// Role (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session)
+	// in the IAM User Guide.
+	//
+	// By default, the value is set to 3600 seconds.
+	//
+	// The DurationSeconds parameter is separate from the duration of a console
+	// session that you might request using the returned credentials. The request
+	// to the federation endpoint for a console sign-in token takes a SessionDuration
+	// parameter that specifies the maximum length of the console session. For more
+	// information, see Creating a URL that Enables Federated Users to Access the
+	// AWS Management Console (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html)
+	// in the IAM User Guide.
+	DurationSeconds *int64 `min:"900" type:"integer"`
+
+	// A unique identifier that is used by third parties when assuming roles in
+	// their customers' accounts. For each role that the third party can assume,
+	// they should instruct their customers to ensure the role's trust policy checks
+	// for the external ID that the third party generated. Each time the third party
+	// assumes the role, they should pass the customer's external ID. The external
+	// ID is useful in order to help third parties bind a role to the customer who
+	// created it. For more information about the external ID, see How to Use an
+	// External ID When Granting Access to Your AWS Resources to a Third Party (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html)
+	// in the IAM User Guide.
+	//
+	// The regex used to validated this parameter is a string of characters consisting
+	// of upper- and lower-case alphanumeric characters with no spaces. You can
+	// also include underscores or any of the following characters: =,.@:/-
+	ExternalId *string `min:"2" type:"string"`
+
+	// An IAM policy in JSON format.
+	//
+	// This parameter is optional. If you pass a policy, the temporary security
+	// credentials that are returned by the operation have the permissions that
+	// are allowed by both (the intersection of) the access policy of the role that
+	// is being assumed, and the policy that you pass. This gives you a way to further
+	// restrict the permissions for the resulting temporary security credentials.
+	// You cannot use the passed policy to grant permissions that are in excess
+	// of those allowed by the access policy of the role that is being assumed.
+	// For more information, see Permissions for AssumeRole, AssumeRoleWithSAML,
+	// and AssumeRoleWithWebIdentity (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html)
+	// in the IAM User Guide.
+	//
+	// The format for this parameter, as described by its regex pattern, is a string
+	// of characters up to 2048 characters in length. The characters can be any
+	// ASCII character from the space character to the end of the valid character
+	// list (\u0020-\u00FF). It can also include the tab (\u0009), linefeed (\u000A),
+	// and carriage return (\u000D) characters.
+	//
+	// The policy plain text must be 2048 bytes or shorter. However, an internal
+	// conversion compresses it into a packed binary format with a separate limit.
+	// The PackedPolicySize response element indicates by percentage how close to
+	// the upper size limit the policy is, with 100% equaling the maximum allowed
+	// size.
+	Policy *string `min:"1" type:"string"`
+
+	// The Amazon Resource Name (ARN) of the role to assume.
+	//
+	// RoleArn is a required field
+	RoleArn *string `min:"20" type:"string" required:"true"`
+
+	// An identifier for the assumed role session.
+	//
+	// Use the role session name to uniquely identify a session when the same role
+	// is assumed by different principals or for different reasons. In cross-account
+	// scenarios, the role session name is visible to, and can be logged by the
+	// account that owns the role. The role session name is also used in the ARN
+	// of the assumed role principal. This means that subsequent cross-account API
+	// requests using the temporary security credentials will expose the role session
+	// name to the external account in their CloudTrail logs.
+	//
+	// The regex used to validate this parameter is a string of characters consisting
+	// of upper- and lower-case alphanumeric characters with no spaces. You can
+	// also include underscores or any of the following characters: =,.@-
+	//
+	// RoleSessionName is a required field
+	RoleSessionName *string `min:"2" type:"string" required:"true"`
+
+	// The identification number of the MFA device that is associated with the user
+	// who is making the AssumeRole call. Specify this value if the trust policy
+	// of the role being assumed includes a condition that requires MFA authentication.
+	// The value is either the serial number for a hardware device (such as GAHT12345678)
+	// or an Amazon Resource Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user).
+	//
+	// The regex used to validate this parameter is a string of characters consisting
+	// of upper- and lower-case alphanumeric characters with no spaces. You can
+	// also include underscores or any of the following characters: =,.@-
+	SerialNumber *string `min:"9" type:"string"`
+
+	// The value provided by the MFA device, if the trust policy of the role being
+	// assumed requires MFA (that is, if the policy includes a condition that tests
+	// for MFA). If the role being assumed requires MFA and if the TokenCode value
+	// is missing or expired, the AssumeRole call returns an "access denied" error.
+	//
+	// The format for this parameter, as described by its regex pattern, is a sequence
+	// of six numeric digits.
+	TokenCode *string `min:"6" type:"string"`
+}
+
+// String returns the string representation
+func (s AssumeRoleInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AssumeRoleInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *AssumeRoleInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "AssumeRoleInput"}
+	if s.DurationSeconds != nil && *s.DurationSeconds < 900 {
+		invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900))
+	}
+	if s.ExternalId != nil && len(*s.ExternalId) < 2 {
+		invalidParams.Add(request.NewErrParamMinLen("ExternalId", 2))
+	}
+	if s.Policy != nil && len(*s.Policy) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Policy", 1))
+	}
+	if s.RoleArn == nil {
+		invalidParams.Add(request.NewErrParamRequired("RoleArn"))
+	}
+	if s.RoleArn != nil && len(*s.RoleArn) < 20 {
+		invalidParams.Add(request.NewErrParamMinLen("RoleArn", 20))
+	}
+	if s.RoleSessionName == nil {
+		invalidParams.Add(request.NewErrParamRequired("RoleSessionName"))
+	}
+	if s.RoleSessionName != nil && len(*s.RoleSessionName) < 2 {
+		invalidParams.Add(request.NewErrParamMinLen("RoleSessionName", 2))
+	}
+	if s.SerialNumber != nil && len(*s.SerialNumber) < 9 {
+		invalidParams.Add(request.NewErrParamMinLen("SerialNumber", 9))
+	}
+	if s.TokenCode != nil && len(*s.TokenCode) < 6 {
+		invalidParams.Add(request.NewErrParamMinLen("TokenCode", 6))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetDurationSeconds sets the DurationSeconds field's value.
+func (s *AssumeRoleInput) SetDurationSeconds(v int64) *AssumeRoleInput {
+	s.DurationSeconds = &v
+	return s
+}
+
+// SetExternalId sets the ExternalId field's value.
+func (s *AssumeRoleInput) SetExternalId(v string) *AssumeRoleInput {
+	s.ExternalId = &v
+	return s
+}
+
+// SetPolicy sets the Policy field's value.
+func (s *AssumeRoleInput) SetPolicy(v string) *AssumeRoleInput {
+	s.Policy = &v
+	return s
+}
+
+// SetRoleArn sets the RoleArn field's value.
+func (s *AssumeRoleInput) SetRoleArn(v string) *AssumeRoleInput {
+	s.RoleArn = &v
+	return s
+}
+
+// SetRoleSessionName sets the RoleSessionName field's value.
+func (s *AssumeRoleInput) SetRoleSessionName(v string) *AssumeRoleInput {
+	s.RoleSessionName = &v
+	return s
+}
+
+// SetSerialNumber sets the SerialNumber field's value.
+func (s *AssumeRoleInput) SetSerialNumber(v string) *AssumeRoleInput {
+	s.SerialNumber = &v
+	return s
+}
+
+// SetTokenCode sets the TokenCode field's value.
+func (s *AssumeRoleInput) SetTokenCode(v string) *AssumeRoleInput {
+	s.TokenCode = &v
+	return s
+}
+
+// Contains the response to a successful AssumeRole request, including temporary
+// AWS credentials that can be used to make AWS requests.
+type AssumeRoleOutput struct {
+	_ struct{} `type:"structure"`
+
+	// The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers
+	// that you can use to refer to the resulting temporary security credentials.
+	// For example, you can reference these credentials as a principal in a resource-based
+	// policy by using the ARN or assumed role ID. The ARN and ID include the RoleSessionName
+	// that you specified when you called AssumeRole.
+	AssumedRoleUser *AssumedRoleUser `type:"structure"`
+
+	// The temporary security credentials, which include an access key ID, a secret
+	// access key, and a security (or session) token.
+	//
+	// Note: The size of the security token that STS APIs return is not fixed. We
+	// strongly recommend that you make no assumptions about the maximum size. As
+	// of this writing, the typical size is less than 4096 bytes, but that can vary.
+	// Also, future updates to AWS might require larger sizes.
+	Credentials *Credentials `type:"structure"`
+
+	// A percentage value that indicates the size of the policy in packed form.
+	// The service rejects any policy with a packed size greater than 100 percent,
+	// which means the policy exceeded the allowed space.
+	PackedPolicySize *int64 `type:"integer"`
+}
+
+// String returns the string representation
+func (s AssumeRoleOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AssumeRoleOutput) GoString() string {
+	return s.String()
+}
+
+// SetAssumedRoleUser sets the AssumedRoleUser field's value.
+func (s *AssumeRoleOutput) SetAssumedRoleUser(v *AssumedRoleUser) *AssumeRoleOutput {
+	s.AssumedRoleUser = v
+	return s
+}
+
+// SetCredentials sets the Credentials field's value.
+func (s *AssumeRoleOutput) SetCredentials(v *Credentials) *AssumeRoleOutput {
+	s.Credentials = v
+	return s
+}
+
+// SetPackedPolicySize sets the PackedPolicySize field's value.
+func (s *AssumeRoleOutput) SetPackedPolicySize(v int64) *AssumeRoleOutput {
+	s.PackedPolicySize = &v
+	return s
+}
+
+type AssumeRoleWithSAMLInput struct {
+	_ struct{} `type:"structure"`
+
+	// The duration, in seconds, of the role session. Your role session lasts for
+	// the duration that you specify for the DurationSeconds parameter, or until
+	// the time specified in the SAML authentication response's SessionNotOnOrAfter
+	// value, whichever is shorter. You can provide a DurationSeconds value from
+	// 900 seconds (15 minutes) up to the maximum session duration setting for the
+	// role. This setting can have a value from 1 hour to 12 hours. If you specify
+	// a value higher than this setting, the operation fails. For example, if you
+	// specify a session duration of 12 hours, but your administrator set the maximum
+	// session duration to 6 hours, your operation fails. To learn how to view the
+	// maximum value for your role, see View the Maximum Session Duration Setting
+	// for a Role (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session)
+	// in the IAM User Guide.
+	//
+	// By default, the value is set to 3600 seconds.
+	//
+	// The DurationSeconds parameter is separate from the duration of a console
+	// session that you might request using the returned credentials. The request
+	// to the federation endpoint for a console sign-in token takes a SessionDuration
+	// parameter that specifies the maximum length of the console session. For more
+	// information, see Creating a URL that Enables Federated Users to Access the
+	// AWS Management Console (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html)
+	// in the IAM User Guide.
+	DurationSeconds *int64 `min:"900" type:"integer"`
+
+	// An IAM policy in JSON format.
+	//
+	// The policy parameter is optional. If you pass a policy, the temporary security
+	// credentials that are returned by the operation have the permissions that
+	// are allowed by both the access policy of the role that is being assumed,
+	// and the policy that you pass. This gives you a way to further restrict the
+	// permissions for the resulting temporary security credentials. You cannot
+	// use the passed policy to grant permissions that are in excess of those allowed
+	// by the access policy of the role that is being assumed. For more information,
+	// Permissions for AssumeRole, AssumeRoleWithSAML, and AssumeRoleWithWebIdentity
+	// (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html)
+	// in the IAM User Guide.
+	//
+	// The format for this parameter, as described by its regex pattern, is a string
+	// of characters up to 2048 characters in length. The characters can be any
+	// ASCII character from the space character to the end of the valid character
+	// list (\u0020-\u00FF). It can also include the tab (\u0009), linefeed (\u000A),
+	// and carriage return (\u000D) characters.
+	//
+	// The policy plain text must be 2048 bytes or shorter. However, an internal
+	// conversion compresses it into a packed binary format with a separate limit.
+	// The PackedPolicySize response element indicates by percentage how close to
+	// the upper size limit the policy is, with 100% equaling the maximum allowed
+	// size.
+	Policy *string `min:"1" type:"string"`
+
+	// The Amazon Resource Name (ARN) of the SAML provider in IAM that describes
+	// the IdP.
+	//
+	// PrincipalArn is a required field
+	PrincipalArn *string `min:"20" type:"string" required:"true"`
+
+	// The Amazon Resource Name (ARN) of the role that the caller is assuming.
+	//
+	// RoleArn is a required field
+	RoleArn *string `min:"20" type:"string" required:"true"`
+
+	// The base-64 encoded SAML authentication response provided by the IdP.
+	//
+	// For more information, see Configuring a Relying Party and Adding Claims (http://docs.aws.amazon.com/IAM/latest/UserGuide/create-role-saml-IdP-tasks.html)
+	// in the Using IAM guide.
+	//
+	// SAMLAssertion is a required field
+	SAMLAssertion *string `min:"4" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s AssumeRoleWithSAMLInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AssumeRoleWithSAMLInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *AssumeRoleWithSAMLInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "AssumeRoleWithSAMLInput"}
+	if s.DurationSeconds != nil && *s.DurationSeconds < 900 {
+		invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900))
+	}
+	if s.Policy != nil && len(*s.Policy) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Policy", 1))
+	}
+	if s.PrincipalArn == nil {
+		invalidParams.Add(request.NewErrParamRequired("PrincipalArn"))
+	}
+	if s.PrincipalArn != nil && len(*s.PrincipalArn) < 20 {
+		invalidParams.Add(request.NewErrParamMinLen("PrincipalArn", 20))
+	}
+	if s.RoleArn == nil {
+		invalidParams.Add(request.NewErrParamRequired("RoleArn"))
+	}
+	if s.RoleArn != nil && len(*s.RoleArn) < 20 {
+		invalidParams.Add(request.NewErrParamMinLen("RoleArn", 20))
+	}
+	if s.SAMLAssertion == nil {
+		invalidParams.Add(request.NewErrParamRequired("SAMLAssertion"))
+	}
+	if s.SAMLAssertion != nil && len(*s.SAMLAssertion) < 4 {
+		invalidParams.Add(request.NewErrParamMinLen("SAMLAssertion", 4))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetDurationSeconds sets the DurationSeconds field's value.
+func (s *AssumeRoleWithSAMLInput) SetDurationSeconds(v int64) *AssumeRoleWithSAMLInput {
+	s.DurationSeconds = &v
+	return s
+}
+
+// SetPolicy sets the Policy field's value.
+func (s *AssumeRoleWithSAMLInput) SetPolicy(v string) *AssumeRoleWithSAMLInput {
+	s.Policy = &v
+	return s
+}
+
+// SetPrincipalArn sets the PrincipalArn field's value.
+func (s *AssumeRoleWithSAMLInput) SetPrincipalArn(v string) *AssumeRoleWithSAMLInput {
+	s.PrincipalArn = &v
+	return s
+}
+
+// SetRoleArn sets the RoleArn field's value.
+func (s *AssumeRoleWithSAMLInput) SetRoleArn(v string) *AssumeRoleWithSAMLInput {
+	s.RoleArn = &v
+	return s
+}
+
+// SetSAMLAssertion sets the SAMLAssertion field's value.
+func (s *AssumeRoleWithSAMLInput) SetSAMLAssertion(v string) *AssumeRoleWithSAMLInput {
+	s.SAMLAssertion = &v
+	return s
+}
+
+// Contains the response to a successful AssumeRoleWithSAML request, including
+// temporary AWS credentials that can be used to make AWS requests.
+type AssumeRoleWithSAMLOutput struct {
+	_ struct{} `type:"structure"`
+
+	// The identifiers for the temporary security credentials that the operation
+	// returns.
+	AssumedRoleUser *AssumedRoleUser `type:"structure"`
+
+	// The value of the Recipient attribute of the SubjectConfirmationData element
+	// of the SAML assertion.
+	Audience *string `type:"string"`
+
+	// The temporary security credentials, which include an access key ID, a secret
+	// access key, and a security (or session) token.
+	//
+	// Note: The size of the security token that STS APIs return is not fixed. We
+	// strongly recommend that you make no assumptions about the maximum size. As
+	// of this writing, the typical size is less than 4096 bytes, but that can vary.
+	// Also, future updates to AWS might require larger sizes.
+	Credentials *Credentials `type:"structure"`
+
+	// The value of the Issuer element of the SAML assertion.
+	Issuer *string `type:"string"`
+
+	// A hash value based on the concatenation of the Issuer response value, the
+	// AWS account ID, and the friendly name (the last part of the ARN) of the SAML
+	// provider in IAM. The combination of NameQualifier and Subject can be used
+	// to uniquely identify a federated user.
+	//
+	// The following pseudocode shows how the hash value is calculated:
+	//
+	// BASE64 ( SHA1 ( "https://example.com/saml" + "123456789012" + "/MySAMLIdP"
+	// ) )
+	NameQualifier *string `type:"string"`
+
+	// A percentage value that indicates the size of the policy in packed form.
+	// The service rejects any policy with a packed size greater than 100 percent,
+	// which means the policy exceeded the allowed space.
+	PackedPolicySize *int64 `type:"integer"`
+
+	// The value of the NameID element in the Subject element of the SAML assertion.
+	Subject *string `type:"string"`
+
+	// The format of the name ID, as defined by the Format attribute in the NameID
+	// element of the SAML assertion. Typical examples of the format are transient
+	// or persistent.
+	//
+	// If the format includes the prefix urn:oasis:names:tc:SAML:2.0:nameid-format,
+	// that prefix is removed. For example, urn:oasis:names:tc:SAML:2.0:nameid-format:transient
+	// is returned as transient. If the format includes any other prefix, the format
+	// is returned with no modifications.
+	SubjectType *string `type:"string"`
+}
+
+// String returns the string representation
+func (s AssumeRoleWithSAMLOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AssumeRoleWithSAMLOutput) GoString() string {
+	return s.String()
+}
+
+// SetAssumedRoleUser sets the AssumedRoleUser field's value.
+func (s *AssumeRoleWithSAMLOutput) SetAssumedRoleUser(v *AssumedRoleUser) *AssumeRoleWithSAMLOutput {
+	s.AssumedRoleUser = v
+	return s
+}
+
+// SetAudience sets the Audience field's value.
+func (s *AssumeRoleWithSAMLOutput) SetAudience(v string) *AssumeRoleWithSAMLOutput {
+	s.Audience = &v
+	return s
+}
+
+// SetCredentials sets the Credentials field's value.
+func (s *AssumeRoleWithSAMLOutput) SetCredentials(v *Credentials) *AssumeRoleWithSAMLOutput {
+	s.Credentials = v
+	return s
+}
+
+// SetIssuer sets the Issuer field's value.
+func (s *AssumeRoleWithSAMLOutput) SetIssuer(v string) *AssumeRoleWithSAMLOutput {
+	s.Issuer = &v
+	return s
+}
+
+// SetNameQualifier sets the NameQualifier field's value.
+func (s *AssumeRoleWithSAMLOutput) SetNameQualifier(v string) *AssumeRoleWithSAMLOutput {
+	s.NameQualifier = &v
+	return s
+}
+
+// SetPackedPolicySize sets the PackedPolicySize field's value.
+func (s *AssumeRoleWithSAMLOutput) SetPackedPolicySize(v int64) *AssumeRoleWithSAMLOutput {
+	s.PackedPolicySize = &v
+	return s
+}
+
+// SetSubject sets the Subject field's value.
+func (s *AssumeRoleWithSAMLOutput) SetSubject(v string) *AssumeRoleWithSAMLOutput {
+	s.Subject = &v
+	return s
+}
+
+// SetSubjectType sets the SubjectType field's value.
+func (s *AssumeRoleWithSAMLOutput) SetSubjectType(v string) *AssumeRoleWithSAMLOutput {
+	s.SubjectType = &v
+	return s
+}
+
+type AssumeRoleWithWebIdentityInput struct {
+	_ struct{} `type:"structure"`
+
+	// The duration, in seconds, of the role session. The value can range from 900
+	// seconds (15 minutes) up to the maximum session duration setting for the role.
+	// This setting can have a value from 1 hour to 12 hours. If you specify a value
+	// higher than this setting, the operation fails. For example, if you specify
+	// a session duration of 12 hours, but your administrator set the maximum session
+	// duration to 6 hours, your operation fails. To learn how to view the maximum
+	// value for your role, see View the Maximum Session Duration Setting for a
+	// Role (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session)
+	// in the IAM User Guide.
+	//
+	// By default, the value is set to 3600 seconds.
+	//
+	// The DurationSeconds parameter is separate from the duration of a console
+	// session that you might request using the returned credentials. The request
+	// to the federation endpoint for a console sign-in token takes a SessionDuration
+	// parameter that specifies the maximum length of the console session. For more
+	// information, see Creating a URL that Enables Federated Users to Access the
+	// AWS Management Console (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html)
+	// in the IAM User Guide.
+	DurationSeconds *int64 `min:"900" type:"integer"`
+
+	// An IAM policy in JSON format.
+	//
+	// The policy parameter is optional. If you pass a policy, the temporary security
+	// credentials that are returned by the operation have the permissions that
+	// are allowed by both the access policy of the role that is being assumed,
+	// and the policy that you pass. This gives you a way to further restrict the
+	// permissions for the resulting temporary security credentials. You cannot
+	// use the passed policy to grant permissions that are in excess of those allowed
+	// by the access policy of the role that is being assumed. For more information,
+	// see Permissions for AssumeRoleWithWebIdentity (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html)
+	// in the IAM User Guide.
+	//
+	// The format for this parameter, as described by its regex pattern, is a string
+	// of characters up to 2048 characters in length. The characters can be any
+	// ASCII character from the space character to the end of the valid character
+	// list (\u0020-\u00FF). It can also include the tab (\u0009), linefeed (\u000A),
+	// and carriage return (\u000D) characters.
+	//
+	// The policy plain text must be 2048 bytes or shorter. However, an internal
+	// conversion compresses it into a packed binary format with a separate limit.
+	// The PackedPolicySize response element indicates by percentage how close to
+	// the upper size limit the policy is, with 100% equaling the maximum allowed
+	// size.
+	Policy *string `min:"1" type:"string"`
+
+	// The fully qualified host component of the domain name of the identity provider.
+	//
+	// Specify this value only for OAuth 2.0 access tokens. Currently www.amazon.com
+	// and graph.facebook.com are the only supported identity providers for OAuth
+	// 2.0 access tokens. Do not include URL schemes and port numbers.
+	//
+	// Do not specify this value for OpenID Connect ID tokens.
+	ProviderId *string `min:"4" type:"string"`
+
+	// The Amazon Resource Name (ARN) of the role that the caller is assuming.
+	//
+	// RoleArn is a required field
+	RoleArn *string `min:"20" type:"string" required:"true"`
+
+	// An identifier for the assumed role session. Typically, you pass the name
+	// or identifier that is associated with the user who is using your application.
+	// That way, the temporary security credentials that your application will use
+	// are associated with that user. This session name is included as part of the
+	// ARN and assumed role ID in the AssumedRoleUser response element.
+	//
+	// The regex used to validate this parameter is a string of characters consisting
+	// of upper- and lower-case alphanumeric characters with no spaces. You can
+	// also include underscores or any of the following characters: =,.@-
+	//
+	// RoleSessionName is a required field
+	RoleSessionName *string `min:"2" type:"string" required:"true"`
+
+	// The OAuth 2.0 access token or OpenID Connect ID token that is provided by
+	// the identity provider. Your application must get this token by authenticating
+	// the user who is using your application with a web identity provider before
+	// the application makes an AssumeRoleWithWebIdentity call.
+	//
+	// WebIdentityToken is a required field
+	WebIdentityToken *string `min:"4" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s AssumeRoleWithWebIdentityInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AssumeRoleWithWebIdentityInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *AssumeRoleWithWebIdentityInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "AssumeRoleWithWebIdentityInput"}
+	if s.DurationSeconds != nil && *s.DurationSeconds < 900 {
+		invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900))
+	}
+	if s.Policy != nil && len(*s.Policy) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Policy", 1))
+	}
+	if s.ProviderId != nil && len(*s.ProviderId) < 4 {
+		invalidParams.Add(request.NewErrParamMinLen("ProviderId", 4))
+	}
+	if s.RoleArn == nil {
+		invalidParams.Add(request.NewErrParamRequired("RoleArn"))
+	}
+	if s.RoleArn != nil && len(*s.RoleArn) < 20 {
+		invalidParams.Add(request.NewErrParamMinLen("RoleArn", 20))
+	}
+	if s.RoleSessionName == nil {
+		invalidParams.Add(request.NewErrParamRequired("RoleSessionName"))
+	}
+	if s.RoleSessionName != nil && len(*s.RoleSessionName) < 2 {
+		invalidParams.Add(request.NewErrParamMinLen("RoleSessionName", 2))
+	}
+	if s.WebIdentityToken == nil {
+		invalidParams.Add(request.NewErrParamRequired("WebIdentityToken"))
+	}
+	if s.WebIdentityToken != nil && len(*s.WebIdentityToken) < 4 {
+		invalidParams.Add(request.NewErrParamMinLen("WebIdentityToken", 4))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetDurationSeconds sets the DurationSeconds field's value.
+func (s *AssumeRoleWithWebIdentityInput) SetDurationSeconds(v int64) *AssumeRoleWithWebIdentityInput {
+	s.DurationSeconds = &v
+	return s
+}
+
+// SetPolicy sets the Policy field's value.
+func (s *AssumeRoleWithWebIdentityInput) SetPolicy(v string) *AssumeRoleWithWebIdentityInput {
+	s.Policy = &v
+	return s
+}
+
+// SetProviderId sets the ProviderId field's value.
+func (s *AssumeRoleWithWebIdentityInput) SetProviderId(v string) *AssumeRoleWithWebIdentityInput {
+	s.ProviderId = &v
+	return s
+}
+
+// SetRoleArn sets the RoleArn field's value.
+func (s *AssumeRoleWithWebIdentityInput) SetRoleArn(v string) *AssumeRoleWithWebIdentityInput {
+	s.RoleArn = &v
+	return s
+}
+
+// SetRoleSessionName sets the RoleSessionName field's value.
+func (s *AssumeRoleWithWebIdentityInput) SetRoleSessionName(v string) *AssumeRoleWithWebIdentityInput {
+	s.RoleSessionName = &v
+	return s
+}
+
+// SetWebIdentityToken sets the WebIdentityToken field's value.
+func (s *AssumeRoleWithWebIdentityInput) SetWebIdentityToken(v string) *AssumeRoleWithWebIdentityInput {
+	s.WebIdentityToken = &v
+	return s
+}
+
+// Contains the response to a successful AssumeRoleWithWebIdentity request,
+// including temporary AWS credentials that can be used to make AWS requests.
+type AssumeRoleWithWebIdentityOutput struct {
+	_ struct{} `type:"structure"`
+
+	// The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers
+	// that you can use to refer to the resulting temporary security credentials.
+	// For example, you can reference these credentials as a principal in a resource-based
+	// policy by using the ARN or assumed role ID. The ARN and ID include the RoleSessionName
+	// that you specified when you called AssumeRole.
+	AssumedRoleUser *AssumedRoleUser `type:"structure"`
+
+	// The intended audience (also known as client ID) of the web identity token.
+	// This is traditionally the client identifier issued to the application that
+	// requested the web identity token.
+	Audience *string `type:"string"`
+
+	// The temporary security credentials, which include an access key ID, a secret
+	// access key, and a security token.
+	//
+	// Note: The size of the security token that STS APIs return is not fixed. We
+	// strongly recommend that you make no assumptions about the maximum size. As
+	// of this writing, the typical size is less than 4096 bytes, but that can vary.
+	// Also, future updates to AWS might require larger sizes.
+	Credentials *Credentials `type:"structure"`
+
+	// A percentage value that indicates the size of the policy in packed form.
+	// The service rejects any policy with a packed size greater than 100 percent,
+	// which means the policy exceeded the allowed space.
+	PackedPolicySize *int64 `type:"integer"`
+
+	// The issuing authority of the web identity token presented. For OpenID Connect
+	// ID Tokens this contains the value of the iss field. For OAuth 2.0 access
+	// tokens, this contains the value of the ProviderId parameter that was passed
+	// in the AssumeRoleWithWebIdentity request.
+	Provider *string `type:"string"`
+
+	// The unique user identifier that is returned by the identity provider. This
+	// identifier is associated with the WebIdentityToken that was submitted with
+	// the AssumeRoleWithWebIdentity call. The identifier is typically unique to
+	// the user and the application that acquired the WebIdentityToken (pairwise
+	// identifier). For OpenID Connect ID tokens, this field contains the value
+	// returned by the identity provider as the token's sub (Subject) claim.
+	SubjectFromWebIdentityToken *string `min:"6" type:"string"`
+}
+
+// String returns the string representation
+func (s AssumeRoleWithWebIdentityOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AssumeRoleWithWebIdentityOutput) GoString() string {
+	return s.String()
+}
+
+// SetAssumedRoleUser sets the AssumedRoleUser field's value.
+func (s *AssumeRoleWithWebIdentityOutput) SetAssumedRoleUser(v *AssumedRoleUser) *AssumeRoleWithWebIdentityOutput {
+	s.AssumedRoleUser = v
+	return s
+}
+
+// SetAudience sets the Audience field's value.
+func (s *AssumeRoleWithWebIdentityOutput) SetAudience(v string) *AssumeRoleWithWebIdentityOutput {
+	s.Audience = &v
+	return s
+}
+
+// SetCredentials sets the Credentials field's value.
+func (s *AssumeRoleWithWebIdentityOutput) SetCredentials(v *Credentials) *AssumeRoleWithWebIdentityOutput {
+	s.Credentials = v
+	return s
+}
+
+// SetPackedPolicySize sets the PackedPolicySize field's value.
+func (s *AssumeRoleWithWebIdentityOutput) SetPackedPolicySize(v int64) *AssumeRoleWithWebIdentityOutput {
+	s.PackedPolicySize = &v
+	return s
+}
+
+// SetProvider sets the Provider field's value.
+func (s *AssumeRoleWithWebIdentityOutput) SetProvider(v string) *AssumeRoleWithWebIdentityOutput {
+	s.Provider = &v
+	return s
+}
+
+// SetSubjectFromWebIdentityToken sets the SubjectFromWebIdentityToken field's value.
+func (s *AssumeRoleWithWebIdentityOutput) SetSubjectFromWebIdentityToken(v string) *AssumeRoleWithWebIdentityOutput {
+	s.SubjectFromWebIdentityToken = &v
+	return s
+}
+
+// The identifiers for the temporary security credentials that the operation
+// returns.
+type AssumedRoleUser struct {
+	_ struct{} `type:"structure"`
+
+	// The ARN of the temporary security credentials that are returned from the
+	// AssumeRole action. For more information about ARNs and how to use them in
+	// policies, see IAM Identifiers (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html)
+	// in Using IAM.
+	//
+	// Arn is a required field
+	Arn *string `min:"20" type:"string" required:"true"`
+
+	// A unique identifier that contains the role ID and the role session name of
+	// the role that is being assumed. The role ID is generated by AWS when the
+	// role is created.
+	//
+	// AssumedRoleId is a required field
+	AssumedRoleId *string `min:"2" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s AssumedRoleUser) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AssumedRoleUser) GoString() string {
+	return s.String()
+}
+
+// SetArn sets the Arn field's value.
+func (s *AssumedRoleUser) SetArn(v string) *AssumedRoleUser {
+	s.Arn = &v
+	return s
+}
+
+// SetAssumedRoleId sets the AssumedRoleId field's value.
+func (s *AssumedRoleUser) SetAssumedRoleId(v string) *AssumedRoleUser {
+	s.AssumedRoleId = &v
+	return s
+}
+
+// AWS credentials for API authentication.
+type Credentials struct {
+	_ struct{} `type:"structure"`
+
+	// The access key ID that identifies the temporary security credentials.
+	//
+	// AccessKeyId is a required field
+	AccessKeyId *string `min:"16" type:"string" required:"true"`
+
+	// The date on which the current credentials expire.
+	//
+	// Expiration is a required field
+	Expiration *time.Time `type:"timestamp" required:"true"`
+
+	// The secret access key that can be used to sign requests.
+	//
+	// SecretAccessKey is a required field
+	SecretAccessKey *string `type:"string" required:"true"`
+
+	// The token that users must pass to the service API to use the temporary credentials.
+	//
+	// SessionToken is a required field
+	SessionToken *string `type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s Credentials) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s Credentials) GoString() string {
+	return s.String()
+}
+
+// SetAccessKeyId sets the AccessKeyId field's value.
+func (s *Credentials) SetAccessKeyId(v string) *Credentials {
+	s.AccessKeyId = &v
+	return s
+}
+
+// SetExpiration sets the Expiration field's value.
+func (s *Credentials) SetExpiration(v time.Time) *Credentials {
+	s.Expiration = &v
+	return s
+}
+
+// SetSecretAccessKey sets the SecretAccessKey field's value.
+func (s *Credentials) SetSecretAccessKey(v string) *Credentials {
+	s.SecretAccessKey = &v
+	return s
+}
+
+// SetSessionToken sets the SessionToken field's value.
+func (s *Credentials) SetSessionToken(v string) *Credentials {
+	s.SessionToken = &v
+	return s
+}
+
+type DecodeAuthorizationMessageInput struct {
+	_ struct{} `type:"structure"`
+
+	// The encoded message that was returned with the response.
+	//
+	// EncodedMessage is a required field
+	EncodedMessage *string `min:"1" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s DecodeAuthorizationMessageInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DecodeAuthorizationMessageInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *DecodeAuthorizationMessageInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "DecodeAuthorizationMessageInput"}
+	if s.EncodedMessage == nil {
+		invalidParams.Add(request.NewErrParamRequired("EncodedMessage"))
+	}
+	if s.EncodedMessage != nil && len(*s.EncodedMessage) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("EncodedMessage", 1))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetEncodedMessage sets the EncodedMessage field's value.
+func (s *DecodeAuthorizationMessageInput) SetEncodedMessage(v string) *DecodeAuthorizationMessageInput {
+	s.EncodedMessage = &v
+	return s
+}
+
+// A document that contains additional information about the authorization status
+// of a request from an encoded message that is returned in response to an AWS
+// request.
+type DecodeAuthorizationMessageOutput struct {
+	_ struct{} `type:"structure"`
+
+	// An XML document that contains the decoded message.
+	DecodedMessage *string `type:"string"`
+}
+
+// String returns the string representation
+func (s DecodeAuthorizationMessageOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DecodeAuthorizationMessageOutput) GoString() string {
+	return s.String()
+}
+
+// SetDecodedMessage sets the DecodedMessage field's value.
+func (s *DecodeAuthorizationMessageOutput) SetDecodedMessage(v string) *DecodeAuthorizationMessageOutput {
+	s.DecodedMessage = &v
+	return s
+}
+
+// Identifiers for the federated user that is associated with the credentials.
+type FederatedUser struct {
+	_ struct{} `type:"structure"`
+
+	// The ARN that specifies the federated user that is associated with the credentials.
+	// For more information about ARNs and how to use them in policies, see IAM
+	// Identifiers (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html)
+	// in Using IAM.
+	//
+	// Arn is a required field
+	Arn *string `min:"20" type:"string" required:"true"`
+
+	// The string that identifies the federated user associated with the credentials,
+	// similar to the unique ID of an IAM user.
+	//
+	// FederatedUserId is a required field
+	FederatedUserId *string `min:"2" type:"string" required:"true"`
+}
+
+// String returns the string representation
+func (s FederatedUser) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s FederatedUser) GoString() string {
+	return s.String()
+}
+
+// SetArn sets the Arn field's value.
+func (s *FederatedUser) SetArn(v string) *FederatedUser {
+	s.Arn = &v
+	return s
+}
+
+// SetFederatedUserId sets the FederatedUserId field's value.
+func (s *FederatedUser) SetFederatedUserId(v string) *FederatedUser {
+	s.FederatedUserId = &v
+	return s
+}
+
+type GetCallerIdentityInput struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation
+func (s GetCallerIdentityInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetCallerIdentityInput) GoString() string {
+	return s.String()
+}
+
+// Contains the response to a successful GetCallerIdentity request, including
+// information about the entity making the request.
+type GetCallerIdentityOutput struct {
+	_ struct{} `type:"structure"`
+
+	// The AWS account ID number of the account that owns or contains the calling
+	// entity.
+	Account *string `type:"string"`
+
+	// The AWS ARN associated with the calling entity.
+	Arn *string `min:"20" type:"string"`
+
+	// The unique identifier of the calling entity. The exact value depends on the
+	// type of entity making the call. The values returned are those listed in the
+	// aws:userid column in the Principal table (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html#principaltable)
+	// found on the Policy Variables reference page in the IAM User Guide.
+	UserId *string `type:"string"`
+}
+
+// String returns the string representation
+func (s GetCallerIdentityOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetCallerIdentityOutput) GoString() string {
+	return s.String()
+}
+
+// SetAccount sets the Account field's value.
+func (s *GetCallerIdentityOutput) SetAccount(v string) *GetCallerIdentityOutput {
+	s.Account = &v
+	return s
+}
+
+// SetArn sets the Arn field's value.
+func (s *GetCallerIdentityOutput) SetArn(v string) *GetCallerIdentityOutput {
+	s.Arn = &v
+	return s
+}
+
+// SetUserId sets the UserId field's value.
+func (s *GetCallerIdentityOutput) SetUserId(v string) *GetCallerIdentityOutput {
+	s.UserId = &v
+	return s
+}
+
+type GetFederationTokenInput struct {
+	_ struct{} `type:"structure"`
+
+	// The duration, in seconds, that the session should last. Acceptable durations
+	// for federation sessions range from 900 seconds (15 minutes) to 129600 seconds
+	// (36 hours), with 43200 seconds (12 hours) as the default. Sessions obtained
+	// using AWS account (root) credentials are restricted to a maximum of 3600
+	// seconds (one hour). If the specified duration is longer than one hour, the
+	// session obtained by using AWS account (root) credentials defaults to one
+	// hour.
+	DurationSeconds *int64 `min:"900" type:"integer"`
+
+	// The name of the federated user. The name is used as an identifier for the
+	// temporary security credentials (such as Bob). For example, you can reference
+	// the federated user name in a resource-based policy, such as in an Amazon
+	// S3 bucket policy.
+	//
+	// The regex used to validate this parameter is a string of characters consisting
+	// of upper- and lower-case alphanumeric characters with no spaces. You can
+	// also include underscores or any of the following characters: =,.@-
+	//
+	// Name is a required field
+	Name *string `min:"2" type:"string" required:"true"`
+
+	// An IAM policy in JSON format that is passed with the GetFederationToken call
+	// and evaluated along with the policy or policies that are attached to the
+	// IAM user whose credentials are used to call GetFederationToken. The passed
+	// policy is used to scope down the permissions that are available to the IAM
+	// user, by allowing only a subset of the permissions that are granted to the
+	// IAM user. The passed policy cannot grant more permissions than those granted
+	// to the IAM user. The final permissions for the federated user are the most
+	// restrictive set based on the intersection of the passed policy and the IAM
+	// user policy.
+	//
+	// If you do not pass a policy, the resulting temporary security credentials
+	// have no effective permissions. The only exception is when the temporary security
+	// credentials are used to access a resource that has a resource-based policy
+	// that specifically allows the federated user to access the resource.
+	//
+	// The format for this parameter, as described by its regex pattern, is a string
+	// of characters up to 2048 characters in length. The characters can be any
+	// ASCII character from the space character to the end of the valid character
+	// list (\u0020-\u00FF). It can also include the tab (\u0009), linefeed (\u000A),
+	// and carriage return (\u000D) characters.
+	//
+	// The policy plain text must be 2048 bytes or shorter. However, an internal
+	// conversion compresses it into a packed binary format with a separate limit.
+	// The PackedPolicySize response element indicates by percentage how close to
+	// the upper size limit the policy is, with 100% equaling the maximum allowed
+	// size.
+	//
+	// For more information about how permissions work, see Permissions for GetFederationToken
+	// (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_getfederationtoken.html).
+	Policy *string `min:"1" type:"string"`
+}
+
+// String returns the string representation
+func (s GetFederationTokenInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetFederationTokenInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetFederationTokenInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetFederationTokenInput"}
+	if s.DurationSeconds != nil && *s.DurationSeconds < 900 {
+		invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900))
+	}
+	if s.Name == nil {
+		invalidParams.Add(request.NewErrParamRequired("Name"))
+	}
+	if s.Name != nil && len(*s.Name) < 2 {
+		invalidParams.Add(request.NewErrParamMinLen("Name", 2))
+	}
+	if s.Policy != nil && len(*s.Policy) < 1 {
+		invalidParams.Add(request.NewErrParamMinLen("Policy", 1))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetDurationSeconds sets the DurationSeconds field's value.
+func (s *GetFederationTokenInput) SetDurationSeconds(v int64) *GetFederationTokenInput {
+	s.DurationSeconds = &v
+	return s
+}
+
+// SetName sets the Name field's value.
+func (s *GetFederationTokenInput) SetName(v string) *GetFederationTokenInput {
+	s.Name = &v
+	return s
+}
+
+// SetPolicy sets the Policy field's value.
+func (s *GetFederationTokenInput) SetPolicy(v string) *GetFederationTokenInput {
+	s.Policy = &v
+	return s
+}
+
+// Contains the response to a successful GetFederationToken request, including
+// temporary AWS credentials that can be used to make AWS requests.
+type GetFederationTokenOutput struct {
+	_ struct{} `type:"structure"`
+
+	// The temporary security credentials, which include an access key ID, a secret
+	// access key, and a security (or session) token.
+	//
+	// Note: The size of the security token that STS APIs return is not fixed. We
+	// strongly recommend that you make no assumptions about the maximum size. As
+	// of this writing, the typical size is less than 4096 bytes, but that can vary.
+	// Also, future updates to AWS might require larger sizes.
+	Credentials *Credentials `type:"structure"`
+
+	// Identifiers for the federated user associated with the credentials (such
+	// as arn:aws:sts::123456789012:federated-user/Bob or 123456789012:Bob). You
+	// can use the federated user's ARN in your resource-based policies, such as
+	// an Amazon S3 bucket policy.
+	FederatedUser *FederatedUser `type:"structure"`
+
+	// A percentage value indicating the size of the policy in packed form. The
+	// service rejects policies for which the packed size is greater than 100 percent
+	// of the allowed value.
+	PackedPolicySize *int64 `type:"integer"`
+}
+
+// String returns the string representation
+func (s GetFederationTokenOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetFederationTokenOutput) GoString() string {
+	return s.String()
+}
+
+// SetCredentials sets the Credentials field's value.
+func (s *GetFederationTokenOutput) SetCredentials(v *Credentials) *GetFederationTokenOutput {
+	s.Credentials = v
+	return s
+}
+
+// SetFederatedUser sets the FederatedUser field's value.
+func (s *GetFederationTokenOutput) SetFederatedUser(v *FederatedUser) *GetFederationTokenOutput {
+	s.FederatedUser = v
+	return s
+}
+
+// SetPackedPolicySize sets the PackedPolicySize field's value.
+func (s *GetFederationTokenOutput) SetPackedPolicySize(v int64) *GetFederationTokenOutput {
+	s.PackedPolicySize = &v
+	return s
+}
+
+type GetSessionTokenInput struct {
+	_ struct{} `type:"structure"`
+
+	// The duration, in seconds, that the credentials should remain valid. Acceptable
+	// durations for IAM user sessions range from 900 seconds (15 minutes) to 129600
+	// seconds (36 hours), with 43200 seconds (12 hours) as the default. Sessions
+	// for AWS account owners are restricted to a maximum of 3600 seconds (one hour).
+	// If the duration is longer than one hour, the session for AWS account owners
+	// defaults to one hour.
+	DurationSeconds *int64 `min:"900" type:"integer"`
+
+	// The identification number of the MFA device that is associated with the IAM
+	// user who is making the GetSessionToken call. Specify this value if the IAM
+	// user has a policy that requires MFA authentication. The value is either the
+	// serial number for a hardware device (such as GAHT12345678) or an Amazon Resource
+	// Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user).
+	// You can find the device for an IAM user by going to the AWS Management Console
+	// and viewing the user's security credentials.
+	//
+	// The regex used to validated this parameter is a string of characters consisting
+	// of upper- and lower-case alphanumeric characters with no spaces. You can
+	// also include underscores or any of the following characters: =,.@:/-
+	SerialNumber *string `min:"9" type:"string"`
+
+	// The value provided by the MFA device, if MFA is required. If any policy requires
+	// the IAM user to submit an MFA code, specify this value. If MFA authentication
+	// is required, and the user does not provide a code when requesting a set of
+	// temporary security credentials, the user will receive an "access denied"
+	// response when requesting resources that require MFA authentication.
+	//
+	// The format for this parameter, as described by its regex pattern, is a sequence
+	// of six numeric digits.
+	TokenCode *string `min:"6" type:"string"`
+}
+
+// String returns the string representation
+func (s GetSessionTokenInput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetSessionTokenInput) GoString() string {
+	return s.String()
+}
+
+// Validate inspects the fields of the type to determine if they are valid.
+func (s *GetSessionTokenInput) Validate() error {
+	invalidParams := request.ErrInvalidParams{Context: "GetSessionTokenInput"}
+	if s.DurationSeconds != nil && *s.DurationSeconds < 900 {
+		invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900))
+	}
+	if s.SerialNumber != nil && len(*s.SerialNumber) < 9 {
+		invalidParams.Add(request.NewErrParamMinLen("SerialNumber", 9))
+	}
+	if s.TokenCode != nil && len(*s.TokenCode) < 6 {
+		invalidParams.Add(request.NewErrParamMinLen("TokenCode", 6))
+	}
+
+	if invalidParams.Len() > 0 {
+		return invalidParams
+	}
+	return nil
+}
+
+// SetDurationSeconds sets the DurationSeconds field's value.
+func (s *GetSessionTokenInput) SetDurationSeconds(v int64) *GetSessionTokenInput {
+	s.DurationSeconds = &v
+	return s
+}
+
+// SetSerialNumber sets the SerialNumber field's value.
+func (s *GetSessionTokenInput) SetSerialNumber(v string) *GetSessionTokenInput {
+	s.SerialNumber = &v
+	return s
+}
+
+// SetTokenCode sets the TokenCode field's value.
+func (s *GetSessionTokenInput) SetTokenCode(v string) *GetSessionTokenInput {
+	s.TokenCode = &v
+	return s
+}
+
+// Contains the response to a successful GetSessionToken request, including
+// temporary AWS credentials that can be used to make AWS requests.
+type GetSessionTokenOutput struct {
+	_ struct{} `type:"structure"`
+
+	// The temporary security credentials, which include an access key ID, a secret
+	// access key, and a security (or session) token.
+	//
+	// Note: The size of the security token that STS APIs return is not fixed. We
+	// strongly recommend that you make no assumptions about the maximum size. As
+	// of this writing, the typical size is less than 4096 bytes, but that can vary.
+	// Also, future updates to AWS might require larger sizes.
+	Credentials *Credentials `type:"structure"`
+}
+
+// String returns the string representation
+func (s GetSessionTokenOutput) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetSessionTokenOutput) GoString() string {
+	return s.String()
+}
+
+// SetCredentials sets the Credentials field's value.
+func (s *GetSessionTokenOutput) SetCredentials(v *Credentials) *GetSessionTokenOutput {
+	s.Credentials = v
+	return s
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/customizations.go b/vendor/github.com/aws/aws-sdk-go/service/sts/customizations.go
new file mode 100644
index 000000000..4010cc7fa
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/service/sts/customizations.go
@@ -0,0 +1,12 @@
+package sts
+
+import "github.com/aws/aws-sdk-go/aws/request"
+
+func init() {
+	initRequest = func(r *request.Request) {
+		switch r.Operation.Name {
+		case opAssumeRoleWithSAML, opAssumeRoleWithWebIdentity:
+			r.Handlers.Sign.Clear() // these operations are unsigned
+		}
+	}
+}
diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/doc.go b/vendor/github.com/aws/aws-sdk-go/service/sts/doc.go
new file mode 100644
index 000000000..ef681ab0c
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/service/sts/doc.go
@@ -0,0 +1,72 @@
+// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
+
+// Package sts provides the client and types for making API
+// requests to AWS Security Token Service.
+//
+// The AWS Security Token Service (STS) is a web service that enables you to
+// request temporary, limited-privilege credentials for AWS Identity and Access
+// Management (IAM) users or for users that you authenticate (federated users).
+// This guide provides descriptions of the STS API. For more detailed information
+// about using this service, go to Temporary Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html).
+//
+// As an alternative to using the API, you can use one of the AWS SDKs, which
+// consist of libraries and sample code for various programming languages and
+// platforms (Java, Ruby, .NET, iOS, Android, etc.). The SDKs provide a convenient
+// way to create programmatic access to STS. For example, the SDKs take care
+// of cryptographically signing requests, managing errors, and retrying requests
+// automatically. For information about the AWS SDKs, including how to download
+// and install them, see the Tools for Amazon Web Services page (http://aws.amazon.com/tools/).
+//
+// For information about setting up signatures and authorization through the
+// API, go to Signing AWS API Requests (http://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html)
+// in the AWS General Reference. For general information about the Query API,
+// go to Making Query Requests (http://docs.aws.amazon.com/IAM/latest/UserGuide/IAM_UsingQueryAPI.html)
+// in Using IAM. For information about using security tokens with other AWS
+// products, go to AWS Services That Work with IAM (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html)
+// in the IAM User Guide.
+//
+// If you're new to AWS and need additional technical information about a specific
+// AWS product, you can find the product's technical documentation at http://aws.amazon.com/documentation/
+// (http://aws.amazon.com/documentation/).
+//
+// Endpoints
+//
+// The AWS Security Token Service (STS) has a default endpoint of https://sts.amazonaws.com
+// that maps to the US East (N. Virginia) region. Additional regions are available
+// and are activated by default. For more information, see Activating and Deactivating
+// AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
+// in the IAM User Guide.
+//
+// For information about STS endpoints, see Regions and Endpoints (http://docs.aws.amazon.com/general/latest/gr/rande.html#sts_region)
+// in the AWS General Reference.
+//
+// Recording API requests
+//
+// STS supports AWS CloudTrail, which is a service that records AWS calls for
+// your AWS account and delivers log files to an Amazon S3 bucket. By using
+// information collected by CloudTrail, you can determine what requests were
+// successfully made to STS, who made the request, when it was made, and so
+// on. To learn more about CloudTrail, including how to turn it on and find
+// your log files, see the AWS CloudTrail User Guide (http://docs.aws.amazon.com/awscloudtrail/latest/userguide/what_is_cloud_trail_top_level.html).
+//
+// See https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15 for more information on this service.
+//
+// See sts package documentation for more information.
+// https://docs.aws.amazon.com/sdk-for-go/api/service/sts/
+//
+// Using the Client
+//
+// To contact AWS Security Token Service with the SDK use the New function to create
+// a new service client. With that client you can make API requests to the service.
+// These clients are safe to use concurrently.
+//
+// See the SDK's documentation for more information on how to use the SDK.
+// https://docs.aws.amazon.com/sdk-for-go/api/
+//
+// See aws.Config documentation for more information on configuring SDK clients.
+// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config
+//
+// See the AWS Security Token Service client STS for more
+// information on creating client for this service.
+// https://docs.aws.amazon.com/sdk-for-go/api/service/sts/#New
+package sts
diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/errors.go b/vendor/github.com/aws/aws-sdk-go/service/sts/errors.go
new file mode 100644
index 000000000..e24884ef3
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/service/sts/errors.go
@@ -0,0 +1,73 @@
+// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
+
+package sts
+
+const (
+
+	// ErrCodeExpiredTokenException for service response error code
+	// "ExpiredTokenException".
+	//
+	// The web identity token that was passed is expired or is not valid. Get a
+	// new identity token from the identity provider and then retry the request.
+	ErrCodeExpiredTokenException = "ExpiredTokenException"
+
+	// ErrCodeIDPCommunicationErrorException for service response error code
+	// "IDPCommunicationError".
+	//
+	// The request could not be fulfilled because the non-AWS identity provider
+	// (IDP) that was asked to verify the incoming identity token could not be reached.
+	// This is often a transient error caused by network conditions. Retry the request
+	// a limited number of times so that you don't exceed the request rate. If the
+	// error persists, the non-AWS identity provider might be down or not responding.
+	ErrCodeIDPCommunicationErrorException = "IDPCommunicationError"
+
+	// ErrCodeIDPRejectedClaimException for service response error code
+	// "IDPRejectedClaim".
+	//
+	// The identity provider (IdP) reported that authentication failed. This might
+	// be because the claim is invalid.
+	//
+	// If this error is returned for the AssumeRoleWithWebIdentity operation, it
+	// can also mean that the claim has expired or has been explicitly revoked.
+	ErrCodeIDPRejectedClaimException = "IDPRejectedClaim"
+
+	// ErrCodeInvalidAuthorizationMessageException for service response error code
+	// "InvalidAuthorizationMessageException".
+	//
+	// The error returned if the message passed to DecodeAuthorizationMessage was
+	// invalid. This can happen if the token contains invalid characters, such as
+	// linebreaks.
+	ErrCodeInvalidAuthorizationMessageException = "InvalidAuthorizationMessageException"
+
+	// ErrCodeInvalidIdentityTokenException for service response error code
+	// "InvalidIdentityToken".
+	//
+	// The web identity token that was passed could not be validated by AWS. Get
+	// a new identity token from the identity provider and then retry the request.
+	ErrCodeInvalidIdentityTokenException = "InvalidIdentityToken"
+
+	// ErrCodeMalformedPolicyDocumentException for service response error code
+	// "MalformedPolicyDocument".
+	//
+	// The request was rejected because the policy document was malformed. The error
+	// message describes the specific error.
+	ErrCodeMalformedPolicyDocumentException = "MalformedPolicyDocument"
+
+	// ErrCodePackedPolicyTooLargeException for service response error code
+	// "PackedPolicyTooLarge".
+	//
+	// The request was rejected because the policy document was too large. The error
+	// message describes how big the policy document is, in packed form, as a percentage
+	// of what the API allows.
+	ErrCodePackedPolicyTooLargeException = "PackedPolicyTooLarge"
+
+	// ErrCodeRegionDisabledException for service response error code
+	// "RegionDisabledException".
+	//
+	// STS is not activated in the requested region for the account that is being
+	// asked to generate credentials. The account administrator must use the IAM
+	// console to activate STS in that region. For more information, see Activating
+	// and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
+	// in the IAM User Guide.
+	ErrCodeRegionDisabledException = "RegionDisabledException"
+)
diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/service.go b/vendor/github.com/aws/aws-sdk-go/service/sts/service.go
new file mode 100644
index 000000000..185c914d1
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go/service/sts/service.go
@@ -0,0 +1,95 @@
+// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
+
+package sts
+
+import (
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/client"
+	"github.com/aws/aws-sdk-go/aws/client/metadata"
+	"github.com/aws/aws-sdk-go/aws/request"
+	"github.com/aws/aws-sdk-go/aws/signer/v4"
+	"github.com/aws/aws-sdk-go/private/protocol/query"
+)
+
+// STS provides the API operation methods for making requests to
+// AWS Security Token Service. See this package's package overview docs
+// for details on the service.
+//
+// STS methods are safe to use concurrently. It is not safe to
+// modify mutate any of the struct's properties though.
+type STS struct {
+	*client.Client
+}
+
+// Used for custom client initialization logic
+var initClient func(*client.Client)
+
+// Used for custom request initialization logic
+var initRequest func(*request.Request)
+
+// Service information constants
+const (
+	ServiceName = "sts"       // Name of service.
+	EndpointsID = ServiceName // ID to lookup a service endpoint with.
+	ServiceID   = "STS"       // ServiceID is a unique identifer of a specific service.
+)
+
+// New creates a new instance of the STS client with a session.
+// If additional configuration is needed for the client instance use the optional
+// aws.Config parameter to add your extra config.
+//
+// Example:
+//     // Create a STS client from just a session.
+//     svc := sts.New(mySession)
+//
+//     // Create a STS client with additional configuration
+//     svc := sts.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
+func New(p client.ConfigProvider, cfgs ...*aws.Config) *STS {
+	c := p.ClientConfig(EndpointsID, cfgs...)
+	return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName)
+}
+
+// newClient creates, initializes and returns a new service client instance.
+func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *STS {
+	svc := &STS{
+		Client: client.New(
+			cfg,
+			metadata.ClientInfo{
+				ServiceName:   ServiceName,
+				ServiceID:     ServiceID,
+				SigningName:   signingName,
+				SigningRegion: signingRegion,
+				Endpoint:      endpoint,
+				APIVersion:    "2011-06-15",
+			},
+			handlers,
+		),
+	}
+
+	// Handlers
+	svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler)
+	svc.Handlers.Build.PushBackNamed(query.BuildHandler)
+	svc.Handlers.Unmarshal.PushBackNamed(query.UnmarshalHandler)
+	svc.Handlers.UnmarshalMeta.PushBackNamed(query.UnmarshalMetaHandler)
+	svc.Handlers.UnmarshalError.PushBackNamed(query.UnmarshalErrorHandler)
+
+	// Run custom client initialization if present
+	if initClient != nil {
+		initClient(svc.Client)
+	}
+
+	return svc
+}
+
+// newRequest creates a new request for a STS operation and runs any
+// custom request initialization.
+func (c *STS) newRequest(op *request.Operation, params, data interface{}) *request.Request {
+	req := c.NewRequest(op, params, data)
+
+	// Run custom request initialization if present
+	if initRequest != nil {
+		initRequest(req)
+	}
+
+	return req
+}
diff --git a/vendor/github.com/bgentry/go-netrc/LICENSE b/vendor/github.com/bgentry/go-netrc/LICENSE
new file mode 100644
index 000000000..aade9a58b
--- /dev/null
+++ b/vendor/github.com/bgentry/go-netrc/LICENSE
@@ -0,0 +1,20 @@
+Original version Copyright © 2010 Fazlul Shahriar . Newer
+portions Copyright © 2014 Blake Gentry .
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/github.com/bgentry/go-netrc/netrc/netrc.go b/vendor/github.com/bgentry/go-netrc/netrc/netrc.go
new file mode 100644
index 000000000..ea49987c0
--- /dev/null
+++ b/vendor/github.com/bgentry/go-netrc/netrc/netrc.go
@@ -0,0 +1,510 @@
+package netrc
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os"
+	"strings"
+	"sync"
+	"unicode"
+	"unicode/utf8"
+)
+
+type tkType int
+
+const (
+	tkMachine tkType = iota
+	tkDefault
+	tkLogin
+	tkPassword
+	tkAccount
+	tkMacdef
+	tkComment
+	tkWhitespace
+)
+
+var keywords = map[string]tkType{
+	"machine":  tkMachine,
+	"default":  tkDefault,
+	"login":    tkLogin,
+	"password": tkPassword,
+	"account":  tkAccount,
+	"macdef":   tkMacdef,
+	"#":        tkComment,
+}
+
+type Netrc struct {
+	tokens     []*token
+	machines   []*Machine
+	macros     Macros
+	updateLock sync.Mutex
+}
+
+// FindMachine returns the Machine in n named by name. If a machine named by
+// name exists, it is returned. If no Machine with name name is found and there
+// is a ``default'' machine, the ``default'' machine is returned. Otherwise, nil
+// is returned.
+func (n *Netrc) FindMachine(name string) (m *Machine) {
+	// TODO(bgentry): not safe for concurrency
+	var def *Machine
+	for _, m = range n.machines {
+		if m.Name == name {
+			return m
+		}
+		if m.IsDefault() {
+			def = m
+		}
+	}
+	if def == nil {
+		return nil
+	}
+	return def
+}
+
+// MarshalText implements the encoding.TextMarshaler interface to encode a
+// Netrc into text format.
+func (n *Netrc) MarshalText() (text []byte, err error) {
+	// TODO(bgentry): not safe for concurrency
+	for i := range n.tokens {
+		switch n.tokens[i].kind {
+		case tkComment, tkDefault, tkWhitespace: // always append these types
+			text = append(text, n.tokens[i].rawkind...)
+		default:
+			if n.tokens[i].value != "" { // skip empty-value tokens
+				text = append(text, n.tokens[i].rawkind...)
+			}
+		}
+		if n.tokens[i].kind == tkMacdef {
+			text = append(text, ' ')
+			text = append(text, n.tokens[i].macroName...)
+		}
+		text = append(text, n.tokens[i].rawvalue...)
+	}
+	return
+}
+
+func (n *Netrc) NewMachine(name, login, password, account string) *Machine {
+	n.updateLock.Lock()
+	defer n.updateLock.Unlock()
+
+	prefix := "\n"
+	if len(n.tokens) == 0 {
+		prefix = ""
+	}
+	m := &Machine{
+		Name:     name,
+		Login:    login,
+		Password: password,
+		Account:  account,
+
+		nametoken: &token{
+			kind:     tkMachine,
+			rawkind:  []byte(prefix + "machine"),
+			value:    name,
+			rawvalue: []byte(" " + name),
+		},
+		logintoken: &token{
+			kind:     tkLogin,
+			rawkind:  []byte("\n\tlogin"),
+			value:    login,
+			rawvalue: []byte(" " + login),
+		},
+		passtoken: &token{
+			kind:     tkPassword,
+			rawkind:  []byte("\n\tpassword"),
+			value:    password,
+			rawvalue: []byte(" " + password),
+		},
+		accounttoken: &token{
+			kind:     tkAccount,
+			rawkind:  []byte("\n\taccount"),
+			value:    account,
+			rawvalue: []byte(" " + account),
+		},
+	}
+	n.insertMachineTokensBeforeDefault(m)
+	for i := range n.machines {
+		if n.machines[i].IsDefault() {
+			n.machines = append(append(n.machines[:i], m), n.machines[i:]...)
+			return m
+		}
+	}
+	n.machines = append(n.machines, m)
+	return m
+}
+
+func (n *Netrc) insertMachineTokensBeforeDefault(m *Machine) {
+	newtokens := []*token{m.nametoken}
+	if m.logintoken.value != "" {
+		newtokens = append(newtokens, m.logintoken)
+	}
+	if m.passtoken.value != "" {
+		newtokens = append(newtokens, m.passtoken)
+	}
+	if m.accounttoken.value != "" {
+		newtokens = append(newtokens, m.accounttoken)
+	}
+	for i := range n.tokens {
+		if n.tokens[i].kind == tkDefault {
+			// found the default, now insert tokens before it
+			n.tokens = append(n.tokens[:i], append(newtokens, n.tokens[i:]...)...)
+			return
+		}
+	}
+	// didn't find a default, just add the newtokens to the end
+	n.tokens = append(n.tokens, newtokens...)
+	return
+}
+
+func (n *Netrc) RemoveMachine(name string) {
+	n.updateLock.Lock()
+	defer n.updateLock.Unlock()
+
+	for i := range n.machines {
+		if n.machines[i] != nil && n.machines[i].Name == name {
+			m := n.machines[i]
+			for _, t := range []*token{
+				m.nametoken, m.logintoken, m.passtoken, m.accounttoken,
+			} {
+				n.removeToken(t)
+			}
+			n.machines = append(n.machines[:i], n.machines[i+1:]...)
+			return
+		}
+	}
+}
+
+func (n *Netrc) removeToken(t *token) {
+	if t != nil {
+		for i := range n.tokens {
+			if n.tokens[i] == t {
+				n.tokens = append(n.tokens[:i], n.tokens[i+1:]...)
+				return
+			}
+		}
+	}
+}
+
+// Machine contains information about a remote machine.
+type Machine struct {
+	Name     string
+	Login    string
+	Password string
+	Account  string
+
+	nametoken    *token
+	logintoken   *token
+	passtoken    *token
+	accounttoken *token
+}
+
+// IsDefault returns true if the machine is a "default" token, denoted by an
+// empty name.
+func (m *Machine) IsDefault() bool {
+	return m.Name == ""
+}
+
+// UpdatePassword sets the password for the Machine m.
+func (m *Machine) UpdatePassword(newpass string) {
+	m.Password = newpass
+	updateTokenValue(m.passtoken, newpass)
+}
+
+// UpdateLogin sets the login for the Machine m.
+func (m *Machine) UpdateLogin(newlogin string) {
+	m.Login = newlogin
+	updateTokenValue(m.logintoken, newlogin)
+}
+
+// UpdateAccount sets the login for the Machine m.
+func (m *Machine) UpdateAccount(newaccount string) {
+	m.Account = newaccount
+	updateTokenValue(m.accounttoken, newaccount)
+}
+
+func updateTokenValue(t *token, value string) {
+	oldvalue := t.value
+	t.value = value
+	newraw := make([]byte, len(t.rawvalue))
+	copy(newraw, t.rawvalue)
+	t.rawvalue = append(
+		bytes.TrimSuffix(newraw, []byte(oldvalue)),
+		[]byte(value)...,
+	)
+}
+
+// Macros contains all the macro definitions in a netrc file.
+type Macros map[string]string
+
+type token struct {
+	kind      tkType
+	macroName string
+	value     string
+	rawkind   []byte
+	rawvalue  []byte
+}
+
+// Error represents a netrc file parse error.
+type Error struct {
+	LineNum int    // Line number
+	Msg     string // Error message
+}
+
+// Error returns a string representation of error e.
+func (e *Error) Error() string {
+	return fmt.Sprintf("line %d: %s", e.LineNum, e.Msg)
+}
+
+func (e *Error) BadDefaultOrder() bool {
+	return e.Msg == errBadDefaultOrder
+}
+
+const errBadDefaultOrder = "default token must appear after all machine tokens"
+
+// scanLinesKeepPrefix is a split function for a Scanner that returns each line
+// of text. The returned token may include newlines if they are before the
+// first non-space character. The returned line may be empty. The end-of-line
+// marker is one optional carriage return followed by one mandatory newline. In
+// regular expression notation, it is `\r?\n`. The last non-empty line of
+// input will be returned even if it has no newline.
+func scanLinesKeepPrefix(data []byte, atEOF bool) (advance int, token []byte, err error) {
+	if atEOF && len(data) == 0 {
+		return 0, nil, nil
+	}
+	// Skip leading spaces.
+	start := 0
+	for width := 0; start < len(data); start += width {
+		var r rune
+		r, width = utf8.DecodeRune(data[start:])
+		if !unicode.IsSpace(r) {
+			break
+		}
+	}
+	if i := bytes.IndexByte(data[start:], '\n'); i >= 0 {
+		// We have a full newline-terminated line.
+		return start + i, data[0 : start+i], nil
+	}
+	// If we're at EOF, we have a final, non-terminated line. Return it.
+	if atEOF {
+		return len(data), data, nil
+	}
+	// Request more data.
+	return 0, nil, nil
+}
+
+// scanWordsKeepPrefix is a split function for a Scanner that returns each
+// space-separated word of text, with prefixing spaces included. It will never
+// return an empty string. The definition of space is set by unicode.IsSpace.
+//
+// Adapted from bufio.ScanWords().
+func scanTokensKeepPrefix(data []byte, atEOF bool) (advance int, token []byte, err error) {
+	// Skip leading spaces.
+	start := 0
+	for width := 0; start < len(data); start += width {
+		var r rune
+		r, width = utf8.DecodeRune(data[start:])
+		if !unicode.IsSpace(r) {
+			break
+		}
+	}
+	if atEOF && len(data) == 0 || start == len(data) {
+		return len(data), data, nil
+	}
+	if len(data) > start && data[start] == '#' {
+		return scanLinesKeepPrefix(data, atEOF)
+	}
+	// Scan until space, marking end of word.
+	for width, i := 0, start; i < len(data); i += width {
+		var r rune
+		r, width = utf8.DecodeRune(data[i:])
+		if unicode.IsSpace(r) {
+			return i, data[:i], nil
+		}
+	}
+	// If we're at EOF, we have a final, non-empty, non-terminated word. Return it.
+	if atEOF && len(data) > start {
+		return len(data), data, nil
+	}
+	// Request more data.
+	return 0, nil, nil
+}
+
+func newToken(rawb []byte) (*token, error) {
+	_, tkind, err := bufio.ScanWords(rawb, true)
+	if err != nil {
+		return nil, err
+	}
+	var ok bool
+	t := token{rawkind: rawb}
+	t.kind, ok = keywords[string(tkind)]
+	if !ok {
+		trimmed := strings.TrimSpace(string(tkind))
+		if trimmed == "" {
+			t.kind = tkWhitespace // whitespace-only, should happen only at EOF
+			return &t, nil
+		}
+		if strings.HasPrefix(trimmed, "#") {
+			t.kind = tkComment // this is a comment
+			return &t, nil
+		}
+		return &t, fmt.Errorf("keyword expected; got " + string(tkind))
+	}
+	return &t, nil
+}
+
+func scanValue(scanner *bufio.Scanner, pos int) ([]byte, string, int, error) {
+	if scanner.Scan() {
+		raw := scanner.Bytes()
+		pos += bytes.Count(raw, []byte{'\n'})
+		return raw, strings.TrimSpace(string(raw)), pos, nil
+	}
+	if err := scanner.Err(); err != nil {
+		return nil, "", pos, &Error{pos, err.Error()}
+	}
+	return nil, "", pos, nil
+}
+
+func parse(r io.Reader, pos int) (*Netrc, error) {
+	b, err := ioutil.ReadAll(r)
+	if err != nil {
+		return nil, err
+	}
+
+	nrc := Netrc{machines: make([]*Machine, 0, 20), macros: make(Macros, 10)}
+
+	defaultSeen := false
+	var currentMacro *token
+	var m *Machine
+	var t *token
+	scanner := bufio.NewScanner(bytes.NewReader(b))
+	scanner.Split(scanTokensKeepPrefix)
+
+	for scanner.Scan() {
+		rawb := scanner.Bytes()
+		if len(rawb) == 0 {
+			break
+		}
+		pos += bytes.Count(rawb, []byte{'\n'})
+		t, err = newToken(rawb)
+		if err != nil {
+			if currentMacro == nil {
+				return nil, &Error{pos, err.Error()}
+			}
+			currentMacro.rawvalue = append(currentMacro.rawvalue, rawb...)
+			continue
+		}
+
+		if currentMacro != nil && bytes.Contains(rawb, []byte{'\n', '\n'}) {
+			// if macro rawvalue + rawb would contain \n\n, then macro def is over
+			currentMacro.value = strings.TrimLeft(string(currentMacro.rawvalue), "\r\n")
+			nrc.macros[currentMacro.macroName] = currentMacro.value
+			currentMacro = nil
+		}
+
+		switch t.kind {
+		case tkMacdef:
+			if _, t.macroName, pos, err = scanValue(scanner, pos); err != nil {
+				return nil, &Error{pos, err.Error()}
+			}
+			currentMacro = t
+		case tkDefault:
+			if defaultSeen {
+				return nil, &Error{pos, "multiple default token"}
+			}
+			if m != nil {
+				nrc.machines, m = append(nrc.machines, m), nil
+			}
+			m = new(Machine)
+			m.Name = ""
+			defaultSeen = true
+		case tkMachine:
+			if defaultSeen {
+				return nil, &Error{pos, errBadDefaultOrder}
+			}
+			if m != nil {
+				nrc.machines, m = append(nrc.machines, m), nil
+			}
+			m = new(Machine)
+			if t.rawvalue, m.Name, pos, err = scanValue(scanner, pos); err != nil {
+				return nil, &Error{pos, err.Error()}
+			}
+			t.value = m.Name
+			m.nametoken = t
+		case tkLogin:
+			if m == nil || m.Login != "" {
+				return nil, &Error{pos, "unexpected token login "}
+			}
+			if t.rawvalue, m.Login, pos, err = scanValue(scanner, pos); err != nil {
+				return nil, &Error{pos, err.Error()}
+			}
+			t.value = m.Login
+			m.logintoken = t
+		case tkPassword:
+			if m == nil || m.Password != "" {
+				return nil, &Error{pos, "unexpected token password"}
+			}
+			if t.rawvalue, m.Password, pos, err = scanValue(scanner, pos); err != nil {
+				return nil, &Error{pos, err.Error()}
+			}
+			t.value = m.Password
+			m.passtoken = t
+		case tkAccount:
+			if m == nil || m.Account != "" {
+				return nil, &Error{pos, "unexpected token account"}
+			}
+			if t.rawvalue, m.Account, pos, err = scanValue(scanner, pos); err != nil {
+				return nil, &Error{pos, err.Error()}
+			}
+			t.value = m.Account
+			m.accounttoken = t
+		}
+
+		nrc.tokens = append(nrc.tokens, t)
+	}
+
+	if err := scanner.Err(); err != nil {
+		return nil, err
+	}
+
+	if m != nil {
+		nrc.machines, m = append(nrc.machines, m), nil
+	}
+	return &nrc, nil
+}
+
+// ParseFile opens the file at filename and then passes its io.Reader to
+// Parse().
+func ParseFile(filename string) (*Netrc, error) {
+	fd, err := os.Open(filename)
+	if err != nil {
+		return nil, err
+	}
+	defer fd.Close()
+	return Parse(fd)
+}
+
+// Parse parses from the the Reader r as a netrc file and returns the set of
+// machine information and macros defined in it. The ``default'' machine,
+// which is intended to be used when no machine name matches, is identified
+// by an empty machine name. There can be only one ``default'' machine.
+//
+// If there is a parsing error, an Error is returned.
+func Parse(r io.Reader) (*Netrc, error) {
+	return parse(r, 1)
+}
+
+// FindMachine parses the netrc file identified by filename and returns the
+// Machine named by name. If a problem occurs parsing the file at filename, an
+// error is returned. If a machine named by name exists, it is returned. If no
+// Machine with name name is found and there is a ``default'' machine, the
+// ``default'' machine is returned. Otherwise, nil is returned.
+func FindMachine(filename, name string) (m *Machine, err error) {
+	n, err := ParseFile(filename)
+	if err != nil {
+		return nil, err
+	}
+	return n.FindMachine(name), nil
+}
diff --git a/vendor/github.com/go-ini/ini/LICENSE b/vendor/github.com/go-ini/ini/LICENSE
new file mode 100644
index 000000000..d361bbcdf
--- /dev/null
+++ b/vendor/github.com/go-ini/ini/LICENSE
@@ -0,0 +1,191 @@
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and
+distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright
+owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities
+that control, are controlled by, or are under common control with that entity.
+For the purposes of this definition, "control" means (i) the power, direct or
+indirect, to cause the direction or management of such entity, whether by
+contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
+outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising
+permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including
+but not limited to software source code, documentation source, and configuration
+files.
+
+"Object" form shall mean any form resulting from mechanical transformation or
+translation of a Source form, including but not limited to compiled object code,
+generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made
+available under the License, as indicated by a copyright notice that is included
+in or attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that
+is based on (or derived from) the Work and for which the editorial revisions,
+annotations, elaborations, or other modifications represent, as a whole, an
+original work of authorship. For the purposes of this License, Derivative Works
+shall not include works that remain separable from, or merely link (or bind by
+name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version
+of the Work and any modifications or additions to that Work or Derivative Works
+thereof, that is intentionally submitted to Licensor for inclusion in the Work
+by the copyright owner or by an individual or Legal Entity authorized to submit
+on behalf of the copyright owner. For the purposes of this definition,
+"submitted" means any form of electronic, verbal, or written communication sent
+to the Licensor or its representatives, including but not limited to
+communication on electronic mailing lists, source code control systems, and
+issue tracking systems that are managed by, or on behalf of, the Licensor for
+the purpose of discussing and improving the Work, but excluding communication
+that is conspicuously marked or otherwise designated in writing by the copyright
+owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
+of whom a Contribution has been received by Licensor and subsequently
+incorporated within the Work.
+
+2. Grant of Copyright License.
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable copyright license to reproduce, prepare Derivative Works of,
+publicly display, publicly perform, sublicense, and distribute the Work and such
+Derivative Works in Source or Object form.
+
+3. Grant of Patent License.
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable (except as stated in this section) patent license to make, have
+made, use, offer to sell, sell, import, and otherwise transfer the Work, where
+such license applies only to those patent claims licensable by such Contributor
+that are necessarily infringed by their Contribution(s) alone or by combination
+of their Contribution(s) with the Work to which such Contribution(s) was
+submitted. If You institute patent litigation against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that the Work or a
+Contribution incorporated within the Work constitutes direct or contributory
+patent infringement, then any patent licenses granted to You under this License
+for that Work shall terminate as of the date such litigation is filed.
+
+4. Redistribution.
+
+You may reproduce and distribute copies of the Work or Derivative Works thereof
+in any medium, with or without modifications, and in Source or Object form,
+provided that You meet the following conditions:
+
+You must give any other recipients of the Work or Derivative Works a copy of
+this License; and
+You must cause any modified files to carry prominent notices stating that You
+changed the files; and
+You must retain, in the Source form of any Derivative Works that You distribute,
+all copyright, patent, trademark, and attribution notices from the Source form
+of the Work, excluding those notices that do not pertain to any part of the
+Derivative Works; and
+If the Work includes a "NOTICE" text file as part of its distribution, then any
+Derivative Works that You distribute must include a readable copy of the
+attribution notices contained within such NOTICE file, excluding those notices
+that do not pertain to any part of the Derivative Works, in at least one of the
+following places: within a NOTICE text file distributed as part of the
+Derivative Works; within the Source form or documentation, if provided along
+with the Derivative Works; or, within a display generated by the Derivative
+Works, if and wherever such third-party notices normally appear. The contents of
+the NOTICE file are for informational purposes only and do not modify the
+License. You may add Your own attribution notices within Derivative Works that
+You distribute, alongside or as an addendum to the NOTICE text from the Work,
+provided that such additional attribution notices cannot be construed as
+modifying the License.
+You may add Your own copyright statement to Your modifications and may provide
+additional or different license terms and conditions for use, reproduction, or
+distribution of Your modifications, or for any such Derivative Works as a whole,
+provided Your use, reproduction, and distribution of the Work otherwise complies
+with the conditions stated in this License.
+
+5. Submission of Contributions.
+
+Unless You explicitly state otherwise, any Contribution intentionally submitted
+for inclusion in the Work by You to the Licensor shall be under the terms and
+conditions of this License, without any additional terms or conditions.
+Notwithstanding the above, nothing herein shall supersede or modify the terms of
+any separate license agreement you may have executed with Licensor regarding
+such Contributions.
+
+6. Trademarks.
+
+This License does not grant permission to use the trade names, trademarks,
+service marks, or product names of the Licensor, except as required for
+reasonable and customary use in describing the origin of the Work and
+reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty.
+
+Unless required by applicable law or agreed to in writing, Licensor provides the
+Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+including, without limitation, any warranties or conditions of TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
+solely responsible for determining the appropriateness of using or
+redistributing the Work and assume any risks associated with Your exercise of
+permissions under this License.
+
+8. Limitation of Liability.
+
+In no event and under no legal theory, whether in tort (including negligence),
+contract, or otherwise, unless required by applicable law (such as deliberate
+and grossly negligent acts) or agreed to in writing, shall any Contributor be
+liable to You for damages, including any direct, indirect, special, incidental,
+or consequential damages of any character arising as a result of this License or
+out of the use or inability to use the Work (including but not limited to
+damages for loss of goodwill, work stoppage, computer failure or malfunction, or
+any and all other commercial damages or losses), even if such Contributor has
+been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability.
+
+While redistributing the Work or Derivative Works thereof, You may choose to
+offer, and charge a fee for, acceptance of support, warranty, indemnity, or
+other liability obligations and/or rights consistent with this License. However,
+in accepting such obligations, You may act only on Your own behalf and on Your
+sole responsibility, not on behalf of any other Contributor, and only if You
+agree to indemnify, defend, and hold each Contributor harmless for any liability
+incurred by, or claims asserted against, such Contributor by reason of your
+accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work
+
+To apply the Apache License to your work, attach the following boilerplate
+notice, with the fields enclosed by brackets "[]" replaced with your own
+identifying information. (Don't include the brackets!) The text should be
+enclosed in the appropriate comment syntax for the file format. We also
+recommend that a file or class name and description of purpose be included on
+the same "printed page" as the copyright notice for easier identification within
+third-party archives.
+
+   Copyright 2014 Unknwon
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/vendor/github.com/go-ini/ini/error.go b/vendor/github.com/go-ini/ini/error.go
new file mode 100644
index 000000000..80afe7431
--- /dev/null
+++ b/vendor/github.com/go-ini/ini/error.go
@@ -0,0 +1,32 @@
+// Copyright 2016 Unknwon
+//
+// Licensed under the Apache License, Version 2.0 (the "License"): you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+package ini
+
+import (
+	"fmt"
+)
+
+type ErrDelimiterNotFound struct {
+	Line string
+}
+
+func IsErrDelimiterNotFound(err error) bool {
+	_, ok := err.(ErrDelimiterNotFound)
+	return ok
+}
+
+func (err ErrDelimiterNotFound) Error() string {
+	return fmt.Sprintf("key-value delimiter not found: %s", err.Line)
+}
diff --git a/vendor/github.com/go-ini/ini/file.go b/vendor/github.com/go-ini/ini/file.go
new file mode 100644
index 000000000..1a3186b9f
--- /dev/null
+++ b/vendor/github.com/go-ini/ini/file.go
@@ -0,0 +1,414 @@
+// Copyright 2017 Unknwon
+//
+// Licensed under the Apache License, Version 2.0 (the "License"): you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+package ini
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os"
+	"strings"
+	"sync"
+)
+
+// File represents a combination of a or more INI file(s) in memory.
+type File struct {
+	options     LoadOptions
+	dataSources []dataSource
+
+	// Should make things safe, but sometimes doesn't matter.
+	BlockMode bool
+	lock      sync.RWMutex
+
+	// To keep data in order.
+	sectionList []string
+	// Actual data is stored here.
+	sections map[string]*Section
+
+	NameMapper
+	ValueMapper
+}
+
+// newFile initializes File object with given data sources.
+func newFile(dataSources []dataSource, opts LoadOptions) *File {
+	return &File{
+		BlockMode:   true,
+		dataSources: dataSources,
+		sections:    make(map[string]*Section),
+		sectionList: make([]string, 0, 10),
+		options:     opts,
+	}
+}
+
+// Empty returns an empty file object.
+func Empty() *File {
+	// Ignore error here, we sure our data is good.
+	f, _ := Load([]byte(""))
+	return f
+}
+
+// NewSection creates a new section.
+func (f *File) NewSection(name string) (*Section, error) {
+	if len(name) == 0 {
+		return nil, errors.New("error creating new section: empty section name")
+	} else if f.options.Insensitive && name != DEFAULT_SECTION {
+		name = strings.ToLower(name)
+	}
+
+	if f.BlockMode {
+		f.lock.Lock()
+		defer f.lock.Unlock()
+	}
+
+	if inSlice(name, f.sectionList) {
+		return f.sections[name], nil
+	}
+
+	f.sectionList = append(f.sectionList, name)
+	f.sections[name] = newSection(f, name)
+	return f.sections[name], nil
+}
+
+// NewRawSection creates a new section with an unparseable body.
+func (f *File) NewRawSection(name, body string) (*Section, error) {
+	section, err := f.NewSection(name)
+	if err != nil {
+		return nil, err
+	}
+
+	section.isRawSection = true
+	section.rawBody = body
+	return section, nil
+}
+
+// NewSections creates a list of sections.
+func (f *File) NewSections(names ...string) (err error) {
+	for _, name := range names {
+		if _, err = f.NewSection(name); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// GetSection returns section by given name.
+func (f *File) GetSection(name string) (*Section, error) {
+	if len(name) == 0 {
+		name = DEFAULT_SECTION
+	}
+	if f.options.Insensitive {
+		name = strings.ToLower(name)
+	}
+
+	if f.BlockMode {
+		f.lock.RLock()
+		defer f.lock.RUnlock()
+	}
+
+	sec := f.sections[name]
+	if sec == nil {
+		return nil, fmt.Errorf("section '%s' does not exist", name)
+	}
+	return sec, nil
+}
+
+// Section assumes named section exists and returns a zero-value when not.
+func (f *File) Section(name string) *Section {
+	sec, err := f.GetSection(name)
+	if err != nil {
+		// Note: It's OK here because the only possible error is empty section name,
+		// but if it's empty, this piece of code won't be executed.
+		sec, _ = f.NewSection(name)
+		return sec
+	}
+	return sec
+}
+
+// Section returns list of Section.
+func (f *File) Sections() []*Section {
+	if f.BlockMode {
+		f.lock.RLock()
+		defer f.lock.RUnlock()
+	}
+
+	sections := make([]*Section, len(f.sectionList))
+	for i, name := range f.sectionList {
+		sections[i] = f.sections[name]
+	}
+	return sections
+}
+
+// ChildSections returns a list of child sections of given section name.
+func (f *File) ChildSections(name string) []*Section {
+	return f.Section(name).ChildSections()
+}
+
+// SectionStrings returns list of section names.
+func (f *File) SectionStrings() []string {
+	list := make([]string, len(f.sectionList))
+	copy(list, f.sectionList)
+	return list
+}
+
+// DeleteSection deletes a section.
+func (f *File) DeleteSection(name string) {
+	if f.BlockMode {
+		f.lock.Lock()
+		defer f.lock.Unlock()
+	}
+
+	if len(name) == 0 {
+		name = DEFAULT_SECTION
+	}
+
+	for i, s := range f.sectionList {
+		if s == name {
+			f.sectionList = append(f.sectionList[:i], f.sectionList[i+1:]...)
+			delete(f.sections, name)
+			return
+		}
+	}
+}
+
+func (f *File) reload(s dataSource) error {
+	r, err := s.ReadCloser()
+	if err != nil {
+		return err
+	}
+	defer r.Close()
+
+	return f.parse(r)
+}
+
+// Reload reloads and parses all data sources.
+func (f *File) Reload() (err error) {
+	for _, s := range f.dataSources {
+		if err = f.reload(s); err != nil {
+			// In loose mode, we create an empty default section for nonexistent files.
+			if os.IsNotExist(err) && f.options.Loose {
+				f.parse(bytes.NewBuffer(nil))
+				continue
+			}
+			return err
+		}
+	}
+	return nil
+}
+
+// Append appends one or more data sources and reloads automatically.
+func (f *File) Append(source interface{}, others ...interface{}) error {
+	ds, err := parseDataSource(source)
+	if err != nil {
+		return err
+	}
+	f.dataSources = append(f.dataSources, ds)
+	for _, s := range others {
+		ds, err = parseDataSource(s)
+		if err != nil {
+			return err
+		}
+		f.dataSources = append(f.dataSources, ds)
+	}
+	return f.Reload()
+}
+
+func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) {
+	equalSign := "="
+	if PrettyFormat || PrettyEqual {
+		equalSign = " = "
+	}
+
+	// Use buffer to make sure target is safe until finish encoding.
+	buf := bytes.NewBuffer(nil)
+	for i, sname := range f.sectionList {
+		sec := f.Section(sname)
+		if len(sec.Comment) > 0 {
+			// Support multiline comments
+			lines := strings.Split(sec.Comment, LineBreak)
+			for i := range lines {
+				if lines[i][0] != '#' && lines[i][0] != ';' {
+					lines[i] = "; " + lines[i]
+				} else {
+					lines[i] = lines[i][:1] + " " + strings.TrimSpace(lines[i][1:])
+				}
+
+				if _, err := buf.WriteString(lines[i] + LineBreak); err != nil {
+					return nil, err
+				}
+			}
+		}
+
+		if i > 0 || DefaultHeader {
+			if _, err := buf.WriteString("[" + sname + "]" + LineBreak); err != nil {
+				return nil, err
+			}
+		} else {
+			// Write nothing if default section is empty
+			if len(sec.keyList) == 0 {
+				continue
+			}
+		}
+
+		if sec.isRawSection {
+			if _, err := buf.WriteString(sec.rawBody); err != nil {
+				return nil, err
+			}
+
+			if PrettySection {
+				// Put a line between sections
+				if _, err := buf.WriteString(LineBreak); err != nil {
+					return nil, err
+				}
+			}
+			continue
+		}
+
+		// Count and generate alignment length and buffer spaces using the
+		// longest key. Keys may be modifed if they contain certain characters so
+		// we need to take that into account in our calculation.
+		alignLength := 0
+		if PrettyFormat {
+			for _, kname := range sec.keyList {
+				keyLength := len(kname)
+				// First case will surround key by ` and second by """
+				if strings.ContainsAny(kname, "\"=:") {
+					keyLength += 2
+				} else if strings.Contains(kname, "`") {
+					keyLength += 6
+				}
+
+				if keyLength > alignLength {
+					alignLength = keyLength
+				}
+			}
+		}
+		alignSpaces := bytes.Repeat([]byte(" "), alignLength)
+
+	KEY_LIST:
+		for _, kname := range sec.keyList {
+			key := sec.Key(kname)
+			if len(key.Comment) > 0 {
+				if len(indent) > 0 && sname != DEFAULT_SECTION {
+					buf.WriteString(indent)
+				}
+
+				// Support multiline comments
+				lines := strings.Split(key.Comment, LineBreak)
+				for i := range lines {
+					if lines[i][0] != '#' && lines[i][0] != ';' {
+						lines[i] = "; " + lines[i]
+					} else {
+						lines[i] = lines[i][:1] + " " + strings.TrimSpace(lines[i][1:])
+					}
+
+					if _, err := buf.WriteString(lines[i] + LineBreak); err != nil {
+						return nil, err
+					}
+				}
+			}
+
+			if len(indent) > 0 && sname != DEFAULT_SECTION {
+				buf.WriteString(indent)
+			}
+
+			switch {
+			case key.isAutoIncrement:
+				kname = "-"
+			case strings.ContainsAny(kname, "\"=:"):
+				kname = "`" + kname + "`"
+			case strings.Contains(kname, "`"):
+				kname = `"""` + kname + `"""`
+			}
+
+			for _, val := range key.ValueWithShadows() {
+				if _, err := buf.WriteString(kname); err != nil {
+					return nil, err
+				}
+
+				if key.isBooleanType {
+					if kname != sec.keyList[len(sec.keyList)-1] {
+						buf.WriteString(LineBreak)
+					}
+					continue KEY_LIST
+				}
+
+				// Write out alignment spaces before "=" sign
+				if PrettyFormat {
+					buf.Write(alignSpaces[:alignLength-len(kname)])
+				}
+
+				// In case key value contains "\n", "`", "\"", "#" or ";"
+				if strings.ContainsAny(val, "\n`") {
+					val = `"""` + val + `"""`
+				} else if !f.options.IgnoreInlineComment && strings.ContainsAny(val, "#;") {
+					val = "`" + val + "`"
+				}
+				if _, err := buf.WriteString(equalSign + val + LineBreak); err != nil {
+					return nil, err
+				}
+			}
+
+			for _, val := range key.nestedValues {
+				if _, err := buf.WriteString(indent + "  " + val + LineBreak); err != nil {
+					return nil, err
+				}
+			}
+		}
+
+		if PrettySection {
+			// Put a line between sections
+			if _, err := buf.WriteString(LineBreak); err != nil {
+				return nil, err
+			}
+		}
+	}
+
+	return buf, nil
+}
+
+// WriteToIndent writes content into io.Writer with given indention.
+// If PrettyFormat has been set to be true,
+// it will align "=" sign with spaces under each section.
+func (f *File) WriteToIndent(w io.Writer, indent string) (int64, error) {
+	buf, err := f.writeToBuffer(indent)
+	if err != nil {
+		return 0, err
+	}
+	return buf.WriteTo(w)
+}
+
+// WriteTo writes file content into io.Writer.
+func (f *File) WriteTo(w io.Writer) (int64, error) {
+	return f.WriteToIndent(w, "")
+}
+
+// SaveToIndent writes content to file system with given value indention.
+func (f *File) SaveToIndent(filename, indent string) error {
+	// Note: Because we are truncating with os.Create,
+	// 	so it's safer to save to a temporary file location and rename afte done.
+	buf, err := f.writeToBuffer(indent)
+	if err != nil {
+		return err
+	}
+
+	return ioutil.WriteFile(filename, buf.Bytes(), 0666)
+}
+
+// SaveTo writes content to file system.
+func (f *File) SaveTo(filename string) error {
+	return f.SaveToIndent(filename, "")
+}
diff --git a/vendor/github.com/go-ini/ini/ini.go b/vendor/github.com/go-ini/ini/ini.go
new file mode 100644
index 000000000..cb55997a3
--- /dev/null
+++ b/vendor/github.com/go-ini/ini/ini.go
@@ -0,0 +1,211 @@
+// +build go1.6
+
+// Copyright 2014 Unknwon
+//
+// Licensed under the Apache License, Version 2.0 (the "License"): you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+// Package ini provides INI file read and write functionality in Go.
+package ini
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os"
+	"regexp"
+	"runtime"
+)
+
+const (
+	// Name for default section. You can use this constant or the string literal.
+	// In most of cases, an empty string is all you need to access the section.
+	DEFAULT_SECTION = "DEFAULT"
+
+	// Maximum allowed depth when recursively substituing variable names.
+	_DEPTH_VALUES = 99
+	_VERSION      = "1.38.2"
+)
+
+// Version returns current package version literal.
+func Version() string {
+	return _VERSION
+}
+
+var (
+	// Delimiter to determine or compose a new line.
+	// This variable will be changed to "\r\n" automatically on Windows
+	// at package init time.
+	LineBreak = "\n"
+
+	// Variable regexp pattern: %(variable)s
+	varPattern = regexp.MustCompile(`%\(([^\)]+)\)s`)
+
+	// Indicate whether to align "=" sign with spaces to produce pretty output
+	// or reduce all possible spaces for compact format.
+	PrettyFormat = true
+
+	// Place spaces around "=" sign even when PrettyFormat is false
+	PrettyEqual = false
+
+	// Explicitly write DEFAULT section header
+	DefaultHeader = false
+
+	// Indicate whether to put a line between sections
+	PrettySection = true
+)
+
+func init() {
+	if runtime.GOOS == "windows" {
+		LineBreak = "\r\n"
+	}
+}
+
+func inSlice(str string, s []string) bool {
+	for _, v := range s {
+		if str == v {
+			return true
+		}
+	}
+	return false
+}
+
+// dataSource is an interface that returns object which can be read and closed.
+type dataSource interface {
+	ReadCloser() (io.ReadCloser, error)
+}
+
+// sourceFile represents an object that contains content on the local file system.
+type sourceFile struct {
+	name string
+}
+
+func (s sourceFile) ReadCloser() (_ io.ReadCloser, err error) {
+	return os.Open(s.name)
+}
+
+// sourceData represents an object that contains content in memory.
+type sourceData struct {
+	data []byte
+}
+
+func (s *sourceData) ReadCloser() (io.ReadCloser, error) {
+	return ioutil.NopCloser(bytes.NewReader(s.data)), nil
+}
+
+// sourceReadCloser represents an input stream with Close method.
+type sourceReadCloser struct {
+	reader io.ReadCloser
+}
+
+func (s *sourceReadCloser) ReadCloser() (io.ReadCloser, error) {
+	return s.reader, nil
+}
+
+func parseDataSource(source interface{}) (dataSource, error) {
+	switch s := source.(type) {
+	case string:
+		return sourceFile{s}, nil
+	case []byte:
+		return &sourceData{s}, nil
+	case io.ReadCloser:
+		return &sourceReadCloser{s}, nil
+	default:
+		return nil, fmt.Errorf("error parsing data source: unknown type '%s'", s)
+	}
+}
+
+type LoadOptions struct {
+	// Loose indicates whether the parser should ignore nonexistent files or return error.
+	Loose bool
+	// Insensitive indicates whether the parser forces all section and key names to lowercase.
+	Insensitive bool
+	// IgnoreContinuation indicates whether to ignore continuation lines while parsing.
+	IgnoreContinuation bool
+	// IgnoreInlineComment indicates whether to ignore comments at the end of value and treat it as part of value.
+	IgnoreInlineComment bool
+	// SkipUnrecognizableLines indicates whether to skip unrecognizable lines that do not conform to key/value pairs.
+	SkipUnrecognizableLines bool
+	// AllowBooleanKeys indicates whether to allow boolean type keys or treat as value is missing.
+	// This type of keys are mostly used in my.cnf.
+	AllowBooleanKeys bool
+	// AllowShadows indicates whether to keep track of keys with same name under same section.
+	AllowShadows bool
+	// AllowNestedValues indicates whether to allow AWS-like nested values.
+	// Docs: http://docs.aws.amazon.com/cli/latest/topic/config-vars.html#nested-values
+	AllowNestedValues bool
+	// AllowPythonMultilineValues indicates whether to allow Python-like multi-line values.
+	// Docs: https://docs.python.org/3/library/configparser.html#supported-ini-file-structure
+	// Relevant quote:  Values can also span multiple lines, as long as they are indented deeper
+	// than the first line of the value.
+	AllowPythonMultilineValues bool
+	// SpaceBeforeInlineComment indicates whether to allow comment symbols (\# and \;) inside value.
+	// Docs: https://docs.python.org/2/library/configparser.html
+	// Quote: Comments may appear on their own in an otherwise empty line, or may be entered in lines holding values or section names.
+	// In the latter case, they need to be preceded by a whitespace character to be recognized as a comment.
+	SpaceBeforeInlineComment bool
+	// UnescapeValueDoubleQuotes indicates whether to unescape double quotes inside value to regular format
+	// when value is surrounded by double quotes, e.g. key="a \"value\"" => key=a "value"
+	UnescapeValueDoubleQuotes bool
+	// UnescapeValueCommentSymbols indicates to unescape comment symbols (\# and \;) inside value to regular format
+	// when value is NOT surrounded by any quotes.
+	// Note: UNSTABLE, behavior might change to only unescape inside double quotes but may noy necessary at all.
+	UnescapeValueCommentSymbols bool
+	// UnparseableSections stores a list of blocks that are allowed with raw content which do not otherwise
+	// conform to key/value pairs. Specify the names of those blocks here.
+	UnparseableSections []string
+}
+
+func LoadSources(opts LoadOptions, source interface{}, others ...interface{}) (_ *File, err error) {
+	sources := make([]dataSource, len(others)+1)
+	sources[0], err = parseDataSource(source)
+	if err != nil {
+		return nil, err
+	}
+	for i := range others {
+		sources[i+1], err = parseDataSource(others[i])
+		if err != nil {
+			return nil, err
+		}
+	}
+	f := newFile(sources, opts)
+	if err = f.Reload(); err != nil {
+		return nil, err
+	}
+	return f, nil
+}
+
+// Load loads and parses from INI data sources.
+// Arguments can be mixed of file name with string type, or raw data in []byte.
+// It will return error if list contains nonexistent files.
+func Load(source interface{}, others ...interface{}) (*File, error) {
+	return LoadSources(LoadOptions{}, source, others...)
+}
+
+// LooseLoad has exactly same functionality as Load function
+// except it ignores nonexistent files instead of returning error.
+func LooseLoad(source interface{}, others ...interface{}) (*File, error) {
+	return LoadSources(LoadOptions{Loose: true}, source, others...)
+}
+
+// InsensitiveLoad has exactly same functionality as Load function
+// except it forces all section and key names to be lowercased.
+func InsensitiveLoad(source interface{}, others ...interface{}) (*File, error) {
+	return LoadSources(LoadOptions{Insensitive: true}, source, others...)
+}
+
+// ShadowLoad has exactly same functionality as Load function
+// except it allows have shadow keys.
+func ShadowLoad(source interface{}, others ...interface{}) (*File, error) {
+	return LoadSources(LoadOptions{AllowShadows: true}, source, others...)
+}
diff --git a/vendor/github.com/go-ini/ini/key.go b/vendor/github.com/go-ini/ini/key.go
new file mode 100644
index 000000000..7c8566a1b
--- /dev/null
+++ b/vendor/github.com/go-ini/ini/key.go
@@ -0,0 +1,751 @@
+// Copyright 2014 Unknwon
+//
+// Licensed under the Apache License, Version 2.0 (the "License"): you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+package ini
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// Key represents a key under a section.
+type Key struct {
+	s               *Section
+	Comment         string
+	name            string
+	value           string
+	isAutoIncrement bool
+	isBooleanType   bool
+
+	isShadow bool
+	shadows  []*Key
+
+	nestedValues []string
+}
+
+// newKey simply return a key object with given values.
+func newKey(s *Section, name, val string) *Key {
+	return &Key{
+		s:     s,
+		name:  name,
+		value: val,
+	}
+}
+
+func (k *Key) addShadow(val string) error {
+	if k.isShadow {
+		return errors.New("cannot add shadow to another shadow key")
+	} else if k.isAutoIncrement || k.isBooleanType {
+		return errors.New("cannot add shadow to auto-increment or boolean key")
+	}
+
+	shadow := newKey(k.s, k.name, val)
+	shadow.isShadow = true
+	k.shadows = append(k.shadows, shadow)
+	return nil
+}
+
+// AddShadow adds a new shadow key to itself.
+func (k *Key) AddShadow(val string) error {
+	if !k.s.f.options.AllowShadows {
+		return errors.New("shadow key is not allowed")
+	}
+	return k.addShadow(val)
+}
+
+func (k *Key) addNestedValue(val string) error {
+	if k.isAutoIncrement || k.isBooleanType {
+		return errors.New("cannot add nested value to auto-increment or boolean key")
+	}
+
+	k.nestedValues = append(k.nestedValues, val)
+	return nil
+}
+
+func (k *Key) AddNestedValue(val string) error {
+	if !k.s.f.options.AllowNestedValues {
+		return errors.New("nested value is not allowed")
+	}
+	return k.addNestedValue(val)
+}
+
+// ValueMapper represents a mapping function for values, e.g. os.ExpandEnv
+type ValueMapper func(string) string
+
+// Name returns name of key.
+func (k *Key) Name() string {
+	return k.name
+}
+
+// Value returns raw value of key for performance purpose.
+func (k *Key) Value() string {
+	return k.value
+}
+
+// ValueWithShadows returns raw values of key and its shadows if any.
+func (k *Key) ValueWithShadows() []string {
+	if len(k.shadows) == 0 {
+		return []string{k.value}
+	}
+	vals := make([]string, len(k.shadows)+1)
+	vals[0] = k.value
+	for i := range k.shadows {
+		vals[i+1] = k.shadows[i].value
+	}
+	return vals
+}
+
+// NestedValues returns nested values stored in the key.
+// It is possible returned value is nil if no nested values stored in the key.
+func (k *Key) NestedValues() []string {
+	return k.nestedValues
+}
+
+// transformValue takes a raw value and transforms to its final string.
+func (k *Key) transformValue(val string) string {
+	if k.s.f.ValueMapper != nil {
+		val = k.s.f.ValueMapper(val)
+	}
+
+	// Fail-fast if no indicate char found for recursive value
+	if !strings.Contains(val, "%") {
+		return val
+	}
+	for i := 0; i < _DEPTH_VALUES; i++ {
+		vr := varPattern.FindString(val)
+		if len(vr) == 0 {
+			break
+		}
+
+		// Take off leading '%(' and trailing ')s'.
+		noption := strings.TrimLeft(vr, "%(")
+		noption = strings.TrimRight(noption, ")s")
+
+		// Search in the same section.
+		nk, err := k.s.GetKey(noption)
+		if err != nil || k == nk {
+			// Search again in default section.
+			nk, _ = k.s.f.Section("").GetKey(noption)
+		}
+
+		// Substitute by new value and take off leading '%(' and trailing ')s'.
+		val = strings.Replace(val, vr, nk.value, -1)
+	}
+	return val
+}
+
+// String returns string representation of value.
+func (k *Key) String() string {
+	return k.transformValue(k.value)
+}
+
+// Validate accepts a validate function which can
+// return modifed result as key value.
+func (k *Key) Validate(fn func(string) string) string {
+	return fn(k.String())
+}
+
+// parseBool returns the boolean value represented by the string.
+//
+// It accepts 1, t, T, TRUE, true, True, YES, yes, Yes, y, ON, on, On,
+// 0, f, F, FALSE, false, False, NO, no, No, n, OFF, off, Off.
+// Any other value returns an error.
+func parseBool(str string) (value bool, err error) {
+	switch str {
+	case "1", "t", "T", "true", "TRUE", "True", "YES", "yes", "Yes", "y", "ON", "on", "On":
+		return true, nil
+	case "0", "f", "F", "false", "FALSE", "False", "NO", "no", "No", "n", "OFF", "off", "Off":
+		return false, nil
+	}
+	return false, fmt.Errorf("parsing \"%s\": invalid syntax", str)
+}
+
+// Bool returns bool type value.
+func (k *Key) Bool() (bool, error) {
+	return parseBool(k.String())
+}
+
+// Float64 returns float64 type value.
+func (k *Key) Float64() (float64, error) {
+	return strconv.ParseFloat(k.String(), 64)
+}
+
+// Int returns int type value.
+func (k *Key) Int() (int, error) {
+	return strconv.Atoi(k.String())
+}
+
+// Int64 returns int64 type value.
+func (k *Key) Int64() (int64, error) {
+	return strconv.ParseInt(k.String(), 10, 64)
+}
+
+// Uint returns uint type valued.
+func (k *Key) Uint() (uint, error) {
+	u, e := strconv.ParseUint(k.String(), 10, 64)
+	return uint(u), e
+}
+
+// Uint64 returns uint64 type value.
+func (k *Key) Uint64() (uint64, error) {
+	return strconv.ParseUint(k.String(), 10, 64)
+}
+
+// Duration returns time.Duration type value.
+func (k *Key) Duration() (time.Duration, error) {
+	return time.ParseDuration(k.String())
+}
+
+// TimeFormat parses with given format and returns time.Time type value.
+func (k *Key) TimeFormat(format string) (time.Time, error) {
+	return time.Parse(format, k.String())
+}
+
+// Time parses with RFC3339 format and returns time.Time type value.
+func (k *Key) Time() (time.Time, error) {
+	return k.TimeFormat(time.RFC3339)
+}
+
+// MustString returns default value if key value is empty.
+func (k *Key) MustString(defaultVal string) string {
+	val := k.String()
+	if len(val) == 0 {
+		k.value = defaultVal
+		return defaultVal
+	}
+	return val
+}
+
+// MustBool always returns value without error,
+// it returns false if error occurs.
+func (k *Key) MustBool(defaultVal ...bool) bool {
+	val, err := k.Bool()
+	if len(defaultVal) > 0 && err != nil {
+		k.value = strconv.FormatBool(defaultVal[0])
+		return defaultVal[0]
+	}
+	return val
+}
+
+// MustFloat64 always returns value without error,
+// it returns 0.0 if error occurs.
+func (k *Key) MustFloat64(defaultVal ...float64) float64 {
+	val, err := k.Float64()
+	if len(defaultVal) > 0 && err != nil {
+		k.value = strconv.FormatFloat(defaultVal[0], 'f', -1, 64)
+		return defaultVal[0]
+	}
+	return val
+}
+
+// MustInt always returns value without error,
+// it returns 0 if error occurs.
+func (k *Key) MustInt(defaultVal ...int) int {
+	val, err := k.Int()
+	if len(defaultVal) > 0 && err != nil {
+		k.value = strconv.FormatInt(int64(defaultVal[0]), 10)
+		return defaultVal[0]
+	}
+	return val
+}
+
+// MustInt64 always returns value without error,
+// it returns 0 if error occurs.
+func (k *Key) MustInt64(defaultVal ...int64) int64 {
+	val, err := k.Int64()
+	if len(defaultVal) > 0 && err != nil {
+		k.value = strconv.FormatInt(defaultVal[0], 10)
+		return defaultVal[0]
+	}
+	return val
+}
+
+// MustUint always returns value without error,
+// it returns 0 if error occurs.
+func (k *Key) MustUint(defaultVal ...uint) uint {
+	val, err := k.Uint()
+	if len(defaultVal) > 0 && err != nil {
+		k.value = strconv.FormatUint(uint64(defaultVal[0]), 10)
+		return defaultVal[0]
+	}
+	return val
+}
+
+// MustUint64 always returns value without error,
+// it returns 0 if error occurs.
+func (k *Key) MustUint64(defaultVal ...uint64) uint64 {
+	val, err := k.Uint64()
+	if len(defaultVal) > 0 && err != nil {
+		k.value = strconv.FormatUint(defaultVal[0], 10)
+		return defaultVal[0]
+	}
+	return val
+}
+
+// MustDuration always returns value without error,
+// it returns zero value if error occurs.
+func (k *Key) MustDuration(defaultVal ...time.Duration) time.Duration {
+	val, err := k.Duration()
+	if len(defaultVal) > 0 && err != nil {
+		k.value = defaultVal[0].String()
+		return defaultVal[0]
+	}
+	return val
+}
+
+// MustTimeFormat always parses with given format and returns value without error,
+// it returns zero value if error occurs.
+func (k *Key) MustTimeFormat(format string, defaultVal ...time.Time) time.Time {
+	val, err := k.TimeFormat(format)
+	if len(defaultVal) > 0 && err != nil {
+		k.value = defaultVal[0].Format(format)
+		return defaultVal[0]
+	}
+	return val
+}
+
+// MustTime always parses with RFC3339 format and returns value without error,
+// it returns zero value if error occurs.
+func (k *Key) MustTime(defaultVal ...time.Time) time.Time {
+	return k.MustTimeFormat(time.RFC3339, defaultVal...)
+}
+
+// In always returns value without error,
+// it returns default value if error occurs or doesn't fit into candidates.
+func (k *Key) In(defaultVal string, candidates []string) string {
+	val := k.String()
+	for _, cand := range candidates {
+		if val == cand {
+			return val
+		}
+	}
+	return defaultVal
+}
+
+// InFloat64 always returns value without error,
+// it returns default value if error occurs or doesn't fit into candidates.
+func (k *Key) InFloat64(defaultVal float64, candidates []float64) float64 {
+	val := k.MustFloat64()
+	for _, cand := range candidates {
+		if val == cand {
+			return val
+		}
+	}
+	return defaultVal
+}
+
+// InInt always returns value without error,
+// it returns default value if error occurs or doesn't fit into candidates.
+func (k *Key) InInt(defaultVal int, candidates []int) int {
+	val := k.MustInt()
+	for _, cand := range candidates {
+		if val == cand {
+			return val
+		}
+	}
+	return defaultVal
+}
+
+// InInt64 always returns value without error,
+// it returns default value if error occurs or doesn't fit into candidates.
+func (k *Key) InInt64(defaultVal int64, candidates []int64) int64 {
+	val := k.MustInt64()
+	for _, cand := range candidates {
+		if val == cand {
+			return val
+		}
+	}
+	return defaultVal
+}
+
+// InUint always returns value without error,
+// it returns default value if error occurs or doesn't fit into candidates.
+func (k *Key) InUint(defaultVal uint, candidates []uint) uint {
+	val := k.MustUint()
+	for _, cand := range candidates {
+		if val == cand {
+			return val
+		}
+	}
+	return defaultVal
+}
+
+// InUint64 always returns value without error,
+// it returns default value if error occurs or doesn't fit into candidates.
+func (k *Key) InUint64(defaultVal uint64, candidates []uint64) uint64 {
+	val := k.MustUint64()
+	for _, cand := range candidates {
+		if val == cand {
+			return val
+		}
+	}
+	return defaultVal
+}
+
+// InTimeFormat always parses with given format and returns value without error,
+// it returns default value if error occurs or doesn't fit into candidates.
+func (k *Key) InTimeFormat(format string, defaultVal time.Time, candidates []time.Time) time.Time {
+	val := k.MustTimeFormat(format)
+	for _, cand := range candidates {
+		if val == cand {
+			return val
+		}
+	}
+	return defaultVal
+}
+
+// InTime always parses with RFC3339 format and returns value without error,
+// it returns default value if error occurs or doesn't fit into candidates.
+func (k *Key) InTime(defaultVal time.Time, candidates []time.Time) time.Time {
+	return k.InTimeFormat(time.RFC3339, defaultVal, candidates)
+}
+
+// RangeFloat64 checks if value is in given range inclusively,
+// and returns default value if it's not.
+func (k *Key) RangeFloat64(defaultVal, min, max float64) float64 {
+	val := k.MustFloat64()
+	if val < min || val > max {
+		return defaultVal
+	}
+	return val
+}
+
+// RangeInt checks if value is in given range inclusively,
+// and returns default value if it's not.
+func (k *Key) RangeInt(defaultVal, min, max int) int {
+	val := k.MustInt()
+	if val < min || val > max {
+		return defaultVal
+	}
+	return val
+}
+
+// RangeInt64 checks if value is in given range inclusively,
+// and returns default value if it's not.
+func (k *Key) RangeInt64(defaultVal, min, max int64) int64 {
+	val := k.MustInt64()
+	if val < min || val > max {
+		return defaultVal
+	}
+	return val
+}
+
+// RangeTimeFormat checks if value with given format is in given range inclusively,
+// and returns default value if it's not.
+func (k *Key) RangeTimeFormat(format string, defaultVal, min, max time.Time) time.Time {
+	val := k.MustTimeFormat(format)
+	if val.Unix() < min.Unix() || val.Unix() > max.Unix() {
+		return defaultVal
+	}
+	return val
+}
+
+// RangeTime checks if value with RFC3339 format is in given range inclusively,
+// and returns default value if it's not.
+func (k *Key) RangeTime(defaultVal, min, max time.Time) time.Time {
+	return k.RangeTimeFormat(time.RFC3339, defaultVal, min, max)
+}
+
+// Strings returns list of string divided by given delimiter.
+func (k *Key) Strings(delim string) []string {
+	str := k.String()
+	if len(str) == 0 {
+		return []string{}
+	}
+
+	runes := []rune(str)
+	vals := make([]string, 0, 2)
+	var buf bytes.Buffer
+	escape := false
+	idx := 0
+	for {
+		if escape {
+			escape = false
+			if runes[idx] != '\\' && !strings.HasPrefix(string(runes[idx:]), delim) {
+				buf.WriteRune('\\')
+			}
+			buf.WriteRune(runes[idx])
+		} else {
+			if runes[idx] == '\\' {
+				escape = true
+			} else if strings.HasPrefix(string(runes[idx:]), delim) {
+				idx += len(delim) - 1
+				vals = append(vals, strings.TrimSpace(buf.String()))
+				buf.Reset()
+			} else {
+				buf.WriteRune(runes[idx])
+			}
+		}
+		idx += 1
+		if idx == len(runes) {
+			break
+		}
+	}
+
+	if buf.Len() > 0 {
+		vals = append(vals, strings.TrimSpace(buf.String()))
+	}
+
+	return vals
+}
+
+// StringsWithShadows returns list of string divided by given delimiter.
+// Shadows will also be appended if any.
+func (k *Key) StringsWithShadows(delim string) []string {
+	vals := k.ValueWithShadows()
+	results := make([]string, 0, len(vals)*2)
+	for i := range vals {
+		if len(vals) == 0 {
+			continue
+		}
+
+		results = append(results, strings.Split(vals[i], delim)...)
+	}
+
+	for i := range results {
+		results[i] = k.transformValue(strings.TrimSpace(results[i]))
+	}
+	return results
+}
+
+// Float64s returns list of float64 divided by given delimiter. Any invalid input will be treated as zero value.
+func (k *Key) Float64s(delim string) []float64 {
+	vals, _ := k.parseFloat64s(k.Strings(delim), true, false)
+	return vals
+}
+
+// Ints returns list of int divided by given delimiter. Any invalid input will be treated as zero value.
+func (k *Key) Ints(delim string) []int {
+	vals, _ := k.parseInts(k.Strings(delim), true, false)
+	return vals
+}
+
+// Int64s returns list of int64 divided by given delimiter. Any invalid input will be treated as zero value.
+func (k *Key) Int64s(delim string) []int64 {
+	vals, _ := k.parseInt64s(k.Strings(delim), true, false)
+	return vals
+}
+
+// Uints returns list of uint divided by given delimiter. Any invalid input will be treated as zero value.
+func (k *Key) Uints(delim string) []uint {
+	vals, _ := k.parseUints(k.Strings(delim), true, false)
+	return vals
+}
+
+// Uint64s returns list of uint64 divided by given delimiter. Any invalid input will be treated as zero value.
+func (k *Key) Uint64s(delim string) []uint64 {
+	vals, _ := k.parseUint64s(k.Strings(delim), true, false)
+	return vals
+}
+
+// TimesFormat parses with given format and returns list of time.Time divided by given delimiter.
+// Any invalid input will be treated as zero value (0001-01-01 00:00:00 +0000 UTC).
+func (k *Key) TimesFormat(format, delim string) []time.Time {
+	vals, _ := k.parseTimesFormat(format, k.Strings(delim), true, false)
+	return vals
+}
+
+// Times parses with RFC3339 format and returns list of time.Time divided by given delimiter.
+// Any invalid input will be treated as zero value (0001-01-01 00:00:00 +0000 UTC).
+func (k *Key) Times(delim string) []time.Time {
+	return k.TimesFormat(time.RFC3339, delim)
+}
+
+// ValidFloat64s returns list of float64 divided by given delimiter. If some value is not float, then
+// it will not be included to result list.
+func (k *Key) ValidFloat64s(delim string) []float64 {
+	vals, _ := k.parseFloat64s(k.Strings(delim), false, false)
+	return vals
+}
+
+// ValidInts returns list of int divided by given delimiter. If some value is not integer, then it will
+// not be included to result list.
+func (k *Key) ValidInts(delim string) []int {
+	vals, _ := k.parseInts(k.Strings(delim), false, false)
+	return vals
+}
+
+// ValidInt64s returns list of int64 divided by given delimiter. If some value is not 64-bit integer,
+// then it will not be included to result list.
+func (k *Key) ValidInt64s(delim string) []int64 {
+	vals, _ := k.parseInt64s(k.Strings(delim), false, false)
+	return vals
+}
+
+// ValidUints returns list of uint divided by given delimiter. If some value is not unsigned integer,
+// then it will not be included to result list.
+func (k *Key) ValidUints(delim string) []uint {
+	vals, _ := k.parseUints(k.Strings(delim), false, false)
+	return vals
+}
+
+// ValidUint64s returns list of uint64 divided by given delimiter. If some value is not 64-bit unsigned
+// integer, then it will not be included to result list.
+func (k *Key) ValidUint64s(delim string) []uint64 {
+	vals, _ := k.parseUint64s(k.Strings(delim), false, false)
+	return vals
+}
+
+// ValidTimesFormat parses with given format and returns list of time.Time divided by given delimiter.
+func (k *Key) ValidTimesFormat(format, delim string) []time.Time {
+	vals, _ := k.parseTimesFormat(format, k.Strings(delim), false, false)
+	return vals
+}
+
+// ValidTimes parses with RFC3339 format and returns list of time.Time divided by given delimiter.
+func (k *Key) ValidTimes(delim string) []time.Time {
+	return k.ValidTimesFormat(time.RFC3339, delim)
+}
+
+// StrictFloat64s returns list of float64 divided by given delimiter or error on first invalid input.
+func (k *Key) StrictFloat64s(delim string) ([]float64, error) {
+	return k.parseFloat64s(k.Strings(delim), false, true)
+}
+
+// StrictInts returns list of int divided by given delimiter or error on first invalid input.
+func (k *Key) StrictInts(delim string) ([]int, error) {
+	return k.parseInts(k.Strings(delim), false, true)
+}
+
+// StrictInt64s returns list of int64 divided by given delimiter or error on first invalid input.
+func (k *Key) StrictInt64s(delim string) ([]int64, error) {
+	return k.parseInt64s(k.Strings(delim), false, true)
+}
+
+// StrictUints returns list of uint divided by given delimiter or error on first invalid input.
+func (k *Key) StrictUints(delim string) ([]uint, error) {
+	return k.parseUints(k.Strings(delim), false, true)
+}
+
+// StrictUint64s returns list of uint64 divided by given delimiter or error on first invalid input.
+func (k *Key) StrictUint64s(delim string) ([]uint64, error) {
+	return k.parseUint64s(k.Strings(delim), false, true)
+}
+
+// StrictTimesFormat parses with given format and returns list of time.Time divided by given delimiter
+// or error on first invalid input.
+func (k *Key) StrictTimesFormat(format, delim string) ([]time.Time, error) {
+	return k.parseTimesFormat(format, k.Strings(delim), false, true)
+}
+
+// StrictTimes parses with RFC3339 format and returns list of time.Time divided by given delimiter
+// or error on first invalid input.
+func (k *Key) StrictTimes(delim string) ([]time.Time, error) {
+	return k.StrictTimesFormat(time.RFC3339, delim)
+}
+
+// parseFloat64s transforms strings to float64s.
+func (k *Key) parseFloat64s(strs []string, addInvalid, returnOnInvalid bool) ([]float64, error) {
+	vals := make([]float64, 0, len(strs))
+	for _, str := range strs {
+		val, err := strconv.ParseFloat(str, 64)
+		if err != nil && returnOnInvalid {
+			return nil, err
+		}
+		if err == nil || addInvalid {
+			vals = append(vals, val)
+		}
+	}
+	return vals, nil
+}
+
+// parseInts transforms strings to ints.
+func (k *Key) parseInts(strs []string, addInvalid, returnOnInvalid bool) ([]int, error) {
+	vals := make([]int, 0, len(strs))
+	for _, str := range strs {
+		val, err := strconv.Atoi(str)
+		if err != nil && returnOnInvalid {
+			return nil, err
+		}
+		if err == nil || addInvalid {
+			vals = append(vals, val)
+		}
+	}
+	return vals, nil
+}
+
+// parseInt64s transforms strings to int64s.
+func (k *Key) parseInt64s(strs []string, addInvalid, returnOnInvalid bool) ([]int64, error) {
+	vals := make([]int64, 0, len(strs))
+	for _, str := range strs {
+		val, err := strconv.ParseInt(str, 10, 64)
+		if err != nil && returnOnInvalid {
+			return nil, err
+		}
+		if err == nil || addInvalid {
+			vals = append(vals, val)
+		}
+	}
+	return vals, nil
+}
+
+// parseUints transforms strings to uints.
+func (k *Key) parseUints(strs []string, addInvalid, returnOnInvalid bool) ([]uint, error) {
+	vals := make([]uint, 0, len(strs))
+	for _, str := range strs {
+		val, err := strconv.ParseUint(str, 10, 0)
+		if err != nil && returnOnInvalid {
+			return nil, err
+		}
+		if err == nil || addInvalid {
+			vals = append(vals, uint(val))
+		}
+	}
+	return vals, nil
+}
+
+// parseUint64s transforms strings to uint64s.
+func (k *Key) parseUint64s(strs []string, addInvalid, returnOnInvalid bool) ([]uint64, error) {
+	vals := make([]uint64, 0, len(strs))
+	for _, str := range strs {
+		val, err := strconv.ParseUint(str, 10, 64)
+		if err != nil && returnOnInvalid {
+			return nil, err
+		}
+		if err == nil || addInvalid {
+			vals = append(vals, val)
+		}
+	}
+	return vals, nil
+}
+
+// parseTimesFormat transforms strings to times in given format.
+func (k *Key) parseTimesFormat(format string, strs []string, addInvalid, returnOnInvalid bool) ([]time.Time, error) {
+	vals := make([]time.Time, 0, len(strs))
+	for _, str := range strs {
+		val, err := time.Parse(format, str)
+		if err != nil && returnOnInvalid {
+			return nil, err
+		}
+		if err == nil || addInvalid {
+			vals = append(vals, val)
+		}
+	}
+	return vals, nil
+}
+
+// SetValue changes key value.
+func (k *Key) SetValue(v string) {
+	if k.s.f.BlockMode {
+		k.s.f.lock.Lock()
+		defer k.s.f.lock.Unlock()
+	}
+
+	k.value = v
+	k.s.keysHash[k.name] = v
+}
diff --git a/vendor/github.com/go-ini/ini/parser.go b/vendor/github.com/go-ini/ini/parser.go
new file mode 100644
index 000000000..3daf54c38
--- /dev/null
+++ b/vendor/github.com/go-ini/ini/parser.go
@@ -0,0 +1,494 @@
+// Copyright 2015 Unknwon
+//
+// Licensed under the Apache License, Version 2.0 (the "License"): you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+package ini
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io"
+	"regexp"
+	"strconv"
+	"strings"
+	"unicode"
+)
+
+var pythonMultiline = regexp.MustCompile("^(\\s+)([^\n]+)")
+
+type tokenType int
+
+const (
+	_TOKEN_INVALID tokenType = iota
+	_TOKEN_COMMENT
+	_TOKEN_SECTION
+	_TOKEN_KEY
+)
+
+type parser struct {
+	buf     *bufio.Reader
+	isEOF   bool
+	count   int
+	comment *bytes.Buffer
+}
+
+func newParser(r io.Reader) *parser {
+	return &parser{
+		buf:     bufio.NewReader(r),
+		count:   1,
+		comment: &bytes.Buffer{},
+	}
+}
+
+// BOM handles header of UTF-8, UTF-16 LE and UTF-16 BE's BOM format.
+// http://en.wikipedia.org/wiki/Byte_order_mark#Representations_of_byte_order_marks_by_encoding
+func (p *parser) BOM() error {
+	mask, err := p.buf.Peek(2)
+	if err != nil && err != io.EOF {
+		return err
+	} else if len(mask) < 2 {
+		return nil
+	}
+
+	switch {
+	case mask[0] == 254 && mask[1] == 255:
+		fallthrough
+	case mask[0] == 255 && mask[1] == 254:
+		p.buf.Read(mask)
+	case mask[0] == 239 && mask[1] == 187:
+		mask, err := p.buf.Peek(3)
+		if err != nil && err != io.EOF {
+			return err
+		} else if len(mask) < 3 {
+			return nil
+		}
+		if mask[2] == 191 {
+			p.buf.Read(mask)
+		}
+	}
+	return nil
+}
+
+func (p *parser) readUntil(delim byte) ([]byte, error) {
+	data, err := p.buf.ReadBytes(delim)
+	if err != nil {
+		if err == io.EOF {
+			p.isEOF = true
+		} else {
+			return nil, err
+		}
+	}
+	return data, nil
+}
+
+func cleanComment(in []byte) ([]byte, bool) {
+	i := bytes.IndexAny(in, "#;")
+	if i == -1 {
+		return nil, false
+	}
+	return in[i:], true
+}
+
+func readKeyName(in []byte) (string, int, error) {
+	line := string(in)
+
+	// Check if key name surrounded by quotes.
+	var keyQuote string
+	if line[0] == '"' {
+		if len(line) > 6 && string(line[0:3]) == `"""` {
+			keyQuote = `"""`
+		} else {
+			keyQuote = `"`
+		}
+	} else if line[0] == '`' {
+		keyQuote = "`"
+	}
+
+	// Get out key name
+	endIdx := -1
+	if len(keyQuote) > 0 {
+		startIdx := len(keyQuote)
+		// FIXME: fail case -> """"""name"""=value
+		pos := strings.Index(line[startIdx:], keyQuote)
+		if pos == -1 {
+			return "", -1, fmt.Errorf("missing closing key quote: %s", line)
+		}
+		pos += startIdx
+
+		// Find key-value delimiter
+		i := strings.IndexAny(line[pos+startIdx:], "=:")
+		if i < 0 {
+			return "", -1, ErrDelimiterNotFound{line}
+		}
+		endIdx = pos + i
+		return strings.TrimSpace(line[startIdx:pos]), endIdx + startIdx + 1, nil
+	}
+
+	endIdx = strings.IndexAny(line, "=:")
+	if endIdx < 0 {
+		return "", -1, ErrDelimiterNotFound{line}
+	}
+	return strings.TrimSpace(line[0:endIdx]), endIdx + 1, nil
+}
+
+func (p *parser) readMultilines(line, val, valQuote string) (string, error) {
+	for {
+		data, err := p.readUntil('\n')
+		if err != nil {
+			return "", err
+		}
+		next := string(data)
+
+		pos := strings.LastIndex(next, valQuote)
+		if pos > -1 {
+			val += next[:pos]
+
+			comment, has := cleanComment([]byte(next[pos:]))
+			if has {
+				p.comment.Write(bytes.TrimSpace(comment))
+			}
+			break
+		}
+		val += next
+		if p.isEOF {
+			return "", fmt.Errorf("missing closing key quote from '%s' to '%s'", line, next)
+		}
+	}
+	return val, nil
+}
+
+func (p *parser) readContinuationLines(val string) (string, error) {
+	for {
+		data, err := p.readUntil('\n')
+		if err != nil {
+			return "", err
+		}
+		next := strings.TrimSpace(string(data))
+
+		if len(next) == 0 {
+			break
+		}
+		val += next
+		if val[len(val)-1] != '\\' {
+			break
+		}
+		val = val[:len(val)-1]
+	}
+	return val, nil
+}
+
+// hasSurroundedQuote check if and only if the first and last characters
+// are quotes \" or \'.
+// It returns false if any other parts also contain same kind of quotes.
+func hasSurroundedQuote(in string, quote byte) bool {
+	return len(in) >= 2 && in[0] == quote && in[len(in)-1] == quote &&
+		strings.IndexByte(in[1:], quote) == len(in)-2
+}
+
+func (p *parser) readValue(in []byte,
+	parserBufferSize int,
+	ignoreContinuation, ignoreInlineComment, unescapeValueDoubleQuotes, unescapeValueCommentSymbols, allowPythonMultilines, spaceBeforeInlineComment bool) (string, error) {
+
+	line := strings.TrimLeftFunc(string(in), unicode.IsSpace)
+	if len(line) == 0 {
+		return "", nil
+	}
+
+	var valQuote string
+	if len(line) > 3 && string(line[0:3]) == `"""` {
+		valQuote = `"""`
+	} else if line[0] == '`' {
+		valQuote = "`"
+	} else if unescapeValueDoubleQuotes && line[0] == '"' {
+		valQuote = `"`
+	}
+
+	if len(valQuote) > 0 {
+		startIdx := len(valQuote)
+		pos := strings.LastIndex(line[startIdx:], valQuote)
+		// Check for multi-line value
+		if pos == -1 {
+			return p.readMultilines(line, line[startIdx:], valQuote)
+		}
+
+		if unescapeValueDoubleQuotes && valQuote == `"` {
+			return strings.Replace(line[startIdx:pos+startIdx], `\"`, `"`, -1), nil
+		}
+		return line[startIdx : pos+startIdx], nil
+	}
+
+	lastChar := line[len(line)-1]
+	// Won't be able to reach here if value only contains whitespace
+	line = strings.TrimSpace(line)
+	trimmedLastChar := line[len(line)-1]
+
+	// Check continuation lines when desired
+	if !ignoreContinuation && trimmedLastChar == '\\' {
+		return p.readContinuationLines(line[:len(line)-1])
+	}
+
+	// Check if ignore inline comment
+	if !ignoreInlineComment {
+		var i int
+		if spaceBeforeInlineComment {
+			i = strings.Index(line, " #")
+			if i == -1 {
+				i = strings.Index(line, " ;")
+			}
+
+		} else {
+			i = strings.IndexAny(line, "#;")
+		}
+
+		if i > -1 {
+			p.comment.WriteString(line[i:])
+			line = strings.TrimSpace(line[:i])
+		}
+
+	}
+
+	// Trim single and double quotes
+	if hasSurroundedQuote(line, '\'') ||
+		hasSurroundedQuote(line, '"') {
+		line = line[1 : len(line)-1]
+	} else if len(valQuote) == 0 && unescapeValueCommentSymbols {
+		if strings.Contains(line, `\;`) {
+			line = strings.Replace(line, `\;`, ";", -1)
+		}
+		if strings.Contains(line, `\#`) {
+			line = strings.Replace(line, `\#`, "#", -1)
+		}
+	} else if allowPythonMultilines && lastChar == '\n' {
+		parserBufferPeekResult, _ := p.buf.Peek(parserBufferSize)
+		peekBuffer := bytes.NewBuffer(parserBufferPeekResult)
+
+		identSize := -1
+		val := line
+
+		for {
+			peekData, peekErr := peekBuffer.ReadBytes('\n')
+			if peekErr != nil {
+				if peekErr == io.EOF {
+					return val, nil
+				}
+				return "", peekErr
+			}
+
+			peekMatches := pythonMultiline.FindStringSubmatch(string(peekData))
+			if len(peekMatches) != 3 {
+				return val, nil
+			}
+
+			currentIdentSize := len(peekMatches[1])
+			// NOTE: Return if not a python-ini multi-line value.
+			if currentIdentSize < 0 {
+				return val, nil
+			}
+			identSize = currentIdentSize
+
+			// NOTE: Just advance the parser reader (buffer) in-sync with the peek buffer.
+			_, err := p.readUntil('\n')
+			if err != nil {
+				return "", err
+			}
+
+			val += fmt.Sprintf("\n%s", peekMatches[2])
+		}
+
+		// NOTE: If it was a Python multi-line value,
+		// return the appended value.
+		if identSize > 0 {
+			return val, nil
+		}
+	}
+
+	return line, nil
+}
+
+// parse parses data through an io.Reader.
+func (f *File) parse(reader io.Reader) (err error) {
+	p := newParser(reader)
+	if err = p.BOM(); err != nil {
+		return fmt.Errorf("BOM: %v", err)
+	}
+
+	// Ignore error because default section name is never empty string.
+	name := DEFAULT_SECTION
+	if f.options.Insensitive {
+		name = strings.ToLower(DEFAULT_SECTION)
+	}
+	section, _ := f.NewSection(name)
+
+	// This "last" is not strictly equivalent to "previous one" if current key is not the first nested key
+	var isLastValueEmpty bool
+	var lastRegularKey *Key
+
+	var line []byte
+	var inUnparseableSection bool
+
+	// NOTE: Iterate and increase `currentPeekSize` until
+	// the size of the parser buffer is found.
+	// TODO(unknwon): When Golang 1.10 is the lowest version supported, replace with `parserBufferSize := p.buf.Size()`.
+	parserBufferSize := 0
+	// NOTE: Peek 1kb at a time.
+	currentPeekSize := 1024
+
+	if f.options.AllowPythonMultilineValues {
+		for {
+			peekBytes, _ := p.buf.Peek(currentPeekSize)
+			peekBytesLength := len(peekBytes)
+
+			if parserBufferSize >= peekBytesLength {
+				break
+			}
+
+			currentPeekSize *= 2
+			parserBufferSize = peekBytesLength
+		}
+	}
+
+	for !p.isEOF {
+		line, err = p.readUntil('\n')
+		if err != nil {
+			return err
+		}
+
+		if f.options.AllowNestedValues &&
+			isLastValueEmpty && len(line) > 0 {
+			if line[0] == ' ' || line[0] == '\t' {
+				lastRegularKey.addNestedValue(string(bytes.TrimSpace(line)))
+				continue
+			}
+		}
+
+		line = bytes.TrimLeftFunc(line, unicode.IsSpace)
+		if len(line) == 0 {
+			continue
+		}
+
+		// Comments
+		if line[0] == '#' || line[0] == ';' {
+			// Note: we do not care ending line break,
+			// it is needed for adding second line,
+			// so just clean it once at the end when set to value.
+			p.comment.Write(line)
+			continue
+		}
+
+		// Section
+		if line[0] == '[' {
+			// Read to the next ']' (TODO: support quoted strings)
+			closeIdx := bytes.LastIndexByte(line, ']')
+			if closeIdx == -1 {
+				return fmt.Errorf("unclosed section: %s", line)
+			}
+
+			name := string(line[1:closeIdx])
+			section, err = f.NewSection(name)
+			if err != nil {
+				return err
+			}
+
+			comment, has := cleanComment(line[closeIdx+1:])
+			if has {
+				p.comment.Write(comment)
+			}
+
+			section.Comment = strings.TrimSpace(p.comment.String())
+
+			// Reset aotu-counter and comments
+			p.comment.Reset()
+			p.count = 1
+
+			inUnparseableSection = false
+			for i := range f.options.UnparseableSections {
+				if f.options.UnparseableSections[i] == name ||
+					(f.options.Insensitive && strings.ToLower(f.options.UnparseableSections[i]) == strings.ToLower(name)) {
+					inUnparseableSection = true
+					continue
+				}
+			}
+			continue
+		}
+
+		if inUnparseableSection {
+			section.isRawSection = true
+			section.rawBody += string(line)
+			continue
+		}
+
+		kname, offset, err := readKeyName(line)
+		if err != nil {
+			// Treat as boolean key when desired, and whole line is key name.
+			if IsErrDelimiterNotFound(err) {
+				switch {
+				case f.options.AllowBooleanKeys:
+					kname, err := p.readValue(line,
+						parserBufferSize,
+						f.options.IgnoreContinuation,
+						f.options.IgnoreInlineComment,
+						f.options.UnescapeValueDoubleQuotes,
+						f.options.UnescapeValueCommentSymbols,
+						f.options.AllowPythonMultilineValues,
+						f.options.SpaceBeforeInlineComment)
+					if err != nil {
+						return err
+					}
+					key, err := section.NewBooleanKey(kname)
+					if err != nil {
+						return err
+					}
+					key.Comment = strings.TrimSpace(p.comment.String())
+					p.comment.Reset()
+					continue
+
+				case f.options.SkipUnrecognizableLines:
+					continue
+				}
+			}
+			return err
+		}
+
+		// Auto increment.
+		isAutoIncr := false
+		if kname == "-" {
+			isAutoIncr = true
+			kname = "#" + strconv.Itoa(p.count)
+			p.count++
+		}
+
+		value, err := p.readValue(line[offset:],
+			parserBufferSize,
+			f.options.IgnoreContinuation,
+			f.options.IgnoreInlineComment,
+			f.options.UnescapeValueDoubleQuotes,
+			f.options.UnescapeValueCommentSymbols,
+			f.options.AllowPythonMultilineValues,
+			f.options.SpaceBeforeInlineComment)
+		if err != nil {
+			return err
+		}
+		isLastValueEmpty = len(value) == 0
+
+		key, err := section.NewKey(kname, value)
+		if err != nil {
+			return err
+		}
+		key.isAutoIncrement = isAutoIncr
+		key.Comment = strings.TrimSpace(p.comment.String())
+		p.comment.Reset()
+		lastRegularKey = key
+	}
+	return nil
+}
diff --git a/vendor/github.com/go-ini/ini/section.go b/vendor/github.com/go-ini/ini/section.go
new file mode 100644
index 000000000..340a1efad
--- /dev/null
+++ b/vendor/github.com/go-ini/ini/section.go
@@ -0,0 +1,258 @@
+// Copyright 2014 Unknwon
+//
+// Licensed under the Apache License, Version 2.0 (the "License"): you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+package ini
+
+import (
+	"errors"
+	"fmt"
+	"strings"
+)
+
+// Section represents a config section.
+type Section struct {
+	f        *File
+	Comment  string
+	name     string
+	keys     map[string]*Key
+	keyList  []string
+	keysHash map[string]string
+
+	isRawSection bool
+	rawBody      string
+}
+
+func newSection(f *File, name string) *Section {
+	return &Section{
+		f:        f,
+		name:     name,
+		keys:     make(map[string]*Key),
+		keyList:  make([]string, 0, 10),
+		keysHash: make(map[string]string),
+	}
+}
+
+// Name returns name of Section.
+func (s *Section) Name() string {
+	return s.name
+}
+
+// Body returns rawBody of Section if the section was marked as unparseable.
+// It still follows the other rules of the INI format surrounding leading/trailing whitespace.
+func (s *Section) Body() string {
+	return strings.TrimSpace(s.rawBody)
+}
+
+// SetBody updates body content only if section is raw.
+func (s *Section) SetBody(body string) {
+	if !s.isRawSection {
+		return
+	}
+	s.rawBody = body
+}
+
+// NewKey creates a new key to given section.
+func (s *Section) NewKey(name, val string) (*Key, error) {
+	if len(name) == 0 {
+		return nil, errors.New("error creating new key: empty key name")
+	} else if s.f.options.Insensitive {
+		name = strings.ToLower(name)
+	}
+
+	if s.f.BlockMode {
+		s.f.lock.Lock()
+		defer s.f.lock.Unlock()
+	}
+
+	if inSlice(name, s.keyList) {
+		if s.f.options.AllowShadows {
+			if err := s.keys[name].addShadow(val); err != nil {
+				return nil, err
+			}
+		} else {
+			s.keys[name].value = val
+			s.keysHash[name] = val
+		}
+		return s.keys[name], nil
+	}
+
+	s.keyList = append(s.keyList, name)
+	s.keys[name] = newKey(s, name, val)
+	s.keysHash[name] = val
+	return s.keys[name], nil
+}
+
+// NewBooleanKey creates a new boolean type key to given section.
+func (s *Section) NewBooleanKey(name string) (*Key, error) {
+	key, err := s.NewKey(name, "true")
+	if err != nil {
+		return nil, err
+	}
+
+	key.isBooleanType = true
+	return key, nil
+}
+
+// GetKey returns key in section by given name.
+func (s *Section) GetKey(name string) (*Key, error) {
+	// FIXME: change to section level lock?
+	if s.f.BlockMode {
+		s.f.lock.RLock()
+	}
+	if s.f.options.Insensitive {
+		name = strings.ToLower(name)
+	}
+	key := s.keys[name]
+	if s.f.BlockMode {
+		s.f.lock.RUnlock()
+	}
+
+	if key == nil {
+		// Check if it is a child-section.
+		sname := s.name
+		for {
+			if i := strings.LastIndex(sname, "."); i > -1 {
+				sname = sname[:i]
+				sec, err := s.f.GetSection(sname)
+				if err != nil {
+					continue
+				}
+				return sec.GetKey(name)
+			} else {
+				break
+			}
+		}
+		return nil, fmt.Errorf("error when getting key of section '%s': key '%s' not exists", s.name, name)
+	}
+	return key, nil
+}
+
+// HasKey returns true if section contains a key with given name.
+func (s *Section) HasKey(name string) bool {
+	key, _ := s.GetKey(name)
+	return key != nil
+}
+
+// Haskey is a backwards-compatible name for HasKey.
+// TODO: delete me in v2
+func (s *Section) Haskey(name string) bool {
+	return s.HasKey(name)
+}
+
+// HasValue returns true if section contains given raw value.
+func (s *Section) HasValue(value string) bool {
+	if s.f.BlockMode {
+		s.f.lock.RLock()
+		defer s.f.lock.RUnlock()
+	}
+
+	for _, k := range s.keys {
+		if value == k.value {
+			return true
+		}
+	}
+	return false
+}
+
+// Key assumes named Key exists in section and returns a zero-value when not.
+func (s *Section) Key(name string) *Key {
+	key, err := s.GetKey(name)
+	if err != nil {
+		// It's OK here because the only possible error is empty key name,
+		// but if it's empty, this piece of code won't be executed.
+		key, _ = s.NewKey(name, "")
+		return key
+	}
+	return key
+}
+
+// Keys returns list of keys of section.
+func (s *Section) Keys() []*Key {
+	keys := make([]*Key, len(s.keyList))
+	for i := range s.keyList {
+		keys[i] = s.Key(s.keyList[i])
+	}
+	return keys
+}
+
+// ParentKeys returns list of keys of parent section.
+func (s *Section) ParentKeys() []*Key {
+	var parentKeys []*Key
+	sname := s.name
+	for {
+		if i := strings.LastIndex(sname, "."); i > -1 {
+			sname = sname[:i]
+			sec, err := s.f.GetSection(sname)
+			if err != nil {
+				continue
+			}
+			parentKeys = append(parentKeys, sec.Keys()...)
+		} else {
+			break
+		}
+
+	}
+	return parentKeys
+}
+
+// KeyStrings returns list of key names of section.
+func (s *Section) KeyStrings() []string {
+	list := make([]string, len(s.keyList))
+	copy(list, s.keyList)
+	return list
+}
+
+// KeysHash returns keys hash consisting of names and values.
+func (s *Section) KeysHash() map[string]string {
+	if s.f.BlockMode {
+		s.f.lock.RLock()
+		defer s.f.lock.RUnlock()
+	}
+
+	hash := map[string]string{}
+	for key, value := range s.keysHash {
+		hash[key] = value
+	}
+	return hash
+}
+
+// DeleteKey deletes a key from section.
+func (s *Section) DeleteKey(name string) {
+	if s.f.BlockMode {
+		s.f.lock.Lock()
+		defer s.f.lock.Unlock()
+	}
+
+	for i, k := range s.keyList {
+		if k == name {
+			s.keyList = append(s.keyList[:i], s.keyList[i+1:]...)
+			delete(s.keys, name)
+			return
+		}
+	}
+}
+
+// ChildSections returns a list of child sections of current section.
+// For example, "[parent.child1]" and "[parent.child12]" are child sections
+// of section "[parent]".
+func (s *Section) ChildSections() []*Section {
+	prefix := s.name + "."
+	children := make([]*Section, 0, 3)
+	for _, name := range s.f.sectionList {
+		if strings.HasPrefix(name, prefix) {
+			children = append(children, s.f.sections[name])
+		}
+	}
+	return children
+}
diff --git a/vendor/github.com/go-ini/ini/struct.go b/vendor/github.com/go-ini/ini/struct.go
new file mode 100644
index 000000000..9719dc698
--- /dev/null
+++ b/vendor/github.com/go-ini/ini/struct.go
@@ -0,0 +1,512 @@
+// Copyright 2014 Unknwon
+//
+// Licensed under the Apache License, Version 2.0 (the "License"): you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+package ini
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"reflect"
+	"strings"
+	"time"
+	"unicode"
+)
+
+// NameMapper represents a ini tag name mapper.
+type NameMapper func(string) string
+
+// Built-in name getters.
+var (
+	// AllCapsUnderscore converts to format ALL_CAPS_UNDERSCORE.
+	AllCapsUnderscore NameMapper = func(raw string) string {
+		newstr := make([]rune, 0, len(raw))
+		for i, chr := range raw {
+			if isUpper := 'A' <= chr && chr <= 'Z'; isUpper {
+				if i > 0 {
+					newstr = append(newstr, '_')
+				}
+			}
+			newstr = append(newstr, unicode.ToUpper(chr))
+		}
+		return string(newstr)
+	}
+	// TitleUnderscore converts to format title_underscore.
+	TitleUnderscore NameMapper = func(raw string) string {
+		newstr := make([]rune, 0, len(raw))
+		for i, chr := range raw {
+			if isUpper := 'A' <= chr && chr <= 'Z'; isUpper {
+				if i > 0 {
+					newstr = append(newstr, '_')
+				}
+				chr -= ('A' - 'a')
+			}
+			newstr = append(newstr, chr)
+		}
+		return string(newstr)
+	}
+)
+
+func (s *Section) parseFieldName(raw, actual string) string {
+	if len(actual) > 0 {
+		return actual
+	}
+	if s.f.NameMapper != nil {
+		return s.f.NameMapper(raw)
+	}
+	return raw
+}
+
+func parseDelim(actual string) string {
+	if len(actual) > 0 {
+		return actual
+	}
+	return ","
+}
+
+var reflectTime = reflect.TypeOf(time.Now()).Kind()
+
+// setSliceWithProperType sets proper values to slice based on its type.
+func setSliceWithProperType(key *Key, field reflect.Value, delim string, allowShadow, isStrict bool) error {
+	var strs []string
+	if allowShadow {
+		strs = key.StringsWithShadows(delim)
+	} else {
+		strs = key.Strings(delim)
+	}
+
+	numVals := len(strs)
+	if numVals == 0 {
+		return nil
+	}
+
+	var vals interface{}
+	var err error
+
+	sliceOf := field.Type().Elem().Kind()
+	switch sliceOf {
+	case reflect.String:
+		vals = strs
+	case reflect.Int:
+		vals, err = key.parseInts(strs, true, false)
+	case reflect.Int64:
+		vals, err = key.parseInt64s(strs, true, false)
+	case reflect.Uint:
+		vals, err = key.parseUints(strs, true, false)
+	case reflect.Uint64:
+		vals, err = key.parseUint64s(strs, true, false)
+	case reflect.Float64:
+		vals, err = key.parseFloat64s(strs, true, false)
+	case reflectTime:
+		vals, err = key.parseTimesFormat(time.RFC3339, strs, true, false)
+	default:
+		return fmt.Errorf("unsupported type '[]%s'", sliceOf)
+	}
+	if err != nil && isStrict {
+		return err
+	}
+
+	slice := reflect.MakeSlice(field.Type(), numVals, numVals)
+	for i := 0; i < numVals; i++ {
+		switch sliceOf {
+		case reflect.String:
+			slice.Index(i).Set(reflect.ValueOf(vals.([]string)[i]))
+		case reflect.Int:
+			slice.Index(i).Set(reflect.ValueOf(vals.([]int)[i]))
+		case reflect.Int64:
+			slice.Index(i).Set(reflect.ValueOf(vals.([]int64)[i]))
+		case reflect.Uint:
+			slice.Index(i).Set(reflect.ValueOf(vals.([]uint)[i]))
+		case reflect.Uint64:
+			slice.Index(i).Set(reflect.ValueOf(vals.([]uint64)[i]))
+		case reflect.Float64:
+			slice.Index(i).Set(reflect.ValueOf(vals.([]float64)[i]))
+		case reflectTime:
+			slice.Index(i).Set(reflect.ValueOf(vals.([]time.Time)[i]))
+		}
+	}
+	field.Set(slice)
+	return nil
+}
+
+func wrapStrictError(err error, isStrict bool) error {
+	if isStrict {
+		return err
+	}
+	return nil
+}
+
+// setWithProperType sets proper value to field based on its type,
+// but it does not return error for failing parsing,
+// because we want to use default value that is already assigned to strcut.
+func setWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string, allowShadow, isStrict bool) error {
+	switch t.Kind() {
+	case reflect.String:
+		if len(key.String()) == 0 {
+			return nil
+		}
+		field.SetString(key.String())
+	case reflect.Bool:
+		boolVal, err := key.Bool()
+		if err != nil {
+			return wrapStrictError(err, isStrict)
+		}
+		field.SetBool(boolVal)
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		durationVal, err := key.Duration()
+		// Skip zero value
+		if err == nil && int64(durationVal) > 0 {
+			field.Set(reflect.ValueOf(durationVal))
+			return nil
+		}
+
+		intVal, err := key.Int64()
+		if err != nil {
+			return wrapStrictError(err, isStrict)
+		}
+		field.SetInt(intVal)
+	//	byte is an alias for uint8, so supporting uint8 breaks support for byte
+	case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		durationVal, err := key.Duration()
+		// Skip zero value
+		if err == nil && int(durationVal) > 0 {
+			field.Set(reflect.ValueOf(durationVal))
+			return nil
+		}
+
+		uintVal, err := key.Uint64()
+		if err != nil {
+			return wrapStrictError(err, isStrict)
+		}
+		field.SetUint(uintVal)
+
+	case reflect.Float32, reflect.Float64:
+		floatVal, err := key.Float64()
+		if err != nil {
+			return wrapStrictError(err, isStrict)
+		}
+		field.SetFloat(floatVal)
+	case reflectTime:
+		timeVal, err := key.Time()
+		if err != nil {
+			return wrapStrictError(err, isStrict)
+		}
+		field.Set(reflect.ValueOf(timeVal))
+	case reflect.Slice:
+		return setSliceWithProperType(key, field, delim, allowShadow, isStrict)
+	default:
+		return fmt.Errorf("unsupported type '%s'", t)
+	}
+	return nil
+}
+
+func parseTagOptions(tag string) (rawName string, omitEmpty bool, allowShadow bool) {
+	opts := strings.SplitN(tag, ",", 3)
+	rawName = opts[0]
+	if len(opts) > 1 {
+		omitEmpty = opts[1] == "omitempty"
+	}
+	if len(opts) > 2 {
+		allowShadow = opts[2] == "allowshadow"
+	}
+	return rawName, omitEmpty, allowShadow
+}
+
+func (s *Section) mapTo(val reflect.Value, isStrict bool) error {
+	if val.Kind() == reflect.Ptr {
+		val = val.Elem()
+	}
+	typ := val.Type()
+
+	for i := 0; i < typ.NumField(); i++ {
+		field := val.Field(i)
+		tpField := typ.Field(i)
+
+		tag := tpField.Tag.Get("ini")
+		if tag == "-" {
+			continue
+		}
+
+		rawName, _, allowShadow := parseTagOptions(tag)
+		fieldName := s.parseFieldName(tpField.Name, rawName)
+		if len(fieldName) == 0 || !field.CanSet() {
+			continue
+		}
+
+		isAnonymous := tpField.Type.Kind() == reflect.Ptr && tpField.Anonymous
+		isStruct := tpField.Type.Kind() == reflect.Struct
+		if isAnonymous {
+			field.Set(reflect.New(tpField.Type.Elem()))
+		}
+
+		if isAnonymous || isStruct {
+			if sec, err := s.f.GetSection(fieldName); err == nil {
+				if err = sec.mapTo(field, isStrict); err != nil {
+					return fmt.Errorf("error mapping field(%s): %v", fieldName, err)
+				}
+				continue
+			}
+		}
+
+		if key, err := s.GetKey(fieldName); err == nil {
+			delim := parseDelim(tpField.Tag.Get("delim"))
+			if err = setWithProperType(tpField.Type, key, field, delim, allowShadow, isStrict); err != nil {
+				return fmt.Errorf("error mapping field(%s): %v", fieldName, err)
+			}
+		}
+	}
+	return nil
+}
+
+// MapTo maps section to given struct.
+func (s *Section) MapTo(v interface{}) error {
+	typ := reflect.TypeOf(v)
+	val := reflect.ValueOf(v)
+	if typ.Kind() == reflect.Ptr {
+		typ = typ.Elem()
+		val = val.Elem()
+	} else {
+		return errors.New("cannot map to non-pointer struct")
+	}
+
+	return s.mapTo(val, false)
+}
+
+// MapTo maps section to given struct in strict mode,
+// which returns all possible error including value parsing error.
+func (s *Section) StrictMapTo(v interface{}) error {
+	typ := reflect.TypeOf(v)
+	val := reflect.ValueOf(v)
+	if typ.Kind() == reflect.Ptr {
+		typ = typ.Elem()
+		val = val.Elem()
+	} else {
+		return errors.New("cannot map to non-pointer struct")
+	}
+
+	return s.mapTo(val, true)
+}
+
+// MapTo maps file to given struct.
+func (f *File) MapTo(v interface{}) error {
+	return f.Section("").MapTo(v)
+}
+
+// MapTo maps file to given struct in strict mode,
+// which returns all possible error including value parsing error.
+func (f *File) StrictMapTo(v interface{}) error {
+	return f.Section("").StrictMapTo(v)
+}
+
+// MapTo maps data sources to given struct with name mapper.
+func MapToWithMapper(v interface{}, mapper NameMapper, source interface{}, others ...interface{}) error {
+	cfg, err := Load(source, others...)
+	if err != nil {
+		return err
+	}
+	cfg.NameMapper = mapper
+	return cfg.MapTo(v)
+}
+
+// StrictMapToWithMapper maps data sources to given struct with name mapper in strict mode,
+// which returns all possible error including value parsing error.
+func StrictMapToWithMapper(v interface{}, mapper NameMapper, source interface{}, others ...interface{}) error {
+	cfg, err := Load(source, others...)
+	if err != nil {
+		return err
+	}
+	cfg.NameMapper = mapper
+	return cfg.StrictMapTo(v)
+}
+
+// MapTo maps data sources to given struct.
+func MapTo(v, source interface{}, others ...interface{}) error {
+	return MapToWithMapper(v, nil, source, others...)
+}
+
+// StrictMapTo maps data sources to given struct in strict mode,
+// which returns all possible error including value parsing error.
+func StrictMapTo(v, source interface{}, others ...interface{}) error {
+	return StrictMapToWithMapper(v, nil, source, others...)
+}
+
+// reflectSliceWithProperType does the opposite thing as setSliceWithProperType.
+func reflectSliceWithProperType(key *Key, field reflect.Value, delim string) error {
+	slice := field.Slice(0, field.Len())
+	if field.Len() == 0 {
+		return nil
+	}
+
+	var buf bytes.Buffer
+	sliceOf := field.Type().Elem().Kind()
+	for i := 0; i < field.Len(); i++ {
+		switch sliceOf {
+		case reflect.String:
+			buf.WriteString(slice.Index(i).String())
+		case reflect.Int, reflect.Int64:
+			buf.WriteString(fmt.Sprint(slice.Index(i).Int()))
+		case reflect.Uint, reflect.Uint64:
+			buf.WriteString(fmt.Sprint(slice.Index(i).Uint()))
+		case reflect.Float64:
+			buf.WriteString(fmt.Sprint(slice.Index(i).Float()))
+		case reflectTime:
+			buf.WriteString(slice.Index(i).Interface().(time.Time).Format(time.RFC3339))
+		default:
+			return fmt.Errorf("unsupported type '[]%s'", sliceOf)
+		}
+		buf.WriteString(delim)
+	}
+	key.SetValue(buf.String()[:buf.Len()-1])
+	return nil
+}
+
+// reflectWithProperType does the opposite thing as setWithProperType.
+func reflectWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string) error {
+	switch t.Kind() {
+	case reflect.String:
+		key.SetValue(field.String())
+	case reflect.Bool:
+		key.SetValue(fmt.Sprint(field.Bool()))
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		key.SetValue(fmt.Sprint(field.Int()))
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		key.SetValue(fmt.Sprint(field.Uint()))
+	case reflect.Float32, reflect.Float64:
+		key.SetValue(fmt.Sprint(field.Float()))
+	case reflectTime:
+		key.SetValue(fmt.Sprint(field.Interface().(time.Time).Format(time.RFC3339)))
+	case reflect.Slice:
+		return reflectSliceWithProperType(key, field, delim)
+	default:
+		return fmt.Errorf("unsupported type '%s'", t)
+	}
+	return nil
+}
+
+// CR: copied from encoding/json/encode.go with modifications of time.Time support.
+// TODO: add more test coverage.
+func isEmptyValue(v reflect.Value) bool {
+	switch v.Kind() {
+	case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
+		return v.Len() == 0
+	case reflect.Bool:
+		return !v.Bool()
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return v.Int() == 0
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return v.Uint() == 0
+	case reflect.Float32, reflect.Float64:
+		return v.Float() == 0
+	case reflect.Interface, reflect.Ptr:
+		return v.IsNil()
+	case reflectTime:
+		t, ok := v.Interface().(time.Time)
+		return ok && t.IsZero()
+	}
+	return false
+}
+
+func (s *Section) reflectFrom(val reflect.Value) error {
+	if val.Kind() == reflect.Ptr {
+		val = val.Elem()
+	}
+	typ := val.Type()
+
+	for i := 0; i < typ.NumField(); i++ {
+		field := val.Field(i)
+		tpField := typ.Field(i)
+
+		tag := tpField.Tag.Get("ini")
+		if tag == "-" {
+			continue
+		}
+
+		opts := strings.SplitN(tag, ",", 2)
+		if len(opts) == 2 && opts[1] == "omitempty" && isEmptyValue(field) {
+			continue
+		}
+
+		fieldName := s.parseFieldName(tpField.Name, opts[0])
+		if len(fieldName) == 0 || !field.CanSet() {
+			continue
+		}
+
+		if (tpField.Type.Kind() == reflect.Ptr && tpField.Anonymous) ||
+			(tpField.Type.Kind() == reflect.Struct && tpField.Type.Name() != "Time") {
+			// Note: The only error here is section doesn't exist.
+			sec, err := s.f.GetSection(fieldName)
+			if err != nil {
+				// Note: fieldName can never be empty here, ignore error.
+				sec, _ = s.f.NewSection(fieldName)
+			}
+
+			// Add comment from comment tag
+			if len(sec.Comment) == 0 {
+				sec.Comment = tpField.Tag.Get("comment")
+			}
+
+			if err = sec.reflectFrom(field); err != nil {
+				return fmt.Errorf("error reflecting field (%s): %v", fieldName, err)
+			}
+			continue
+		}
+
+		// Note: Same reason as secion.
+		key, err := s.GetKey(fieldName)
+		if err != nil {
+			key, _ = s.NewKey(fieldName, "")
+		}
+
+		// Add comment from comment tag
+		if len(key.Comment) == 0 {
+			key.Comment = tpField.Tag.Get("comment")
+		}
+
+		if err = reflectWithProperType(tpField.Type, key, field, parseDelim(tpField.Tag.Get("delim"))); err != nil {
+			return fmt.Errorf("error reflecting field (%s): %v", fieldName, err)
+		}
+
+	}
+	return nil
+}
+
+// ReflectFrom reflects secion from given struct.
+func (s *Section) ReflectFrom(v interface{}) error {
+	typ := reflect.TypeOf(v)
+	val := reflect.ValueOf(v)
+	if typ.Kind() == reflect.Ptr {
+		typ = typ.Elem()
+		val = val.Elem()
+	} else {
+		return errors.New("cannot reflect from non-pointer struct")
+	}
+
+	return s.reflectFrom(val)
+}
+
+// ReflectFrom reflects file from given struct.
+func (f *File) ReflectFrom(v interface{}) error {
+	return f.Section("").ReflectFrom(v)
+}
+
+// ReflectFrom reflects data sources from given struct with name mapper.
+func ReflectFromWithMapper(cfg *File, v interface{}, mapper NameMapper) error {
+	cfg.NameMapper = mapper
+	return cfg.ReflectFrom(v)
+}
+
+// ReflectFrom reflects data sources from given struct.
+func ReflectFrom(cfg *File, v interface{}) error {
+	return ReflectFromWithMapper(cfg, v, nil)
+}
diff --git a/vendor/github.com/hashicorp/go-cleanhttp/LICENSE b/vendor/github.com/hashicorp/go-cleanhttp/LICENSE
new file mode 100644
index 000000000..e87a115e4
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-cleanhttp/LICENSE
@@ -0,0 +1,363 @@
+Mozilla Public License, version 2.0
+
+1. Definitions
+
+1.1. "Contributor"
+
+     means each individual or legal entity that creates, contributes to the
+     creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+
+     means the combination of the Contributions of others (if any) used by a
+     Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+
+     means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+
+     means Source Code Form to which the initial Contributor has attached the
+     notice in Exhibit A, the Executable Form of such Source Code Form, and
+     Modifications of such Source Code Form, in each case including portions
+     thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+     means
+
+     a. that the initial Contributor has attached the notice described in
+        Exhibit B to the Covered Software; or
+
+     b. that the Covered Software was made available under the terms of
+        version 1.1 or earlier of the License, but not also under the terms of
+        a Secondary License.
+
+1.6. "Executable Form"
+
+     means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+
+     means a work that combines Covered Software with other material, in a
+     separate file or files, that is not Covered Software.
+
+1.8. "License"
+
+     means this document.
+
+1.9. "Licensable"
+
+     means having the right to grant, to the maximum extent possible, whether
+     at the time of the initial grant or subsequently, any and all of the
+     rights conveyed by this License.
+
+1.10. "Modifications"
+
+     means any of the following:
+
+     a. any file in Source Code Form that results from an addition to,
+        deletion from, or modification of the contents of Covered Software; or
+
+     b. any new file in Source Code Form that contains any Covered Software.
+
+1.11. "Patent Claims" of a Contributor
+
+      means any patent claim(s), including without limitation, method,
+      process, and apparatus claims, in any patent Licensable by such
+      Contributor that would be infringed, but for the grant of the License,
+      by the making, using, selling, offering for sale, having made, import,
+      or transfer of either its Contributions or its Contributor Version.
+
+1.12. "Secondary License"
+
+      means either the GNU General Public License, Version 2.0, the GNU Lesser
+      General Public License, Version 2.1, the GNU Affero General Public
+      License, Version 3.0, or any later versions of those licenses.
+
+1.13. "Source Code Form"
+
+      means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+
+      means an individual or a legal entity exercising rights under this
+      License. For legal entities, "You" includes any entity that controls, is
+      controlled by, or is under common control with You. For purposes of this
+      definition, "control" means (a) the power, direct or indirect, to cause
+      the direction or management of such entity, whether by contract or
+      otherwise, or (b) ownership of more than fifty percent (50%) of the
+      outstanding shares or beneficial ownership of such entity.
+
+
+2. License Grants and Conditions
+
+2.1. Grants
+
+     Each Contributor hereby grants You a world-wide, royalty-free,
+     non-exclusive license:
+
+     a. under intellectual property rights (other than patent or trademark)
+        Licensable by such Contributor to use, reproduce, make available,
+        modify, display, perform, distribute, and otherwise exploit its
+        Contributions, either on an unmodified basis, with Modifications, or
+        as part of a Larger Work; and
+
+     b. under Patent Claims of such Contributor to make, use, sell, offer for
+        sale, have made, import, and otherwise transfer either its
+        Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+     The licenses granted in Section 2.1 with respect to any Contribution
+     become effective for each Contribution on the date the Contributor first
+     distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+     The licenses granted in this Section 2 are the only rights granted under
+     this License. No additional rights or licenses will be implied from the
+     distribution or licensing of Covered Software under this License.
+     Notwithstanding Section 2.1(b) above, no patent license is granted by a
+     Contributor:
+
+     a. for any code that a Contributor has removed from Covered Software; or
+
+     b. for infringements caused by: (i) Your and any other third party's
+        modifications of Covered Software, or (ii) the combination of its
+        Contributions with other software (except as part of its Contributor
+        Version); or
+
+     c. under Patent Claims infringed by Covered Software in the absence of
+        its Contributions.
+
+     This License does not grant any rights in the trademarks, service marks,
+     or logos of any Contributor (except as may be necessary to comply with
+     the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+     No Contributor makes additional grants as a result of Your choice to
+     distribute the Covered Software under a subsequent version of this
+     License (see Section 10.2) or under the terms of a Secondary License (if
+     permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+     Each Contributor represents that the Contributor believes its
+     Contributions are its original creation(s) or it has sufficient rights to
+     grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+     This License is not intended to limit any rights You have under
+     applicable copyright doctrines of fair use, fair dealing, or other
+     equivalents.
+
+2.7. Conditions
+
+     Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
+     Section 2.1.
+
+
+3. Responsibilities
+
+3.1. Distribution of Source Form
+
+     All distribution of Covered Software in Source Code Form, including any
+     Modifications that You create or to which You contribute, must be under
+     the terms of this License. You must inform recipients that the Source
+     Code Form of the Covered Software is governed by the terms of this
+     License, and how they can obtain a copy of this License. You may not
+     attempt to alter or restrict the recipients' rights in the Source Code
+     Form.
+
+3.2. Distribution of Executable Form
+
+     If You distribute Covered Software in Executable Form then:
+
+     a. such Covered Software must also be made available in Source Code Form,
+        as described in Section 3.1, and You must inform recipients of the
+        Executable Form how they can obtain a copy of such Source Code Form by
+        reasonable means in a timely manner, at a charge no more than the cost
+        of distribution to the recipient; and
+
+     b. You may distribute such Executable Form under the terms of this
+        License, or sublicense it under different terms, provided that the
+        license for the Executable Form does not attempt to limit or alter the
+        recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+     You may create and distribute a Larger Work under terms of Your choice,
+     provided that You also comply with the requirements of this License for
+     the Covered Software. If the Larger Work is a combination of Covered
+     Software with a work governed by one or more Secondary Licenses, and the
+     Covered Software is not Incompatible With Secondary Licenses, this
+     License permits You to additionally distribute such Covered Software
+     under the terms of such Secondary License(s), so that the recipient of
+     the Larger Work may, at their option, further distribute the Covered
+     Software under the terms of either this License or such Secondary
+     License(s).
+
+3.4. Notices
+
+     You may not remove or alter the substance of any license notices
+     (including copyright notices, patent notices, disclaimers of warranty, or
+     limitations of liability) contained within the Source Code Form of the
+     Covered Software, except that You may alter any license notices to the
+     extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+     You may choose to offer, and to charge a fee for, warranty, support,
+     indemnity or liability obligations to one or more recipients of Covered
+     Software. However, You may do so only on Your own behalf, and not on
+     behalf of any Contributor. You must make it absolutely clear that any
+     such warranty, support, indemnity, or liability obligation is offered by
+     You alone, and You hereby agree to indemnify every Contributor for any
+     liability incurred by such Contributor as a result of warranty, support,
+     indemnity or liability terms You offer. You may include additional
+     disclaimers of warranty and limitations of liability specific to any
+     jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+
+   If it is impossible for You to comply with any of the terms of this License
+   with respect to some or all of the Covered Software due to statute,
+   judicial order, or regulation then You must: (a) comply with the terms of
+   this License to the maximum extent possible; and (b) describe the
+   limitations and the code they affect. Such description must be placed in a
+   text file included with all distributions of the Covered Software under
+   this License. Except to the extent prohibited by statute or regulation,
+   such description must be sufficiently detailed for a recipient of ordinary
+   skill to be able to understand it.
+
+5. Termination
+
+5.1. The rights granted under this License will terminate automatically if You
+     fail to comply with any of its terms. However, if You become compliant,
+     then the rights granted under this License from a particular Contributor
+     are reinstated (a) provisionally, unless and until such Contributor
+     explicitly and finally terminates Your grants, and (b) on an ongoing
+     basis, if such Contributor fails to notify You of the non-compliance by
+     some reasonable means prior to 60 days after You have come back into
+     compliance. Moreover, Your grants from a particular Contributor are
+     reinstated on an ongoing basis if such Contributor notifies You of the
+     non-compliance by some reasonable means, this is the first time You have
+     received notice of non-compliance with this License from such
+     Contributor, and You become compliant prior to 30 days after Your receipt
+     of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+     infringement claim (excluding declaratory judgment actions,
+     counter-claims, and cross-claims) alleging that a Contributor Version
+     directly or indirectly infringes any patent, then the rights granted to
+     You by any and all Contributors for the Covered Software under Section
+     2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
+     license agreements (excluding distributors and resellers) which have been
+     validly granted by You or Your distributors under this License prior to
+     termination shall survive termination.
+
+6. Disclaimer of Warranty
+
+   Covered Software is provided under this License on an "as is" basis,
+   without warranty of any kind, either expressed, implied, or statutory,
+   including, without limitation, warranties that the Covered Software is free
+   of defects, merchantable, fit for a particular purpose or non-infringing.
+   The entire risk as to the quality and performance of the Covered Software
+   is with You. Should any Covered Software prove defective in any respect,
+   You (not any Contributor) assume the cost of any necessary servicing,
+   repair, or correction. This disclaimer of warranty constitutes an essential
+   part of this License. No use of  any Covered Software is authorized under
+   this License except under this disclaimer.
+
+7. Limitation of Liability
+
+   Under no circumstances and under no legal theory, whether tort (including
+   negligence), contract, or otherwise, shall any Contributor, or anyone who
+   distributes Covered Software as permitted above, be liable to You for any
+   direct, indirect, special, incidental, or consequential damages of any
+   character including, without limitation, damages for lost profits, loss of
+   goodwill, work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses, even if such party shall have been
+   informed of the possibility of such damages. This limitation of liability
+   shall not apply to liability for death or personal injury resulting from
+   such party's negligence to the extent applicable law prohibits such
+   limitation. Some jurisdictions do not allow the exclusion or limitation of
+   incidental or consequential damages, so this exclusion and limitation may
+   not apply to You.
+
+8. Litigation
+
+   Any litigation relating to this License may be brought only in the courts
+   of a jurisdiction where the defendant maintains its principal place of
+   business and such litigation shall be governed by laws of that
+   jurisdiction, without reference to its conflict-of-law provisions. Nothing
+   in this Section shall prevent a party's ability to bring cross-claims or
+   counter-claims.
+
+9. Miscellaneous
+
+   This License represents the complete agreement concerning the subject
+   matter hereof. If any provision of this License is held to be
+   unenforceable, such provision shall be reformed only to the extent
+   necessary to make it enforceable. Any law or regulation which provides that
+   the language of a contract shall be construed against the drafter shall not
+   be used to construe this License against a Contributor.
+
+
+10. Versions of the License
+
+10.1. New Versions
+
+      Mozilla Foundation is the license steward. Except as provided in Section
+      10.3, no one other than the license steward has the right to modify or
+      publish new versions of this License. Each version will be given a
+      distinguishing version number.
+
+10.2. Effect of New Versions
+
+      You may distribute the Covered Software under the terms of the version
+      of the License under which You originally received the Covered Software,
+      or under the terms of any subsequent version published by the license
+      steward.
+
+10.3. Modified Versions
+
+      If you create software not governed by this License, and you want to
+      create a new license for such software, you may create and use a
+      modified version of this License if you rename the license and remove
+      any references to the name of the license steward (except to note that
+      such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+      Licenses If You choose to distribute Source Code Form that is
+      Incompatible With Secondary Licenses under the terms of this version of
+      the License, the notice described in Exhibit B of this License must be
+      attached.
+
+Exhibit A - Source Code Form License Notice
+
+      This Source Code Form is subject to the
+      terms of the Mozilla Public License, v.
+      2.0. If a copy of the MPL was not
+      distributed with this file, You can
+      obtain one at
+      http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular file,
+then You may include the notice in a location (such as a LICENSE file in a
+relevant directory) where a recipient would be likely to look for such a
+notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+
+      This Source Code Form is "Incompatible
+      With Secondary Licenses", as defined by
+      the Mozilla Public License, v. 2.0.
+
diff --git a/vendor/github.com/hashicorp/go-cleanhttp/cleanhttp.go b/vendor/github.com/hashicorp/go-cleanhttp/cleanhttp.go
new file mode 100644
index 000000000..8d306bf51
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-cleanhttp/cleanhttp.go
@@ -0,0 +1,57 @@
+package cleanhttp
+
+import (
+	"net"
+	"net/http"
+	"runtime"
+	"time"
+)
+
+// DefaultTransport returns a new http.Transport with similar default values to
+// http.DefaultTransport, but with idle connections and keepalives disabled.
+func DefaultTransport() *http.Transport {
+	transport := DefaultPooledTransport()
+	transport.DisableKeepAlives = true
+	transport.MaxIdleConnsPerHost = -1
+	return transport
+}
+
+// DefaultPooledTransport returns a new http.Transport with similar default
+// values to http.DefaultTransport. Do not use this for transient transports as
+// it can leak file descriptors over time. Only use this for transports that
+// will be re-used for the same host(s).
+func DefaultPooledTransport() *http.Transport {
+	transport := &http.Transport{
+		Proxy: http.ProxyFromEnvironment,
+		DialContext: (&net.Dialer{
+			Timeout:   30 * time.Second,
+			KeepAlive: 30 * time.Second,
+			DualStack: true,
+		}).DialContext,
+		MaxIdleConns:          100,
+		IdleConnTimeout:       90 * time.Second,
+		TLSHandshakeTimeout:   10 * time.Second,
+		ExpectContinueTimeout: 1 * time.Second,
+		MaxIdleConnsPerHost:   runtime.GOMAXPROCS(0) + 1,
+	}
+	return transport
+}
+
+// DefaultClient returns a new http.Client with similar default values to
+// http.Client, but with a non-shared Transport, idle connections disabled, and
+// keepalives disabled.
+func DefaultClient() *http.Client {
+	return &http.Client{
+		Transport: DefaultTransport(),
+	}
+}
+
+// DefaultPooledClient returns a new http.Client with similar default values to
+// http.Client, but with a shared Transport. Do not use this function for
+// transient clients as it can leak file descriptors over time. Only use this
+// for clients that will be re-used for the same host(s).
+func DefaultPooledClient() *http.Client {
+	return &http.Client{
+		Transport: DefaultPooledTransport(),
+	}
+}
diff --git a/vendor/github.com/hashicorp/go-cleanhttp/doc.go b/vendor/github.com/hashicorp/go-cleanhttp/doc.go
new file mode 100644
index 000000000..05841092a
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-cleanhttp/doc.go
@@ -0,0 +1,20 @@
+// Package cleanhttp offers convenience utilities for acquiring "clean"
+// http.Transport and http.Client structs.
+//
+// Values set on http.DefaultClient and http.DefaultTransport affect all
+// callers. This can have detrimental effects, esepcially in TLS contexts,
+// where client or root certificates set to talk to multiple endpoints can end
+// up displacing each other, leading to hard-to-debug issues. This package
+// provides non-shared http.Client and http.Transport structs to ensure that
+// the configuration will not be overwritten by other parts of the application
+// or dependencies.
+//
+// The DefaultClient and DefaultTransport functions disable idle connections
+// and keepalives. Without ensuring that idle connections are closed before
+// garbage collection, short-term clients/transports can leak file descriptors,
+// eventually leading to "too many open files" errors. If you will be
+// connecting to the same hosts repeatedly from the same client, you can use
+// DefaultPooledClient to receive a client that has connection pooling
+// semantics similar to http.DefaultClient.
+//
+package cleanhttp
diff --git a/vendor/github.com/hashicorp/go-cleanhttp/handlers.go b/vendor/github.com/hashicorp/go-cleanhttp/handlers.go
new file mode 100644
index 000000000..7eda3777f
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-cleanhttp/handlers.go
@@ -0,0 +1,43 @@
+package cleanhttp
+
+import (
+	"net/http"
+	"strings"
+	"unicode"
+)
+
+// HandlerInput provides input options to cleanhttp's handlers
+type HandlerInput struct {
+	ErrStatus int
+}
+
+// PrintablePathCheckHandler is a middleware that ensures the request path
+// contains only printable runes.
+func PrintablePathCheckHandler(next http.Handler, input *HandlerInput) http.Handler {
+	// Nil-check on input to make it optional
+	if input == nil {
+		input = &HandlerInput{
+			ErrStatus: http.StatusBadRequest,
+		}
+	}
+
+	// Default to http.StatusBadRequest on error
+	if input.ErrStatus == 0 {
+		input.ErrStatus = http.StatusBadRequest
+	}
+
+	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		// Check URL path for non-printable characters
+		idx := strings.IndexFunc(r.URL.Path, func(c rune) bool {
+			return !unicode.IsPrint(c)
+		})
+
+		if idx != -1 {
+			w.WriteHeader(input.ErrStatus)
+			return
+		}
+
+		next.ServeHTTP(w, r)
+		return
+	})
+}
diff --git a/vendor/github.com/hashicorp/go-getter/LICENSE b/vendor/github.com/hashicorp/go-getter/LICENSE
new file mode 100644
index 000000000..c33dcc7c9
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-getter/LICENSE
@@ -0,0 +1,354 @@
+Mozilla Public License, version 2.0
+
+1. Definitions
+
+1.1. “Contributor”
+
+     means each individual or legal entity that creates, contributes to the
+     creation of, or owns Covered Software.
+
+1.2. “Contributor Version”
+
+     means the combination of the Contributions of others (if any) used by a
+     Contributor and that particular Contributor’s Contribution.
+
+1.3. “Contribution”
+
+     means Covered Software of a particular Contributor.
+
+1.4. “Covered Software”
+
+     means Source Code Form to which the initial Contributor has attached the
+     notice in Exhibit A, the Executable Form of such Source Code Form, and
+     Modifications of such Source Code Form, in each case including portions
+     thereof.
+
+1.5. “Incompatible With Secondary Licenses”
+     means
+
+     a. that the initial Contributor has attached the notice described in
+        Exhibit B to the Covered Software; or
+
+     b. that the Covered Software was made available under the terms of version
+        1.1 or earlier of the License, but not also under the terms of a
+        Secondary License.
+
+1.6. “Executable Form”
+
+     means any form of the work other than Source Code Form.
+
+1.7. “Larger Work”
+
+     means a work that combines Covered Software with other material, in a separate
+     file or files, that is not Covered Software.
+
+1.8. “License”
+
+     means this document.
+
+1.9. “Licensable”
+
+     means having the right to grant, to the maximum extent possible, whether at the
+     time of the initial grant or subsequently, any and all of the rights conveyed by
+     this License.
+
+1.10. “Modifications”
+
+     means any of the following:
+
+     a. any file in Source Code Form that results from an addition to, deletion
+        from, or modification of the contents of Covered Software; or
+
+     b. any new file in Source Code Form that contains any Covered Software.
+
+1.11. “Patent Claims” of a Contributor
+
+      means any patent claim(s), including without limitation, method, process,
+      and apparatus claims, in any patent Licensable by such Contributor that
+      would be infringed, but for the grant of the License, by the making,
+      using, selling, offering for sale, having made, import, or transfer of
+      either its Contributions or its Contributor Version.
+
+1.12. “Secondary License”
+
+      means either the GNU General Public License, Version 2.0, the GNU Lesser
+      General Public License, Version 2.1, the GNU Affero General Public
+      License, Version 3.0, or any later versions of those licenses.
+
+1.13. “Source Code Form”
+
+      means the form of the work preferred for making modifications.
+
+1.14. “You” (or “Your”)
+
+      means an individual or a legal entity exercising rights under this
+      License. For legal entities, “You” includes any entity that controls, is
+      controlled by, or is under common control with You. For purposes of this
+      definition, “control” means (a) the power, direct or indirect, to cause
+      the direction or management of such entity, whether by contract or
+      otherwise, or (b) ownership of more than fifty percent (50%) of the
+      outstanding shares or beneficial ownership of such entity.
+
+
+2. License Grants and Conditions
+
+2.1. Grants
+
+     Each Contributor hereby grants You a world-wide, royalty-free,
+     non-exclusive license:
+
+     a. under intellectual property rights (other than patent or trademark)
+        Licensable by such Contributor to use, reproduce, make available,
+        modify, display, perform, distribute, and otherwise exploit its
+        Contributions, either on an unmodified basis, with Modifications, or as
+        part of a Larger Work; and
+
+     b. under Patent Claims of such Contributor to make, use, sell, offer for
+        sale, have made, import, and otherwise transfer either its Contributions
+        or its Contributor Version.
+
+2.2. Effective Date
+
+     The licenses granted in Section 2.1 with respect to any Contribution become
+     effective for each Contribution on the date the Contributor first distributes
+     such Contribution.
+
+2.3. Limitations on Grant Scope
+
+     The licenses granted in this Section 2 are the only rights granted under this
+     License. No additional rights or licenses will be implied from the distribution
+     or licensing of Covered Software under this License. Notwithstanding Section
+     2.1(b) above, no patent license is granted by a Contributor:
+
+     a. for any code that a Contributor has removed from Covered Software; or
+
+     b. for infringements caused by: (i) Your and any other third party’s
+        modifications of Covered Software, or (ii) the combination of its
+        Contributions with other software (except as part of its Contributor
+        Version); or
+
+     c. under Patent Claims infringed by Covered Software in the absence of its
+        Contributions.
+
+     This License does not grant any rights in the trademarks, service marks, or
+     logos of any Contributor (except as may be necessary to comply with the
+     notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+     No Contributor makes additional grants as a result of Your choice to
+     distribute the Covered Software under a subsequent version of this License
+     (see Section 10.2) or under the terms of a Secondary License (if permitted
+     under the terms of Section 3.3).
+
+2.5. Representation
+
+     Each Contributor represents that the Contributor believes its Contributions
+     are its original creation(s) or it has sufficient rights to grant the
+     rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+     This License is not intended to limit any rights You have under applicable
+     copyright doctrines of fair use, fair dealing, or other equivalents.
+
+2.7. Conditions
+
+     Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
+     Section 2.1.
+
+
+3. Responsibilities
+
+3.1. Distribution of Source Form
+
+     All distribution of Covered Software in Source Code Form, including any
+     Modifications that You create or to which You contribute, must be under the
+     terms of this License. You must inform recipients that the Source Code Form
+     of the Covered Software is governed by the terms of this License, and how
+     they can obtain a copy of this License. You may not attempt to alter or
+     restrict the recipients’ rights in the Source Code Form.
+
+3.2. Distribution of Executable Form
+
+     If You distribute Covered Software in Executable Form then:
+
+     a. such Covered Software must also be made available in Source Code Form,
+        as described in Section 3.1, and You must inform recipients of the
+        Executable Form how they can obtain a copy of such Source Code Form by
+        reasonable means in a timely manner, at a charge no more than the cost
+        of distribution to the recipient; and
+
+     b. You may distribute such Executable Form under the terms of this License,
+        or sublicense it under different terms, provided that the license for
+        the Executable Form does not attempt to limit or alter the recipients’
+        rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+     You may create and distribute a Larger Work under terms of Your choice,
+     provided that You also comply with the requirements of this License for the
+     Covered Software. If the Larger Work is a combination of Covered Software
+     with a work governed by one or more Secondary Licenses, and the Covered
+     Software is not Incompatible With Secondary Licenses, this License permits
+     You to additionally distribute such Covered Software under the terms of
+     such Secondary License(s), so that the recipient of the Larger Work may, at
+     their option, further distribute the Covered Software under the terms of
+     either this License or such Secondary License(s).
+
+3.4. Notices
+
+     You may not remove or alter the substance of any license notices (including
+     copyright notices, patent notices, disclaimers of warranty, or limitations
+     of liability) contained within the Source Code Form of the Covered
+     Software, except that You may alter any license notices to the extent
+     required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+     You may choose to offer, and to charge a fee for, warranty, support,
+     indemnity or liability obligations to one or more recipients of Covered
+     Software. However, You may do so only on Your own behalf, and not on behalf
+     of any Contributor. You must make it absolutely clear that any such
+     warranty, support, indemnity, or liability obligation is offered by You
+     alone, and You hereby agree to indemnify every Contributor for any
+     liability incurred by such Contributor as a result of warranty, support,
+     indemnity or liability terms You offer. You may include additional
+     disclaimers of warranty and limitations of liability specific to any
+     jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+
+   If it is impossible for You to comply with any of the terms of this License
+   with respect to some or all of the Covered Software due to statute, judicial
+   order, or regulation then You must: (a) comply with the terms of this License
+   to the maximum extent possible; and (b) describe the limitations and the code
+   they affect. Such description must be placed in a text file included with all
+   distributions of the Covered Software under this License. Except to the
+   extent prohibited by statute or regulation, such description must be
+   sufficiently detailed for a recipient of ordinary skill to be able to
+   understand it.
+
+5. Termination
+
+5.1. The rights granted under this License will terminate automatically if You
+     fail to comply with any of its terms. However, if You become compliant,
+     then the rights granted under this License from a particular Contributor
+     are reinstated (a) provisionally, unless and until such Contributor
+     explicitly and finally terminates Your grants, and (b) on an ongoing basis,
+     if such Contributor fails to notify You of the non-compliance by some
+     reasonable means prior to 60 days after You have come back into compliance.
+     Moreover, Your grants from a particular Contributor are reinstated on an
+     ongoing basis if such Contributor notifies You of the non-compliance by
+     some reasonable means, this is the first time You have received notice of
+     non-compliance with this License from such Contributor, and You become
+     compliant prior to 30 days after Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+     infringement claim (excluding declaratory judgment actions, counter-claims,
+     and cross-claims) alleging that a Contributor Version directly or
+     indirectly infringes any patent, then the rights granted to You by any and
+     all Contributors for the Covered Software under Section 2.1 of this License
+     shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
+     license agreements (excluding distributors and resellers) which have been
+     validly granted by You or Your distributors under this License prior to
+     termination shall survive termination.
+
+6. Disclaimer of Warranty
+
+   Covered Software is provided under this License on an “as is” basis, without
+   warranty of any kind, either expressed, implied, or statutory, including,
+   without limitation, warranties that the Covered Software is free of defects,
+   merchantable, fit for a particular purpose or non-infringing. The entire
+   risk as to the quality and performance of the Covered Software is with You.
+   Should any Covered Software prove defective in any respect, You (not any
+   Contributor) assume the cost of any necessary servicing, repair, or
+   correction. This disclaimer of warranty constitutes an essential part of this
+   License. No use of  any Covered Software is authorized under this License
+   except under this disclaimer.
+
+7. Limitation of Liability
+
+   Under no circumstances and under no legal theory, whether tort (including
+   negligence), contract, or otherwise, shall any Contributor, or anyone who
+   distributes Covered Software as permitted above, be liable to You for any
+   direct, indirect, special, incidental, or consequential damages of any
+   character including, without limitation, damages for lost profits, loss of
+   goodwill, work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses, even if such party shall have been
+   informed of the possibility of such damages. This limitation of liability
+   shall not apply to liability for death or personal injury resulting from such
+   party’s negligence to the extent applicable law prohibits such limitation.
+   Some jurisdictions do not allow the exclusion or limitation of incidental or
+   consequential damages, so this exclusion and limitation may not apply to You.
+
+8. Litigation
+
+   Any litigation relating to this License may be brought only in the courts of
+   a jurisdiction where the defendant maintains its principal place of business
+   and such litigation shall be governed by laws of that jurisdiction, without
+   reference to its conflict-of-law provisions. Nothing in this Section shall
+   prevent a party’s ability to bring cross-claims or counter-claims.
+
+9. Miscellaneous
+
+   This License represents the complete agreement concerning the subject matter
+   hereof. If any provision of this License is held to be unenforceable, such
+   provision shall be reformed only to the extent necessary to make it
+   enforceable. Any law or regulation which provides that the language of a
+   contract shall be construed against the drafter shall not be used to construe
+   this License against a Contributor.
+
+
+10. Versions of the License
+
+10.1. New Versions
+
+      Mozilla Foundation is the license steward. Except as provided in Section
+      10.3, no one other than the license steward has the right to modify or
+      publish new versions of this License. Each version will be given a
+      distinguishing version number.
+
+10.2. Effect of New Versions
+
+      You may distribute the Covered Software under the terms of the version of
+      the License under which You originally received the Covered Software, or
+      under the terms of any subsequent version published by the license
+      steward.
+
+10.3. Modified Versions
+
+      If you create software not governed by this License, and you want to
+      create a new license for such software, you may create and use a modified
+      version of this License if you rename the license and remove any
+      references to the name of the license steward (except to note that such
+      modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
+      If You choose to distribute Source Code Form that is Incompatible With
+      Secondary Licenses under the terms of this version of the License, the
+      notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+
+      This Source Code Form is subject to the
+      terms of the Mozilla Public License, v.
+      2.0. If a copy of the MPL was not
+      distributed with this file, You can
+      obtain one at
+      http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular file, then
+You may include the notice in a location (such as a LICENSE file in a relevant
+directory) where a recipient would be likely to look for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - “Incompatible With Secondary Licenses” Notice
+
+      This Source Code Form is “Incompatible
+      With Secondary Licenses”, as defined by
+      the Mozilla Public License, v. 2.0.
+
diff --git a/vendor/github.com/hashicorp/go-getter/helper/url/url.go b/vendor/github.com/hashicorp/go-getter/helper/url/url.go
new file mode 100644
index 000000000..02497c254
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-getter/helper/url/url.go
@@ -0,0 +1,14 @@
+package url
+
+import (
+	"net/url"
+)
+
+// Parse parses rawURL into a URL structure.
+// The rawURL may be relative or absolute.
+//
+// Parse is a wrapper for the Go stdlib net/url Parse function, but returns
+// Windows "safe" URLs on Windows platforms.
+func Parse(rawURL string) (*url.URL, error) {
+	return parse(rawURL)
+}
diff --git a/vendor/github.com/hashicorp/go-getter/helper/url/url_unix.go b/vendor/github.com/hashicorp/go-getter/helper/url/url_unix.go
new file mode 100644
index 000000000..ed1352a91
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-getter/helper/url/url_unix.go
@@ -0,0 +1,11 @@
+// +build !windows
+
+package url
+
+import (
+	"net/url"
+)
+
+func parse(rawURL string) (*url.URL, error) {
+	return url.Parse(rawURL)
+}
diff --git a/vendor/github.com/hashicorp/go-getter/helper/url/url_windows.go b/vendor/github.com/hashicorp/go-getter/helper/url/url_windows.go
new file mode 100644
index 000000000..4655226f6
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-getter/helper/url/url_windows.go
@@ -0,0 +1,40 @@
+package url
+
+import (
+	"fmt"
+	"net/url"
+	"path/filepath"
+	"strings"
+)
+
+func parse(rawURL string) (*url.URL, error) {
+	// Make sure we're using "/" since URLs are "/"-based.
+	rawURL = filepath.ToSlash(rawURL)
+
+	u, err := url.Parse(rawURL)
+	if err != nil {
+		return nil, err
+	}
+
+	if len(rawURL) > 1 && rawURL[1] == ':' {
+		// Assume we're dealing with a drive letter file path where the drive
+		// letter has been parsed into the URL Scheme, and the rest of the path
+		// has been parsed into the URL Path without the leading ':' character.
+		u.Path = fmt.Sprintf("%s:%s", string(rawURL[0]), u.Path)
+		u.Scheme = ""
+	}
+
+	if len(u.Host) > 1 && u.Host[1] == ':' && strings.HasPrefix(rawURL, "file://") {
+		// Assume we're dealing with a drive letter file path where the drive
+		// letter has been parsed into the URL Host.
+		u.Path = fmt.Sprintf("%s%s", u.Host, u.Path)
+		u.Host = ""
+	}
+
+	// Remove leading slash for absolute file paths.
+	if len(u.Path) > 2 && u.Path[0] == '/' && u.Path[2] == ':' {
+		u.Path = u.Path[1:]
+	}
+
+	return u, err
+}
diff --git a/vendor/github.com/hashicorp/go-getter/test-fixtures/detect-file-symlink-pwd/syml/pwd b/vendor/github.com/hashicorp/go-getter/test-fixtures/detect-file-symlink-pwd/syml/pwd
new file mode 120000
index 000000000..05b44e001
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-getter/test-fixtures/detect-file-symlink-pwd/syml/pwd
@@ -0,0 +1 @@
+../real
\ No newline at end of file
diff --git a/vendor/github.com/hashicorp/go-safetemp/LICENSE b/vendor/github.com/hashicorp/go-safetemp/LICENSE
new file mode 100644
index 000000000..be2cc4dfb
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-safetemp/LICENSE
@@ -0,0 +1,362 @@
+Mozilla Public License, version 2.0
+
+1. Definitions
+
+1.1. "Contributor"
+
+     means each individual or legal entity that creates, contributes to the
+     creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+
+     means the combination of the Contributions of others (if any) used by a
+     Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+
+     means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+
+     means Source Code Form to which the initial Contributor has attached the
+     notice in Exhibit A, the Executable Form of such Source Code Form, and
+     Modifications of such Source Code Form, in each case including portions
+     thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+     means
+
+     a. that the initial Contributor has attached the notice described in
+        Exhibit B to the Covered Software; or
+
+     b. that the Covered Software was made available under the terms of
+        version 1.1 or earlier of the License, but not also under the terms of
+        a Secondary License.
+
+1.6. "Executable Form"
+
+     means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+
+     means a work that combines Covered Software with other material, in a
+     separate file or files, that is not Covered Software.
+
+1.8. "License"
+
+     means this document.
+
+1.9. "Licensable"
+
+     means having the right to grant, to the maximum extent possible, whether
+     at the time of the initial grant or subsequently, any and all of the
+     rights conveyed by this License.
+
+1.10. "Modifications"
+
+     means any of the following:
+
+     a. any file in Source Code Form that results from an addition to,
+        deletion from, or modification of the contents of Covered Software; or
+
+     b. any new file in Source Code Form that contains any Covered Software.
+
+1.11. "Patent Claims" of a Contributor
+
+      means any patent claim(s), including without limitation, method,
+      process, and apparatus claims, in any patent Licensable by such
+      Contributor that would be infringed, but for the grant of the License,
+      by the making, using, selling, offering for sale, having made, import,
+      or transfer of either its Contributions or its Contributor Version.
+
+1.12. "Secondary License"
+
+      means either the GNU General Public License, Version 2.0, the GNU Lesser
+      General Public License, Version 2.1, the GNU Affero General Public
+      License, Version 3.0, or any later versions of those licenses.
+
+1.13. "Source Code Form"
+
+      means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+
+      means an individual or a legal entity exercising rights under this
+      License. For legal entities, "You" includes any entity that controls, is
+      controlled by, or is under common control with You. For purposes of this
+      definition, "control" means (a) the power, direct or indirect, to cause
+      the direction or management of such entity, whether by contract or
+      otherwise, or (b) ownership of more than fifty percent (50%) of the
+      outstanding shares or beneficial ownership of such entity.
+
+
+2. License Grants and Conditions
+
+2.1. Grants
+
+     Each Contributor hereby grants You a world-wide, royalty-free,
+     non-exclusive license:
+
+     a. under intellectual property rights (other than patent or trademark)
+        Licensable by such Contributor to use, reproduce, make available,
+        modify, display, perform, distribute, and otherwise exploit its
+        Contributions, either on an unmodified basis, with Modifications, or
+        as part of a Larger Work; and
+
+     b. under Patent Claims of such Contributor to make, use, sell, offer for
+        sale, have made, import, and otherwise transfer either its
+        Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+     The licenses granted in Section 2.1 with respect to any Contribution
+     become effective for each Contribution on the date the Contributor first
+     distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+     The licenses granted in this Section 2 are the only rights granted under
+     this License. No additional rights or licenses will be implied from the
+     distribution or licensing of Covered Software under this License.
+     Notwithstanding Section 2.1(b) above, no patent license is granted by a
+     Contributor:
+
+     a. for any code that a Contributor has removed from Covered Software; or
+
+     b. for infringements caused by: (i) Your and any other third party's
+        modifications of Covered Software, or (ii) the combination of its
+        Contributions with other software (except as part of its Contributor
+        Version); or
+
+     c. under Patent Claims infringed by Covered Software in the absence of
+        its Contributions.
+
+     This License does not grant any rights in the trademarks, service marks,
+     or logos of any Contributor (except as may be necessary to comply with
+     the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+     No Contributor makes additional grants as a result of Your choice to
+     distribute the Covered Software under a subsequent version of this
+     License (see Section 10.2) or under the terms of a Secondary License (if
+     permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+     Each Contributor represents that the Contributor believes its
+     Contributions are its original creation(s) or it has sufficient rights to
+     grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+     This License is not intended to limit any rights You have under
+     applicable copyright doctrines of fair use, fair dealing, or other
+     equivalents.
+
+2.7. Conditions
+
+     Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
+     Section 2.1.
+
+
+3. Responsibilities
+
+3.1. Distribution of Source Form
+
+     All distribution of Covered Software in Source Code Form, including any
+     Modifications that You create or to which You contribute, must be under
+     the terms of this License. You must inform recipients that the Source
+     Code Form of the Covered Software is governed by the terms of this
+     License, and how they can obtain a copy of this License. You may not
+     attempt to alter or restrict the recipients' rights in the Source Code
+     Form.
+
+3.2. Distribution of Executable Form
+
+     If You distribute Covered Software in Executable Form then:
+
+     a. such Covered Software must also be made available in Source Code Form,
+        as described in Section 3.1, and You must inform recipients of the
+        Executable Form how they can obtain a copy of such Source Code Form by
+        reasonable means in a timely manner, at a charge no more than the cost
+        of distribution to the recipient; and
+
+     b. You may distribute such Executable Form under the terms of this
+        License, or sublicense it under different terms, provided that the
+        license for the Executable Form does not attempt to limit or alter the
+        recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+     You may create and distribute a Larger Work under terms of Your choice,
+     provided that You also comply with the requirements of this License for
+     the Covered Software. If the Larger Work is a combination of Covered
+     Software with a work governed by one or more Secondary Licenses, and the
+     Covered Software is not Incompatible With Secondary Licenses, this
+     License permits You to additionally distribute such Covered Software
+     under the terms of such Secondary License(s), so that the recipient of
+     the Larger Work may, at their option, further distribute the Covered
+     Software under the terms of either this License or such Secondary
+     License(s).
+
+3.4. Notices
+
+     You may not remove or alter the substance of any license notices
+     (including copyright notices, patent notices, disclaimers of warranty, or
+     limitations of liability) contained within the Source Code Form of the
+     Covered Software, except that You may alter any license notices to the
+     extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+     You may choose to offer, and to charge a fee for, warranty, support,
+     indemnity or liability obligations to one or more recipients of Covered
+     Software. However, You may do so only on Your own behalf, and not on
+     behalf of any Contributor. You must make it absolutely clear that any
+     such warranty, support, indemnity, or liability obligation is offered by
+     You alone, and You hereby agree to indemnify every Contributor for any
+     liability incurred by such Contributor as a result of warranty, support,
+     indemnity or liability terms You offer. You may include additional
+     disclaimers of warranty and limitations of liability specific to any
+     jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+
+   If it is impossible for You to comply with any of the terms of this License
+   with respect to some or all of the Covered Software due to statute,
+   judicial order, or regulation then You must: (a) comply with the terms of
+   this License to the maximum extent possible; and (b) describe the
+   limitations and the code they affect. Such description must be placed in a
+   text file included with all distributions of the Covered Software under
+   this License. Except to the extent prohibited by statute or regulation,
+   such description must be sufficiently detailed for a recipient of ordinary
+   skill to be able to understand it.
+
+5. Termination
+
+5.1. The rights granted under this License will terminate automatically if You
+     fail to comply with any of its terms. However, if You become compliant,
+     then the rights granted under this License from a particular Contributor
+     are reinstated (a) provisionally, unless and until such Contributor
+     explicitly and finally terminates Your grants, and (b) on an ongoing
+     basis, if such Contributor fails to notify You of the non-compliance by
+     some reasonable means prior to 60 days after You have come back into
+     compliance. Moreover, Your grants from a particular Contributor are
+     reinstated on an ongoing basis if such Contributor notifies You of the
+     non-compliance by some reasonable means, this is the first time You have
+     received notice of non-compliance with this License from such
+     Contributor, and You become compliant prior to 30 days after Your receipt
+     of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+     infringement claim (excluding declaratory judgment actions,
+     counter-claims, and cross-claims) alleging that a Contributor Version
+     directly or indirectly infringes any patent, then the rights granted to
+     You by any and all Contributors for the Covered Software under Section
+     2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
+     license agreements (excluding distributors and resellers) which have been
+     validly granted by You or Your distributors under this License prior to
+     termination shall survive termination.
+
+6. Disclaimer of Warranty
+
+   Covered Software is provided under this License on an "as is" basis,
+   without warranty of any kind, either expressed, implied, or statutory,
+   including, without limitation, warranties that the Covered Software is free
+   of defects, merchantable, fit for a particular purpose or non-infringing.
+   The entire risk as to the quality and performance of the Covered Software
+   is with You. Should any Covered Software prove defective in any respect,
+   You (not any Contributor) assume the cost of any necessary servicing,
+   repair, or correction. This disclaimer of warranty constitutes an essential
+   part of this License. No use of  any Covered Software is authorized under
+   this License except under this disclaimer.
+
+7. Limitation of Liability
+
+   Under no circumstances and under no legal theory, whether tort (including
+   negligence), contract, or otherwise, shall any Contributor, or anyone who
+   distributes Covered Software as permitted above, be liable to You for any
+   direct, indirect, special, incidental, or consequential damages of any
+   character including, without limitation, damages for lost profits, loss of
+   goodwill, work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses, even if such party shall have been
+   informed of the possibility of such damages. This limitation of liability
+   shall not apply to liability for death or personal injury resulting from
+   such party's negligence to the extent applicable law prohibits such
+   limitation. Some jurisdictions do not allow the exclusion or limitation of
+   incidental or consequential damages, so this exclusion and limitation may
+   not apply to You.
+
+8. Litigation
+
+   Any litigation relating to this License may be brought only in the courts
+   of a jurisdiction where the defendant maintains its principal place of
+   business and such litigation shall be governed by laws of that
+   jurisdiction, without reference to its conflict-of-law provisions. Nothing
+   in this Section shall prevent a party's ability to bring cross-claims or
+   counter-claims.
+
+9. Miscellaneous
+
+   This License represents the complete agreement concerning the subject
+   matter hereof. If any provision of this License is held to be
+   unenforceable, such provision shall be reformed only to the extent
+   necessary to make it enforceable. Any law or regulation which provides that
+   the language of a contract shall be construed against the drafter shall not
+   be used to construe this License against a Contributor.
+
+
+10. Versions of the License
+
+10.1. New Versions
+
+      Mozilla Foundation is the license steward. Except as provided in Section
+      10.3, no one other than the license steward has the right to modify or
+      publish new versions of this License. Each version will be given a
+      distinguishing version number.
+
+10.2. Effect of New Versions
+
+      You may distribute the Covered Software under the terms of the version
+      of the License under which You originally received the Covered Software,
+      or under the terms of any subsequent version published by the license
+      steward.
+
+10.3. Modified Versions
+
+      If you create software not governed by this License, and you want to
+      create a new license for such software, you may create and use a
+      modified version of this License if you rename the license and remove
+      any references to the name of the license steward (except to note that
+      such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+      Licenses If You choose to distribute Source Code Form that is
+      Incompatible With Secondary Licenses under the terms of this version of
+      the License, the notice described in Exhibit B of this License must be
+      attached.
+
+Exhibit A - Source Code Form License Notice
+
+      This Source Code Form is subject to the
+      terms of the Mozilla Public License, v.
+      2.0. If a copy of the MPL was not
+      distributed with this file, You can
+      obtain one at
+      http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular file,
+then You may include the notice in a location (such as a LICENSE file in a
+relevant directory) where a recipient would be likely to look for such a
+notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+
+      This Source Code Form is "Incompatible
+      With Secondary Licenses", as defined by
+      the Mozilla Public License, v. 2.0.
diff --git a/vendor/github.com/hashicorp/go-safetemp/safetemp.go b/vendor/github.com/hashicorp/go-safetemp/safetemp.go
new file mode 100644
index 000000000..c4ae72b78
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-safetemp/safetemp.go
@@ -0,0 +1,40 @@
+package safetemp
+
+import (
+	"io"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+)
+
+// Dir creates a new temporary directory that isn't yet created. This
+// can be used with calls that expect a non-existent directory.
+//
+// The directory is created as a child of a temporary directory created
+// within the directory dir starting with prefix. The temporary directory
+// returned is always named "temp". The parent directory has the specified
+// prefix.
+//
+// The returned io.Closer should be used to clean up the returned directory.
+// This will properly remove the returned directory and any other temporary
+// files created.
+//
+// If an error is returned, the Closer does not need to be called (and will
+// be nil).
+func Dir(dir, prefix string) (string, io.Closer, error) {
+	// Create the temporary directory
+	td, err := ioutil.TempDir(dir, prefix)
+	if err != nil {
+		return "", nil, err
+	}
+
+	return filepath.Join(td, "temp"), pathCloser(td), nil
+}
+
+// pathCloser implements io.Closer to remove the given path on Close.
+type pathCloser string
+
+// Close deletes this path.
+func (p pathCloser) Close() error {
+	return os.RemoveAll(string(p))
+}
diff --git a/vendor/github.com/hashicorp/go-version/LICENSE b/vendor/github.com/hashicorp/go-version/LICENSE
new file mode 100644
index 000000000..c33dcc7c9
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-version/LICENSE
@@ -0,0 +1,354 @@
+Mozilla Public License, version 2.0
+
+1. Definitions
+
+1.1. “Contributor”
+
+     means each individual or legal entity that creates, contributes to the
+     creation of, or owns Covered Software.
+
+1.2. “Contributor Version”
+
+     means the combination of the Contributions of others (if any) used by a
+     Contributor and that particular Contributor’s Contribution.
+
+1.3. “Contribution”
+
+     means Covered Software of a particular Contributor.
+
+1.4. “Covered Software”
+
+     means Source Code Form to which the initial Contributor has attached the
+     notice in Exhibit A, the Executable Form of such Source Code Form, and
+     Modifications of such Source Code Form, in each case including portions
+     thereof.
+
+1.5. “Incompatible With Secondary Licenses”
+     means
+
+     a. that the initial Contributor has attached the notice described in
+        Exhibit B to the Covered Software; or
+
+     b. that the Covered Software was made available under the terms of version
+        1.1 or earlier of the License, but not also under the terms of a
+        Secondary License.
+
+1.6. “Executable Form”
+
+     means any form of the work other than Source Code Form.
+
+1.7. “Larger Work”
+
+     means a work that combines Covered Software with other material, in a separate
+     file or files, that is not Covered Software.
+
+1.8. “License”
+
+     means this document.
+
+1.9. “Licensable”
+
+     means having the right to grant, to the maximum extent possible, whether at the
+     time of the initial grant or subsequently, any and all of the rights conveyed by
+     this License.
+
+1.10. “Modifications”
+
+     means any of the following:
+
+     a. any file in Source Code Form that results from an addition to, deletion
+        from, or modification of the contents of Covered Software; or
+
+     b. any new file in Source Code Form that contains any Covered Software.
+
+1.11. “Patent Claims” of a Contributor
+
+      means any patent claim(s), including without limitation, method, process,
+      and apparatus claims, in any patent Licensable by such Contributor that
+      would be infringed, but for the grant of the License, by the making,
+      using, selling, offering for sale, having made, import, or transfer of
+      either its Contributions or its Contributor Version.
+
+1.12. “Secondary License”
+
+      means either the GNU General Public License, Version 2.0, the GNU Lesser
+      General Public License, Version 2.1, the GNU Affero General Public
+      License, Version 3.0, or any later versions of those licenses.
+
+1.13. “Source Code Form”
+
+      means the form of the work preferred for making modifications.
+
+1.14. “You” (or “Your”)
+
+      means an individual or a legal entity exercising rights under this
+      License. For legal entities, “You” includes any entity that controls, is
+      controlled by, or is under common control with You. For purposes of this
+      definition, “control” means (a) the power, direct or indirect, to cause
+      the direction or management of such entity, whether by contract or
+      otherwise, or (b) ownership of more than fifty percent (50%) of the
+      outstanding shares or beneficial ownership of such entity.
+
+
+2. License Grants and Conditions
+
+2.1. Grants
+
+     Each Contributor hereby grants You a world-wide, royalty-free,
+     non-exclusive license:
+
+     a. under intellectual property rights (other than patent or trademark)
+        Licensable by such Contributor to use, reproduce, make available,
+        modify, display, perform, distribute, and otherwise exploit its
+        Contributions, either on an unmodified basis, with Modifications, or as
+        part of a Larger Work; and
+
+     b. under Patent Claims of such Contributor to make, use, sell, offer for
+        sale, have made, import, and otherwise transfer either its Contributions
+        or its Contributor Version.
+
+2.2. Effective Date
+
+     The licenses granted in Section 2.1 with respect to any Contribution become
+     effective for each Contribution on the date the Contributor first distributes
+     such Contribution.
+
+2.3. Limitations on Grant Scope
+
+     The licenses granted in this Section 2 are the only rights granted under this
+     License. No additional rights or licenses will be implied from the distribution
+     or licensing of Covered Software under this License. Notwithstanding Section
+     2.1(b) above, no patent license is granted by a Contributor:
+
+     a. for any code that a Contributor has removed from Covered Software; or
+
+     b. for infringements caused by: (i) Your and any other third party’s
+        modifications of Covered Software, or (ii) the combination of its
+        Contributions with other software (except as part of its Contributor
+        Version); or
+
+     c. under Patent Claims infringed by Covered Software in the absence of its
+        Contributions.
+
+     This License does not grant any rights in the trademarks, service marks, or
+     logos of any Contributor (except as may be necessary to comply with the
+     notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+     No Contributor makes additional grants as a result of Your choice to
+     distribute the Covered Software under a subsequent version of this License
+     (see Section 10.2) or under the terms of a Secondary License (if permitted
+     under the terms of Section 3.3).
+
+2.5. Representation
+
+     Each Contributor represents that the Contributor believes its Contributions
+     are its original creation(s) or it has sufficient rights to grant the
+     rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+     This License is not intended to limit any rights You have under applicable
+     copyright doctrines of fair use, fair dealing, or other equivalents.
+
+2.7. Conditions
+
+     Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
+     Section 2.1.
+
+
+3. Responsibilities
+
+3.1. Distribution of Source Form
+
+     All distribution of Covered Software in Source Code Form, including any
+     Modifications that You create or to which You contribute, must be under the
+     terms of this License. You must inform recipients that the Source Code Form
+     of the Covered Software is governed by the terms of this License, and how
+     they can obtain a copy of this License. You may not attempt to alter or
+     restrict the recipients’ rights in the Source Code Form.
+
+3.2. Distribution of Executable Form
+
+     If You distribute Covered Software in Executable Form then:
+
+     a. such Covered Software must also be made available in Source Code Form,
+        as described in Section 3.1, and You must inform recipients of the
+        Executable Form how they can obtain a copy of such Source Code Form by
+        reasonable means in a timely manner, at a charge no more than the cost
+        of distribution to the recipient; and
+
+     b. You may distribute such Executable Form under the terms of this License,
+        or sublicense it under different terms, provided that the license for
+        the Executable Form does not attempt to limit or alter the recipients’
+        rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+     You may create and distribute a Larger Work under terms of Your choice,
+     provided that You also comply with the requirements of this License for the
+     Covered Software. If the Larger Work is a combination of Covered Software
+     with a work governed by one or more Secondary Licenses, and the Covered
+     Software is not Incompatible With Secondary Licenses, this License permits
+     You to additionally distribute such Covered Software under the terms of
+     such Secondary License(s), so that the recipient of the Larger Work may, at
+     their option, further distribute the Covered Software under the terms of
+     either this License or such Secondary License(s).
+
+3.4. Notices
+
+     You may not remove or alter the substance of any license notices (including
+     copyright notices, patent notices, disclaimers of warranty, or limitations
+     of liability) contained within the Source Code Form of the Covered
+     Software, except that You may alter any license notices to the extent
+     required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+     You may choose to offer, and to charge a fee for, warranty, support,
+     indemnity or liability obligations to one or more recipients of Covered
+     Software. However, You may do so only on Your own behalf, and not on behalf
+     of any Contributor. You must make it absolutely clear that any such
+     warranty, support, indemnity, or liability obligation is offered by You
+     alone, and You hereby agree to indemnify every Contributor for any
+     liability incurred by such Contributor as a result of warranty, support,
+     indemnity or liability terms You offer. You may include additional
+     disclaimers of warranty and limitations of liability specific to any
+     jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+
+   If it is impossible for You to comply with any of the terms of this License
+   with respect to some or all of the Covered Software due to statute, judicial
+   order, or regulation then You must: (a) comply with the terms of this License
+   to the maximum extent possible; and (b) describe the limitations and the code
+   they affect. Such description must be placed in a text file included with all
+   distributions of the Covered Software under this License. Except to the
+   extent prohibited by statute or regulation, such description must be
+   sufficiently detailed for a recipient of ordinary skill to be able to
+   understand it.
+
+5. Termination
+
+5.1. The rights granted under this License will terminate automatically if You
+     fail to comply with any of its terms. However, if You become compliant,
+     then the rights granted under this License from a particular Contributor
+     are reinstated (a) provisionally, unless and until such Contributor
+     explicitly and finally terminates Your grants, and (b) on an ongoing basis,
+     if such Contributor fails to notify You of the non-compliance by some
+     reasonable means prior to 60 days after You have come back into compliance.
+     Moreover, Your grants from a particular Contributor are reinstated on an
+     ongoing basis if such Contributor notifies You of the non-compliance by
+     some reasonable means, this is the first time You have received notice of
+     non-compliance with this License from such Contributor, and You become
+     compliant prior to 30 days after Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+     infringement claim (excluding declaratory judgment actions, counter-claims,
+     and cross-claims) alleging that a Contributor Version directly or
+     indirectly infringes any patent, then the rights granted to You by any and
+     all Contributors for the Covered Software under Section 2.1 of this License
+     shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
+     license agreements (excluding distributors and resellers) which have been
+     validly granted by You or Your distributors under this License prior to
+     termination shall survive termination.
+
+6. Disclaimer of Warranty
+
+   Covered Software is provided under this License on an “as is” basis, without
+   warranty of any kind, either expressed, implied, or statutory, including,
+   without limitation, warranties that the Covered Software is free of defects,
+   merchantable, fit for a particular purpose or non-infringing. The entire
+   risk as to the quality and performance of the Covered Software is with You.
+   Should any Covered Software prove defective in any respect, You (not any
+   Contributor) assume the cost of any necessary servicing, repair, or
+   correction. This disclaimer of warranty constitutes an essential part of this
+   License. No use of  any Covered Software is authorized under this License
+   except under this disclaimer.
+
+7. Limitation of Liability
+
+   Under no circumstances and under no legal theory, whether tort (including
+   negligence), contract, or otherwise, shall any Contributor, or anyone who
+   distributes Covered Software as permitted above, be liable to You for any
+   direct, indirect, special, incidental, or consequential damages of any
+   character including, without limitation, damages for lost profits, loss of
+   goodwill, work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses, even if such party shall have been
+   informed of the possibility of such damages. This limitation of liability
+   shall not apply to liability for death or personal injury resulting from such
+   party’s negligence to the extent applicable law prohibits such limitation.
+   Some jurisdictions do not allow the exclusion or limitation of incidental or
+   consequential damages, so this exclusion and limitation may not apply to You.
+
+8. Litigation
+
+   Any litigation relating to this License may be brought only in the courts of
+   a jurisdiction where the defendant maintains its principal place of business
+   and such litigation shall be governed by laws of that jurisdiction, without
+   reference to its conflict-of-law provisions. Nothing in this Section shall
+   prevent a party’s ability to bring cross-claims or counter-claims.
+
+9. Miscellaneous
+
+   This License represents the complete agreement concerning the subject matter
+   hereof. If any provision of this License is held to be unenforceable, such
+   provision shall be reformed only to the extent necessary to make it
+   enforceable. Any law or regulation which provides that the language of a
+   contract shall be construed against the drafter shall not be used to construe
+   this License against a Contributor.
+
+
+10. Versions of the License
+
+10.1. New Versions
+
+      Mozilla Foundation is the license steward. Except as provided in Section
+      10.3, no one other than the license steward has the right to modify or
+      publish new versions of this License. Each version will be given a
+      distinguishing version number.
+
+10.2. Effect of New Versions
+
+      You may distribute the Covered Software under the terms of the version of
+      the License under which You originally received the Covered Software, or
+      under the terms of any subsequent version published by the license
+      steward.
+
+10.3. Modified Versions
+
+      If you create software not governed by this License, and you want to
+      create a new license for such software, you may create and use a modified
+      version of this License if you rename the license and remove any
+      references to the name of the license steward (except to note that such
+      modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
+      If You choose to distribute Source Code Form that is Incompatible With
+      Secondary Licenses under the terms of this version of the License, the
+      notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+
+      This Source Code Form is subject to the
+      terms of the Mozilla Public License, v.
+      2.0. If a copy of the MPL was not
+      distributed with this file, You can
+      obtain one at
+      http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular file, then
+You may include the notice in a location (such as a LICENSE file in a relevant
+directory) where a recipient would be likely to look for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - “Incompatible With Secondary Licenses” Notice
+
+      This Source Code Form is “Incompatible
+      With Secondary Licenses”, as defined by
+      the Mozilla Public License, v. 2.0.
+
diff --git a/vendor/github.com/hashicorp/go-version/constraint.go b/vendor/github.com/hashicorp/go-version/constraint.go
new file mode 100644
index 000000000..d05575961
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-version/constraint.go
@@ -0,0 +1,204 @@
+package version
+
+import (
+	"fmt"
+	"reflect"
+	"regexp"
+	"strings"
+)
+
+// Constraint represents a single constraint for a version, such as
+// ">= 1.0".
+type Constraint struct {
+	f        constraintFunc
+	check    *Version
+	original string
+}
+
+// Constraints is a slice of constraints. We make a custom type so that
+// we can add methods to it.
+type Constraints []*Constraint
+
+type constraintFunc func(v, c *Version) bool
+
+var constraintOperators map[string]constraintFunc
+
+var constraintRegexp *regexp.Regexp
+
+func init() {
+	constraintOperators = map[string]constraintFunc{
+		"":   constraintEqual,
+		"=":  constraintEqual,
+		"!=": constraintNotEqual,
+		">":  constraintGreaterThan,
+		"<":  constraintLessThan,
+		">=": constraintGreaterThanEqual,
+		"<=": constraintLessThanEqual,
+		"~>": constraintPessimistic,
+	}
+
+	ops := make([]string, 0, len(constraintOperators))
+	for k := range constraintOperators {
+		ops = append(ops, regexp.QuoteMeta(k))
+	}
+
+	constraintRegexp = regexp.MustCompile(fmt.Sprintf(
+		`^\s*(%s)\s*(%s)\s*$`,
+		strings.Join(ops, "|"),
+		VersionRegexpRaw))
+}
+
+// NewConstraint will parse one or more constraints from the given
+// constraint string. The string must be a comma-separated list of
+// constraints.
+func NewConstraint(v string) (Constraints, error) {
+	vs := strings.Split(v, ",")
+	result := make([]*Constraint, len(vs))
+	for i, single := range vs {
+		c, err := parseSingle(single)
+		if err != nil {
+			return nil, err
+		}
+
+		result[i] = c
+	}
+
+	return Constraints(result), nil
+}
+
+// Check tests if a version satisfies all the constraints.
+func (cs Constraints) Check(v *Version) bool {
+	for _, c := range cs {
+		if !c.Check(v) {
+			return false
+		}
+	}
+
+	return true
+}
+
+// Returns the string format of the constraints
+func (cs Constraints) String() string {
+	csStr := make([]string, len(cs))
+	for i, c := range cs {
+		csStr[i] = c.String()
+	}
+
+	return strings.Join(csStr, ",")
+}
+
+// Check tests if a constraint is validated by the given version.
+func (c *Constraint) Check(v *Version) bool {
+	return c.f(v, c.check)
+}
+
+func (c *Constraint) String() string {
+	return c.original
+}
+
+func parseSingle(v string) (*Constraint, error) {
+	matches := constraintRegexp.FindStringSubmatch(v)
+	if matches == nil {
+		return nil, fmt.Errorf("Malformed constraint: %s", v)
+	}
+
+	check, err := NewVersion(matches[2])
+	if err != nil {
+		return nil, err
+	}
+
+	return &Constraint{
+		f:        constraintOperators[matches[1]],
+		check:    check,
+		original: v,
+	}, nil
+}
+
+func prereleaseCheck(v, c *Version) bool {
+	switch vPre, cPre := v.Prerelease() != "", c.Prerelease() != ""; {
+	case cPre && vPre:
+		// A constraint with a pre-release can only match a pre-release version
+		// with the same base segments.
+		return reflect.DeepEqual(c.Segments64(), v.Segments64())
+
+	case !cPre && vPre:
+		// A constraint without a pre-release can only match a version without a
+		// pre-release.
+		return false
+
+	case cPre && !vPre:
+		// OK, except with the pessimistic operator
+	case !cPre && !vPre:
+		// OK
+	}
+	return true
+}
+
+//-------------------------------------------------------------------
+// Constraint functions
+//-------------------------------------------------------------------
+
+func constraintEqual(v, c *Version) bool {
+	return v.Equal(c)
+}
+
+func constraintNotEqual(v, c *Version) bool {
+	return !v.Equal(c)
+}
+
+func constraintGreaterThan(v, c *Version) bool {
+	return prereleaseCheck(v, c) && v.Compare(c) == 1
+}
+
+func constraintLessThan(v, c *Version) bool {
+	return prereleaseCheck(v, c) && v.Compare(c) == -1
+}
+
+func constraintGreaterThanEqual(v, c *Version) bool {
+	return prereleaseCheck(v, c) && v.Compare(c) >= 0
+}
+
+func constraintLessThanEqual(v, c *Version) bool {
+	return prereleaseCheck(v, c) && v.Compare(c) <= 0
+}
+
+func constraintPessimistic(v, c *Version) bool {
+	// Using a pessimistic constraint with a pre-release, restricts versions to pre-releases
+	if !prereleaseCheck(v, c) || (c.Prerelease() != "" && v.Prerelease() == "") {
+		return false
+	}
+
+	// If the version being checked is naturally less than the constraint, then there
+	// is no way for the version to be valid against the constraint
+	if v.LessThan(c) {
+		return false
+	}
+	// We'll use this more than once, so grab the length now so it's a little cleaner
+	// to write the later checks
+	cs := len(c.segments)
+
+	// If the version being checked has less specificity than the constraint, then there
+	// is no way for the version to be valid against the constraint
+	if cs > len(v.segments) {
+		return false
+	}
+
+	// Check the segments in the constraint against those in the version. If the version
+	// being checked, at any point, does not have the same values in each index of the
+	// constraints segments, then it cannot be valid against the constraint.
+	for i := 0; i < c.si-1; i++ {
+		if v.segments[i] != c.segments[i] {
+			return false
+		}
+	}
+
+	// Check the last part of the segment in the constraint. If the version segment at
+	// this index is less than the constraints segment at this index, then it cannot
+	// be valid against the constraint
+	if c.segments[cs-1] > v.segments[cs-1] {
+		return false
+	}
+
+	// If nothing has rejected the version by now, it's valid
+	return true
+}
diff --git a/vendor/github.com/hashicorp/go-version/version.go b/vendor/github.com/hashicorp/go-version/version.go
new file mode 100644
index 000000000..4d1e6e221
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-version/version.go
@@ -0,0 +1,347 @@
+package version
+
+import (
+	"bytes"
+	"fmt"
+	"reflect"
+	"regexp"
+	"strconv"
+	"strings"
+)
+
+// The compiled regular expression used to test the validity of a version.
+var versionRegexp *regexp.Regexp
+
+// The raw regular expression string used for testing the validity
+// of a version.
+const VersionRegexpRaw string = `v?([0-9]+(\.[0-9]+)*?)` +
+	`(-([0-9]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)|(-?([A-Za-z\-~]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)))?` +
+	`(\+([0-9A-Za-z\-~]+(\.[0-9A-Za-z\-~]+)*))?` +
+	`?`
+
+// Version represents a single version.
+type Version struct {
+	metadata string
+	pre      string
+	segments []int64
+	si       int
+	original string
+}
+
+func init() {
+	versionRegexp = regexp.MustCompile("^" + VersionRegexpRaw + "$")
+}
+
+// NewVersion parses the given version and returns a new
+// Version.
+func NewVersion(v string) (*Version, error) {
+	matches := versionRegexp.FindStringSubmatch(v)
+	if matches == nil {
+		return nil, fmt.Errorf("Malformed version: %s", v)
+	}
+	segmentsStr := strings.Split(matches[1], ".")
+	segments := make([]int64, len(segmentsStr))
+	si := 0
+	for i, str := range segmentsStr {
+		val, err := strconv.ParseInt(str, 10, 64)
+		if err != nil {
+			return nil, fmt.Errorf(
+				"Error parsing version: %s", err)
+		}
+
+		segments[i] = int64(val)
+		si++
+	}
+
+	// Even though we could support more than three segments, if we
+	// got less than three, pad it with 0s. This is to cover the basic
+	// default usecase of semver, which is MAJOR.MINOR.PATCH at the minimum
+	for i := len(segments); i < 3; i++ {
+		segments = append(segments, 0)
+	}
+
+	pre := matches[7]
+	if pre == "" {
+		pre = matches[4]
+	}
+
+	return &Version{
+		metadata: matches[10],
+		pre:      pre,
+		segments: segments,
+		si:       si,
+		original: v,
+	}, nil
+}
+
+// Must is a helper that wraps a call to a function returning (*Version, error)
+// and panics if error is non-nil.
+func Must(v *Version, err error) *Version {
+	if err != nil {
+		panic(err)
+	}
+
+	return v
+}
+
+// Compare compares this version to another version. This
+// returns -1, 0, or 1 if this version is smaller, equal,
+// or larger than the other version, respectively.
+//
+// If you want boolean results, use the LessThan, Equal,
+// or GreaterThan methods.
+func (v *Version) Compare(other *Version) int {
+	// A quick, efficient equality check
+	if v.String() == other.String() {
+		return 0
+	}
+
+	segmentsSelf := v.Segments64()
+	segmentsOther := other.Segments64()
+
+	// If the segments are the same, we must compare on prerelease info
+	if reflect.DeepEqual(segmentsSelf, segmentsOther) {
+		preSelf := v.Prerelease()
+		preOther := other.Prerelease()
+		if preSelf == "" && preOther == "" {
+			return 0
+		}
+		if preSelf == "" {
+			return 1
+		}
+		if preOther == "" {
+			return -1
+		}
+
+		return comparePrereleases(preSelf, preOther)
+	}
+
+	// Get the highest specificity (hS), or if they're equal, just use segmentSelf length
+	lenSelf := len(segmentsSelf)
+	lenOther := len(segmentsOther)
+	hS := lenSelf
+	if lenSelf < lenOther {
+		hS = lenOther
+	}
+	// Compare the segments
+	// Because a constraint could have more/less specificity than the version it's
+	// checking, we need to account for a lopsided or jagged comparison
+	for i := 0; i < hS; i++ {
+		if i > lenSelf-1 {
+			// This means Self had the lower specificity
+			// Check to see if the remaining segments in Other are all zeros
+			if !allZero(segmentsOther[i:]) {
+				// if not, it means that Other has to be greater than Self
+				return -1
+			}
+			break
+		} else if i > lenOther-1 {
+			// this means Other had the lower specificity
+			// Check to see if the remaining segments in Self are all zeros -
+			if !allZero(segmentsSelf[i:]) {
+				//if not, it means that Self has to be greater than Other
+				return 1
+			}
+			break
+		}
+		lhs := segmentsSelf[i]
+		rhs := segmentsOther[i]
+		if lhs == rhs {
+			continue
+		} else if lhs < rhs {
+			return -1
+		}
+		// Otherwis, rhs was > lhs, they're not equal
+		return 1
+	}
+
+	// if we got this far, they're equal
+	return 0
+}
+
+func allZero(segs []int64) bool {
+	for _, s := range segs {
+		if s != 0 {
+			return false
+		}
+	}
+	return true
+}
+
+func comparePart(preSelf string, preOther string) int {
+	if preSelf == preOther {
+		return 0
+	}
+
+	var selfInt int64
+	selfNumeric := true
+	selfInt, err := strconv.ParseInt(preSelf, 10, 64)
+	if err != nil {
+		selfNumeric = false
+	}
+
+	var otherInt int64
+	otherNumeric := true
+	otherInt, err = strconv.ParseInt(preOther, 10, 64)
+	if err != nil {
+		otherNumeric = false
+	}
+
+	// if a part is empty, we use the other to decide
+	if preSelf == "" {
+		if otherNumeric {
+			return -1
+		}
+		return 1
+	}
+
+	if preOther == "" {
+		if selfNumeric {
+			return 1
+		}
+		return -1
+	}
+
+	if selfNumeric && !otherNumeric {
+		return -1
+	} else if !selfNumeric && otherNumeric {
+		return 1
+	} else if !selfNumeric && !otherNumeric && preSelf > preOther {
+		return 1
+	} else if selfInt > otherInt {
+		return 1
+	}
+
+	return -1
+}
+
+func comparePrereleases(v string, other string) int {
+	// the same pre release!
+	if v == other {
+		return 0
+	}
+
+	// split both pre releases for analyse their parts
+	selfPreReleaseMeta := strings.Split(v, ".")
+	otherPreReleaseMeta := strings.Split(other, ".")
+
+	selfPreReleaseLen := len(selfPreReleaseMeta)
+	otherPreReleaseLen := len(otherPreReleaseMeta)
+
+	biggestLen := otherPreReleaseLen
+	if selfPreReleaseLen > otherPreReleaseLen {
+		biggestLen = selfPreReleaseLen
+	}
+
+	// loop for parts to find the first difference
+	for i := 0; i < biggestLen; i = i + 1 {
+		partSelfPre := ""
+		if i < selfPreReleaseLen {
+			partSelfPre = selfPreReleaseMeta[i]
+		}
+
+		partOtherPre := ""
+		if i < otherPreReleaseLen {
+			partOtherPre = otherPreReleaseMeta[i]
+		}
+
+		compare := comparePart(partSelfPre, partOtherPre)
+		// if parts are equals, continue the loop
+		if compare != 0 {
+			return compare
+		}
+	}
+
+	return 0
+}
+
+// Equal tests if two versions are equal.
+func (v *Version) Equal(o *Version) bool {
+	return v.Compare(o) == 0
+}
+
+// GreaterThan tests if this version is greater than another version.
+func (v *Version) GreaterThan(o *Version) bool {
+	return v.Compare(o) > 0
+}
+
+// LessThan tests if this version is less than another version.
+func (v *Version) LessThan(o *Version) bool {
+	return v.Compare(o) < 0
+}
+
+// Metadata returns any metadata that was part of the version
+// string.
+//
+// Metadata is anything that comes after the "+" in the version.
+// For example, with "1.2.3+beta", the metadata is "beta".
+func (v *Version) Metadata() string {
+	return v.metadata
+}
+
+// Prerelease returns any prerelease data that is part of the version,
+// or blank if there is no prerelease data.
+//
+// Prerelease information is anything that comes after the "-" in the
+// version (but before any metadata). For example, with "1.2.3-beta",
+// the prerelease information is "beta".
+func (v *Version) Prerelease() string {
+	return v.pre
+}
+
+// Segments returns the numeric segments of the version as a slice of ints.
+//
+// This excludes any metadata or pre-release information. For example,
+// for a version "1.2.3-beta", segments will return a slice of
+// 1, 2, 3.
+func (v *Version) Segments() []int {
+	segmentSlice := make([]int, len(v.segments))
+	for i, v := range v.segments {
+		segmentSlice[i] = int(v)
+	}
+	return segmentSlice
+}
+
+// Segments64 returns the numeric segments of the version as a slice of int64s.
+//
+// This excludes any metadata or pre-release information. For example,
+// for a version "1.2.3-beta", segments will return a slice of
+// 1, 2, 3.
+func (v *Version) Segments64() []int64 {
+	result := make([]int64, len(v.segments))
+	copy(result, v.segments)
+	return result
+}
+
+// String returns the full version string included pre-release
+// and metadata information.
+//
+// This value is rebuilt according to the parsed segments and other
+// information. Therefore, ambiguities in the version string such as
+// prefixed zeroes (1.04.0 => 1.4.0), `v` prefix (v1.0.0 => 1.0.0), and
+// missing parts (1.0 => 1.0.0) will be made into a canonicalized form
+// as shown in the parenthesized examples.
+func (v *Version) String() string {
+	var buf bytes.Buffer
+	fmtParts := make([]string, len(v.segments))
+	for i, s := range v.segments {
+		// We can ignore err here since we've pre-parsed the values in segments
+		str := strconv.FormatInt(s, 10)
+		fmtParts[i] = str
+	}
+	fmt.Fprintf(&buf, strings.Join(fmtParts, "."))
+	if v.pre != "" {
+		fmt.Fprintf(&buf, "-%s", v.pre)
+	}
+	if v.metadata != "" {
+		fmt.Fprintf(&buf, "+%s", v.metadata)
+	}
+
+	return buf.String()
+}
+
+// Original returns the original parsed version as-is, including any
+// potential whitespace, `v` prefix, etc.
+func (v *Version) Original() string {
+	return v.original
+}
diff --git a/vendor/github.com/hashicorp/go-version/version_collection.go b/vendor/github.com/hashicorp/go-version/version_collection.go
new file mode 100644
index 000000000..cc888d43e
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-version/version_collection.go
@@ -0,0 +1,17 @@
+package version
+
+// Collection is a type that implements the sort.Interface interface
+// so that versions can be sorted.
+type Collection []*Version
+
+func (v Collection) Len() int {
+	return len(v)
+}
+
+func (v Collection) Less(i, j int) bool {
+	return v[i].LessThan(v[j])
+}
+
+func (v Collection) Swap(i, j int) {
+	v[i], v[j] = v[j], v[i]
+}
diff --git a/vendor/github.com/heroku/rollrus/LICENSE b/vendor/github.com/heroku/rollrus/LICENSE
new file mode 100644
index 000000000..8d4a5174d
--- /dev/null
+++ b/vendor/github.com/heroku/rollrus/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright © Heroku 2014 - 2015
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/heroku/rollrus/rollrus.go b/vendor/github.com/heroku/rollrus/rollrus.go
new file mode 100644
index 000000000..50dd225da
--- /dev/null
+++ b/vendor/github.com/heroku/rollrus/rollrus.go
@@ -0,0 +1,287 @@
+// Package rollrus combines github.com/stvp/roll with github.com/sirupsen/logrus
+// via logrus.Hook mechanism, so that whenever logrus' logger.Error/f(),
+// logger.Fatal/f() or logger.Panic/f() are used the messages are
+// intercepted and sent to rollbar.
+//
+// Using SetupLogging should suffice for basic use cases that use the logrus
+// singleton logger.
+//
+// More custom uses are supported by creating a new Hook with NewHook and
+// registering that hook with the logrus Logger of choice.
+//
+// The levels can be customized with the WithLevels OptionFunc.
+//
+// Specific errors can be ignored with the WithIgnoredErrors OptionFunc. This is
+// useful for ignoring errors such as context.Canceled.
+//
+// See the Examples in the tests for more usage.
+package rollrus
+
+import (
+	"fmt"
+	"os"
+	"time"
+
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
+	"github.com/stvp/roll"
+)
+
+var defaultTriggerLevels = []logrus.Level{
+	logrus.ErrorLevel,
+	logrus.FatalLevel,
+	logrus.PanicLevel,
+}
+
+// Hook is a wrapper for the rollbar Client and is usable as a logrus.Hook.
+type Hook struct {
+	roll.Client
+	triggers        []logrus.Level
+	ignoredErrors   map[error]struct{}
+	ignoreErrorFunc func(error) bool
+	ignoreFunc      func(error, map[string]string) bool
+
+	// only used for tests to verify whether or not a report happened.
+	reported bool
+}
+
+// OptionFunc that can be passed to NewHook.
+type OptionFunc func(*Hook)
+
+// wellKnownErrorFields are the names of the fields to be checked for values of
+// type `error`, in priority order.
+var wellKnownErrorFields = []string{
+	logrus.ErrorKey, "err",
+}
+
+// WithLevels is an OptionFunc that customizes the log.Levels the hook will
+// report on.
+func WithLevels(levels ...logrus.Level) OptionFunc {
+	return func(h *Hook) {
+		h.triggers = levels
+	}
+}
+
+// WithMinLevel is an OptionFunc that customizes the log.Levels the hook will
+// report on by selecting all levels more severe than the one provided.
+func WithMinLevel(level logrus.Level) OptionFunc {
+	var levels []logrus.Level
+	for _, l := range logrus.AllLevels {
+		if l <= level {
+			levels = append(levels, l)
+		}
+	}
+
+	return func(h *Hook) {
+		h.triggers = levels
+	}
+}
+
+// WithIgnoredErrors is an OptionFunc that whitelists certain errors to prevent
+// them from firing.
+func WithIgnoredErrors(errors ...error) OptionFunc {
+	return func(h *Hook) {
+		for _, e := range errors {
+			h.ignoredErrors[e] = struct{}{}
+		}
+	}
+}
+
+// WithIgnoreErrorFunc is an OptionFunc that receives the error that is about
+// to be logged and returns true/false if it wants to fire a rollbar alert for.
+func WithIgnoreErrorFunc(fn func(error) bool) OptionFunc {
+	return func(h *Hook) {
+		h.ignoreErrorFunc = fn
+	}
+}
+
+// WithIgnoreFunc is an OptionFunc that receives the error and custom fields that are about
+// to be logged and returns true/false if it wants to fire a rollbar alert for.
+func WithIgnoreFunc(fn func(err error, fields map[string]string) bool) OptionFunc {
+	return func(h *Hook) {
+		h.ignoreFunc = fn
+	}
+}
+
+// NewHook creates a hook that is intended for use with your own logrus.Logger
+// instance. Uses the defualt report levels defined in wellKnownErrorFields.
+func NewHook(token string, env string, opts ...OptionFunc) *Hook {
+	h := NewHookForLevels(token, env, defaultTriggerLevels)
+
+	for _, o := range opts {
+		o(h)
+	}
+
+	return h
+}
+
+// NewHookForLevels provided by the caller. Otherwise works like NewHook.
+func NewHookForLevels(token string, env string, levels []logrus.Level) *Hook {
+	return &Hook{
+		Client:          roll.New(token, env),
+		triggers:        levels,
+		ignoredErrors:   make(map[error]struct{}),
+		ignoreErrorFunc: func(error) bool { return false },
+		ignoreFunc:      func(error, map[string]string) bool { return false },
+	}
+}
+
+// SetupLogging for use on Heroku. If token is not an empty string a rollbar
+// hook is added with the environment set to env. The log formatter is set to a
+// TextFormatter with timestamps disabled.
+func SetupLogging(token, env string) {
+	setupLogging(token, env, defaultTriggerLevels)
+}
+
+// SetupLoggingForLevels works like SetupLogging, but allows you to
+// set the levels on which to trigger this hook.
+func SetupLoggingForLevels(token, env string, levels []logrus.Level) {
+	setupLogging(token, env, levels)
+}
+
+func setupLogging(token, env string, levels []logrus.Level) {
+	logrus.SetFormatter(&logrus.TextFormatter{DisableTimestamp: true})
+
+	if token != "" {
+		logrus.AddHook(NewHookForLevels(token, env, levels))
+	}
+}
+
+// ReportPanic attempts to report the panic to rollbar using the provided
+// client and then re-panic. If it can't report the panic it will print an
+// error to stderr.
+func (r *Hook) ReportPanic() {
+	if p := recover(); p != nil {
+		if _, err := r.Client.Critical(fmt.Errorf("panic: %q", p), nil); err != nil {
+			fmt.Fprintf(os.Stderr, "reporting_panic=false err=%q\n", err)
+		}
+		panic(p)
+	}
+}
+
+// ReportPanic attempts to report the panic to rollbar if the token is set
+func ReportPanic(token, env string) {
+	if token != "" {
+		h := &Hook{Client: roll.New(token, env)}
+		h.ReportPanic()
+	}
+}
+
+// Levels returns the logrus log.Levels that this hook handles
+func (r *Hook) Levels() []logrus.Level {
+	if r.triggers == nil {
+		return defaultTriggerLevels
+	}
+	return r.triggers
+}
+
+// Fire the hook. This is called by Logrus for entries that match the levels
+// returned by Levels().
+func (r *Hook) Fire(entry *logrus.Entry) error {
+	trace, cause := extractError(entry)
+	if _, ok := r.ignoredErrors[cause]; ok {
+		return nil
+	}
+
+	if r.ignoreErrorFunc(cause) {
+		return nil
+	}
+
+	m := convertFields(entry.Data)
+	if _, exists := m["time"]; !exists {
+		m["time"] = entry.Time.Format(time.RFC3339)
+	}
+
+	if r.ignoreFunc(cause, m) {
+		return nil
+	}
+
+	return r.report(entry, cause, m, trace)
+}
+
+func (r *Hook) report(entry *logrus.Entry, cause error, m map[string]string, trace []uintptr) (err error) {
+	hasTrace := len(trace) > 0
+	level := entry.Level
+
+	r.reported = true
+
+	switch {
+	case hasTrace && level == logrus.FatalLevel:
+		_, err = r.Client.CriticalStack(cause, trace, m)
+	case hasTrace && level == logrus.PanicLevel:
+		_, err = r.Client.CriticalStack(cause, trace, m)
+	case hasTrace && level == logrus.ErrorLevel:
+		_, err = r.Client.ErrorStack(cause, trace, m)
+	case hasTrace && level == logrus.WarnLevel:
+		_, err = r.Client.WarningStack(cause, trace, m)
+	case level == logrus.FatalLevel || level == logrus.PanicLevel:
+		_, err = r.Client.Critical(cause, m)
+	case level == logrus.ErrorLevel:
+		_, err = r.Client.Error(cause, m)
+	case level == logrus.WarnLevel:
+		_, err = r.Client.Warning(cause, m)
+	case level == logrus.InfoLevel:
+		_, err = r.Client.Info(entry.Message, m)
+	case level == logrus.DebugLevel:
+		_, err = r.Client.Debug(entry.Message, m)
+	}
+	return err
+}
+
+// convertFields converts from log.Fields to map[string]string so that we can
+// report extra fields to Rollbar
+func convertFields(fields logrus.Fields) map[string]string {
+	m := make(map[string]string)
+	for k, v := range fields {
+		switch t := v.(type) {
+		case time.Time:
+			m[k] = t.Format(time.RFC3339)
+		default:
+			if s, ok := v.(fmt.Stringer); ok {
+				m[k] = s.String()
+			} else {
+				m[k] = fmt.Sprintf("%+v", t)
+			}
+		}
+	}
+
+	return m
+}
+
+// extractError attempts to extract an error from a well known field, err or error
+func extractError(entry *logrus.Entry) ([]uintptr, error) {
+	var trace []uintptr
+	fields := entry.Data
+
+	type stackTracer interface {
+		StackTrace() errors.StackTrace
+	}
+
+	for _, f := range wellKnownErrorFields {
+		e, ok := fields[f]
+		if !ok {
+			continue
+		}
+		err, ok := e.(error)
+		if !ok {
+			continue
+		}
+
+		cause := errors.Cause(err)
+		tracer, ok := err.(stackTracer)
+		if ok {
+			return copyStackTrace(tracer.StackTrace()), cause
+		}
+		return trace, cause
+	}
+
+	// when no error found, default to the logged message.
+	return trace, fmt.Errorf(entry.Message)
+}
+
+func copyStackTrace(trace errors.StackTrace) (out []uintptr) {
+	for _, frame := range trace {
+		out = append(out, uintptr(frame))
+	}
+	return
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/LICENSE b/vendor/github.com/jesseduffield/go-getter/LICENSE
new file mode 100644
index 000000000..c33dcc7c9
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/LICENSE
@@ -0,0 +1,354 @@
+Mozilla Public License, version 2.0
+
+1. Definitions
+
+1.1. “Contributor”
+
+     means each individual or legal entity that creates, contributes to the
+     creation of, or owns Covered Software.
+
+1.2. “Contributor Version”
+
+     means the combination of the Contributions of others (if any) used by a
+     Contributor and that particular Contributor’s Contribution.
+
+1.3. “Contribution”
+
+     means Covered Software of a particular Contributor.
+
+1.4. “Covered Software”
+
+     means Source Code Form to which the initial Contributor has attached the
+     notice in Exhibit A, the Executable Form of such Source Code Form, and
+     Modifications of such Source Code Form, in each case including portions
+     thereof.
+
+1.5. “Incompatible With Secondary Licenses”
+     means
+
+     a. that the initial Contributor has attached the notice described in
+        Exhibit B to the Covered Software; or
+
+     b. that the Covered Software was made available under the terms of version
+        1.1 or earlier of the License, but not also under the terms of a
+        Secondary License.
+
+1.6. “Executable Form”
+
+     means any form of the work other than Source Code Form.
+
+1.7. “Larger Work”
+
+     means a work that combines Covered Software with other material, in a separate
+     file or files, that is not Covered Software.
+
+1.8. “License”
+
+     means this document.
+
+1.9. “Licensable”
+
+     means having the right to grant, to the maximum extent possible, whether at the
+     time of the initial grant or subsequently, any and all of the rights conveyed by
+     this License.
+
+1.10. “Modifications”
+
+     means any of the following:
+
+     a. any file in Source Code Form that results from an addition to, deletion
+        from, or modification of the contents of Covered Software; or
+
+     b. any new file in Source Code Form that contains any Covered Software.
+
+1.11. “Patent Claims” of a Contributor
+
+      means any patent claim(s), including without limitation, method, process,
+      and apparatus claims, in any patent Licensable by such Contributor that
+      would be infringed, but for the grant of the License, by the making,
+      using, selling, offering for sale, having made, import, or transfer of
+      either its Contributions or its Contributor Version.
+
+1.12. “Secondary License”
+
+      means either the GNU General Public License, Version 2.0, the GNU Lesser
+      General Public License, Version 2.1, the GNU Affero General Public
+      License, Version 3.0, or any later versions of those licenses.
+
+1.13. “Source Code Form”
+
+      means the form of the work preferred for making modifications.
+
+1.14. “You” (or “Your”)
+
+      means an individual or a legal entity exercising rights under this
+      License. For legal entities, “You” includes any entity that controls, is
+      controlled by, or is under common control with You. For purposes of this
+      definition, “control” means (a) the power, direct or indirect, to cause
+      the direction or management of such entity, whether by contract or
+      otherwise, or (b) ownership of more than fifty percent (50%) of the
+      outstanding shares or beneficial ownership of such entity.
+
+
+2. License Grants and Conditions
+
+2.1. Grants
+
+     Each Contributor hereby grants You a world-wide, royalty-free,
+     non-exclusive license:
+
+     a. under intellectual property rights (other than patent or trademark)
+        Licensable by such Contributor to use, reproduce, make available,
+        modify, display, perform, distribute, and otherwise exploit its
+        Contributions, either on an unmodified basis, with Modifications, or as
+        part of a Larger Work; and
+
+     b. under Patent Claims of such Contributor to make, use, sell, offer for
+        sale, have made, import, and otherwise transfer either its Contributions
+        or its Contributor Version.
+
+2.2. Effective Date
+
+     The licenses granted in Section 2.1 with respect to any Contribution become
+     effective for each Contribution on the date the Contributor first distributes
+     such Contribution.
+
+2.3. Limitations on Grant Scope
+
+     The licenses granted in this Section 2 are the only rights granted under this
+     License. No additional rights or licenses will be implied from the distribution
+     or licensing of Covered Software under this License. Notwithstanding Section
+     2.1(b) above, no patent license is granted by a Contributor:
+
+     a. for any code that a Contributor has removed from Covered Software; or
+
+     b. for infringements caused by: (i) Your and any other third party’s
+        modifications of Covered Software, or (ii) the combination of its
+        Contributions with other software (except as part of its Contributor
+        Version); or
+
+     c. under Patent Claims infringed by Covered Software in the absence of its
+        Contributions.
+
+     This License does not grant any rights in the trademarks, service marks, or
+     logos of any Contributor (except as may be necessary to comply with the
+     notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+     No Contributor makes additional grants as a result of Your choice to
+     distribute the Covered Software under a subsequent version of this License
+     (see Section 10.2) or under the terms of a Secondary License (if permitted
+     under the terms of Section 3.3).
+
+2.5. Representation
+
+     Each Contributor represents that the Contributor believes its Contributions
+     are its original creation(s) or it has sufficient rights to grant the
+     rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+     This License is not intended to limit any rights You have under applicable
+     copyright doctrines of fair use, fair dealing, or other equivalents.
+
+2.7. Conditions
+
+     Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
+     Section 2.1.
+
+
+3. Responsibilities
+
+3.1. Distribution of Source Form
+
+     All distribution of Covered Software in Source Code Form, including any
+     Modifications that You create or to which You contribute, must be under the
+     terms of this License. You must inform recipients that the Source Code Form
+     of the Covered Software is governed by the terms of this License, and how
+     they can obtain a copy of this License. You may not attempt to alter or
+     restrict the recipients’ rights in the Source Code Form.
+
+3.2. Distribution of Executable Form
+
+     If You distribute Covered Software in Executable Form then:
+
+     a. such Covered Software must also be made available in Source Code Form,
+        as described in Section 3.1, and You must inform recipients of the
+        Executable Form how they can obtain a copy of such Source Code Form by
+        reasonable means in a timely manner, at a charge no more than the cost
+        of distribution to the recipient; and
+
+     b. You may distribute such Executable Form under the terms of this License,
+        or sublicense it under different terms, provided that the license for
+        the Executable Form does not attempt to limit or alter the recipients’
+        rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+     You may create and distribute a Larger Work under terms of Your choice,
+     provided that You also comply with the requirements of this License for the
+     Covered Software. If the Larger Work is a combination of Covered Software
+     with a work governed by one or more Secondary Licenses, and the Covered
+     Software is not Incompatible With Secondary Licenses, this License permits
+     You to additionally distribute such Covered Software under the terms of
+     such Secondary License(s), so that the recipient of the Larger Work may, at
+     their option, further distribute the Covered Software under the terms of
+     either this License or such Secondary License(s).
+
+3.4. Notices
+
+     You may not remove or alter the substance of any license notices (including
+     copyright notices, patent notices, disclaimers of warranty, or limitations
+     of liability) contained within the Source Code Form of the Covered
+     Software, except that You may alter any license notices to the extent
+     required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+     You may choose to offer, and to charge a fee for, warranty, support,
+     indemnity or liability obligations to one or more recipients of Covered
+     Software. However, You may do so only on Your own behalf, and not on behalf
+     of any Contributor. You must make it absolutely clear that any such
+     warranty, support, indemnity, or liability obligation is offered by You
+     alone, and You hereby agree to indemnify every Contributor for any
+     liability incurred by such Contributor as a result of warranty, support,
+     indemnity or liability terms You offer. You may include additional
+     disclaimers of warranty and limitations of liability specific to any
+     jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+
+   If it is impossible for You to comply with any of the terms of this License
+   with respect to some or all of the Covered Software due to statute, judicial
+   order, or regulation then You must: (a) comply with the terms of this License
+   to the maximum extent possible; and (b) describe the limitations and the code
+   they affect. Such description must be placed in a text file included with all
+   distributions of the Covered Software under this License. Except to the
+   extent prohibited by statute or regulation, such description must be
+   sufficiently detailed for a recipient of ordinary skill to be able to
+   understand it.
+
+5. Termination
+
+5.1. The rights granted under this License will terminate automatically if You
+     fail to comply with any of its terms. However, if You become compliant,
+     then the rights granted under this License from a particular Contributor
+     are reinstated (a) provisionally, unless and until such Contributor
+     explicitly and finally terminates Your grants, and (b) on an ongoing basis,
+     if such Contributor fails to notify You of the non-compliance by some
+     reasonable means prior to 60 days after You have come back into compliance.
+     Moreover, Your grants from a particular Contributor are reinstated on an
+     ongoing basis if such Contributor notifies You of the non-compliance by
+     some reasonable means, this is the first time You have received notice of
+     non-compliance with this License from such Contributor, and You become
+     compliant prior to 30 days after Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+     infringement claim (excluding declaratory judgment actions, counter-claims,
+     and cross-claims) alleging that a Contributor Version directly or
+     indirectly infringes any patent, then the rights granted to You by any and
+     all Contributors for the Covered Software under Section 2.1 of this License
+     shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
+     license agreements (excluding distributors and resellers) which have been
+     validly granted by You or Your distributors under this License prior to
+     termination shall survive termination.
+
+6. Disclaimer of Warranty
+
+   Covered Software is provided under this License on an “as is” basis, without
+   warranty of any kind, either expressed, implied, or statutory, including,
+   without limitation, warranties that the Covered Software is free of defects,
+   merchantable, fit for a particular purpose or non-infringing. The entire
+   risk as to the quality and performance of the Covered Software is with You.
+   Should any Covered Software prove defective in any respect, You (not any
+   Contributor) assume the cost of any necessary servicing, repair, or
+   correction. This disclaimer of warranty constitutes an essential part of this
+   License. No use of  any Covered Software is authorized under this License
+   except under this disclaimer.
+
+7. Limitation of Liability
+
+   Under no circumstances and under no legal theory, whether tort (including
+   negligence), contract, or otherwise, shall any Contributor, or anyone who
+   distributes Covered Software as permitted above, be liable to You for any
+   direct, indirect, special, incidental, or consequential damages of any
+   character including, without limitation, damages for lost profits, loss of
+   goodwill, work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses, even if such party shall have been
+   informed of the possibility of such damages. This limitation of liability
+   shall not apply to liability for death or personal injury resulting from such
+   party’s negligence to the extent applicable law prohibits such limitation.
+   Some jurisdictions do not allow the exclusion or limitation of incidental or
+   consequential damages, so this exclusion and limitation may not apply to You.
+
+8. Litigation
+
+   Any litigation relating to this License may be brought only in the courts of
+   a jurisdiction where the defendant maintains its principal place of business
+   and such litigation shall be governed by laws of that jurisdiction, without
+   reference to its conflict-of-law provisions. Nothing in this Section shall
+   prevent a party’s ability to bring cross-claims or counter-claims.
+
+9. Miscellaneous
+
+   This License represents the complete agreement concerning the subject matter
+   hereof. If any provision of this License is held to be unenforceable, such
+   provision shall be reformed only to the extent necessary to make it
+   enforceable. Any law or regulation which provides that the language of a
+   contract shall be construed against the drafter shall not be used to construe
+   this License against a Contributor.
+
+
+10. Versions of the License
+
+10.1. New Versions
+
+      Mozilla Foundation is the license steward. Except as provided in Section
+      10.3, no one other than the license steward has the right to modify or
+      publish new versions of this License. Each version will be given a
+      distinguishing version number.
+
+10.2. Effect of New Versions
+
+      You may distribute the Covered Software under the terms of the version of
+      the License under which You originally received the Covered Software, or
+      under the terms of any subsequent version published by the license
+      steward.
+
+10.3. Modified Versions
+
+      If you create software not governed by this License, and you want to
+      create a new license for such software, you may create and use a modified
+      version of this License if you rename the license and remove any
+      references to the name of the license steward (except to note that such
+      modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
+      If You choose to distribute Source Code Form that is Incompatible With
+      Secondary Licenses under the terms of this version of the License, the
+      notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+
+      This Source Code Form is subject to the
+      terms of the Mozilla Public License, v.
+      2.0. If a copy of the MPL was not
+      distributed with this file, You can
+      obtain one at
+      http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular file, then
+You may include the notice in a location (such as a LICENSE file in a relevant
+directory) where a recipient would be likely to look for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - “Incompatible With Secondary Licenses” Notice
+
+      This Source Code Form is “Incompatible
+      With Secondary Licenses”, as defined by
+      the Mozilla Public License, v. 2.0.
+
diff --git a/vendor/github.com/jesseduffield/go-getter/client.go b/vendor/github.com/jesseduffield/go-getter/client.go
new file mode 100644
index 000000000..300301c2e
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/client.go
@@ -0,0 +1,350 @@
+package getter
+
+import (
+	"bytes"
+	"crypto/md5"
+	"crypto/sha1"
+	"crypto/sha256"
+	"crypto/sha512"
+	"encoding/hex"
+	"fmt"
+	"hash"
+	"io"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"strconv"
+	"strings"
+
+	urlhelper "github.com/hashicorp/go-getter/helper/url"
+	"github.com/hashicorp/go-safetemp"
+)
+
+// Client is a client for downloading things.
+//
+// Top-level functions such as Get are shortcuts for interacting with a client.
+// Using a client directly allows more fine-grained control over how downloading
+// is done, as well as customizing the protocols supported.
+type Client struct {
+	// Src is the source URL to get.
+	//
+	// Dst is the path to save the downloaded thing as. If Dir is set to
+	// true, then this should be a directory. If the directory doesn't exist,
+	// it will be created for you.
+	//
+	// Pwd is the working directory for detection. If this isn't set, some
+	// detection may fail. Client will not default pwd to the current
+	// working directory for security reasons.
+	Src string
+	Dst string
+	Pwd string
+
+	// Mode is the method of download the client will use. See ClientMode
+	// for documentation.
+	Mode ClientMode
+
+	// Detectors is the list of detectors that are tried on the source.
+	// If this is nil, then the default Detectors will be used.
+	Detectors []Detector
+
+	// Decompressors is the map of decompressors supported by this client.
+	// If this is nil, then the default value is the Decompressors global.
+	Decompressors map[string]Decompressor
+
+	// Getters is the map of protocols supported by this client. If this
+	// is nil, then the default Getters variable will be used.
+	Getters map[string]Getter
+
+	// Dir, if true, tells the Client it is downloading a directory (versus
+	// a single file). This distinction is necessary since filenames and
+	// directory names follow the same format so disambiguating is impossible
+	// without knowing ahead of time.
+	//
+	// WARNING: deprecated. If Mode is set, that will take precedence.
+	Dir bool
+}
+
+// Get downloads the configured source to the destination.
+func (c *Client) Get() error {
+	// Store this locally since there are cases we swap this
+	mode := c.Mode
+	if mode == ClientModeInvalid {
+		if c.Dir {
+			mode = ClientModeDir
+		} else {
+			mode = ClientModeFile
+		}
+	}
+
+	// Default decompressor value
+	decompressors := c.Decompressors
+	if decompressors == nil {
+		decompressors = Decompressors
+	}
+
+	// Detect the URL. This is safe if it is already detected.
+	detectors := c.Detectors
+	if detectors == nil {
+		detectors = Detectors
+	}
+	src, err := Detect(c.Src, c.Pwd, detectors)
+	if err != nil {
+		return err
+	}
+
+	// Determine if we have a forced protocol, i.e. "git::http://..."
+	force, src := getForcedGetter(src)
+
+	// If there is a subdir component, then we download the root separately
+	// and then copy over the proper subdir.
+	var realDst string
+	dst := c.Dst
+	src, subDir := SourceDirSubdir(src)
+	if subDir != "" {
+		td, tdcloser, err := safetemp.Dir("", "getter")
+		if err != nil {
+			return err
+		}
+		defer tdcloser.Close()
+
+		realDst = dst
+		dst = td
+	}
+
+	u, err := urlhelper.Parse(src)
+	if err != nil {
+		return err
+	}
+	if force == "" {
+		force = u.Scheme
+	}
+
+	getters := c.Getters
+	if getters == nil {
+		getters = Getters
+	}
+
+	g, ok := getters[force]
+	if !ok {
+		return fmt.Errorf(
+			"download not supported for scheme '%s'", force)
+	}
+
+	// We have magic query parameters that we use to signal different features
+	q := u.Query()
+
+	// Determine if we have an archive type
+	archiveV := q.Get("archive")
+	if archiveV != "" {
+		// Delete the paramter since it is a magic parameter we don't
+		// want to pass on to the Getter
+		q.Del("archive")
+		u.RawQuery = q.Encode()
+
+		// If we can parse the value as a bool and it is false, then
+		// set the archive to "-" which should never map to a decompressor
+		if b, err := strconv.ParseBool(archiveV); err == nil && !b {
+			archiveV = "-"
+		}
+	}
+	if archiveV == "" {
+		// We don't appear to... but is it part of the filename?
+		matchingLen := 0
+		for k, _ := range decompressors {
+			if strings.HasSuffix(u.Path, "."+k) && len(k) > matchingLen {
+				archiveV = k
+				matchingLen = len(k)
+			}
+		}
+	}
+
+	// If we have a decompressor, then we need to change the destination
+	// to download to a temporary path. We unarchive this into the final,
+	// real path.
+	var decompressDst string
+	var decompressDir bool
+	decompressor := decompressors[archiveV]
+	if decompressor != nil {
+		// Create a temporary directory to store our archive. We delete
+		// this at the end of everything.
+		td, err := ioutil.TempDir("", "getter")
+		if err != nil {
+			return fmt.Errorf(
+				"Error creating temporary directory for archive: %s", err)
+		}
+		defer os.RemoveAll(td)
+
+		// Swap the download directory to be our temporary path and
+		// store the old values.
+		decompressDst = dst
+		decompressDir = mode != ClientModeFile
+		dst = filepath.Join(td, "archive")
+		mode = ClientModeFile
+	}
+
+	// Determine if we have a checksum
+	var checksumHash hash.Hash
+	var checksumValue []byte
+	if v := q.Get("checksum"); v != "" {
+		// Delete the query parameter if we have it.
+		q.Del("checksum")
+		u.RawQuery = q.Encode()
+
+		// Determine the checksum hash type
+		checksumType := ""
+		idx := strings.Index(v, ":")
+		if idx > -1 {
+			checksumType = v[:idx]
+		}
+		switch checksumType {
+		case "md5":
+			checksumHash = md5.New()
+		case "sha1":
+			checksumHash = sha1.New()
+		case "sha256":
+			checksumHash = sha256.New()
+		case "sha512":
+			checksumHash = sha512.New()
+		default:
+			return fmt.Errorf(
+				"unsupported checksum type: %s", checksumType)
+		}
+
+		// Get the remainder of the value and parse it into bytes
+		b, err := hex.DecodeString(v[idx+1:])
+		if err != nil {
+			return fmt.Errorf("invalid checksum: %s", err)
+		}
+
+		// Set our value
+		checksumValue = b
+	}
+
+	if mode == ClientModeAny {
+		// Ask the getter which client mode to use
+		mode, err = g.ClientMode(u)
+		if err != nil {
+			return err
+		}
+
+		// Destination is the base name of the URL path in "any" mode when
+		// a file source is detected.
+		if mode == ClientModeFile {
+			filename := filepath.Base(u.Path)
+
+			// Determine if we have a custom file name
+			if v := q.Get("filename"); v != "" {
+				// Delete the query parameter if we have it.
+				q.Del("filename")
+				u.RawQuery = q.Encode()
+
+				filename = v
+			}
+
+			dst = filepath.Join(dst, filename)
+		}
+	}
+
+	// If we're not downloading a directory, then just download the file
+	// and return.
+	if mode == ClientModeFile {
+		err := g.GetFile(dst, u)
+		if err != nil {
+			return err
+		}
+
+		if checksumHash != nil {
+			if err := checksum(dst, checksumHash, checksumValue); err != nil {
+				return err
+			}
+		}
+
+		if decompressor != nil {
+			// We have a decompressor, so decompress the current destination
+			// into the final destination with the proper mode.
+			err := decompressor.Decompress(decompressDst, dst, decompressDir)
+			if err != nil {
+				return err
+			}
+
+			// Swap the information back
+			dst = decompressDst
+			if decompressDir {
+				mode = ClientModeAny
+			} else {
+				mode = ClientModeFile
+			}
+		}
+
+		// We check the dir value again because it can be switched back
+		// if we were unarchiving. If we're still only Get-ing a file, then
+		// we're done.
+		if mode == ClientModeFile {
+			return nil
+		}
+	}
+
+	// If we're at this point we're either downloading a directory or we've
+	// downloaded and unarchived a directory and we're just checking subdir.
+	// In the case we have a decompressor we don't Get because it was Get
+	// above.
+	if decompressor == nil {
+		// If we're getting a directory, then this is an error. You cannot
+		// checksum a directory. TODO: test
+		if checksumHash != nil {
+			return fmt.Errorf(
+				"checksum cannot be specified for directory download")
+		}
+
+		// We're downloading a directory, which might require a bit more work
+		// if we're specifying a subdir.
+		err := g.Get(dst, u)
+		if err != nil {
+			err = fmt.Errorf("error downloading '%s': %s", src, err)
+			return err
+		}
+	}
+
+	// If we have a subdir, copy that over
+	if subDir != "" {
+		if err := os.RemoveAll(realDst); err != nil {
+			return err
+		}
+		if err := os.MkdirAll(realDst, 0755); err != nil {
+			return err
+		}
+
+		// Process any globs
+		subDir, err := SubdirGlob(dst, subDir)
+		if err != nil {
+			return err
+		}
+
+		return copyDir(realDst, subDir, false)
+	}
+
+	return nil
+}
+
+// checksum is a simple method to compute the checksum of a source file
+// and compare it to the given expected value.
+func checksum(source string, h hash.Hash, v []byte) error {
+	f, err := os.Open(source)
+	if err != nil {
+		return fmt.Errorf("Failed to open file for checksum: %s", err)
+	}
+	defer f.Close()
+
+	if _, err := io.Copy(h, f); err != nil {
+		return fmt.Errorf("Failed to hash: %s", err)
+	}
+
+	if actual := h.Sum(nil); !bytes.Equal(actual, v) {
+		return fmt.Errorf(
+			"Checksums did not match.\nExpected: %s\nGot: %s",
+			hex.EncodeToString(v),
+			hex.EncodeToString(actual))
+	}
+
+	return nil
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/client_mode.go b/vendor/github.com/jesseduffield/go-getter/client_mode.go
new file mode 100644
index 000000000..7f02509a7
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/client_mode.go
@@ -0,0 +1,24 @@
+package getter
+
+// ClientMode is the mode that the client operates in.
+type ClientMode uint
+
+const (
+	ClientModeInvalid ClientMode = iota
+
+	// ClientModeAny downloads anything it can. In this mode, dst must
+	// be a directory. If src is a file, it is saved into the directory
+	// with the basename of the URL. If src is a directory or archive,
+	// it is unpacked directly into dst.
+	ClientModeAny
+
+	// ClientModeFile downloads a single file. In this mode, dst must
+	// be a file path (doesn't have to exist). src must point to a single
+	// file. It is saved as dst.
+	ClientModeFile
+
+	// ClientModeDir downloads a directory. In this mode, dst must be
+	// a directory path (doesn't have to exist). src must point to an
+	// archive or directory (such as in s3).
+	ClientModeDir
+)
diff --git a/vendor/github.com/jesseduffield/go-getter/copy_dir.go b/vendor/github.com/jesseduffield/go-getter/copy_dir.go
new file mode 100644
index 000000000..2f58e8aeb
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/copy_dir.go
@@ -0,0 +1,78 @@
+package getter
+
+import (
+	"io"
+	"os"
+	"path/filepath"
+	"strings"
+)
+
+// copyDir copies the src directory contents into dst. Both directories
+// should already exist.
+//
+// If ignoreDot is set to true, then dot-prefixed files/folders are ignored.
+func copyDir(dst string, src string, ignoreDot bool) error {
+	src, err := filepath.EvalSymlinks(src)
+	if err != nil {
+		return err
+	}
+
+	walkFn := func(path string, info os.FileInfo, err error) error {
+		if err != nil {
+			return err
+		}
+		if path == src {
+			return nil
+		}
+
+		if ignoreDot && strings.HasPrefix(filepath.Base(path), ".") {
+			// Skip any dot files
+			if info.IsDir() {
+				return filepath.SkipDir
+			} else {
+				return nil
+			}
+		}
+
+		// The "path" has the src prefixed to it. We need to join our
+		// destination with the path without the src on it.
+		dstPath := filepath.Join(dst, path[len(src):])
+
+		// If we have a directory, make that subdirectory, then continue
+		// the walk.
+		if info.IsDir() {
+			if path == filepath.Join(src, dst) {
+				// dst is in src; don't walk it.
+				return nil
+			}
+
+			if err := os.MkdirAll(dstPath, 0755); err != nil {
+				return err
+			}
+
+			return nil
+		}
+
+		// If we have a file, copy the contents.
+		srcF, err := os.Open(path)
+		if err != nil {
+			return err
+		}
+		defer srcF.Close()
+
+		dstF, err := os.Create(dstPath)
+		if err != nil {
+			return err
+		}
+		defer dstF.Close()
+
+		if _, err := io.Copy(dstF, srcF); err != nil {
+			return err
+		}
+
+		// Chmod it
+		return os.Chmod(dstPath, info.Mode())
+	}
+
+	return filepath.Walk(src, walkFn)
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/decompress.go b/vendor/github.com/jesseduffield/go-getter/decompress.go
new file mode 100644
index 000000000..198bb0edd
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/decompress.go
@@ -0,0 +1,58 @@
+package getter
+
+import (
+	"strings"
+)
+
+// Decompressor defines the interface that must be implemented to add
+// support for decompressing a type.
+//
+// Important: if you're implementing a decompressor, please use the
+// containsDotDot helper in this file to ensure that files can't be
+// decompressed outside of the specified directory.
+type Decompressor interface {
+	// Decompress should decompress src to dst. dir specifies whether dst
+	// is a directory or single file. src is guaranteed to be a single file
+	// that exists. dst is not guaranteed to exist already.
+	Decompress(dst, src string, dir bool) error
+}
+
+// Decompressors is the mapping of extension to the Decompressor implementation
+// that will decompress that extension/type.
+var Decompressors map[string]Decompressor
+
+func init() {
+	tbzDecompressor := new(TarBzip2Decompressor)
+	tgzDecompressor := new(TarGzipDecompressor)
+	txzDecompressor := new(TarXzDecompressor)
+
+	Decompressors = map[string]Decompressor{
+		"bz2":     new(Bzip2Decompressor),
+		"gz":      new(GzipDecompressor),
+		"xz":      new(XzDecompressor),
+		"tar.bz2": tbzDecompressor,
+		"tar.gz":  tgzDecompressor,
+		"tar.xz":  txzDecompressor,
+		"tbz2":    tbzDecompressor,
+		"tgz":     tgzDecompressor,
+		"txz":     txzDecompressor,
+		"zip":     new(ZipDecompressor),
+	}
+}
+
+// containsDotDot checks if the filepath value v contains a ".." entry.
+// This will check filepath components by splitting along / or \. This
+// function is copied directly from the Go net/http implementation.
+func containsDotDot(v string) bool {
+	if !strings.Contains(v, "..") {
+		return false
+	}
+	for _, ent := range strings.FieldsFunc(v, isSlashRune) {
+		if ent == ".." {
+			return true
+		}
+	}
+	return false
+}
+
+func isSlashRune(r rune) bool { return r == '/' || r == '\\' }
diff --git a/vendor/github.com/jesseduffield/go-getter/decompress_bzip2.go b/vendor/github.com/jesseduffield/go-getter/decompress_bzip2.go
new file mode 100644
index 000000000..339f4cf7a
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/decompress_bzip2.go
@@ -0,0 +1,45 @@
+package getter
+
+import (
+	"compress/bzip2"
+	"fmt"
+	"io"
+	"os"
+	"path/filepath"
+)
+
+// Bzip2Decompressor is an implementation of Decompressor that can
+// decompress bz2 files.
+type Bzip2Decompressor struct{}
+
+func (d *Bzip2Decompressor) Decompress(dst, src string, dir bool) error {
+	// Directory isn't supported at all
+	if dir {
+		return fmt.Errorf("bzip2-compressed files can only unarchive to a single file")
+	}
+
+	// If we're going into a directory we should make that first
+	if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
+		return err
+	}
+
+	// File first
+	f, err := os.Open(src)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+
+	// Bzip2 compression is second
+	bzipR := bzip2.NewReader(f)
+
+	// Copy it out
+	dstF, err := os.Create(dst)
+	if err != nil {
+		return err
+	}
+	defer dstF.Close()
+
+	_, err = io.Copy(dstF, bzipR)
+	return err
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/decompress_gzip.go b/vendor/github.com/jesseduffield/go-getter/decompress_gzip.go
new file mode 100644
index 000000000..5ebf709b4
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/decompress_gzip.go
@@ -0,0 +1,49 @@
+package getter
+
+import (
+	"compress/gzip"
+	"fmt"
+	"io"
+	"os"
+	"path/filepath"
+)
+
+// GzipDecompressor is an implementation of Decompressor that can
+// decompress gzip files.
+type GzipDecompressor struct{}
+
+func (d *GzipDecompressor) Decompress(dst, src string, dir bool) error {
+	// Directory isn't supported at all
+	if dir {
+		return fmt.Errorf("gzip-compressed files can only unarchive to a single file")
+	}
+
+	// If we're going into a directory we should make that first
+	if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
+		return err
+	}
+
+	// File first
+	f, err := os.Open(src)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+
+	// gzip compression is second
+	gzipR, err := gzip.NewReader(f)
+	if err != nil {
+		return err
+	}
+	defer gzipR.Close()
+
+	// Copy it out
+	dstF, err := os.Create(dst)
+	if err != nil {
+		return err
+	}
+	defer dstF.Close()
+
+	_, err = io.Copy(dstF, gzipR)
+	return err
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/decompress_tar.go b/vendor/github.com/jesseduffield/go-getter/decompress_tar.go
new file mode 100644
index 000000000..b6986a25a
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/decompress_tar.go
@@ -0,0 +1,160 @@
+package getter
+
+import (
+	"archive/tar"
+	"fmt"
+	"io"
+	"os"
+	"path/filepath"
+	"time"
+)
+
+// untar is a shared helper for untarring an archive. The reader should provide
+// an uncompressed view of the tar archive.
+func untar(input io.Reader, dst, src string, dir bool) error {
+	tarR := tar.NewReader(input)
+	done := false
+	dirHdrs := []*tar.Header{}
+	now := time.Now()
+	for {
+		hdr, err := tarR.Next()
+		if err == io.EOF {
+			if !done {
+				// Empty archive
+				return fmt.Errorf("empty archive: %s", src)
+			}
+
+			break
+		}
+		if err != nil {
+			return err
+		}
+
+		if hdr.Typeflag == tar.TypeXGlobalHeader || hdr.Typeflag == tar.TypeXHeader {
+			// don't unpack extended headers as files
+			continue
+		}
+
+		path := dst
+		if dir {
+			// Disallow parent traversal
+			if containsDotDot(hdr.Name) {
+				return fmt.Errorf("entry contains '..': %s", hdr.Name)
+			}
+
+			path = filepath.Join(path, hdr.Name)
+		}
+
+		if hdr.FileInfo().IsDir() {
+			if !dir {
+				return fmt.Errorf("expected a single file: %s", src)
+			}
+
+			// A directory, just make the directory and continue unarchiving...
+			if err := os.MkdirAll(path, 0755); err != nil {
+				return err
+			}
+
+			// Record the directory information so that we may set its attributes
+			// after all files have been extracted
+			dirHdrs = append(dirHdrs, hdr)
+
+			continue
+		} else {
+			// There is no ordering guarantee that a file in a directory is
+			// listed before the directory
+			dstPath := filepath.Dir(path)
+
+			// Check that the directory exists, otherwise create it
+			if _, err := os.Stat(dstPath); os.IsNotExist(err) {
+				if err := os.MkdirAll(dstPath, 0755); err != nil {
+					return err
+				}
+			}
+		}
+
+		// We have a file. If we already decoded, then it is an error
+		if !dir && done {
+			return fmt.Errorf("expected a single file, got multiple: %s", src)
+		}
+
+		// Mark that we're done so future in single file mode errors
+		done = true
+
+		// Open the file for writing
+		dstF, err := os.Create(path)
+		if err != nil {
+			return err
+		}
+		_, err = io.Copy(dstF, tarR)
+		dstF.Close()
+		if err != nil {
+			return err
+		}
+
+		// Chmod the file
+		if err := os.Chmod(path, hdr.FileInfo().Mode()); err != nil {
+			return err
+		}
+
+		// Set the access and modification time if valid, otherwise default to current time
+		aTime := now
+		mTime := now
+		if hdr.AccessTime.Unix() > 0 {
+			aTime = hdr.AccessTime
+		}
+		if hdr.ModTime.Unix() > 0 {
+			mTime = hdr.ModTime
+		}
+		if err := os.Chtimes(path, aTime, mTime); err != nil {
+			return err
+		}
+	}
+
+	// Perform a final pass over extracted directories to update metadata
+	for _, dirHdr := range dirHdrs {
+		path := filepath.Join(dst, dirHdr.Name)
+		// Chmod the directory since they might be created before we know the mode flags
+		if err := os.Chmod(path, dirHdr.FileInfo().Mode()); err != nil {
+			return err
+		}
+		// Set the mtime/atime attributes since they would have been changed during extraction
+		aTime := now
+		mTime := now
+		if dirHdr.AccessTime.Unix() > 0 {
+			aTime = dirHdr.AccessTime
+		}
+		if dirHdr.ModTime.Unix() > 0 {
+			mTime = dirHdr.ModTime
+		}
+		if err := os.Chtimes(path, aTime, mTime); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+// tarDecompressor is an implementation of Decompressor that can
+// unpack tar files.
+type tarDecompressor struct{}
+
+func (d *tarDecompressor) Decompress(dst, src string, dir bool) error {
+	// If we're going into a directory we should make that first
+	mkdir := dst
+	if !dir {
+		mkdir = filepath.Dir(dst)
+	}
+	if err := os.MkdirAll(mkdir, 0755); err != nil {
+		return err
+	}
+
+	// File first
+	f, err := os.Open(src)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+
+	return untar(f, dst, src, dir)
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/decompress_tbz2.go b/vendor/github.com/jesseduffield/go-getter/decompress_tbz2.go
new file mode 100644
index 000000000..5391b5c8c
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/decompress_tbz2.go
@@ -0,0 +1,33 @@
+package getter
+
+import (
+	"compress/bzip2"
+	"os"
+	"path/filepath"
+)
+
+// TarBzip2Decompressor is an implementation of Decompressor that can
+// decompress tar.bz2 files.
+type TarBzip2Decompressor struct{}
+
+func (d *TarBzip2Decompressor) Decompress(dst, src string, dir bool) error {
+	// If we're going into a directory we should make that first
+	mkdir := dst
+	if !dir {
+		mkdir = filepath.Dir(dst)
+	}
+	if err := os.MkdirAll(mkdir, 0755); err != nil {
+		return err
+	}
+
+	// File first
+	f, err := os.Open(src)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+
+	// Bzip2 compression is second
+	bzipR := bzip2.NewReader(f)
+	return untar(bzipR, dst, src, dir)
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/decompress_testing.go b/vendor/github.com/jesseduffield/go-getter/decompress_testing.go
new file mode 100644
index 000000000..a13c0aaa6
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/decompress_testing.go
@@ -0,0 +1,169 @@
+package getter
+
+import (
+	"crypto/md5"
+	"encoding/hex"
+	"io"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"reflect"
+	"runtime"
+	"sort"
+	"strings"
+	"time"
+
+	"github.com/mitchellh/go-testing-interface"
+)
+
+// TestDecompressCase is a single test case for testing decompressors
+type TestDecompressCase struct {
+	Input   string   // Input is the complete path to the input file
+	Dir     bool     // Dir is whether or not we're testing directory mode
+	Err     bool     // Err is whether we expect an error or not
+	DirList []string // DirList is the list of files for Dir mode
+	FileMD5 string   // FileMD5 is the expected MD5 for a single file
+	Mtime *time.Time // Mtime is the optionally expected mtime for a single file (or all files if in Dir mode)
+}
+
+// TestDecompressor is a helper function for testing generic decompressors.
+func TestDecompressor(t testing.T, d Decompressor, cases []TestDecompressCase) {
+	for _, tc := range cases {
+		t.Logf("Testing: %s", tc.Input)
+
+		// Temporary dir to store stuff
+		td, err := ioutil.TempDir("", "getter")
+		if err != nil {
+			t.Fatalf("err: %s", err)
+		}
+
+		// Destination is always joining result so that we have a new path
+		dst := filepath.Join(td, "subdir", "result")
+
+		// We use a function so defers work
+		func() {
+			defer os.RemoveAll(td)
+
+			// Decompress
+			err := d.Decompress(dst, tc.Input, tc.Dir)
+			if (err != nil) != tc.Err {
+				t.Fatalf("err %s: %s", tc.Input, err)
+			}
+			if tc.Err {
+				return
+			}
+
+			// If it isn't a directory, then check for a single file
+			if !tc.Dir {
+				fi, err := os.Stat(dst)
+				if err != nil {
+					t.Fatalf("err %s: %s", tc.Input, err)
+				}
+				if fi.IsDir() {
+					t.Fatalf("err %s: expected file, got directory", tc.Input)
+				}
+				if tc.FileMD5 != "" {
+					actual := testMD5(t, dst)
+					expected := tc.FileMD5
+					if actual != expected {
+						t.Fatalf("err %s: expected MD5 %s, got %s", tc.Input, expected, actual)
+					}
+				}
+
+				if tc.Mtime != nil {
+					actual := fi.ModTime()
+					if tc.Mtime.Unix() > 0 {
+						expected := *tc.Mtime
+						if actual != expected {
+							t.Fatalf("err %s: expected mtime '%s' for %s, got '%s'", tc.Input, expected.String(), dst, actual.String())
+						}
+					} else if actual.Unix() <= 0 {
+						t.Fatalf("err %s: expected mtime to be > 0, got '%s'", actual.String())
+					}
+				}
+
+				return
+			}
+
+			// Convert expected for windows
+			expected := tc.DirList
+			if runtime.GOOS == "windows" {
+				for i, v := range expected {
+					expected[i] = strings.Replace(v, "/", "\\", -1)
+				}
+			}
+
+			// Directory, check for the correct contents
+			actual := testListDir(t, dst)
+			if !reflect.DeepEqual(actual, expected) {
+				t.Fatalf("bad %s\n\n%#v\n\n%#v", tc.Input, actual, expected)
+			}
+			// Check for correct atime/mtime
+			for _, dir := range actual {
+				path := filepath.Join(dst, dir)
+				if tc.Mtime != nil {
+					fi, err := os.Stat(path)
+					if err != nil {
+						t.Fatalf("err: %s", err)
+					}
+					actual := fi.ModTime()
+					if tc.Mtime.Unix() > 0 {
+						expected := *tc.Mtime
+						if actual != expected {
+							t.Fatalf("err %s: expected mtime '%s' for %s, got '%s'", tc.Input, expected.String(), path, actual.String())
+						}
+					} else if actual.Unix() < 0 {
+						t.Fatalf("err %s: expected mtime to be > 0, got '%s'", actual.String())
+					}
+
+				}
+			}
+		}()
+	}
+}
+
+func testListDir(t testing.T, path string) []string {
+	var result []string
+	err := filepath.Walk(path, func(sub string, info os.FileInfo, err error) error {
+		if err != nil {
+			return err
+		}
+
+		sub = strings.TrimPrefix(sub, path)
+		if sub == "" {
+			return nil
+		}
+		sub = sub[1:] // Trim the leading path sep.
+
+		// If it is a dir, add trailing sep
+		if info.IsDir() {
+			sub += string(os.PathSeparator)
+		}
+
+		result = append(result, sub)
+		return nil
+	})
+	if err != nil {
+		t.Fatalf("err: %s", err)
+	}
+
+	sort.Strings(result)
+	return result
+}
+
+func testMD5(t testing.T, path string) string {
+	f, err := os.Open(path)
+	if err != nil {
+		t.Fatalf("err: %s", err)
+	}
+	defer f.Close()
+
+	h := md5.New()
+	_, err = io.Copy(h, f)
+	if err != nil {
+		t.Fatalf("err: %s", err)
+	}
+
+	result := h.Sum(nil)
+	return hex.EncodeToString(result)
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/decompress_tgz.go b/vendor/github.com/jesseduffield/go-getter/decompress_tgz.go
new file mode 100644
index 000000000..65eb70dd2
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/decompress_tgz.go
@@ -0,0 +1,39 @@
+package getter
+
+import (
+	"compress/gzip"
+	"fmt"
+	"os"
+	"path/filepath"
+)
+
+// TarGzipDecompressor is an implementation of Decompressor that can
+// decompress tar.gzip files.
+type TarGzipDecompressor struct{}
+
+func (d *TarGzipDecompressor) Decompress(dst, src string, dir bool) error {
+	// If we're going into a directory we should make that first
+	mkdir := dst
+	if !dir {
+		mkdir = filepath.Dir(dst)
+	}
+	if err := os.MkdirAll(mkdir, 0755); err != nil {
+		return err
+	}
+
+	// File first
+	f, err := os.Open(src)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+
+	// Gzip compression is second
+	gzipR, err := gzip.NewReader(f)
+	if err != nil {
+		return fmt.Errorf("Error opening a gzip reader for %s: %s", src, err)
+	}
+	defer gzipR.Close()
+
+	return untar(gzipR, dst, src, dir)
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/decompress_txz.go b/vendor/github.com/jesseduffield/go-getter/decompress_txz.go
new file mode 100644
index 000000000..5e151c127
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/decompress_txz.go
@@ -0,0 +1,39 @@
+package getter
+
+import (
+	"fmt"
+	"os"
+	"path/filepath"
+
+	"github.com/ulikunitz/xz"
+)
+
+// TarXzDecompressor is an implementation of Decompressor that can
+// decompress tar.xz files.
+type TarXzDecompressor struct{}
+
+func (d *TarXzDecompressor) Decompress(dst, src string, dir bool) error {
+	// If we're going into a directory we should make that first
+	mkdir := dst
+	if !dir {
+		mkdir = filepath.Dir(dst)
+	}
+	if err := os.MkdirAll(mkdir, 0755); err != nil {
+		return err
+	}
+
+	// File first
+	f, err := os.Open(src)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+
+	// xz compression is second
+	txzR, err := xz.NewReader(f)
+	if err != nil {
+		return fmt.Errorf("Error opening an xz reader for %s: %s", src, err)
+	}
+
+	return untar(txzR, dst, src, dir)
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/decompress_xz.go b/vendor/github.com/jesseduffield/go-getter/decompress_xz.go
new file mode 100644
index 000000000..4e37abab1
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/decompress_xz.go
@@ -0,0 +1,49 @@
+package getter
+
+import (
+	"fmt"
+	"io"
+	"os"
+	"path/filepath"
+
+	"github.com/ulikunitz/xz"
+)
+
+// XzDecompressor is an implementation of Decompressor that can
+// decompress xz files.
+type XzDecompressor struct{}
+
+func (d *XzDecompressor) Decompress(dst, src string, dir bool) error {
+	// Directory isn't supported at all
+	if dir {
+		return fmt.Errorf("xz-compressed files can only unarchive to a single file")
+	}
+
+	// If we're going into a directory we should make that first
+	if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
+		return err
+	}
+
+	// File first
+	f, err := os.Open(src)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+
+	// xz compression is second
+	xzR, err := xz.NewReader(f)
+	if err != nil {
+		return err
+	}
+
+	// Copy it out
+	dstF, err := os.Create(dst)
+	if err != nil {
+		return err
+	}
+	defer dstF.Close()
+
+	_, err = io.Copy(dstF, xzR)
+	return err
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/decompress_zip.go b/vendor/github.com/jesseduffield/go-getter/decompress_zip.go
new file mode 100644
index 000000000..b0e70cac3
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/decompress_zip.go
@@ -0,0 +1,101 @@
+package getter
+
+import (
+	"archive/zip"
+	"fmt"
+	"io"
+	"os"
+	"path/filepath"
+)
+
+// ZipDecompressor is an implementation of Decompressor that can
+// decompress tar.gzip files.
+type ZipDecompressor struct{}
+
+func (d *ZipDecompressor) Decompress(dst, src string, dir bool) error {
+	// If we're going into a directory we should make that first
+	mkdir := dst
+	if !dir {
+		mkdir = filepath.Dir(dst)
+	}
+	if err := os.MkdirAll(mkdir, 0755); err != nil {
+		return err
+	}
+
+	// Open the zip
+	zipR, err := zip.OpenReader(src)
+	if err != nil {
+		return err
+	}
+	defer zipR.Close()
+
+	// Check the zip integrity
+	if len(zipR.File) == 0 {
+		// Empty archive
+		return fmt.Errorf("empty archive: %s", src)
+	}
+	if !dir && len(zipR.File) > 1 {
+		return fmt.Errorf("expected a single file: %s", src)
+	}
+
+	// Go through and unarchive
+	for _, f := range zipR.File {
+		path := dst
+		if dir {
+			// Disallow parent traversal
+			if containsDotDot(f.Name) {
+				return fmt.Errorf("entry contains '..': %s", f.Name)
+			}
+
+			path = filepath.Join(path, f.Name)
+		}
+
+		if f.FileInfo().IsDir() {
+			if !dir {
+				return fmt.Errorf("expected a single file: %s", src)
+			}
+
+			// A directory, just make the directory and continue unarchiving...
+			if err := os.MkdirAll(path, 0755); err != nil {
+				return err
+			}
+
+			continue
+		}
+
+		// Create the enclosing directories if we must. ZIP files aren't
+		// required to contain entries for just the directories so this
+		// can happen.
+		if dir {
+			if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
+				return err
+			}
+		}
+
+		// Open the file for reading
+		srcF, err := f.Open()
+		if err != nil {
+			return err
+		}
+
+		// Open the file for writing
+		dstF, err := os.Create(path)
+		if err != nil {
+			srcF.Close()
+			return err
+		}
+		_, err = io.Copy(dstF, srcF)
+		srcF.Close()
+		dstF.Close()
+		if err != nil {
+			return err
+		}
+
+		// Chmod the file
+		if err := os.Chmod(path, f.Mode()); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/detect.go b/vendor/github.com/jesseduffield/go-getter/detect.go
new file mode 100644
index 000000000..c3695510b
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/detect.go
@@ -0,0 +1,103 @@
+package getter
+
+import (
+	"fmt"
+	"path/filepath"
+
+	"github.com/hashicorp/go-getter/helper/url"
+)
+
+// Detector defines the interface that an invalid URL or a URL with a blank
+// scheme is passed through in order to determine if its shorthand for
+// something else well-known.
+type Detector interface {
+	// Detect will detect whether the string matches a known pattern to
+	// turn it into a proper URL.
+	Detect(string, string) (string, bool, error)
+}
+
+// Detectors is the list of detectors that are tried on an invalid URL.
+// This is also the order they're tried (index 0 is first).
+var Detectors []Detector
+
+func init() {
+	Detectors = []Detector{
+		new(GitHubDetector),
+		new(BitBucketDetector),
+		new(S3Detector),
+		new(FileDetector),
+	}
+}
+
+// Detect turns a source string into another source string if it is
+// detected to be of a known pattern.
+//
+// The third parameter should be the list of detectors to use in the
+// order to try them. If you don't want to configure this, just use
+// the global Detectors variable.
+//
+// This is safe to be called with an already valid source string: Detect
+// will just return it.
+func Detect(src string, pwd string, ds []Detector) (string, error) {
+	getForce, getSrc := getForcedGetter(src)
+
+	// Separate out the subdir if there is one, we don't pass that to detect
+	getSrc, subDir := SourceDirSubdir(getSrc)
+
+	u, err := url.Parse(getSrc)
+	if err == nil && u.Scheme != "" {
+		// Valid URL
+		return src, nil
+	}
+
+	for _, d := range ds {
+		result, ok, err := d.Detect(getSrc, pwd)
+		if err != nil {
+			return "", err
+		}
+		if !ok {
+			continue
+		}
+
+		var detectForce string
+		detectForce, result = getForcedGetter(result)
+		result, detectSubdir := SourceDirSubdir(result)
+
+		// If we have a subdir from the detection, then prepend it to our
+		// requested subdir.
+		if detectSubdir != "" {
+			if subDir != "" {
+				subDir = filepath.Join(detectSubdir, subDir)
+			} else {
+				subDir = detectSubdir
+			}
+		}
+
+		if subDir != "" {
+			u, err := url.Parse(result)
+			if err != nil {
+				return "", fmt.Errorf("Error parsing URL: %s", err)
+			}
+			u.Path += "//" + subDir
+
+			// a subdir may contain wildcards, but in order to support them we
+			// have to ensure the path isn't escaped.
+			u.RawPath = u.Path
+
+			result = u.String()
+		}
+
+		// Preserve the forced getter if it exists. We try to use the
+		// original set force first, followed by any force set by the
+		// detector.
+		if getForce != "" {
+			result = fmt.Sprintf("%s::%s", getForce, result)
+		} else if detectForce != "" {
+			result = fmt.Sprintf("%s::%s", detectForce, result)
+		}
+
+		return result, nil
+	}
+
+	return "", fmt.Errorf("invalid source string: %s", src)
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/detect_bitbucket.go b/vendor/github.com/jesseduffield/go-getter/detect_bitbucket.go
new file mode 100644
index 000000000..a183a17df
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/detect_bitbucket.go
@@ -0,0 +1,66 @@
+package getter
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+	"net/url"
+	"strings"
+)
+
+// BitBucketDetector implements Detector to detect BitBucket URLs and turn
+// them into URLs that the Git or Hg Getter can understand.
+type BitBucketDetector struct{}
+
+func (d *BitBucketDetector) Detect(src, _ string) (string, bool, error) {
+	if len(src) == 0 {
+		return "", false, nil
+	}
+
+	if strings.HasPrefix(src, "bitbucket.org/") {
+		return d.detectHTTP(src)
+	}
+
+	return "", false, nil
+}
+
+func (d *BitBucketDetector) detectHTTP(src string) (string, bool, error) {
+	u, err := url.Parse("https://" + src)
+	if err != nil {
+		return "", true, fmt.Errorf("error parsing BitBucket URL: %s", err)
+	}
+
+	// We need to get info on this BitBucket repository to determine whether
+	// it is Git or Hg.
+	var info struct {
+		SCM string `json:"scm"`
+	}
+	infoUrl := "https://api.bitbucket.org/1.0/repositories" + u.Path
+	resp, err := http.Get(infoUrl)
+	if err != nil {
+		return "", true, fmt.Errorf("error looking up BitBucket URL: %s", err)
+	}
+	if resp.StatusCode == 403 {
+		// A private repo
+		return "", true, fmt.Errorf(
+			"shorthand BitBucket URL can't be used for private repos, " +
+				"please use a full URL")
+	}
+	dec := json.NewDecoder(resp.Body)
+	if err := dec.Decode(&info); err != nil {
+		return "", true, fmt.Errorf("error looking up BitBucket URL: %s", err)
+	}
+
+	switch info.SCM {
+	case "git":
+		if !strings.HasSuffix(u.Path, ".git") {
+			u.Path += ".git"
+		}
+
+		return "git::" + u.String(), true, nil
+	case "hg":
+		return "hg::" + u.String(), true, nil
+	default:
+		return "", true, fmt.Errorf("unknown BitBucket SCM type: %s", info.SCM)
+	}
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/detect_file.go b/vendor/github.com/jesseduffield/go-getter/detect_file.go
new file mode 100644
index 000000000..4ef41ea73
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/detect_file.go
@@ -0,0 +1,67 @@
+package getter
+
+import (
+	"fmt"
+	"os"
+	"path/filepath"
+	"runtime"
+)
+
+// FileDetector implements Detector to detect file paths.
+type FileDetector struct{}
+
+func (d *FileDetector) Detect(src, pwd string) (string, bool, error) {
+	if len(src) == 0 {
+		return "", false, nil
+	}
+
+	if !filepath.IsAbs(src) {
+		if pwd == "" {
+			return "", true, fmt.Errorf(
+				"relative paths require a module with a pwd")
+		}
+
+		// Stat the pwd to determine if its a symbolic link. If it is,
+		// then the pwd becomes the original directory. Otherwise,
+		// `filepath.Join` below does some weird stuff.
+		//
+		// We just ignore if the pwd doesn't exist. That error will be
+		// caught later when we try to use the URL.
+		if fi, err := os.Lstat(pwd); !os.IsNotExist(err) {
+			if err != nil {
+				return "", true, err
+			}
+			if fi.Mode()&os.ModeSymlink != 0 {
+				pwd, err = filepath.EvalSymlinks(pwd)
+				if err != nil {
+					return "", true, err
+				}
+
+				// The symlink itself might be a relative path, so we have to
+				// resolve this to have a correctly rooted URL.
+				pwd, err = filepath.Abs(pwd)
+				if err != nil {
+					return "", true, err
+				}
+			}
+		}
+
+		src = filepath.Join(pwd, src)
+	}
+
+	return fmtFileURL(src), true, nil
+}
+
+func fmtFileURL(path string) string {
+	if runtime.GOOS == "windows" {
+		// Make sure we're using "/" on Windows. URLs are "/"-based.
+		path = filepath.ToSlash(path)
+		return fmt.Sprintf("file://%s", path)
+	}
+
+	// Make sure that we don't start with "/" since we add that below.
+	if path[0] == '/' {
+		path = path[1:]
+	}
+	return fmt.Sprintf("file:///%s", path)
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/detect_github.go b/vendor/github.com/jesseduffield/go-getter/detect_github.go
new file mode 100644
index 000000000..c084ad9ac
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/detect_github.go
@@ -0,0 +1,73 @@
+package getter
+
+import (
+	"fmt"
+	"net/url"
+	"strings"
+)
+
+// GitHubDetector implements Detector to detect GitHub URLs and turn
+// them into URLs that the Git Getter can understand.
+type GitHubDetector struct{}
+
+func (d *GitHubDetector) Detect(src, _ string) (string, bool, error) {
+	if len(src) == 0 {
+		return "", false, nil
+	}
+
+	if strings.HasPrefix(src, "github.com/") {
+		return d.detectHTTP(src)
+	} else if strings.HasPrefix(src, "git@github.com:") {
+		return d.detectSSH(src)
+	}
+
+	return "", false, nil
+}
+
+func (d *GitHubDetector) detectHTTP(src string) (string, bool, error) {
+	parts := strings.Split(src, "/")
+	if len(parts) < 3 {
+		return "", false, fmt.Errorf(
+			"GitHub URLs should be github.com/username/repo")
+	}
+
+	urlStr := fmt.Sprintf("https://%s", strings.Join(parts[:3], "/"))
+	url, err := url.Parse(urlStr)
+	if err != nil {
+		return "", true, fmt.Errorf("error parsing GitHub URL: %s", err)
+	}
+
+	if !strings.HasSuffix(url.Path, ".git") {
+		url.Path += ".git"
+	}
+
+	if len(parts) > 3 {
+		url.Path += "//" + strings.Join(parts[3:], "/")
+	}
+
+	return "git::" + url.String(), true, nil
+}
+
+func (d *GitHubDetector) detectSSH(src string) (string, bool, error) {
+	idx := strings.Index(src, ":")
+	qidx := strings.Index(src, "?")
+	if qidx == -1 {
+		qidx = len(src)
+	}
+
+	var u url.URL
+	u.Scheme = "ssh"
+	u.User = url.User("git")
+	u.Host = "github.com"
+	u.Path = src[idx+1 : qidx]
+	if qidx < len(src) {
+		q, err := url.ParseQuery(src[qidx+1:])
+		if err != nil {
+			return "", true, fmt.Errorf("error parsing GitHub SSH URL: %s", err)
+		}
+
+		u.RawQuery = q.Encode()
+	}
+
+	return "git::" + u.String(), true, nil
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/detect_s3.go b/vendor/github.com/jesseduffield/go-getter/detect_s3.go
new file mode 100644
index 000000000..8e0f4a03b
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/detect_s3.go
@@ -0,0 +1,61 @@
+package getter
+
+import (
+	"fmt"
+	"net/url"
+	"strings"
+)
+
+// S3Detector implements Detector to detect S3 URLs and turn
+// them into URLs that the S3 getter can understand.
+type S3Detector struct{}
+
+func (d *S3Detector) Detect(src, _ string) (string, bool, error) {
+	if len(src) == 0 {
+		return "", false, nil
+	}
+
+	if strings.Contains(src, ".amazonaws.com/") {
+		return d.detectHTTP(src)
+	}
+
+	return "", false, nil
+}
+
+func (d *S3Detector) detectHTTP(src string) (string, bool, error) {
+	parts := strings.Split(src, "/")
+	if len(parts) < 2 {
+		return "", false, fmt.Errorf(
+			"URL is not a valid S3 URL")
+	}
+
+	hostParts := strings.Split(parts[0], ".")
+	if len(hostParts) == 3 {
+		return d.detectPathStyle(hostParts[0], parts[1:])
+	} else if len(hostParts) == 4 {
+		return d.detectVhostStyle(hostParts[1], hostParts[0], parts[1:])
+	} else {
+		return "", false, fmt.Errorf(
+			"URL is not a valid S3 URL")
+	}
+}
+
+func (d *S3Detector) detectPathStyle(region string, parts []string) (string, bool, error) {
+	urlStr := fmt.Sprintf("https://%s.amazonaws.com/%s", region, strings.Join(parts, "/"))
+	url, err := url.Parse(urlStr)
+	if err != nil {
+		return "", false, fmt.Errorf("error parsing S3 URL: %s", err)
+	}
+
+	return "s3::" + url.String(), true, nil
+}
+
+func (d *S3Detector) detectVhostStyle(region, bucket string, parts []string) (string, bool, error) {
+	urlStr := fmt.Sprintf("https://%s.amazonaws.com/%s/%s", region, bucket, strings.Join(parts, "/"))
+	url, err := url.Parse(urlStr)
+	if err != nil {
+		return "", false, fmt.Errorf("error parsing S3 URL: %s", err)
+	}
+
+	return "s3::" + url.String(), true, nil
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/folder_storage.go b/vendor/github.com/jesseduffield/go-getter/folder_storage.go
new file mode 100644
index 000000000..647ccf459
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/folder_storage.go
@@ -0,0 +1,65 @@
+package getter
+
+import (
+	"crypto/md5"
+	"encoding/hex"
+	"fmt"
+	"os"
+	"path/filepath"
+)
+
+// FolderStorage is an implementation of the Storage interface that manages
+// modules on the disk.
+type FolderStorage struct {
+	// StorageDir is the directory where the modules will be stored.
+	StorageDir string
+}
+
+// Dir implements Storage.Dir
+func (s *FolderStorage) Dir(key string) (d string, e bool, err error) {
+	d = s.dir(key)
+	_, err = os.Stat(d)
+	if err == nil {
+		// Directory exists
+		e = true
+		return
+	}
+	if os.IsNotExist(err) {
+		// Directory doesn't exist
+		d = ""
+		e = false
+		err = nil
+		return
+	}
+
+	// An error
+	d = ""
+	e = false
+	return
+}
+
+// Get implements Storage.Get
+func (s *FolderStorage) Get(key string, source string, update bool) error {
+	dir := s.dir(key)
+	if !update {
+		if _, err := os.Stat(dir); err == nil {
+			// If the directory already exists, then we're done since
+			// we're not updating.
+			return nil
+		} else if !os.IsNotExist(err) {
+			// If the error we got wasn't a file-not-exist error, then
+			// something went wrong and we should report it.
+			return fmt.Errorf("Error reading module directory: %s", err)
+		}
+	}
+
+	// Get the source. This always forces an update.
+	return Get(dir, source)
+}
+
+// dir returns the directory name internally that we'll use to map to
+// internally.
+func (s *FolderStorage) dir(key string) string {
+	sum := md5.Sum([]byte(key))
+	return filepath.Join(s.StorageDir, hex.EncodeToString(sum[:]))
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/get.go b/vendor/github.com/jesseduffield/go-getter/get.go
new file mode 100644
index 000000000..e6053d934
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/get.go
@@ -0,0 +1,146 @@
+// getter is a package for downloading files or directories from a variety of
+// protocols.
+//
+// getter is unique in its ability to download both directories and files.
+// It also detects certain source strings to be protocol-specific URLs. For
+// example, "github.com/hashicorp/go-getter" would turn into a Git URL and
+// use the Git protocol.
+//
+// Protocols and detectors are extensible.
+//
+// To get started, see Client.
+package getter
+
+import (
+	"bytes"
+	"fmt"
+	"net/url"
+	"os/exec"
+	"regexp"
+	"syscall"
+
+	cleanhttp "github.com/hashicorp/go-cleanhttp"
+)
+
+// Getter defines the interface that schemes must implement to download
+// things.
+type Getter interface {
+	// Get downloads the given URL into the given directory. This always
+	// assumes that we're updating and gets the latest version that it can.
+	//
+	// The directory may already exist (if we're updating). If it is in a
+	// format that isn't understood, an error should be returned. Get shouldn't
+	// simply nuke the directory.
+	Get(string, *url.URL) error
+
+	// GetFile downloads the give URL into the given path. The URL must
+	// reference a single file. If possible, the Getter should check if
+	// the remote end contains the same file and no-op this operation.
+	GetFile(string, *url.URL) error
+
+	// ClientMode returns the mode based on the given URL. This is used to
+	// allow clients to let the getters decide which mode to use.
+	ClientMode(*url.URL) (ClientMode, error)
+}
+
+// Getters is the mapping of scheme to the Getter implementation that will
+// be used to get a dependency.
+var Getters map[string]Getter
+
+// forcedRegexp is the regular expression that finds forced getters. This
+// syntax is schema::url, example: git::https://foo.com
+var forcedRegexp = regexp.MustCompile(`^([A-Za-z0-9]+)::(.+)$`)
+
+// httpClient is the default client to be used by HttpGetters.
+var httpClient = cleanhttp.DefaultClient()
+
+func init() {
+	httpGetter := &HttpGetter{
+		Netrc: true,
+	}
+
+	Getters = map[string]Getter{
+		"file":  new(FileGetter),
+		"git":   new(GitGetter),
+		"hg":    new(HgGetter),
+		"s3":    new(S3Getter),
+		"http":  httpGetter,
+		"https": httpGetter,
+	}
+}
+
+// Get downloads the directory specified by src into the folder specified by
+// dst. If dst already exists, Get will attempt to update it.
+//
+// src is a URL, whereas dst is always just a file path to a folder. This
+// folder doesn't need to exist. It will be created if it doesn't exist.
+func Get(dst, src string) error {
+	return (&Client{
+		Src:     src,
+		Dst:     dst,
+		Dir:     true,
+		Getters: Getters,
+	}).Get()
+}
+
+// GetAny downloads a URL into the given destination. Unlike Get or
+// GetFile, both directories and files are supported.
+//
+// dst must be a directory. If src is a file, it will be downloaded
+// into dst with the basename of the URL. If src is a directory or
+// archive, it will be unpacked directly into dst.
+func GetAny(dst, src string) error {
+	return (&Client{
+		Src:     src,
+		Dst:     dst,
+		Mode:    ClientModeAny,
+		Getters: Getters,
+	}).Get()
+}
+
+// GetFile downloads the file specified by src into the path specified by
+// dst.
+func GetFile(dst, src string) error {
+	return (&Client{
+		Src:     src,
+		Dst:     dst,
+		Dir:     false,
+		Getters: Getters,
+	}).Get()
+}
+
+// getRunCommand is a helper that will run a command and capture the output
+// in the case an error happens.
+func getRunCommand(cmd *exec.Cmd) error {
+	var buf bytes.Buffer
+	cmd.Stdout = &buf
+	cmd.Stderr = &buf
+	err := cmd.Run()
+	if err == nil {
+		return nil
+	}
+	if exiterr, ok := err.(*exec.ExitError); ok {
+		// The program has exited with an exit code != 0
+		if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
+			return fmt.Errorf(
+				"%s exited with %d: %s",
+				cmd.Path,
+				status.ExitStatus(),
+				buf.String())
+		}
+	}
+
+	return fmt.Errorf("error running %s: %s", cmd.Path, buf.String())
+}
+
+// getForcedGetter takes a source and returns the tuple of the forced
+// getter and the raw URL (without the force syntax).
+func getForcedGetter(src string) (string, string) {
+	var forced string
+	if ms := forcedRegexp.FindStringSubmatch(src); ms != nil {
+		forced = ms[1]
+		src = ms[2]
+	}
+
+	return forced, src
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/get_file.go b/vendor/github.com/jesseduffield/go-getter/get_file.go
new file mode 100644
index 000000000..e5d2d61d7
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/get_file.go
@@ -0,0 +1,32 @@
+package getter
+
+import (
+	"net/url"
+	"os"
+)
+
+// FileGetter is a Getter implementation that will download a module from
+// a file scheme.
+type FileGetter struct {
+	// Copy, if set to true, will copy data instead of using a symlink
+	Copy bool
+}
+
+func (g *FileGetter) ClientMode(u *url.URL) (ClientMode, error) {
+	path := u.Path
+	if u.RawPath != "" {
+		path = u.RawPath
+	}
+
+	fi, err := os.Stat(path)
+	if err != nil {
+		return 0, err
+	}
+
+	// Check if the source is a directory.
+	if fi.IsDir() {
+		return ClientModeDir, nil
+	}
+
+	return ClientModeFile, nil
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/get_file_unix.go b/vendor/github.com/jesseduffield/go-getter/get_file_unix.go
new file mode 100644
index 000000000..c89a2d5a4
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/get_file_unix.go
@@ -0,0 +1,103 @@
+// +build !windows
+
+package getter
+
+import (
+	"fmt"
+	"io"
+	"net/url"
+	"os"
+	"path/filepath"
+)
+
+func (g *FileGetter) Get(dst string, u *url.URL) error {
+	path := u.Path
+	if u.RawPath != "" {
+		path = u.RawPath
+	}
+
+	// The source path must exist and be a directory to be usable.
+	if fi, err := os.Stat(path); err != nil {
+		return fmt.Errorf("source path error: %s", err)
+	} else if !fi.IsDir() {
+		return fmt.Errorf("source path must be a directory")
+	}
+
+	fi, err := os.Lstat(dst)
+	if err != nil && !os.IsNotExist(err) {
+		return err
+	}
+
+	// If the destination already exists, it must be a symlink
+	if err == nil {
+		mode := fi.Mode()
+		if mode&os.ModeSymlink == 0 {
+			return fmt.Errorf("destination exists and is not a symlink")
+		}
+
+		// Remove the destination
+		if err := os.Remove(dst); err != nil {
+			return err
+		}
+	}
+
+	// Create all the parent directories
+	if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
+		return err
+	}
+
+	return os.Symlink(path, dst)
+}
+
+func (g *FileGetter) GetFile(dst string, u *url.URL) error {
+	path := u.Path
+	if u.RawPath != "" {
+		path = u.RawPath
+	}
+
+	// The source path must exist and be a file to be usable.
+	if fi, err := os.Stat(path); err != nil {
+		return fmt.Errorf("source path error: %s", err)
+	} else if fi.IsDir() {
+		return fmt.Errorf("source path must be a file")
+	}
+
+	_, err := os.Lstat(dst)
+	if err != nil && !os.IsNotExist(err) {
+		return err
+	}
+
+	// If the destination already exists, it must be a symlink
+	if err == nil {
+		// Remove the destination
+		if err := os.Remove(dst); err != nil {
+			return err
+		}
+	}
+
+	// Create all the parent directories
+	if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
+		return err
+	}
+
+	// If we're not copying, just symlink and we're done
+	if !g.Copy {
+		return os.Symlink(path, dst)
+	}
+
+	// Copy
+	srcF, err := os.Open(path)
+	if err != nil {
+		return err
+	}
+	defer srcF.Close()
+
+	dstF, err := os.Create(dst)
+	if err != nil {
+		return err
+	}
+	defer dstF.Close()
+
+	_, err = io.Copy(dstF, srcF)
+	return err
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/get_file_windows.go b/vendor/github.com/jesseduffield/go-getter/get_file_windows.go
new file mode 100644
index 000000000..f87ed0a0b
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/get_file_windows.go
@@ -0,0 +1,120 @@
+// +build windows
+
+package getter
+
+import (
+	"fmt"
+	"io"
+	"net/url"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+)
+
+func (g *FileGetter) Get(dst string, u *url.URL) error {
+	path := u.Path
+	if u.RawPath != "" {
+		path = u.RawPath
+	}
+
+	// The source path must exist and be a directory to be usable.
+	if fi, err := os.Stat(path); err != nil {
+		return fmt.Errorf("source path error: %s", err)
+	} else if !fi.IsDir() {
+		return fmt.Errorf("source path must be a directory")
+	}
+
+	fi, err := os.Lstat(dst)
+	if err != nil && !os.IsNotExist(err) {
+		return err
+	}
+
+	// If the destination already exists, it must be a symlink
+	if err == nil {
+		mode := fi.Mode()
+		if mode&os.ModeSymlink == 0 {
+			return fmt.Errorf("destination exists and is not a symlink")
+		}
+
+		// Remove the destination
+		if err := os.Remove(dst); err != nil {
+			return err
+		}
+	}
+
+	// Create all the parent directories
+	if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
+		return err
+	}
+
+	sourcePath := toBackslash(path)
+
+	// Use mklink to create a junction point
+	output, err := exec.Command("cmd", "/c", "mklink", "/J", dst, sourcePath).CombinedOutput()
+	if err != nil {
+		return fmt.Errorf("failed to run mklink %v %v: %v %q", dst, sourcePath, err, output)
+	}
+
+	return nil
+}
+
+func (g *FileGetter) GetFile(dst string, u *url.URL) error {
+	path := u.Path
+	if u.RawPath != "" {
+		path = u.RawPath
+	}
+
+	// The source path must exist and be a directory to be usable.
+	if fi, err := os.Stat(path); err != nil {
+		return fmt.Errorf("source path error: %s", err)
+	} else if fi.IsDir() {
+		return fmt.Errorf("source path must be a file")
+	}
+
+	_, err := os.Lstat(dst)
+	if err != nil && !os.IsNotExist(err) {
+		return err
+	}
+
+	// If the destination already exists, it must be a symlink
+	if err == nil {
+		// Remove the destination
+		if err := os.Remove(dst); err != nil {
+			return err
+		}
+	}
+
+	// Create all the parent directories
+	if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
+		return err
+	}
+
+	// If we're not copying, just symlink and we're done
+	if !g.Copy {
+		return os.Symlink(path, dst)
+	}
+
+	// Copy
+	srcF, err := os.Open(path)
+	if err != nil {
+		return err
+	}
+	defer srcF.Close()
+
+	dstF, err := os.Create(dst)
+	if err != nil {
+		return err
+	}
+	defer dstF.Close()
+
+	_, err = io.Copy(dstF, srcF)
+	return err
+}
+
+// toBackslash returns the result of replacing each slash character
+// in path with a backslash ('\') character. Multiple separators are
+// replaced by multiple backslashes.
+func toBackslash(path string) string {
+	return strings.Replace(path, "/", "\\", -1)
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/get_git.go b/vendor/github.com/jesseduffield/go-getter/get_git.go
new file mode 100644
index 000000000..48df5f1a6
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/get_git.go
@@ -0,0 +1,241 @@
+package getter
+
+import (
+	"encoding/base64"
+	"fmt"
+	"io/ioutil"
+	"net/url"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+
+	urlhelper "github.com/hashicorp/go-getter/helper/url"
+	"github.com/hashicorp/go-safetemp"
+	"github.com/hashicorp/go-version"
+)
+
+// GitGetter is a Getter implementation that will download a module from
+// a git repository.
+type GitGetter struct{}
+
+func (g *GitGetter) ClientMode(_ *url.URL) (ClientMode, error) {
+	return ClientModeDir, nil
+}
+
+func (g *GitGetter) Get(dst string, u *url.URL) error {
+	if _, err := exec.LookPath("git"); err != nil {
+		return fmt.Errorf("git must be available and on the PATH")
+	}
+
+	// Extract some query parameters we use
+	var ref, sshKey string
+	q := u.Query()
+	if len(q) > 0 {
+		ref = q.Get("ref")
+		q.Del("ref")
+
+		sshKey = q.Get("sshkey")
+		q.Del("sshkey")
+
+		// Copy the URL
+		var newU url.URL = *u
+		u = &newU
+		u.RawQuery = q.Encode()
+	}
+
+	var sshKeyFile string
+	if sshKey != "" {
+		// Check that the git version is sufficiently new.
+		if err := checkGitVersion("2.3"); err != nil {
+			return fmt.Errorf("Error using ssh key: %v", err)
+		}
+
+		// We have an SSH key - decode it.
+		raw, err := base64.StdEncoding.DecodeString(sshKey)
+		if err != nil {
+			return err
+		}
+
+		// Create a temp file for the key and ensure it is removed.
+		fh, err := ioutil.TempFile("", "go-getter")
+		if err != nil {
+			return err
+		}
+		sshKeyFile = fh.Name()
+		defer os.Remove(sshKeyFile)
+
+		// Set the permissions prior to writing the key material.
+		if err := os.Chmod(sshKeyFile, 0600); err != nil {
+			return err
+		}
+
+		// Write the raw key into the temp file.
+		_, err = fh.Write(raw)
+		fh.Close()
+		if err != nil {
+			return err
+		}
+	}
+
+	// Clone or update the repository
+	_, err := os.Stat(dst)
+	if err != nil && !os.IsNotExist(err) {
+		return err
+	}
+	if err == nil {
+		err = g.update(dst, sshKeyFile, ref)
+	} else {
+		err = g.clone(dst, sshKeyFile, u)
+	}
+	if err != nil {
+		return err
+	}
+
+	// Next: check out the proper tag/branch if it is specified, and checkout
+	if ref != "" {
+		if err := g.checkout(dst, ref); err != nil {
+			return err
+		}
+	}
+
+	// Lastly, download any/all submodules.
+	return g.fetchSubmodules(dst, sshKeyFile)
+}
+
+// GetFile for Git doesn't support updating at this time. It will download
+// the file every time.
+func (g *GitGetter) GetFile(dst string, u *url.URL) error {
+	td, tdcloser, err := safetemp.Dir("", "getter")
+	if err != nil {
+		return err
+	}
+	defer tdcloser.Close()
+
+	// Get the filename, and strip the filename from the URL so we can
+	// just get the repository directly.
+	filename := filepath.Base(u.Path)
+	u.Path = filepath.Dir(u.Path)
+
+	// Get the full repository
+	if err := g.Get(td, u); err != nil {
+		return err
+	}
+
+	// Copy the single file
+	u, err = urlhelper.Parse(fmtFileURL(filepath.Join(td, filename)))
+	if err != nil {
+		return err
+	}
+
+	fg := &FileGetter{Copy: true}
+	return fg.GetFile(dst, u)
+}
+
+func (g *GitGetter) checkout(dst string, ref string) error {
+	cmd := exec.Command("git", "checkout", ref)
+	cmd.Dir = dst
+	return getRunCommand(cmd)
+}
+
+func (g *GitGetter) clone(dst, sshKeyFile string, u *url.URL) error {
+	cmd := exec.Command("git", "clone", u.String(), dst)
+	setupGitEnv(cmd, sshKeyFile)
+	return getRunCommand(cmd)
+}
+
+func (g *GitGetter) update(dst, sshKeyFile, ref string) error {
+	// Determine if we're a branch. If we're NOT a branch, then we just
+	// switch to master prior to checking out
+	cmd := exec.Command("git", "show-ref", "-q", "--verify", "refs/heads/"+ref)
+	cmd.Dir = dst
+
+	if getRunCommand(cmd) != nil {
+		// Not a branch, switch to master. This will also catch non-existent
+		// branches, in which case we want to switch to master and then
+		// checkout the proper branch later.
+		ref = "master"
+	}
+
+	// We have to be on a branch to pull
+	if err := g.checkout(dst, ref); err != nil {
+		return err
+	}
+
+	cmd = exec.Command("git", "pull", "--ff-only")
+	cmd.Dir = dst
+	setupGitEnv(cmd, sshKeyFile)
+	return getRunCommand(cmd)
+}
+
+// fetchSubmodules downloads any configured submodules recursively.
+func (g *GitGetter) fetchSubmodules(dst, sshKeyFile string) error {
+	cmd := exec.Command("git", "submodule", "update", "--init", "--recursive")
+	cmd.Dir = dst
+	setupGitEnv(cmd, sshKeyFile)
+	return getRunCommand(cmd)
+}
+
+// setupGitEnv sets up the environment for the given command. This is used to
+// pass configuration data to git and ssh and enables advanced cloning methods.
+func setupGitEnv(cmd *exec.Cmd, sshKeyFile string) {
+	const gitSSHCommand = "GIT_SSH_COMMAND="
+	var sshCmd []string
+
+	// If we have an existing GIT_SSH_COMMAND, we need to append our options.
+	// We will also remove our old entry to make sure the behavior is the same
+	// with versions of Go < 1.9.
+	env := os.Environ()
+	for i, v := range env {
+		if strings.HasPrefix(v, gitSSHCommand) {
+			sshCmd = []string{v}
+
+			env[i], env[len(env)-1] = env[len(env)-1], env[i]
+			env = env[:len(env)-1]
+			break
+		}
+	}
+
+	if len(sshCmd) == 0 {
+		sshCmd = []string{gitSSHCommand + "ssh"}
+	}
+
+	if sshKeyFile != "" {
+		// We have an SSH key temp file configured, tell ssh about this.
+		sshCmd = append(sshCmd, "-i", sshKeyFile)
+	}
+
+	env = append(env, strings.Join(sshCmd, " "))
+	cmd.Env = env
+}
+
+// checkGitVersion is used to check the version of git installed on the system
+// against a known minimum version. Returns an error if the installed version
+// is older than the given minimum.
+func checkGitVersion(min string) error {
+	want, err := version.NewVersion(min)
+	if err != nil {
+		return err
+	}
+
+	out, err := exec.Command("git", "version").Output()
+	if err != nil {
+		return err
+	}
+
+	fields := strings.Fields(string(out))
+	if len(fields) < 3 {
+		return fmt.Errorf("Unexpected 'git version' output: %q", string(out))
+	}
+
+	have, err := version.NewVersion(fields[2])
+	if err != nil {
+		return err
+	}
+
+	if have.LessThan(want) {
+		return fmt.Errorf("Required git version = %s, have %s", want, have)
+	}
+
+	return nil
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/get_hg.go b/vendor/github.com/jesseduffield/go-getter/get_hg.go
new file mode 100644
index 000000000..f38692270
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/get_hg.go
@@ -0,0 +1,131 @@
+package getter
+
+import (
+	"fmt"
+	"net/url"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+
+	urlhelper "github.com/hashicorp/go-getter/helper/url"
+	"github.com/hashicorp/go-safetemp"
+)
+
+// HgGetter is a Getter implementation that will download a module from
+// a Mercurial repository.
+type HgGetter struct{}
+
+func (g *HgGetter) ClientMode(_ *url.URL) (ClientMode, error) {
+	return ClientModeDir, nil
+}
+
+func (g *HgGetter) Get(dst string, u *url.URL) error {
+	if _, err := exec.LookPath("hg"); err != nil {
+		return fmt.Errorf("hg must be available and on the PATH")
+	}
+
+	newURL, err := urlhelper.Parse(u.String())
+	if err != nil {
+		return err
+	}
+	if fixWindowsDrivePath(newURL) {
+		// See valid file path form on http://www.selenic.com/hg/help/urls
+		newURL.Path = fmt.Sprintf("/%s", newURL.Path)
+	}
+
+	// Extract some query parameters we use
+	var rev string
+	q := newURL.Query()
+	if len(q) > 0 {
+		rev = q.Get("rev")
+		q.Del("rev")
+
+		newURL.RawQuery = q.Encode()
+	}
+
+	_, err = os.Stat(dst)
+	if err != nil && !os.IsNotExist(err) {
+		return err
+	}
+	if err != nil {
+		if err := g.clone(dst, newURL); err != nil {
+			return err
+		}
+	}
+
+	if err := g.pull(dst, newURL); err != nil {
+		return err
+	}
+
+	return g.update(dst, newURL, rev)
+}
+
+// GetFile for Hg doesn't support updating at this time. It will download
+// the file every time.
+func (g *HgGetter) GetFile(dst string, u *url.URL) error {
+	// Create a temporary directory to store the full source. This has to be
+	// a non-existent directory.
+	td, tdcloser, err := safetemp.Dir("", "getter")
+	if err != nil {
+		return err
+	}
+	defer tdcloser.Close()
+
+	// Get the filename, and strip the filename from the URL so we can
+	// just get the repository directly.
+	filename := filepath.Base(u.Path)
+	u.Path = filepath.ToSlash(filepath.Dir(u.Path))
+
+	// If we're on Windows, we need to set the host to "localhost" for hg
+	if runtime.GOOS == "windows" {
+		u.Host = "localhost"
+	}
+
+	// Get the full repository
+	if err := g.Get(td, u); err != nil {
+		return err
+	}
+
+	// Copy the single file
+	u, err = urlhelper.Parse(fmtFileURL(filepath.Join(td, filename)))
+	if err != nil {
+		return err
+	}
+
+	fg := &FileGetter{Copy: true}
+	return fg.GetFile(dst, u)
+}
+
+func (g *HgGetter) clone(dst string, u *url.URL) error {
+	cmd := exec.Command("hg", "clone", "-U", u.String(), dst)
+	return getRunCommand(cmd)
+}
+
+func (g *HgGetter) pull(dst string, u *url.URL) error {
+	cmd := exec.Command("hg", "pull")
+	cmd.Dir = dst
+	return getRunCommand(cmd)
+}
+
+func (g *HgGetter) update(dst string, u *url.URL, rev string) error {
+	args := []string{"update"}
+	if rev != "" {
+		args = append(args, rev)
+	}
+
+	cmd := exec.Command("hg", args...)
+	cmd.Dir = dst
+	return getRunCommand(cmd)
+}
+
+func fixWindowsDrivePath(u *url.URL) bool {
+	// hg assumes a file:/// prefix for Windows drive letter file paths.
+	// (e.g. file:///c:/foo/bar)
+	// If the URL Path does not begin with a '/' character, the resulting URL
+	// path will have a file:// prefix. (e.g. file://c:/foo/bar)
+	// See http://www.selenic.com/hg/help/urls and the examples listed in
+	// http://selenic.com/repo/hg-stable/file/1265a3a71d75/mercurial/util.py#l1936
+	return runtime.GOOS == "windows" && u.Scheme == "file" &&
+		len(u.Path) > 1 && u.Path[0] != '/' && u.Path[1] == ':'
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/get_http.go b/vendor/github.com/jesseduffield/go-getter/get_http.go
new file mode 100644
index 000000000..358151a9c
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/get_http.go
@@ -0,0 +1,250 @@
+package getter
+
+import (
+	"encoding/xml"
+	"fmt"
+	"io"
+	"net/http"
+	"net/url"
+	"os"
+	"path/filepath"
+	"strings"
+
+	"github.com/hashicorp/go-safetemp"
+)
+
+// HttpGetter is a Getter implementation that will download from an HTTP
+// endpoint.
+//
+// For file downloads, HTTP is used directly.
+//
+// The protocol for downloading a directory from an HTTP endpoing is as follows:
+//
+// An HTTP GET request is made to the URL with the additional GET parameter
+// "terraform-get=1". This lets you handle that scenario specially if you
+// wish. The response must be a 2xx.
+//
+// First, a header is looked for "X-Terraform-Get" which should contain
+// a source URL to download.
+//
+// If the header is not present, then a meta tag is searched for named
+// "terraform-get" and the content should be a source URL.
+//
+// The source URL, whether from the header or meta tag, must be a fully
+// formed URL. The shorthand syntax of "github.com/foo/bar" or relative
+// paths are not allowed.
+type HttpGetter struct {
+	// Netrc, if true, will lookup and use auth information found
+	// in the user's netrc file if available.
+	Netrc bool
+
+	// Client is the http.Client to use for Get requests.
+	// This defaults to a cleanhttp.DefaultClient if left unset.
+	Client *http.Client
+}
+
+func (g *HttpGetter) ClientMode(u *url.URL) (ClientMode, error) {
+	if strings.HasSuffix(u.Path, "/") {
+		return ClientModeDir, nil
+	}
+	return ClientModeFile, nil
+}
+
+func (g *HttpGetter) Get(dst string, u *url.URL) error {
+	// Copy the URL so we can modify it
+	var newU url.URL = *u
+	u = &newU
+
+	if g.Netrc {
+		// Add auth from netrc if we can
+		if err := addAuthFromNetrc(u); err != nil {
+			return err
+		}
+	}
+
+	if g.Client == nil {
+		g.Client = httpClient
+	}
+
+	// Add terraform-get to the parameter.
+	q := u.Query()
+	q.Add("terraform-get", "1")
+	u.RawQuery = q.Encode()
+
+	// Get the URL
+	resp, err := g.Client.Get(u.String())
+	if err != nil {
+		return err
+	}
+	defer resp.Body.Close()
+	if resp.StatusCode < 200 || resp.StatusCode >= 300 {
+		return fmt.Errorf("bad response code: %d", resp.StatusCode)
+	}
+
+	// Extract the source URL
+	var source string
+	if v := resp.Header.Get("X-Terraform-Get"); v != "" {
+		source = v
+	} else {
+		source, err = g.parseMeta(resp.Body)
+		if err != nil {
+			source = u.String() // xml parse errors are getting in the way of our downloads
+		}
+	}
+	if source == "" {
+		return fmt.Errorf("no source URL was returned")
+	}
+
+	// If there is a subdir component, then we download the root separately
+	// into a temporary directory, then copy over the proper subdir.
+	source, subDir := SourceDirSubdir(source)
+	if subDir == "" {
+		return Get(dst, source)
+	}
+
+	// We have a subdir, time to jump some hoops
+	return g.getSubdir(dst, source, subDir)
+}
+
+func (g *HttpGetter) GetFile(dst string, u *url.URL) error {
+	if g.Netrc {
+		// Add auth from netrc if we can
+		if err := addAuthFromNetrc(u); err != nil {
+			return err
+		}
+	}
+
+	if g.Client == nil {
+		g.Client = httpClient
+	}
+
+	resp, err := g.Client.Get(u.String())
+	if err != nil {
+		return err
+	}
+	defer resp.Body.Close()
+	if resp.StatusCode != 200 {
+		return fmt.Errorf("bad response code: %d", resp.StatusCode)
+	}
+
+	// Create all the parent directories
+	if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
+		return err
+	}
+
+	f, err := os.Create(dst)
+	if err != nil {
+		return err
+	}
+
+	n, err := io.Copy(f, resp.Body)
+	if err == nil && n < resp.ContentLength {
+		err = io.ErrShortWrite
+	}
+	if err1 := f.Close(); err == nil {
+		err = err1
+	}
+	return err
+}
+
+// getSubdir downloads the source into the destination, but with
+// the proper subdir.
+func (g *HttpGetter) getSubdir(dst, source, subDir string) error {
+	// Create a temporary directory to store the full source. This has to be
+	// a non-existent directory.
+	td, tdcloser, err := safetemp.Dir("", "getter")
+	if err != nil {
+		return err
+	}
+	defer tdcloser.Close()
+
+	// Download that into the given directory
+	if err := Get(td, source); err != nil {
+		return err
+	}
+
+	// Process any globbing
+	sourcePath, err := SubdirGlob(td, subDir)
+	if err != nil {
+		return err
+	}
+
+	// Make sure the subdir path actually exists
+	if _, err := os.Stat(sourcePath); err != nil {
+		return fmt.Errorf(
+			"Error downloading %s: %s", source, err)
+	}
+
+	// Copy the subdirectory into our actual destination.
+	if err := os.RemoveAll(dst); err != nil {
+		return err
+	}
+
+	// Make the final destination
+	if err := os.MkdirAll(dst, 0755); err != nil {
+		return err
+	}
+
+	return copyDir(dst, sourcePath, false)
+}
+
+// parseMeta looks for the first meta tag in the given reader that
+// will give us the source URL.
+func (g *HttpGetter) parseMeta(r io.Reader) (string, error) {
+	d := xml.NewDecoder(r)
+	d.CharsetReader = charsetReader
+	d.Strict = false
+	var err error
+	var t xml.Token
+	for {
+		t, err = d.Token()
+		if err != nil {
+			if err == io.EOF {
+				err = nil
+			}
+			return "", err
+		}
+		if e, ok := t.(xml.StartElement); ok && strings.EqualFold(e.Name.Local, "body") {
+			return "", nil
+		}
+		if e, ok := t.(xml.EndElement); ok && strings.EqualFold(e.Name.Local, "head") {
+			return "", nil
+		}
+		e, ok := t.(xml.StartElement)
+		if !ok || !strings.EqualFold(e.Name.Local, "meta") {
+			continue
+		}
+		if attrValue(e.Attr, "name") != "terraform-get" {
+			continue
+		}
+		if f := attrValue(e.Attr, "content"); f != "" {
+			return f, nil
+		}
+	}
+}
+
+// attrValue returns the attribute value for the case-insensitive key
+// `name', or the empty string if nothing is found.
+func attrValue(attrs []xml.Attr, name string) string {
+	for _, a := range attrs {
+		if strings.EqualFold(a.Name.Local, name) {
+			return a.Value
+		}
+	}
+	return ""
+}
+
+// charsetReader returns a reader for the given charset. Currently
+// it only supports UTF-8 and ASCII. Otherwise, it returns a meaningful
+// error which is printed by go get, so the user can find why the package
+// wasn't downloaded if the encoding is not supported. Note that, in
+// order to reduce potential errors, ASCII is treated as UTF-8 (i.e. characters
+// greater than 0x7f are not rejected).
+func charsetReader(charset string, input io.Reader) (io.Reader, error) {
+	switch strings.ToLower(charset) {
+	case "ascii":
+		return input, nil
+	default:
+		return nil, fmt.Errorf("can't decode XML document using charset %q", charset)
+	}
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/get_mock.go b/vendor/github.com/jesseduffield/go-getter/get_mock.go
new file mode 100644
index 000000000..882e694dc
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/get_mock.go
@@ -0,0 +1,52 @@
+package getter
+
+import (
+	"net/url"
+)
+
+// MockGetter is an implementation of Getter that can be used for tests.
+type MockGetter struct {
+	// Proxy, if set, will be called after recording the calls below.
+	// If it isn't set, then the *Err values will be returned.
+	Proxy Getter
+
+	GetCalled bool
+	GetDst    string
+	GetURL    *url.URL
+	GetErr    error
+
+	GetFileCalled bool
+	GetFileDst    string
+	GetFileURL    *url.URL
+	GetFileErr    error
+}
+
+func (g *MockGetter) Get(dst string, u *url.URL) error {
+	g.GetCalled = true
+	g.GetDst = dst
+	g.GetURL = u
+
+	if g.Proxy != nil {
+		return g.Proxy.Get(dst, u)
+	}
+
+	return g.GetErr
+}
+
+func (g *MockGetter) GetFile(dst string, u *url.URL) error {
+	g.GetFileCalled = true
+	g.GetFileDst = dst
+	g.GetFileURL = u
+
+	if g.Proxy != nil {
+		return g.Proxy.GetFile(dst, u)
+	}
+	return g.GetFileErr
+}
+
+func (g *MockGetter) ClientMode(u *url.URL) (ClientMode, error) {
+	if l := len(u.Path); l > 0 && u.Path[l-1:] == "/" {
+		return ClientModeDir, nil
+	}
+	return ClientModeFile, nil
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/get_s3.go b/vendor/github.com/jesseduffield/go-getter/get_s3.go
new file mode 100644
index 000000000..ebb321741
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/get_s3.go
@@ -0,0 +1,270 @@
+package getter
+
+import (
+	"fmt"
+	"io"
+	"net/url"
+	"os"
+	"path/filepath"
+	"strings"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/credentials"
+	"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
+	"github.com/aws/aws-sdk-go/aws/ec2metadata"
+	"github.com/aws/aws-sdk-go/aws/session"
+	"github.com/aws/aws-sdk-go/service/s3"
+)
+
+// S3Getter is a Getter implementation that will download a module from
+// a S3 bucket.
+type S3Getter struct{}
+
+func (g *S3Getter) ClientMode(u *url.URL) (ClientMode, error) {
+	// Parse URL
+	region, bucket, path, _, creds, err := g.parseUrl(u)
+	if err != nil {
+		return 0, err
+	}
+
+	// Create client config
+	config := g.getAWSConfig(region, u, creds)
+	sess := session.New(config)
+	client := s3.New(sess)
+
+	// List the object(s) at the given prefix
+	req := &s3.ListObjectsInput{
+		Bucket: aws.String(bucket),
+		Prefix: aws.String(path),
+	}
+	resp, err := client.ListObjects(req)
+	if err != nil {
+		return 0, err
+	}
+
+	for _, o := range resp.Contents {
+		// Use file mode on exact match.
+		if *o.Key == path {
+			return ClientModeFile, nil
+		}
+
+		// Use dir mode if child keys are found.
+		if strings.HasPrefix(*o.Key, path+"/") {
+			return ClientModeDir, nil
+		}
+	}
+
+	// There was no match, so just return file mode. The download is going
+	// to fail but we will let S3 return the proper error later.
+	return ClientModeFile, nil
+}
+
+func (g *S3Getter) Get(dst string, u *url.URL) error {
+	// Parse URL
+	region, bucket, path, _, creds, err := g.parseUrl(u)
+	if err != nil {
+		return err
+	}
+
+	// Remove destination if it already exists
+	_, err = os.Stat(dst)
+	if err != nil && !os.IsNotExist(err) {
+		return err
+	}
+
+	if err == nil {
+		// Remove the destination
+		if err := os.RemoveAll(dst); err != nil {
+			return err
+		}
+	}
+
+	// Create all the parent directories
+	if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
+		return err
+	}
+
+	config := g.getAWSConfig(region, u, creds)
+	sess := session.New(config)
+	client := s3.New(sess)
+
+	// List files in path, keep listing until no more objects are found
+	lastMarker := ""
+	hasMore := true
+	for hasMore {
+		req := &s3.ListObjectsInput{
+			Bucket: aws.String(bucket),
+			Prefix: aws.String(path),
+		}
+		if lastMarker != "" {
+			req.Marker = aws.String(lastMarker)
+		}
+
+		resp, err := client.ListObjects(req)
+		if err != nil {
+			return err
+		}
+
+		hasMore = aws.BoolValue(resp.IsTruncated)
+
+		// Get each object storing each file relative to the destination path
+		for _, object := range resp.Contents {
+			lastMarker = aws.StringValue(object.Key)
+			objPath := aws.StringValue(object.Key)
+
+			// If the key ends with a backslash assume it is a directory and ignore
+			if strings.HasSuffix(objPath, "/") {
+				continue
+			}
+
+			// Get the object destination path
+			objDst, err := filepath.Rel(path, objPath)
+			if err != nil {
+				return err
+			}
+			objDst = filepath.Join(dst, objDst)
+
+			if err := g.getObject(client, objDst, bucket, objPath, ""); err != nil {
+				return err
+			}
+		}
+	}
+
+	return nil
+}
+
+func (g *S3Getter) GetFile(dst string, u *url.URL) error {
+	region, bucket, path, version, creds, err := g.parseUrl(u)
+	if err != nil {
+		return err
+	}
+
+	config := g.getAWSConfig(region, u, creds)
+	sess := session.New(config)
+	client := s3.New(sess)
+	return g.getObject(client, dst, bucket, path, version)
+}
+
+func (g *S3Getter) getObject(client *s3.S3, dst, bucket, key, version string) error {
+	req := &s3.GetObjectInput{
+		Bucket: aws.String(bucket),
+		Key:    aws.String(key),
+	}
+	if version != "" {
+		req.VersionId = aws.String(version)
+	}
+
+	resp, err := client.GetObject(req)
+	if err != nil {
+		return err
+	}
+
+	// Create all the parent directories
+	if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
+		return err
+	}
+
+	f, err := os.Create(dst)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+
+	_, err = io.Copy(f, resp.Body)
+	return err
+}
+
+func (g *S3Getter) getAWSConfig(region string, url *url.URL, creds *credentials.Credentials) *aws.Config {
+	conf := &aws.Config{}
+	if creds == nil {
+		// Grab the metadata URL
+		metadataURL := os.Getenv("AWS_METADATA_URL")
+		if metadataURL == "" {
+			metadataURL = "http://169.254.169.254:80/latest"
+		}
+
+		creds = credentials.NewChainCredentials(
+			[]credentials.Provider{
+				&credentials.EnvProvider{},
+				&credentials.SharedCredentialsProvider{Filename: "", Profile: ""},
+				&ec2rolecreds.EC2RoleProvider{
+					Client: ec2metadata.New(session.New(&aws.Config{
+						Endpoint: aws.String(metadataURL),
+					})),
+				},
+			})
+	}
+
+	if creds != nil {
+		conf.Endpoint = &url.Host
+		conf.S3ForcePathStyle = aws.Bool(true)
+		if url.Scheme == "http" {
+			conf.DisableSSL = aws.Bool(true)
+		}
+	}
+
+	conf.Credentials = creds
+	if region != "" {
+		conf.Region = aws.String(region)
+	}
+
+	return conf
+}
+
+func (g *S3Getter) parseUrl(u *url.URL) (region, bucket, path, version string, creds *credentials.Credentials, err error) {
+	// This just check whether we are dealing with S3 or
+	// any other S3 compliant service. S3 has a predictable
+	// url as others do not
+	if strings.Contains(u.Host, "amazonaws.com") {
+		// Expected host style: s3.amazonaws.com. They always have 3 parts,
+		// although the first may differ if we're accessing a specific region.
+		hostParts := strings.Split(u.Host, ".")
+		if len(hostParts) != 3 {
+			err = fmt.Errorf("URL is not a valid S3 URL")
+			return
+		}
+
+		// Parse the region out of the first part of the host
+		region = strings.TrimPrefix(strings.TrimPrefix(hostParts[0], "s3-"), "s3")
+		if region == "" {
+			region = "us-east-1"
+		}
+
+		pathParts := strings.SplitN(u.Path, "/", 3)
+		if len(pathParts) != 3 {
+			err = fmt.Errorf("URL is not a valid S3 URL")
+			return
+		}
+
+		bucket = pathParts[1]
+		path = pathParts[2]
+		version = u.Query().Get("version")
+
+	} else {
+		pathParts := strings.SplitN(u.Path, "/", 3)
+		if len(pathParts) != 3 {
+			err = fmt.Errorf("URL is not a valid S3 complaint URL")
+			return
+		}
+		bucket = pathParts[1]
+		path = pathParts[2]
+		version = u.Query().Get("version")
+		region = u.Query().Get("region")
+		if region == "" {
+			region = "us-east-1"
+		}
+	}
+
+	_, hasAwsId := u.Query()["aws_access_key_id"]
+	_, hasAwsSecret := u.Query()["aws_access_key_secret"]
+	_, hasAwsToken := u.Query()["aws_access_token"]
+	if hasAwsId || hasAwsSecret || hasAwsToken {
+		creds = credentials.NewStaticCredentials(
+			u.Query().Get("aws_access_key_id"),
+			u.Query().Get("aws_access_key_secret"),
+			u.Query().Get("aws_access_token"),
+		)
+	}
+
+	return
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/netrc.go b/vendor/github.com/jesseduffield/go-getter/netrc.go
new file mode 100644
index 000000000..c7f6a3fb3
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/netrc.go
@@ -0,0 +1,67 @@
+package getter
+
+import (
+	"fmt"
+	"net/url"
+	"os"
+	"runtime"
+
+	"github.com/bgentry/go-netrc/netrc"
+	"github.com/mitchellh/go-homedir"
+)
+
+// addAuthFromNetrc adds auth information to the URL from the user's
+// netrc file if it can be found. This will only add the auth info
+// if the URL doesn't already have auth info specified and the
+// the username is blank.
+func addAuthFromNetrc(u *url.URL) error {
+	// If the URL already has auth information, do nothing
+	if u.User != nil && u.User.Username() != "" {
+		return nil
+	}
+
+	// Get the netrc file path
+	path := os.Getenv("NETRC")
+	if path == "" {
+		filename := ".netrc"
+		if runtime.GOOS == "windows" {
+			filename = "_netrc"
+		}
+
+		var err error
+		path, err = homedir.Expand("~/" + filename)
+		if err != nil {
+			return err
+		}
+	}
+
+	// If the file is not a file, then do nothing
+	if fi, err := os.Stat(path); err != nil {
+		// File doesn't exist, do nothing
+		if os.IsNotExist(err) {
+			return nil
+		}
+
+		// Some other error!
+		return err
+	} else if fi.IsDir() {
+		// File is directory, ignore
+		return nil
+	}
+
+	// Load up the netrc file
+	net, err := netrc.ParseFile(path)
+	if err != nil {
+		return fmt.Errorf("Error parsing netrc file at %q: %s", path, err)
+	}
+
+	machine := net.FindMachine(u.Host)
+	if machine == nil {
+		// Machine not found, no problem
+		return nil
+	}
+
+	// Set the user info
+	u.User = url.UserPassword(machine.Login, machine.Password)
+	return nil
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/source.go b/vendor/github.com/jesseduffield/go-getter/source.go
new file mode 100644
index 000000000..c63f2bbaf
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/source.go
@@ -0,0 +1,62 @@
+package getter
+
+import (
+	"fmt"
+	"path/filepath"
+	"strings"
+)
+
+// SourceDirSubdir takes a source and returns a tuple of the URL without
+// the subdir and the URL with the subdir.
+func SourceDirSubdir(src string) (string, string) {
+	// Calcaulate an offset to avoid accidentally marking the scheme
+	// as the dir.
+	var offset int
+	if idx := strings.Index(src, "://"); idx > -1 {
+		offset = idx + 3
+	}
+
+	// First see if we even have an explicit subdir
+	idx := strings.Index(src[offset:], "//")
+	if idx == -1 {
+		return src, ""
+	}
+
+	idx += offset
+	subdir := src[idx+2:]
+	src = src[:idx]
+
+	// Next, check if we have query parameters and push them onto the
+	// URL.
+	if idx = strings.Index(subdir, "?"); idx > -1 {
+		query := subdir[idx:]
+		subdir = subdir[:idx]
+		src += query
+	}
+
+	return src, subdir
+}
+
+// SubdirGlob returns the actual subdir with globbing processed.
+//
+// dst should be a destination directory that is already populated (the
+// download is complete) and subDir should be the set subDir. If subDir
+// is an empty string, this returns an empty string.
+//
+// The returned path is the full absolute path.
+func SubdirGlob(dst, subDir string) (string, error) {
+	matches, err := filepath.Glob(filepath.Join(dst, subDir))
+	if err != nil {
+		return "", err
+	}
+
+	if len(matches) == 0 {
+		return "", fmt.Errorf("subdir %q not found", subDir)
+	}
+
+	if len(matches) > 1 {
+		return "", fmt.Errorf("subdir %q matches multiple paths", subDir)
+	}
+
+	return matches[0], nil
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/storage.go b/vendor/github.com/jesseduffield/go-getter/storage.go
new file mode 100644
index 000000000..2bc6b9ec3
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/storage.go
@@ -0,0 +1,13 @@
+package getter
+
+// Storage is an interface that knows how to lookup downloaded directories
+// as well as download and update directories from their sources into the
+// proper location.
+type Storage interface {
+	// Dir returns the directory on local disk where the directory source
+	// can be loaded from.
+	Dir(string) (string, bool, error)
+
+	// Get will download and optionally update the given directory.
+	Get(string, string, bool) error
+}
diff --git a/vendor/github.com/jesseduffield/go-getter/test-fixtures/detect-file-symlink-pwd/syml/pwd b/vendor/github.com/jesseduffield/go-getter/test-fixtures/detect-file-symlink-pwd/syml/pwd
new file mode 120000
index 000000000..05b44e001
--- /dev/null
+++ b/vendor/github.com/jesseduffield/go-getter/test-fixtures/detect-file-symlink-pwd/syml/pwd
@@ -0,0 +1 @@
+../real
\ No newline at end of file
diff --git a/vendor/github.com/jesseduffield/gocui/edit.go b/vendor/github.com/jesseduffield/gocui/edit.go
index e1b19c20b..c339d75fb 100644
--- a/vendor/github.com/jesseduffield/gocui/edit.go
+++ b/vendor/github.com/jesseduffield/gocui/edit.go
@@ -4,7 +4,11 @@
 
 package gocui
 
-import "errors"
+import (
+	"errors"
+
+	"github.com/mattn/go-runewidth"
+)
 
 const maxInt = int(^uint(0) >> 1)
 
@@ -54,8 +58,9 @@ func simpleEditor(v *View, key Key, ch rune, mod Modifier) {
 
 // EditWrite writes a rune at the cursor position.
 func (v *View) EditWrite(ch rune) {
+	w := runewidth.RuneWidth(ch)
 	v.writeRune(v.cx, v.cy, ch)
-	v.MoveCursor(1, 0, true)
+	v.moveCursor(w, 0, true)
 }
 
 // EditDelete deletes a rune at the cursor position. back determines the
@@ -89,12 +94,12 @@ func (v *View) EditDelete(back bool) {
 					v.MoveCursor(-1, 0, true)
 				}
 			} else { // wrapped line
-				v.deleteRune(len(v.viewLines[y-1].line)-1, v.cy-1)
-				v.MoveCursor(-1, 0, true)
+				n, _ := v.deleteRune(len(v.viewLines[y-1].line)-1, v.cy-1)
+				v.MoveCursor(-n, 0, true)
 			}
 		} else { // middle/end of the line
-			v.deleteRune(v.cx-1, v.cy)
-			v.MoveCursor(-1, 0, true)
+			n, _ := v.deleteRune(v.cx-1, v.cy)
+			v.MoveCursor(-n, 0, true)
 		}
 	} else {
 		if x == len(v.viewLines[y].line) { // end of the line
@@ -109,42 +114,81 @@ func (v *View) EditDelete(back bool) {
 func (v *View) EditNewLine() {
 	v.breakLine(v.cx, v.cy)
 	v.ox = 0
+	v.cy = v.cy + 1
 	v.cx = 0
-	v.MoveCursor(0, 1, true)
 }
 
 // MoveCursor moves the cursor taking into account the width of the line/view,
 // displacing the origin if necessary.
 func (v *View) MoveCursor(dx, dy int, writeMode bool) {
+	ox, oy := v.cx+v.ox, v.cy+v.oy
+	x, y := ox+dx, oy+dy
+
+	if y < 0 || y >= len(v.viewLines) {
+		v.moveCursor(dx, dy, writeMode)
+		return
+	}
+
+	// Removing newline.
+	if x < 0 {
+		var prevLen int
+		if y-1 >= 0 && y-1 < len(v.viewLines) {
+			prevLen = lineWidth(v.viewLines[y-1].line)
+		}
+
+		v.MoveCursor(prevLen, -1, writeMode)
+		return
+	}
+
+	line := v.viewLines[y].line
+	var col int
+	var prevCol int
+	for i := range line {
+		prevCol = col
+		col += runewidth.RuneWidth(line[i].chr)
+		if dx > 0 {
+			if x <= col {
+				x = col
+				break
+			}
+			continue
+		}
+
+		if x < col {
+			x = prevCol
+			break
+		}
+	}
+
+	v.moveCursor(x-ox, y-oy, writeMode)
+}
+
+func (v *View) moveCursor(dx, dy int, writeMode bool) {
 	maxX, maxY := v.Size()
 	cx, cy := v.cx+dx, v.cy+dy
 	x, y := v.ox+cx, v.oy+cy
 
 	var curLineWidth, prevLineWidth int
 	// get the width of the current line
-	if writeMode {
-		if v.Wrap {
-			curLineWidth = maxX - 1
-		} else {
-			curLineWidth = maxInt
-		}
-	} else {
+	curLineWidth = maxInt
+	if v.Wrap {
+		curLineWidth = maxX - 1
+	}
+
+	if !writeMode {
+		curLineWidth = 0
 		if y >= 0 && y < len(v.viewLines) {
-			curLineWidth = len(v.viewLines[y].line)
+			curLineWidth = lineWidth(v.viewLines[y].line)
 			if v.Wrap && curLineWidth >= maxX {
 				curLineWidth = maxX - 1
 			}
-		} else {
-			curLineWidth = 0
 		}
 	}
 	// get the width of the previous line
+	prevLineWidth = 0
 	if y-1 >= 0 && y-1 < len(v.viewLines) {
-		prevLineWidth = len(v.viewLines[y-1].line)
-	} else {
-		prevLineWidth = 0
+		prevLineWidth = lineWidth(v.viewLines[y-1].line)
 	}
-
 	// adjust cursor's x position and view's x origin
 	if x > curLineWidth { // move to next line
 		if dx > 0 { // horizontal movement
@@ -190,10 +234,9 @@ func (v *View) MoveCursor(dx, dy int, writeMode bool) {
 				if !v.Wrap { // set origin so the EOL is visible
 					nox := prevLineWidth - maxX + 1
 					if nox < 0 {
-						v.ox = 0
-					} else {
-						v.ox = nox
+						nox = 0
 					}
+					v.ox = nox
 				}
 				v.cx = prevLineWidth
 			} else {
@@ -275,19 +318,31 @@ func (v *View) writeRune(x, y int, ch rune) error {
 
 // deleteRune removes a rune from the view's internal buffer, at the
 // position corresponding to the point (x, y).
-func (v *View) deleteRune(x, y int) error {
+// returns the amount of columns that where removed.
+func (v *View) deleteRune(x, y int) (int, error) {
 	v.tainted = true
 
 	x, y, err := v.realPosition(x, y)
 	if err != nil {
-		return err
+		return 0, err
 	}
 
 	if x < 0 || y < 0 || y >= len(v.lines) || x >= len(v.lines[y]) {
-		return errors.New("invalid point")
+		return 0, errors.New("invalid point")
 	}
-	v.lines[y] = append(v.lines[y][:x], v.lines[y][x+1:]...)
-	return nil
+
+	var tw int
+	for i := range v.lines[y] {
+		w := runewidth.RuneWidth(v.lines[y][i].chr)
+		tw += w
+		if tw > x {
+			v.lines[y] = append(v.lines[y][:i], v.lines[y][i+1:]...)
+			return w, nil
+		}
+
+	}
+
+	return 0, nil
 }
 
 // mergeLines merges the lines "y" and "y+1" if possible.
diff --git a/vendor/github.com/jesseduffield/gocui/gui.go b/vendor/github.com/jesseduffield/gocui/gui.go
index 28a52d1cd..4393c06c4 100644
--- a/vendor/github.com/jesseduffield/gocui/gui.go
+++ b/vendor/github.com/jesseduffield/gocui/gui.go
@@ -476,6 +476,11 @@ func (g *Gui) flush() error {
 					return err
 				}
 			}
+			if v.Subtitle != "" {
+				if err := g.drawSubtitle(v, fgColor, bgColor); err != nil {
+					return err
+				}
+			}
 		}
 		if err := g.draw(v); err != nil {
 			return err
@@ -582,6 +587,25 @@ func (g *Gui) drawTitle(v *View, fgColor, bgColor Attribute) error {
 	return nil
 }
 
+// drawSubtitle draws the subtitle of the view.
+func (g *Gui) drawSubtitle(v *View, fgColor, bgColor Attribute) error {
+	if v.y0 < 0 || v.y0 >= g.maxY {
+		return nil
+	}
+
+	start := v.x1 - 5 - len(v.Subtitle)
+	for i, ch := range v.Subtitle {
+		x := start + i
+		if x >= v.x1 {
+			break
+		}
+		if err := g.SetRune(x, v.y0, ch, fgColor, bgColor); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
 // draw manages the cursor and calls the draw function of a view.
 func (g *Gui) draw(v *View) error {
 	if g.Cursor {
@@ -653,17 +677,31 @@ func (g *Gui) onKey(ev *termbox.Event) error {
 // execKeybindings executes the keybinding handlers that match the passed view
 // and event. The value of matched is true if there is a match and no errors.
 func (g *Gui) execKeybindings(v *View, ev *termbox.Event) (matched bool, err error) {
-	matched = false
+	var globalKb *keybinding
 	for _, kb := range g.keybindings {
 		if kb.handler == nil {
 			continue
 		}
-		if kb.matchKeypress(Key(ev.Key), ev.Ch, Modifier(ev.Mod)) && kb.matchView(v) {
-			if err := kb.handler(g, v); err != nil {
-				return false, err
-			}
-			matched = true
+		if !kb.matchKeypress(Key(ev.Key), ev.Ch, Modifier(ev.Mod)) {
+			continue
+		}
+		if kb.matchView(v) {
+			return g.execKeybinding(v, kb)
+		}
+		if kb.viewName == "" && (!v.Editable || kb.ch == 0) {
+			globalKb = kb
 		}
 	}
-	return matched, nil
+	if globalKb != nil {
+		return g.execKeybinding(v, globalKb)
+	}
+	return false, nil
+}
+
+// execKeybinding executes a given keybinding
+func (g *Gui) execKeybinding(v *View, kb *keybinding) (bool, error) {
+	if err := kb.handler(g, v); err != nil {
+		return false, err
+	}
+	return true, nil
 }
diff --git a/vendor/github.com/jesseduffield/gocui/keybinding.go b/vendor/github.com/jesseduffield/gocui/keybinding.go
index 7efdb75c6..82d1acc9f 100644
--- a/vendor/github.com/jesseduffield/gocui/keybinding.go
+++ b/vendor/github.com/jesseduffield/gocui/keybinding.go
@@ -38,9 +38,6 @@ func (kb *keybinding) matchView(v *View) bool {
 	if v.Editable == true && kb.ch != 0 {
 		return false
 	}
-	if kb.viewName == "" {
-		return true
-	}
 	return v != nil && kb.viewName == v.name
 }
 
diff --git a/vendor/github.com/jesseduffield/gocui/view.go b/vendor/github.com/jesseduffield/gocui/view.go
index 462cb474e..53ab06f8c 100644
--- a/vendor/github.com/jesseduffield/gocui/view.go
+++ b/vendor/github.com/jesseduffield/gocui/view.go
@@ -10,6 +10,7 @@ import (
 	"io"
 	"strings"
 
+	"github.com/mattn/go-runewidth"
 	"github.com/nsf/termbox-go"
 )
 
@@ -76,6 +77,9 @@ type View struct {
 	// If Frame is true, Title allows to configure a title for the view.
 	Title string
 
+	// If Frame is true, Subtitle allows to configure a subtitle for the view.
+	Subtitle string
+
 	// If Mask is true, the View will display the mask instead of the real
 	// content
 	Mask rune
@@ -312,24 +316,14 @@ func (v *View) draw() error {
 	if v.tainted {
 		v.viewLines = nil
 		for i, line := range v.lines {
+			wrap := 0
 			if v.Wrap {
-				if len(line) < maxX {
-					vline := viewLine{linesX: 0, linesY: i, line: line}
-					v.viewLines = append(v.viewLines, vline)
-					continue
-				} else {
-					for n := 0; n <= len(line); n += maxX {
-						if len(line[n:]) <= maxX {
-							vline := viewLine{linesX: n, linesY: i, line: line[n:]}
-							v.viewLines = append(v.viewLines, vline)
-						} else {
-							vline := viewLine{linesX: n, linesY: i, line: line[n : n+maxX]}
-							v.viewLines = append(v.viewLines, vline)
-						}
-					}
-				}
-			} else {
-				vline := viewLine{linesX: 0, linesY: i, line: line}
+				wrap = maxX
+			}
+
+			ls := lineWrap(line, wrap)
+			for j := range ls {
+				vline := viewLine{linesX: j, linesY: i, line: ls[j]}
 				v.viewLines = append(v.viewLines, vline)
 			}
 		}
@@ -368,7 +362,7 @@ func (v *View) draw() error {
 			if err := v.setRune(x, y, c.chr, fgColor, bgColor); err != nil {
 				return err
 			}
-			x++
+			x += runewidth.RuneWidth(c.chr)
 		}
 		y++
 	}
@@ -438,11 +432,7 @@ func (v *View) BufferLines() []string {
 // Buffer returns a string with the contents of the view's internal
 // buffer.
 func (v *View) Buffer() string {
-	str := ""
-	for _, l := range v.lines {
-		str += lineType(l).String() + "\n"
-	}
-	return strings.Replace(str, "\x00", " ", -1)
+	return linesToString(v.lines)
 }
 
 // ViewBufferLines returns the lines in the view's internal
@@ -460,11 +450,12 @@ func (v *View) ViewBufferLines() []string {
 // ViewBuffer returns a string with the contents of the view's buffer that is
 // shown to the user.
 func (v *View) ViewBuffer() string {
-	str := ""
-	for _, l := range v.viewLines {
-		str += lineType(l.line).String() + "\n"
+	lines := make([][]cell, len(v.viewLines))
+	for i := range v.viewLines {
+		lines[i] = v.viewLines[i].line
 	}
-	return strings.Replace(str, "\x00", " ", -1)
+
+	return linesToString(lines)
 }
 
 // Line returns a string with the line of the view's internal buffer
@@ -516,3 +507,49 @@ func (v *View) Word(x, y int) (string, error) {
 func indexFunc(r rune) bool {
 	return r == ' ' || r == 0
 }
+
+func lineWidth(line []cell) (n int) {
+	for i := range line {
+		n += runewidth.RuneWidth(line[i].chr)
+	}
+
+	return
+}
+
+func lineWrap(line []cell, columns int) [][]cell {
+	if columns == 0 {
+		return [][]cell{line}
+	}
+
+	var n int
+	var offset int
+	lines := make([][]cell, 0, 1)
+	for i := range line {
+		rw := runewidth.RuneWidth(line[i].chr)
+		n += rw
+		if n > columns {
+			n = rw
+			lines = append(lines, line[offset:i-1])
+			offset = i
+		}
+	}
+
+	lines = append(lines, line[offset:])
+	return lines
+}
+
+func linesToString(lines [][]cell) string {
+	str := make([]string, len(lines))
+	for i := range lines {
+		rns := make([]rune, 0, len(lines[i]))
+		line := lineType(lines[i]).String()
+		for _, c := range line {
+			if c != '\x00' {
+				rns = append(rns, c)
+			}
+		}
+		str[i] = string(rns)
+	}
+
+	return strings.Join(str, "\n")
+}
diff --git a/vendor/github.com/jmespath/go-jmespath/LICENSE b/vendor/github.com/jmespath/go-jmespath/LICENSE
new file mode 100644
index 000000000..b03310a91
--- /dev/null
+++ b/vendor/github.com/jmespath/go-jmespath/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2015 James Saryerwinnie
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/vendor/github.com/jmespath/go-jmespath/api.go b/vendor/github.com/jmespath/go-jmespath/api.go
new file mode 100644
index 000000000..9cfa988bc
--- /dev/null
+++ b/vendor/github.com/jmespath/go-jmespath/api.go
@@ -0,0 +1,49 @@
+package jmespath
+
+import "strconv"
+
+// JmesPath is the epresentation of a compiled JMES path query. A JmesPath is
+// safe for concurrent use by multiple goroutines.
+type JMESPath struct {
+	ast  ASTNode
+	intr *treeInterpreter
+}
+
+// Compile parses a JMESPath expression and returns, if successful, a JMESPath
+// object that can be used to match against data.
+func Compile(expression string) (*JMESPath, error) {
+	parser := NewParser()
+	ast, err := parser.Parse(expression)
+	if err != nil {
+		return nil, err
+	}
+	jmespath := &JMESPath{ast: ast, intr: newInterpreter()}
+	return jmespath, nil
+}
+
+// MustCompile is like Compile but panics if the expression cannot be parsed.
+// It simplifies safe initialization of global variables holding compiled
+// JMESPaths.
+func MustCompile(expression string) *JMESPath {
+	jmespath, err := Compile(expression)
+	if err != nil {
+		panic(`jmespath: Compile(` + strconv.Quote(expression) + `): ` + err.Error())
+	}
+	return jmespath
+}
+
+// Search evaluates a JMESPath expression against input data and returns the result.
+func (jp *JMESPath) Search(data interface{}) (interface{}, error) {
+	return jp.intr.Execute(jp.ast, data)
+}
+
+// Search evaluates a JMESPath expression against input data and returns the result.
+func Search(expression string, data interface{}) (interface{}, error) {
+	intr := newInterpreter()
+	parser := NewParser()
+	ast, err := parser.Parse(expression)
+	if err != nil {
+		return nil, err
+	}
+	return intr.Execute(ast, data)
+}
diff --git a/vendor/github.com/jmespath/go-jmespath/astnodetype_string.go b/vendor/github.com/jmespath/go-jmespath/astnodetype_string.go
new file mode 100644
index 000000000..1cd2d239c
--- /dev/null
+++ b/vendor/github.com/jmespath/go-jmespath/astnodetype_string.go
@@ -0,0 +1,16 @@
+// generated by stringer -type astNodeType; DO NOT EDIT
+
+package jmespath
+
+import "fmt"
+
+const _astNodeType_name = "ASTEmptyASTComparatorASTCurrentNodeASTExpRefASTFunctionExpressionASTFieldASTFilterProjectionASTFlattenASTIdentityASTIndexASTIndexExpressionASTKeyValPairASTLiteralASTMultiSelectHashASTMultiSelectListASTOrExpressionASTAndExpressionASTNotExpressionASTPipeASTProjectionASTSubexpressionASTSliceASTValueProjection"
+
+var _astNodeType_index = [...]uint16{0, 8, 21, 35, 44, 65, 73, 92, 102, 113, 121, 139, 152, 162, 180, 198, 213, 229, 245, 252, 265, 281, 289, 307}
+
+func (i astNodeType) String() string {
+	if i < 0 || i >= astNodeType(len(_astNodeType_index)-1) {
+		return fmt.Sprintf("astNodeType(%d)", i)
+	}
+	return _astNodeType_name[_astNodeType_index[i]:_astNodeType_index[i+1]]
+}
diff --git a/vendor/github.com/jmespath/go-jmespath/functions.go b/vendor/github.com/jmespath/go-jmespath/functions.go
new file mode 100644
index 000000000..9b7cd89b4
--- /dev/null
+++ b/vendor/github.com/jmespath/go-jmespath/functions.go
@@ -0,0 +1,842 @@
+package jmespath
+
+import (
+	"encoding/json"
+	"errors"
+	"fmt"
+	"math"
+	"reflect"
+	"sort"
+	"strconv"
+	"strings"
+	"unicode/utf8"
+)
+
+type jpFunction func(arguments []interface{}) (interface{}, error)
+
+type jpType string
+
+const (
+	jpUnknown     jpType = "unknown"
+	jpNumber      jpType = "number"
+	jpString      jpType = "string"
+	jpArray       jpType = "array"
+	jpObject      jpType = "object"
+	jpArrayNumber jpType = "array[number]"
+	jpArrayString jpType = "array[string]"
+	jpExpref      jpType = "expref"
+	jpAny         jpType = "any"
+)
+
+type functionEntry struct {
+	name      string
+	arguments []argSpec
+	handler   jpFunction
+	hasExpRef bool
+}
+
+type argSpec struct {
+	types    []jpType
+	variadic bool
+}
+
+type byExprString struct {
+	intr     *treeInterpreter
+	node     ASTNode
+	items    []interface{}
+	hasError bool
+}
+
+func (a *byExprString) Len() int {
+	return len(a.items)
+}
+func (a *byExprString) Swap(i, j int) {
+	a.items[i], a.items[j] = a.items[j], a.items[i]
+}
+func (a *byExprString) Less(i, j int) bool {
+	first, err := a.intr.Execute(a.node, a.items[i])
+	if err != nil {
+		a.hasError = true
+		// Return a dummy value.
+		return true
+	}
+	ith, ok := first.(string)
+	if !ok {
+		a.hasError = true
+		return true
+	}
+	second, err := a.intr.Execute(a.node, a.items[j])
+	if err != nil {
+		a.hasError = true
+		// Return a dummy value.
+		return true
+	}
+	jth, ok := second.(string)
+	if !ok {
+		a.hasError = true
+		return true
+	}
+	return ith < jth
+}
+
+type byExprFloat struct {
+	intr     *treeInterpreter
+	node     ASTNode
+	items    []interface{}
+	hasError bool
+}
+
+func (a *byExprFloat) Len() int {
+	return len(a.items)
+}
+func (a *byExprFloat) Swap(i, j int) {
+	a.items[i], a.items[j] = a.items[j], a.items[i]
+}
+func (a *byExprFloat) Less(i, j int) bool {
+	first, err := a.intr.Execute(a.node, a.items[i])
+	if err != nil {
+		a.hasError = true
+		// Return a dummy value.
+		return true
+	}
+	ith, ok := first.(float64)
+	if !ok {
+		a.hasError = true
+		return true
+	}
+	second, err := a.intr.Execute(a.node, a.items[j])
+	if err != nil {
+		a.hasError = true
+		// Return a dummy value.
+		return true
+	}
+	jth, ok := second.(float64)
+	if !ok {
+		a.hasError = true
+		return true
+	}
+	return ith < jth
+}
+
+type functionCaller struct {
+	functionTable map[string]functionEntry
+}
+
+func newFunctionCaller() *functionCaller {
+	caller := &functionCaller{}
+	caller.functionTable = map[string]functionEntry{
+		"length": {
+			name: "length",
+			arguments: []argSpec{
+				{types: []jpType{jpString, jpArray, jpObject}},
+			},
+			handler: jpfLength,
+		},
+		"starts_with": {
+			name: "starts_with",
+			arguments: []argSpec{
+				{types: []jpType{jpString}},
+				{types: []jpType{jpString}},
+			},
+			handler: jpfStartsWith,
+		},
+		"abs": {
+			name: "abs",
+			arguments: []argSpec{
+				{types: []jpType{jpNumber}},
+			},
+			handler: jpfAbs,
+		},
+		"avg": {
+			name: "avg",
+			arguments: []argSpec{
+				{types: []jpType{jpArrayNumber}},
+			},
+			handler: jpfAvg,
+		},
+		"ceil": {
+			name: "ceil",
+			arguments: []argSpec{
+				{types: []jpType{jpNumber}},
+			},
+			handler: jpfCeil,
+		},
+		"contains": {
+			name: "contains",
+			arguments: []argSpec{
+				{types: []jpType{jpArray, jpString}},
+				{types: []jpType{jpAny}},
+			},
+			handler: jpfContains,
+		},
+		"ends_with": {
+			name: "ends_with",
+			arguments: []argSpec{
+				{types: []jpType{jpString}},
+				{types: []jpType{jpString}},
+			},
+			handler: jpfEndsWith,
+		},
+		"floor": {
+			name: "floor",
+			arguments: []argSpec{
+				{types: []jpType{jpNumber}},
+			},
+			handler: jpfFloor,
+		},
+		"map": {
+			name: "amp",
+			arguments: []argSpec{
+				{types: []jpType{jpExpref}},
+				{types: []jpType{jpArray}},
+			},
+			handler:   jpfMap,
+			hasExpRef: true,
+		},
+		"max": {
+			name: "max",
+			arguments: []argSpec{
+				{types: []jpType{jpArrayNumber, jpArrayString}},
+			},
+			handler: jpfMax,
+		},
+		"merge": {
+			name: "merge",
+			arguments: []argSpec{
+				{types: []jpType{jpObject}, variadic: true},
+			},
+			handler: jpfMerge,
+		},
+		"max_by": {
+			name: "max_by",
+			arguments: []argSpec{
+				{types: []jpType{jpArray}},
+				{types: []jpType{jpExpref}},
+			},
+			handler:   jpfMaxBy,
+			hasExpRef: true,
+		},
+		"sum": {
+			name: "sum",
+			arguments: []argSpec{
+				{types: []jpType{jpArrayNumber}},
+			},
+			handler: jpfSum,
+		},
+		"min": {
+			name: "min",
+			arguments: []argSpec{
+				{types: []jpType{jpArrayNumber, jpArrayString}},
+			},
+			handler: jpfMin,
+		},
+		"min_by": {
+			name: "min_by",
+			arguments: []argSpec{
+				{types: []jpType{jpArray}},
+				{types: []jpType{jpExpref}},
+			},
+			handler:   jpfMinBy,
+			hasExpRef: true,
+		},
+		"type": {
+			name: "type",
+			arguments: []argSpec{
+				{types: []jpType{jpAny}},
+			},
+			handler: jpfType,
+		},
+		"keys": {
+			name: "keys",
+			arguments: []argSpec{
+				{types: []jpType{jpObject}},
+			},
+			handler: jpfKeys,
+		},
+		"values": {
+			name: "values",
+			arguments: []argSpec{
+				{types: []jpType{jpObject}},
+			},
+			handler: jpfValues,
+		},
+		"sort": {
+			name: "sort",
+			arguments: []argSpec{
+				{types: []jpType{jpArrayString, jpArrayNumber}},
+			},
+			handler: jpfSort,
+		},
+		"sort_by": {
+			name: "sort_by",
+			arguments: []argSpec{
+				{types: []jpType{jpArray}},
+				{types: []jpType{jpExpref}},
+			},
+			handler:   jpfSortBy,
+			hasExpRef: true,
+		},
+		"join": {
+			name: "join",
+			arguments: []argSpec{
+				{types: []jpType{jpString}},
+				{types: []jpType{jpArrayString}},
+			},
+			handler: jpfJoin,
+		},
+		"reverse": {
+			name: "reverse",
+			arguments: []argSpec{
+				{types: []jpType{jpArray, jpString}},
+			},
+			handler: jpfReverse,
+		},
+		"to_array": {
+			name: "to_array",
+			arguments: []argSpec{
+				{types: []jpType{jpAny}},
+			},
+			handler: jpfToArray,
+		},
+		"to_string": {
+			name: "to_string",
+			arguments: []argSpec{
+				{types: []jpType{jpAny}},
+			},
+			handler: jpfToString,
+		},
+		"to_number": {
+			name: "to_number",
+			arguments: []argSpec{
+				{types: []jpType{jpAny}},
+			},
+			handler: jpfToNumber,
+		},
+		"not_null": {
+			name: "not_null",
+			arguments: []argSpec{
+				{types: []jpType{jpAny}, variadic: true},
+			},
+			handler: jpfNotNull,
+		},
+	}
+	return caller
+}
+
+func (e *functionEntry) resolveArgs(arguments []interface{}) ([]interface{}, error) {
+	if len(e.arguments) == 0 {
+		return arguments, nil
+	}
+	if !e.arguments[len(e.arguments)-1].variadic {
+		if len(e.arguments) != len(arguments) {
+			return nil, errors.New("incorrect number of args")
+		}
+		for i, spec := range e.arguments {
+			userArg := arguments[i]
+			err := spec.typeCheck(userArg)
+			if err != nil {
+				return nil, err
+			}
+		}
+		return arguments, nil
+	}
+	if len(arguments) < len(e.arguments) {
+		return nil, errors.New("Invalid arity.")
+	}
+	return arguments, nil
+}
+
+func (a *argSpec) typeCheck(arg interface{}) error {
+	for _, t := range a.types {
+		switch t {
+		case jpNumber:
+			if _, ok := arg.(float64); ok {
+				return nil
+			}
+		case jpString:
+			if _, ok := arg.(string); ok {
+				return nil
+			}
+		case jpArray:
+			if isSliceType(arg) {
+				return nil
+			}
+		case jpObject:
+			if _, ok := arg.(map[string]interface{}); ok {
+				return nil
+			}
+		case jpArrayNumber:
+			if _, ok := toArrayNum(arg); ok {
+				return nil
+			}
+		case jpArrayString:
+			if _, ok := toArrayStr(arg); ok {
+				return nil
+			}
+		case jpAny:
+			return nil
+		case jpExpref:
+			if _, ok := arg.(expRef); ok {
+				return nil
+			}
+		}
+	}
+	return fmt.Errorf("Invalid type for: %v, expected: %#v", arg, a.types)
+}
+
+func (f *functionCaller) CallFunction(name string, arguments []interface{}, intr *treeInterpreter) (interface{}, error) {
+	entry, ok := f.functionTable[name]
+	if !ok {
+		return nil, errors.New("unknown function: " + name)
+	}
+	resolvedArgs, err := entry.resolveArgs(arguments)
+	if err != nil {
+		return nil, err
+	}
+	if entry.hasExpRef {
+		var extra []interface{}
+		extra = append(extra, intr)
+		resolvedArgs = append(extra, resolvedArgs...)
+	}
+	return entry.handler(resolvedArgs)
+}
+
+func jpfAbs(arguments []interface{}) (interface{}, error) {
+	num := arguments[0].(float64)
+	return math.Abs(num), nil
+}
+
+func jpfLength(arguments []interface{}) (interface{}, error) {
+	arg := arguments[0]
+	if c, ok := arg.(string); ok {
+		return float64(utf8.RuneCountInString(c)), nil
+	} else if isSliceType(arg) {
+		v := reflect.ValueOf(arg)
+		return float64(v.Len()), nil
+	} else if c, ok := arg.(map[string]interface{}); ok {
+		return float64(len(c)), nil
+	}
+	return nil, errors.New("could not compute length()")
+}
+
+func jpfStartsWith(arguments []interface{}) (interface{}, error) {
+	search := arguments[0].(string)
+	prefix := arguments[1].(string)
+	return strings.HasPrefix(search, prefix), nil
+}
+
+func jpfAvg(arguments []interface{}) (interface{}, error) {
+	// We've already type checked the value so we can safely use
+	// type assertions.
+	args := arguments[0].([]interface{})
+	length := float64(len(args))
+	numerator := 0.0
+	for _, n := range args {
+		numerator += n.(float64)
+	}
+	return numerator / length, nil
+}
+func jpfCeil(arguments []interface{}) (interface{}, error) {
+	val := arguments[0].(float64)
+	return math.Ceil(val), nil
+}
+func jpfContains(arguments []interface{}) (interface{}, error) {
+	search := arguments[0]
+	el := arguments[1]
+	if searchStr, ok := search.(string); ok {
+		if elStr, ok := el.(string); ok {
+			return strings.Index(searchStr, elStr) != -1, nil
+		}
+		return false, nil
+	}
+	// Otherwise this is a generic contains for []interface{}
+	general := search.([]interface{})
+	for _, item := range general {
+		if item == el {
+			return true, nil
+		}
+	}
+	return false, nil
+}
+func jpfEndsWith(arguments []interface{}) (interface{}, error) {
+	search := arguments[0].(string)
+	suffix := arguments[1].(string)
+	return strings.HasSuffix(search, suffix), nil
+}
+func jpfFloor(arguments []interface{}) (interface{}, error) {
+	val := arguments[0].(float64)
+	return math.Floor(val), nil
+}
+func jpfMap(arguments []interface{}) (interface{}, error) {
+	intr := arguments[0].(*treeInterpreter)
+	exp := arguments[1].(expRef)
+	node := exp.ref
+	arr := arguments[2].([]interface{})
+	mapped := make([]interface{}, 0, len(arr))
+	for _, value := range arr {
+		current, err := intr.Execute(node, value)
+		if err != nil {
+			return nil, err
+		}
+		mapped = append(mapped, current)
+	}
+	return mapped, nil
+}
+func jpfMax(arguments []interface{}) (interface{}, error) {
+	if items, ok := toArrayNum(arguments[0]); ok {
+		if len(items) == 0 {
+			return nil, nil
+		}
+		if len(items) == 1 {
+			return items[0], nil
+		}
+		best := items[0]
+		for _, item := range items[1:] {
+			if item > best {
+				best = item
+			}
+		}
+		return best, nil
+	}
+	// Otherwise we're dealing with a max() of strings.
+	items, _ := toArrayStr(arguments[0])
+	if len(items) == 0 {
+		return nil, nil
+	}
+	if len(items) == 1 {
+		return items[0], nil
+	}
+	best := items[0]
+	for _, item := range items[1:] {
+		if item > best {
+			best = item
+		}
+	}
+	return best, nil
+}
+func jpfMerge(arguments []interface{}) (interface{}, error) {
+	final := make(map[string]interface{})
+	for _, m := range arguments {
+		mapped := m.(map[string]interface{})
+		for key, value := range mapped {
+			final[key] = value
+		}
+	}
+	return final, nil
+}
+func jpfMaxBy(arguments []interface{}) (interface{}, error) {
+	intr := arguments[0].(*treeInterpreter)
+	arr := arguments[1].([]interface{})
+	exp := arguments[2].(expRef)
+	node := exp.ref
+	if len(arr) == 0 {
+		return nil, nil
+	} else if len(arr) == 1 {
+		return arr[0], nil
+	}
+	start, err := intr.Execute(node, arr[0])
+	if err != nil {
+		return nil, err
+	}
+	switch t := start.(type) {
+	case float64:
+		bestVal := t
+		bestItem := arr[0]
+		for _, item := range arr[1:] {
+			result, err := intr.Execute(node, item)
+			if err != nil {
+				return nil, err
+			}
+			current, ok := result.(float64)
+			if !ok {
+				return nil, errors.New("invalid type, must be number")
+			}
+			if current > bestVal {
+				bestVal = current
+				bestItem = item
+			}
+		}
+		return bestItem, nil
+	case string:
+		bestVal := t
+		bestItem := arr[0]
+		for _, item := range arr[1:] {
+			result, err := intr.Execute(node, item)
+			if err != nil {
+				return nil, err
+			}
+			current, ok := result.(string)
+			if !ok {
+				return nil, errors.New("invalid type, must be string")
+			}
+			if current > bestVal {
+				bestVal = current
+				bestItem = item
+			}
+		}
+		return bestItem, nil
+	default:
+		return nil, errors.New("invalid type, must be number of string")
+	}
+}
+func jpfSum(arguments []interface{}) (interface{}, error) {
+	items, _ := toArrayNum(arguments[0])
+	sum := 0.0
+	for _, item := range items {
+		sum += item
+	}
+	return sum, nil
+}
+
+func jpfMin(arguments []interface{}) (interface{}, error) {
+	if items, ok := toArrayNum(arguments[0]); ok {
+		if len(items) == 0 {
+			return nil, nil
+		}
+		if len(items) == 1 {
+			return items[0], nil
+		}
+		best := items[0]
+		for _, item := range items[1:] {
+			if item < best {
+				best = item
+			}
+		}
+		return best, nil
+	}
+	items, _ := toArrayStr(arguments[0])
+	if len(items) == 0 {
+		return nil, nil
+	}
+	if len(items) == 1 {
+		return items[0], nil
+	}
+	best := items[0]
+	for _, item := range items[1:] {
+		if item < best {
+			best = item
+		}
+	}
+	return best, nil
+}
+
+func jpfMinBy(arguments []interface{}) (interface{}, error) {
+	intr := arguments[0].(*treeInterpreter)
+	arr := arguments[1].([]interface{})
+	exp := arguments[2].(expRef)
+	node := exp.ref
+	if len(arr) == 0 {
+		return nil, nil
+	} else if len(arr) == 1 {
+		return arr[0], nil
+	}
+	start, err := intr.Execute(node, arr[0])
+	if err != nil {
+		return nil, err
+	}
+	if t, ok := start.(float64); ok {
+		bestVal := t
+		bestItem := arr[0]
+		for _, item := range arr[1:] {
+			result, err := intr.Execute(node, item)
+			if err != nil {
+				return nil, err
+			}
+			current, ok := result.(float64)
+			if !ok {
+				return nil, errors.New("invalid type, must be number")
+			}
+			if current < bestVal {
+				bestVal = current
+				bestItem = item
+			}
+		}
+		return bestItem, nil
+	} else if t, ok := start.(string); ok {
+		bestVal := t
+		bestItem := arr[0]
+		for _, item := range arr[1:] {
+			result, err := intr.Execute(node, item)
+			if err != nil {
+				return nil, err
+			}
+			current, ok := result.(string)
+			if !ok {
+				return nil, errors.New("invalid type, must be string")
+			}
+			if current < bestVal {
+				bestVal = current
+				bestItem = item
+			}
+		}
+		return bestItem, nil
+	} else {
+		return nil, errors.New("invalid type, must be number of string")
+	}
+}
+func jpfType(arguments []interface{}) (interface{}, error) {
+	arg := arguments[0]
+	if _, ok := arg.(float64); ok {
+		return "number", nil
+	}
+	if _, ok := arg.(string); ok {
+		return "string", nil
+	}
+	if _, ok := arg.([]interface{}); ok {
+		return "array", nil
+	}
+	if _, ok := arg.(map[string]interface{}); ok {
+		return "object", nil
+	}
+	if arg == nil {
+		return "null", nil
+	}
+	if arg == true || arg == false {
+		return "boolean", nil
+	}
+	return nil, errors.New("unknown type")
+}
+func jpfKeys(arguments []interface{}) (interface{}, error) {
+	arg := arguments[0].(map[string]interface{})
+	collected := make([]interface{}, 0, len(arg))
+	for key := range arg {
+		collected = append(collected, key)
+	}
+	return collected, nil
+}
+func jpfValues(arguments []interface{}) (interface{}, error) {
+	arg := arguments[0].(map[string]interface{})
+	collected := make([]interface{}, 0, len(arg))
+	for _, value := range arg {
+		collected = append(collected, value)
+	}
+	return collected, nil
+}
+func jpfSort(arguments []interface{}) (interface{}, error) {
+	if items, ok := toArrayNum(arguments[0]); ok {
+		d := sort.Float64Slice(items)
+		sort.Stable(d)
+		final := make([]interface{}, len(d))
+		for i, val := range d {
+			final[i] = val
+		}
+		return final, nil
+	}
+	// Otherwise we're dealing with sort()'ing strings.
+	items, _ := toArrayStr(arguments[0])
+	d := sort.StringSlice(items)
+	sort.Stable(d)
+	final := make([]interface{}, len(d))
+	for i, val := range d {
+		final[i] = val
+	}
+	return final, nil
+}
+func jpfSortBy(arguments []interface{}) (interface{}, error) {
+	intr := arguments[0].(*treeInterpreter)
+	arr := arguments[1].([]interface{})
+	exp := arguments[2].(expRef)
+	node := exp.ref
+	if len(arr) == 0 {
+		return arr, nil
+	} else if len(arr) == 1 {
+		return arr, nil
+	}
+	start, err := intr.Execute(node, arr[0])
+	if err != nil {
+		return nil, err
+	}
+	if _, ok := start.(float64); ok {
+		sortable := &byExprFloat{intr, node, arr, false}
+		sort.Stable(sortable)
+		if sortable.hasError {
+			return nil, errors.New("error in sort_by comparison")
+		}
+		return arr, nil
+	} else if _, ok := start.(string); ok {
+		sortable := &byExprString{intr, node, arr, false}
+		sort.Stable(sortable)
+		if sortable.hasError {
+			return nil, errors.New("error in sort_by comparison")
+		}
+		return arr, nil
+	} else {
+		return nil, errors.New("invalid type, must be number of string")
+	}
+}
+func jpfJoin(arguments []interface{}) (interface{}, error) {
+	sep := arguments[0].(string)
+	// We can't just do arguments[1].([]string), we have to
+	// manually convert each item to a string.
+	arrayStr := []string{}
+	for _, item := range arguments[1].([]interface{}) {
+		arrayStr = append(arrayStr, item.(string))
+	}
+	return strings.Join(arrayStr, sep), nil
+}
+func jpfReverse(arguments []interface{}) (interface{}, error) {
+	if s, ok := arguments[0].(string); ok {
+		r := []rune(s)
+		for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
+			r[i], r[j] = r[j], r[i]
+		}
+		return string(r), nil
+	}
+	items := arguments[0].([]interface{})
+	length := len(items)
+	reversed := make([]interface{}, length)
+	for i, item := range items {
+		reversed[length-(i+1)] = item
+	}
+	return reversed, nil
+}
+func jpfToArray(arguments []interface{}) (interface{}, error) {
+	if _, ok := arguments[0].([]interface{}); ok {
+		return arguments[0], nil
+	}
+	return arguments[:1:1], nil
+}
+func jpfToString(arguments []interface{}) (interface{}, error) {
+	if v, ok := arguments[0].(string); ok {
+		return v, nil
+	}
+	result, err := json.Marshal(arguments[0])
+	if err != nil {
+		return nil, err
+	}
+	return string(result), nil
+}
+func jpfToNumber(arguments []interface{}) (interface{}, error) {
+	arg := arguments[0]
+	if v, ok := arg.(float64); ok {
+		return v, nil
+	}
+	if v, ok := arg.(string); ok {
+		conv, err := strconv.ParseFloat(v, 64)
+		if err != nil {
+			return nil, nil
+		}
+		return conv, nil
+	}
+	if _, ok := arg.([]interface{}); ok {
+		return nil, nil
+	}
+	if _, ok := arg.(map[string]interface{}); ok {
+		return nil, nil
+	}
+	if arg == nil {
+		return nil, nil
+	}
+	if arg == true || arg == false {
+		return nil, nil
+	}
+	return nil, errors.New("unknown type")
+}
+func jpfNotNull(arguments []interface{}) (interface{}, error) {
+	for _, arg := range arguments {
+		if arg != nil {
+			return arg, nil
+		}
+	}
+	return nil, nil
+}
diff --git a/vendor/github.com/jmespath/go-jmespath/interpreter.go b/vendor/github.com/jmespath/go-jmespath/interpreter.go
new file mode 100644
index 000000000..13c74604c
--- /dev/null
+++ b/vendor/github.com/jmespath/go-jmespath/interpreter.go
@@ -0,0 +1,418 @@
+package jmespath
+
+import (
+	"errors"
+	"reflect"
+	"unicode"
+	"unicode/utf8"
+)
+
+/* This is a tree based interpreter.  It walks the AST and directly
+   interprets the AST to search through a JSON document.
+*/
+
+type treeInterpreter struct {
+	fCall *functionCaller
+}
+
+func newInterpreter() *treeInterpreter {
+	interpreter := treeInterpreter{}
+	interpreter.fCall = newFunctionCaller()
+	return &interpreter
+}
+
+type expRef struct {
+	ref ASTNode
+}
+
+// Execute takes an ASTNode and input data and interprets the AST directly.
+// It will produce the result of applying the JMESPath expression associated
+// with the ASTNode to the input data "value".
+func (intr *treeInterpreter) Execute(node ASTNode, value interface{}) (interface{}, error) {
+	switch node.nodeType {
+	case ASTComparator:
+		left, err := intr.Execute(node.children[0], value)
+		if err != nil {
+			return nil, err
+		}
+		right, err := intr.Execute(node.children[1], value)
+		if err != nil {
+			return nil, err
+		}
+		switch node.value {
+		case tEQ:
+			return objsEqual(left, right), nil
+		case tNE:
+			return !objsEqual(left, right), nil
+		}
+		leftNum, ok := left.(float64)
+		if !ok {
+			return nil, nil
+		}
+		rightNum, ok := right.(float64)
+		if !ok {
+			return nil, nil
+		}
+		switch node.value {
+		case tGT:
+			return leftNum > rightNum, nil
+		case tGTE:
+			return leftNum >= rightNum, nil
+		case tLT:
+			return leftNum < rightNum, nil
+		case tLTE:
+			return leftNum <= rightNum, nil
+		}
+	case ASTExpRef:
+		return expRef{ref: node.children[0]}, nil
+	case ASTFunctionExpression:
+		resolvedArgs := []interface{}{}
+		for _, arg := range node.children {
+			current, err := intr.Execute(arg, value)
+			if err != nil {
+				return nil, err
+			}
+			resolvedArgs = append(resolvedArgs, current)
+		}
+		return intr.fCall.CallFunction(node.value.(string), resolvedArgs, intr)
+	case ASTField:
+		if m, ok := value.(map[string]interface{}); ok {
+			key := node.value.(string)
+			return m[key], nil
+		}
+		return intr.fieldFromStruct(node.value.(string), value)
+	case ASTFilterProjection:
+		left, err := intr.Execute(node.children[0], value)
+		if err != nil {
+			return nil, nil
+		}
+		sliceType, ok := left.([]interface{})
+		if !ok {
+			if isSliceType(left) {
+				return intr.filterProjectionWithReflection(node, left)
+			}
+			return nil, nil
+		}
+		compareNode := node.children[2]
+		collected := []interface{}{}
+		for _, element := range sliceType {
+			result, err := intr.Execute(compareNode, element)
+			if err != nil {
+				return nil, err
+			}
+			if !isFalse(result) {
+				current, err := intr.Execute(node.children[1], element)
+				if err != nil {
+					return nil, err
+				}
+				if current != nil {
+					collected = append(collected, current)
+				}
+			}
+		}
+		return collected, nil
+	case ASTFlatten:
+		left, err := intr.Execute(node.children[0], value)
+		if err != nil {
+			return nil, nil
+		}
+		sliceType, ok := left.([]interface{})
+		if !ok {
+			// If we can't type convert to []interface{}, there's
+			// a chance this could still work via reflection if we're
+			// dealing with user provided types.
+			if isSliceType(left) {
+				return intr.flattenWithReflection(left)
+			}
+			return nil, nil
+		}
+		flattened := []interface{}{}
+		for _, element := range sliceType {
+			if elementSlice, ok := element.([]interface{}); ok {
+				flattened = append(flattened, elementSlice...)
+			} else if isSliceType(element) {
+				reflectFlat := []interface{}{}
+				v := reflect.ValueOf(element)
+				for i := 0; i < v.Len(); i++ {
+					reflectFlat = append(reflectFlat, v.Index(i).Interface())
+				}
+				flattened = append(flattened, reflectFlat...)
+			} else {
+				flattened = append(flattened, element)
+			}
+		}
+		return flattened, nil
+	case ASTIdentity, ASTCurrentNode:
+		return value, nil
+	case ASTIndex:
+		if sliceType, ok := value.([]interface{}); ok {
+			index := node.value.(int)
+			if index < 0 {
+				index += len(sliceType)
+			}
+			if index < len(sliceType) && index >= 0 {
+				return sliceType[index], nil
+			}
+			return nil, nil
+		}
+		// Otherwise try via reflection.
+		rv := reflect.ValueOf(value)
+		if rv.Kind() == reflect.Slice {
+			index := node.value.(int)
+			if index < 0 {
+				index += rv.Len()
+			}
+			if index < rv.Len() && index >= 0 {
+				v := rv.Index(index)
+				return v.Interface(), nil
+			}
+		}
+		return nil, nil
+	case ASTKeyValPair:
+		return intr.Execute(node.children[0], value)
+	case ASTLiteral:
+		return node.value, nil
+	case ASTMultiSelectHash:
+		if value == nil {
+			return nil, nil
+		}
+		collected := make(map[string]interface{})
+		for _, child := range node.children {
+			current, err := intr.Execute(child, value)
+			if err != nil {
+				return nil, err
+			}
+			key := child.value.(string)
+			collected[key] = current
+		}
+		return collected, nil
+	case ASTMultiSelectList:
+		if value == nil {
+			return nil, nil
+		}
+		collected := []interface{}{}
+		for _, child := range node.children {
+			current, err := intr.Execute(child, value)
+			if err != nil {
+				return nil, err
+			}
+			collected = append(collected, current)
+		}
+		return collected, nil
+	case ASTOrExpression:
+		matched, err := intr.Execute(node.children[0], value)
+		if err != nil {
+			return nil, err
+		}
+		if isFalse(matched) {
+			matched, err = intr.Execute(node.children[1], value)
+			if err != nil {
+				return nil, err
+			}
+		}
+		return matched, nil
+	case ASTAndExpression:
+		matched, err := intr.Execute(node.children[0], value)
+		if err != nil {
+			return nil, err
+		}
+		if isFalse(matched) {
+			return matched, nil
+		}
+		return intr.Execute(node.children[1], value)
+	case ASTNotExpression:
+		matched, err := intr.Execute(node.children[0], value)
+		if err != nil {
+			return nil, err
+		}
+		if isFalse(matched) {
+			return true, nil
+		}
+		return false, nil
+	case ASTPipe:
+		result := value
+		var err error
+		for _, child := range node.children {
+			result, err = intr.Execute(child, result)
+			if err != nil {
+				return nil, err
+			}
+		}
+		return result, nil
+	case ASTProjection:
+		left, err := intr.Execute(node.children[0], value)
+		if err != nil {
+			return nil, err
+		}
+		sliceType, ok := left.([]interface{})
+		if !ok {
+			if isSliceType(left) {
+				return intr.projectWithReflection(node, left)
+			}
+			return nil, nil
+		}
+		collected := []interface{}{}
+		var current interface{}
+		for _, element := range sliceType {
+			current, err = intr.Execute(node.children[1], element)
+			if err != nil {
+				return nil, err
+			}
+			if current != nil {
+				collected = append(collected, current)
+			}
+		}
+		return collected, nil
+	case ASTSubexpression, ASTIndexExpression:
+		left, err := intr.Execute(node.children[0], value)
+		if err != nil {
+			return nil, err
+		}
+		return intr.Execute(node.children[1], left)
+	case ASTSlice:
+		sliceType, ok := value.([]interface{})
+		if !ok {
+			if isSliceType(value) {
+				return intr.sliceWithReflection(node, value)
+			}
+			return nil, nil
+		}
+		parts := node.value.([]*int)
+		sliceParams := make([]sliceParam, 3)
+		for i, part := range parts {
+			if part != nil {
+				sliceParams[i].Specified = true
+				sliceParams[i].N = *part
+			}
+		}
+		return slice(sliceType, sliceParams)
+	case ASTValueProjection:
+		left, err := intr.Execute(node.children[0], value)
+		if err != nil {
+			return nil, nil
+		}
+		mapType, ok := left.(map[string]interface{})
+		if !ok {
+			return nil, nil
+		}
+		values := make([]interface{}, len(mapType))
+		for _, value := range mapType {
+			values = append(values, value)
+		}
+		collected := []interface{}{}
+		for _, element := range values {
+			current, err := intr.Execute(node.children[1], element)
+			if err != nil {
+				return nil, err
+			}
+			if current != nil {
+				collected = append(collected, current)
+			}
+		}
+		return collected, nil
+	}
+	return nil, errors.New("Unknown AST node: " + node.nodeType.String())
+}
+
+func (intr *treeInterpreter) fieldFromStruct(key string, value interface{}) (interface{}, error) {
+	rv := reflect.ValueOf(value)
+	first, n := utf8.DecodeRuneInString(key)
+	fieldName := string(unicode.ToUpper(first)) + key[n:]
+	if rv.Kind() == reflect.Struct {
+		v := rv.FieldByName(fieldName)
+		if !v.IsValid() {
+			return nil, nil
+		}
+		return v.Interface(), nil
+	} else if rv.Kind() == reflect.Ptr {
+		// Handle multiple levels of indirection?
+		if rv.IsNil() {
+			return nil, nil
+		}
+		rv = rv.Elem()
+		v := rv.FieldByName(fieldName)
+		if !v.IsValid() {
+			return nil, nil
+		}
+		return v.Interface(), nil
+	}
+	return nil, nil
+}
+
+func (intr *treeInterpreter) flattenWithReflection(value interface{}) (interface{}, error) {
+	v := reflect.ValueOf(value)
+	flattened := []interface{}{}
+	for i := 0; i < v.Len(); i++ {
+		element := v.Index(i).Interface()
+		if reflect.TypeOf(element).Kind() == reflect.Slice {
+			// Then insert the contents of the element
+			// slice into the flattened slice,
+			// i.e flattened = append(flattened, mySlice...)
+			elementV := reflect.ValueOf(element)
+			for j := 0; j < elementV.Len(); j++ {
+				flattened = append(
+					flattened, elementV.Index(j).Interface())
+			}
+		} else {
+			flattened = append(flattened, element)
+		}
+	}
+	return flattened, nil
+}
+
+func (intr *treeInterpreter) sliceWithReflection(node ASTNode, value interface{}) (interface{}, error) {
+	v := reflect.ValueOf(value)
+	parts := node.value.([]*int)
+	sliceParams := make([]sliceParam, 3)
+	for i, part := range parts {
+		if part != nil {
+			sliceParams[i].Specified = true
+			sliceParams[i].N = *part
+		}
+	}
+	final := []interface{}{}
+	for i := 0; i < v.Len(); i++ {
+		element := v.Index(i).Interface()
+		final = append(final, element)
+	}
+	return slice(final, sliceParams)
+}
+
+func (intr *treeInterpreter) filterProjectionWithReflection(node ASTNode, value interface{}) (interface{}, error) {
+	compareNode := node.children[2]
+	collected := []interface{}{}
+	v := reflect.ValueOf(value)
+	for i := 0; i < v.Len(); i++ {
+		element := v.Index(i).Interface()
+		result, err := intr.Execute(compareNode, element)
+		if err != nil {
+			return nil, err
+		}
+		if !isFalse(result) {
+			current, err := intr.Execute(node.children[1], element)
+			if err != nil {
+				return nil, err
+			}
+			if current != nil {
+				collected = append(collected, current)
+			}
+		}
+	}
+	return collected, nil
+}
+
+func (intr *treeInterpreter) projectWithReflection(node ASTNode, value interface{}) (interface{}, error) {
+	collected := []interface{}{}
+	v := reflect.ValueOf(value)
+	for i := 0; i < v.Len(); i++ {
+		element := v.Index(i).Interface()
+		result, err := intr.Execute(node.children[1], element)
+		if err != nil {
+			return nil, err
+		}
+		if result != nil {
+			collected = append(collected, result)
+		}
+	}
+	return collected, nil
+}
diff --git a/vendor/github.com/jmespath/go-jmespath/lexer.go b/vendor/github.com/jmespath/go-jmespath/lexer.go
new file mode 100644
index 000000000..817900c8f
--- /dev/null
+++ b/vendor/github.com/jmespath/go-jmespath/lexer.go
@@ -0,0 +1,420 @@
+package jmespath
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"strconv"
+	"strings"
+	"unicode/utf8"
+)
+
+type token struct {
+	tokenType tokType
+	value     string
+	position  int
+	length    int
+}
+
+type tokType int
+
+const eof = -1
+
+// Lexer contains information about the expression being tokenized.
+type Lexer struct {
+	expression string       // The expression provided by the user.
+	currentPos int          // The current position in the string.
+	lastWidth  int          // The width of the current rune.  This
+	buf        bytes.Buffer // Internal buffer used for building up values.
+}
+
+// SyntaxError is the main error used whenever a lexing or parsing error occurs.
+type SyntaxError struct {
+	msg        string // Error message displayed to user
+	Expression string // Expression that generated a SyntaxError
+	Offset     int    // The location in the string where the error occurred
+}
+
+func (e SyntaxError) Error() string {
+	// In the future, it would be good to underline the specific
+	// location where the error occurred.
+	return "SyntaxError: " + e.msg
+}
+
+// HighlightLocation will show where the syntax error occurred.
+// It will place a "^" character on a line below the expression
+// at the point where the syntax error occurred.
+func (e SyntaxError) HighlightLocation() string {
+	return e.Expression + "\n" + strings.Repeat(" ", e.Offset) + "^"
+}
+
+//go:generate stringer -type=tokType
+const (
+	tUnknown tokType = iota
+	tStar
+	tDot
+	tFilter
+	tFlatten
+	tLparen
+	tRparen
+	tLbracket
+	tRbracket
+	tLbrace
+	tRbrace
+	tOr
+	tPipe
+	tNumber
+	tUnquotedIdentifier
+	tQuotedIdentifier
+	tComma
+	tColon
+	tLT
+	tLTE
+	tGT
+	tGTE
+	tEQ
+	tNE
+	tJSONLiteral
+	tStringLiteral
+	tCurrent
+	tExpref
+	tAnd
+	tNot
+	tEOF
+)
+
+var basicTokens = map[rune]tokType{
+	'.': tDot,
+	'*': tStar,
+	',': tComma,
+	':': tColon,
+	'{': tLbrace,
+	'}': tRbrace,
+	']': tRbracket, // tLbracket not included because it could be "[]"
+	'(': tLparen,
+	')': tRparen,
+	'@': tCurrent,
+}
+
+// Bit mask for [a-zA-Z_] shifted down 64 bits to fit in a single uint64.
+// When using this bitmask just be sure to shift the rune down 64 bits
+// before checking against identifierStartBits.
+const identifierStartBits uint64 = 576460745995190270
+
+// Bit mask for [a-zA-Z0-9], 128 bits -> 2 uint64s.
+var identifierTrailingBits = [2]uint64{287948901175001088, 576460745995190270}
+
+var whiteSpace = map[rune]bool{
+	' ': true, '\t': true, '\n': true, '\r': true,
+}
+
+func (t token) String() string {
+	return fmt.Sprintf("Token{%+v, %s, %d, %d}",
+		t.tokenType, t.value, t.position, t.length)
+}
+
+// NewLexer creates a new JMESPath lexer.
+func NewLexer() *Lexer {
+	lexer := Lexer{}
+	return &lexer
+}
+
+func (lexer *Lexer) next() rune {
+	if lexer.currentPos >= len(lexer.expression) {
+		lexer.lastWidth = 0
+		return eof
+	}
+	r, w := utf8.DecodeRuneInString(lexer.expression[lexer.currentPos:])
+	lexer.lastWidth = w
+	lexer.currentPos += w
+	return r
+}
+
+func (lexer *Lexer) back() {
+	lexer.currentPos -= lexer.lastWidth
+}
+
+func (lexer *Lexer) peek() rune {
+	t := lexer.next()
+	lexer.back()
+	return t
+}
+
+// tokenize takes an expression and returns corresponding tokens.
+func (lexer *Lexer) tokenize(expression string) ([]token, error) {
+	var tokens []token
+	lexer.expression = expression
+	lexer.currentPos = 0
+	lexer.lastWidth = 0
+loop:
+	for {
+		r := lexer.next()
+		if identifierStartBits&(1<<(uint64(r)-64)) > 0 {
+			t := lexer.consumeUnquotedIdentifier()
+			tokens = append(tokens, t)
+		} else if val, ok := basicTokens[r]; ok {
+			// Basic single char token.
+			t := token{
+				tokenType: val,
+				value:     string(r),
+				position:  lexer.currentPos - lexer.lastWidth,
+				length:    1,
+			}
+			tokens = append(tokens, t)
+		} else if r == '-' || (r >= '0' && r <= '9') {
+			t := lexer.consumeNumber()
+			tokens = append(tokens, t)
+		} else if r == '[' {
+			t := lexer.consumeLBracket()
+			tokens = append(tokens, t)
+		} else if r == '"' {
+			t, err := lexer.consumeQuotedIdentifier()
+			if err != nil {
+				return tokens, err
+			}
+			tokens = append(tokens, t)
+		} else if r == '\'' {
+			t, err := lexer.consumeRawStringLiteral()
+			if err != nil {
+				return tokens, err
+			}
+			tokens = append(tokens, t)
+		} else if r == '`' {
+			t, err := lexer.consumeLiteral()
+			if err != nil {
+				return tokens, err
+			}
+			tokens = append(tokens, t)
+		} else if r == '|' {
+			t := lexer.matchOrElse(r, '|', tOr, tPipe)
+			tokens = append(tokens, t)
+		} else if r == '<' {
+			t := lexer.matchOrElse(r, '=', tLTE, tLT)
+			tokens = append(tokens, t)
+		} else if r == '>' {
+			t := lexer.matchOrElse(r, '=', tGTE, tGT)
+			tokens = append(tokens, t)
+		} else if r == '!' {
+			t := lexer.matchOrElse(r, '=', tNE, tNot)
+			tokens = append(tokens, t)
+		} else if r == '=' {
+			t := lexer.matchOrElse(r, '=', tEQ, tUnknown)
+			tokens = append(tokens, t)
+		} else if r == '&' {
+			t := lexer.matchOrElse(r, '&', tAnd, tExpref)
+			tokens = append(tokens, t)
+		} else if r == eof {
+			break loop
+		} else if _, ok := whiteSpace[r]; ok {
+			// Ignore whitespace
+		} else {
+			return tokens, lexer.syntaxError(fmt.Sprintf("Unknown char: %s", strconv.QuoteRuneToASCII(r)))
+		}
+	}
+	tokens = append(tokens, token{tEOF, "", len(lexer.expression), 0})
+	return tokens, nil
+}
+
+// Consume characters until the ending rune "r" is reached.
+// If the end of the expression is reached before seeing the
+// terminating rune "r", then an error is returned.
+// If no error occurs then the matching substring is returned.
+// The returned string will not include the ending rune.
+func (lexer *Lexer) consumeUntil(end rune) (string, error) {
+	start := lexer.currentPos
+	current := lexer.next()
+	for current != end && current != eof {
+		if current == '\\' && lexer.peek() != eof {
+			lexer.next()
+		}
+		current = lexer.next()
+	}
+	if lexer.lastWidth == 0 {
+		// Then we hit an EOF so we never reached the closing
+		// delimiter.
+		return "", SyntaxError{
+			msg:        "Unclosed delimiter: " + string(end),
+			Expression: lexer.expression,
+			Offset:     len(lexer.expression),
+		}
+	}
+	return lexer.expression[start : lexer.currentPos-lexer.lastWidth], nil
+}
+
+func (lexer *Lexer) consumeLiteral() (token, error) {
+	start := lexer.currentPos
+	value, err := lexer.consumeUntil('`')
+	if err != nil {
+		return token{}, err
+	}
+	value = strings.Replace(value, "\\`", "`", -1)
+	return token{
+		tokenType: tJSONLiteral,
+		value:     value,
+		position:  start,
+		length:    len(value),
+	}, nil
+}
+
+func (lexer *Lexer) consumeRawStringLiteral() (token, error) {
+	start := lexer.currentPos
+	currentIndex := start
+	current := lexer.next()
+	for current != '\'' && lexer.peek() != eof {
+		if current == '\\' && lexer.peek() == '\'' {
+			chunk := lexer.expression[currentIndex : lexer.currentPos-1]
+			lexer.buf.WriteString(chunk)
+			lexer.buf.WriteString("'")
+			lexer.next()
+			currentIndex = lexer.currentPos
+		}
+		current = lexer.next()
+	}
+	if lexer.lastWidth == 0 {
+		// Then we hit an EOF so we never reached the closing
+		// delimiter.
+		return token{}, SyntaxError{
+			msg:        "Unclosed delimiter: '",
+			Expression: lexer.expression,
+			Offset:     len(lexer.expression),
+		}
+	}
+	if currentIndex < lexer.currentPos {
+		lexer.buf.WriteString(lexer.expression[currentIndex : lexer.currentPos-1])
+	}
+	value := lexer.buf.String()
+	// Reset the buffer so it can reused again.
+	lexer.buf.Reset()
+	return token{
+		tokenType: tStringLiteral,
+		value:     value,
+		position:  start,
+		length:    len(value),
+	}, nil
+}
+
+func (lexer *Lexer) syntaxError(msg string) SyntaxError {
+	return SyntaxError{
+		msg:        msg,
+		Expression: lexer.expression,
+		Offset:     lexer.currentPos - 1,
+	}
+}
+
+// Checks for a two char token, otherwise matches a single character
+// token. This is used whenever a two char token overlaps a single
+// char token, e.g. "||" -> tPipe, "|" -> tOr.
+func (lexer *Lexer) matchOrElse(first rune, second rune, matchedType tokType, singleCharType tokType) token {
+	start := lexer.currentPos - lexer.lastWidth
+	nextRune := lexer.next()
+	var t token
+	if nextRune == second {
+		t = token{
+			tokenType: matchedType,
+			value:     string(first) + string(second),
+			position:  start,
+			length:    2,
+		}
+	} else {
+		lexer.back()
+		t = token{
+			tokenType: singleCharType,
+			value:     string(first),
+			position:  start,
+			length:    1,
+		}
+	}
+	return t
+}
+
+func (lexer *Lexer) consumeLBracket() token {
+	// There's three options here:
+	// 1. A filter expression "[?"
+	// 2. A flatten operator "[]"
+	// 3. A bare rbracket "["
+	start := lexer.currentPos - lexer.lastWidth
+	nextRune := lexer.next()
+	var t token
+	if nextRune == '?' {
+		t = token{
+			tokenType: tFilter,
+			value:     "[?",
+			position:  start,
+			length:    2,
+		}
+	} else if nextRune == ']' {
+		t = token{
+			tokenType: tFlatten,
+			value:     "[]",
+			position:  start,
+			length:    2,
+		}
+	} else {
+		t = token{
+			tokenType: tLbracket,
+			value:     "[",
+			position:  start,
+			length:    1,
+		}
+		lexer.back()
+	}
+	return t
+}
+
+func (lexer *Lexer) consumeQuotedIdentifier() (token, error) {
+	start := lexer.currentPos
+	value, err := lexer.consumeUntil('"')
+	if err != nil {
+		return token{}, err
+	}
+	var decoded string
+	asJSON := []byte("\"" + value + "\"")
+	if err := json.Unmarshal([]byte(asJSON), &decoded); err != nil {
+		return token{}, err
+	}
+	return token{
+		tokenType: tQuotedIdentifier,
+		value:     decoded,
+		position:  start - 1,
+		length:    len(decoded),
+	}, nil
+}
+
+func (lexer *Lexer) consumeUnquotedIdentifier() token {
+	// Consume runes until we reach the end of an unquoted
+	// identifier.
+	start := lexer.currentPos - lexer.lastWidth
+	for {
+		r := lexer.next()
+		if r < 0 || r > 128 || identifierTrailingBits[uint64(r)/64]&(1<<(uint64(r)%64)) == 0 {
+			lexer.back()
+			break
+		}
+	}
+	value := lexer.expression[start:lexer.currentPos]
+	return token{
+		tokenType: tUnquotedIdentifier,
+		value:     value,
+		position:  start,
+		length:    lexer.currentPos - start,
+	}
+}
+
+func (lexer *Lexer) consumeNumber() token {
+	// Consume runes until we reach something that's not a number.
+	start := lexer.currentPos - lexer.lastWidth
+	for {
+		r := lexer.next()
+		if r < '0' || r > '9' {
+			lexer.back()
+			break
+		}
+	}
+	value := lexer.expression[start:lexer.currentPos]
+	return token{
+		tokenType: tNumber,
+		value:     value,
+		position:  start,
+		length:    lexer.currentPos - start,
+	}
+}
diff --git a/vendor/github.com/jmespath/go-jmespath/parser.go b/vendor/github.com/jmespath/go-jmespath/parser.go
new file mode 100644
index 000000000..1240a1755
--- /dev/null
+++ b/vendor/github.com/jmespath/go-jmespath/parser.go
@@ -0,0 +1,603 @@
+package jmespath
+
+import (
+	"encoding/json"
+	"fmt"
+	"strconv"
+	"strings"
+)
+
+type astNodeType int
+
+//go:generate stringer -type astNodeType
+const (
+	ASTEmpty astNodeType = iota
+	ASTComparator
+	ASTCurrentNode
+	ASTExpRef
+	ASTFunctionExpression
+	ASTField
+	ASTFilterProjection
+	ASTFlatten
+	ASTIdentity
+	ASTIndex
+	ASTIndexExpression
+	ASTKeyValPair
+	ASTLiteral
+	ASTMultiSelectHash
+	ASTMultiSelectList
+	ASTOrExpression
+	ASTAndExpression
+	ASTNotExpression
+	ASTPipe
+	ASTProjection
+	ASTSubexpression
+	ASTSlice
+	ASTValueProjection
+)
+
+// ASTNode represents the abstract syntax tree of a JMESPath expression.
+type ASTNode struct {
+	nodeType astNodeType
+	value    interface{}
+	children []ASTNode
+}
+
+func (node ASTNode) String() string {
+	return node.PrettyPrint(0)
+}
+
+// PrettyPrint will pretty print the parsed AST.
+// The AST is an implementation detail and this pretty print
+// function is provided as a convenience method to help with
+// debugging.  You should not rely on its output as the internal
+// structure of the AST may change at any time.
+func (node ASTNode) PrettyPrint(indent int) string {
+	spaces := strings.Repeat(" ", indent)
+	output := fmt.Sprintf("%s%s {\n", spaces, node.nodeType)
+	nextIndent := indent + 2
+	if node.value != nil {
+		if converted, ok := node.value.(fmt.Stringer); ok {
+			// Account for things like comparator nodes
+			// that are enums with a String() method.
+			output += fmt.Sprintf("%svalue: %s\n", strings.Repeat(" ", nextIndent), converted.String())
+		} else {
+			output += fmt.Sprintf("%svalue: %#v\n", strings.Repeat(" ", nextIndent), node.value)
+		}
+	}
+	lastIndex := len(node.children)
+	if lastIndex > 0 {
+		output += fmt.Sprintf("%schildren: {\n", strings.Repeat(" ", nextIndent))
+		childIndent := nextIndent + 2
+		for _, elem := range node.children {
+			output += elem.PrettyPrint(childIndent)
+		}
+	}
+	output += fmt.Sprintf("%s}\n", spaces)
+	return output
+}
+
+var bindingPowers = map[tokType]int{
+	tEOF:                0,
+	tUnquotedIdentifier: 0,
+	tQuotedIdentifier:   0,
+	tRbracket:           0,
+	tRparen:             0,
+	tComma:              0,
+	tRbrace:             0,
+	tNumber:             0,
+	tCurrent:            0,
+	tExpref:             0,
+	tColon:              0,
+	tPipe:               1,
+	tOr:                 2,
+	tAnd:                3,
+	tEQ:                 5,
+	tLT:                 5,
+	tLTE:                5,
+	tGT:                 5,
+	tGTE:                5,
+	tNE:                 5,
+	tFlatten:            9,
+	tStar:               20,
+	tFilter:             21,
+	tDot:                40,
+	tNot:                45,
+	tLbrace:             50,
+	tLbracket:           55,
+	tLparen:             60,
+}
+
+// Parser holds state about the current expression being parsed.
+type Parser struct {
+	expression string
+	tokens     []token
+	index      int
+}
+
+// NewParser creates a new JMESPath parser.
+func NewParser() *Parser {
+	p := Parser{}
+	return &p
+}
+
+// Parse will compile a JMESPath expression.
+func (p *Parser) Parse(expression string) (ASTNode, error) {
+	lexer := NewLexer()
+	p.expression = expression
+	p.index = 0
+	tokens, err := lexer.tokenize(expression)
+	if err != nil {
+		return ASTNode{}, err
+	}
+	p.tokens = tokens
+	parsed, err := p.parseExpression(0)
+	if err != nil {
+		return ASTNode{}, err
+	}
+	if p.current() != tEOF {
+		return ASTNode{}, p.syntaxError(fmt.Sprintf(
+			"Unexpected token at the end of the expresssion: %s", p.current()))
+	}
+	return parsed, nil
+}
+
+func (p *Parser) parseExpression(bindingPower int) (ASTNode, error) {
+	var err error
+	leftToken := p.lookaheadToken(0)
+	p.advance()
+	leftNode, err := p.nud(leftToken)
+	if err != nil {
+		return ASTNode{}, err
+	}
+	currentToken := p.current()
+	for bindingPower < bindingPowers[currentToken] {
+		p.advance()
+		leftNode, err = p.led(currentToken, leftNode)
+		if err != nil {
+			return ASTNode{}, err
+		}
+		currentToken = p.current()
+	}
+	return leftNode, nil
+}
+
+func (p *Parser) parseIndexExpression() (ASTNode, error) {
+	if p.lookahead(0) == tColon || p.lookahead(1) == tColon {
+		return p.parseSliceExpression()
+	}
+	indexStr := p.lookaheadToken(0).value
+	parsedInt, err := strconv.Atoi(indexStr)
+	if err != nil {
+		return ASTNode{}, err
+	}
+	indexNode := ASTNode{nodeType: ASTIndex, value: parsedInt}
+	p.advance()
+	if err := p.match(tRbracket); err != nil {
+		return ASTNode{}, err
+	}
+	return indexNode, nil
+}
+
+func (p *Parser) parseSliceExpression() (ASTNode, error) {
+	parts := []*int{nil, nil, nil}
+	index := 0
+	current := p.current()
+	for current != tRbracket && index < 3 {
+		if current == tColon {
+			index++
+			p.advance()
+		} else if current == tNumber {
+			parsedInt, err := strconv.Atoi(p.lookaheadToken(0).value)
+			if err != nil {
+				return ASTNode{}, err
+			}
+			parts[index] = &parsedInt
+			p.advance()
+		} else {
+			return ASTNode{}, p.syntaxError(
+				"Expected tColon or tNumber" + ", received: " + p.current().String())
+		}
+		current = p.current()
+	}
+	if err := p.match(tRbracket); err != nil {
+		return ASTNode{}, err
+	}
+	return ASTNode{
+		nodeType: ASTSlice,
+		value:    parts,
+	}, nil
+}
+
+func (p *Parser) match(tokenType tokType) error {
+	if p.current() == tokenType {
+		p.advance()
+		return nil
+	}
+	return p.syntaxError("Expected " + tokenType.String() + ", received: " + p.current().String())
+}
+
+func (p *Parser) led(tokenType tokType, node ASTNode) (ASTNode, error) {
+	switch tokenType {
+	case tDot:
+		if p.current() != tStar {
+			right, err := p.parseDotRHS(bindingPowers[tDot])
+			return ASTNode{
+				nodeType: ASTSubexpression,
+				children: []ASTNode{node, right},
+			}, err
+		}
+		p.advance()
+		right, err := p.parseProjectionRHS(bindingPowers[tDot])
+		return ASTNode{
+			nodeType: ASTValueProjection,
+			children: []ASTNode{node, right},
+		}, err
+	case tPipe:
+		right, err := p.parseExpression(bindingPowers[tPipe])
+		return ASTNode{nodeType: ASTPipe, children: []ASTNode{node, right}}, err
+	case tOr:
+		right, err := p.parseExpression(bindingPowers[tOr])
+		return ASTNode{nodeType: ASTOrExpression, children: []ASTNode{node, right}}, err
+	case tAnd:
+		right, err := p.parseExpression(bindingPowers[tAnd])
+		return ASTNode{nodeType: ASTAndExpression, children: []ASTNode{node, right}}, err
+	case tLparen:
+		name := node.value
+		var args []ASTNode
+		for p.current() != tRparen {
+			expression, err := p.parseExpression(0)
+			if err != nil {
+				return ASTNode{}, err
+			}
+			if p.current() == tComma {
+				if err := p.match(tComma); err != nil {
+					return ASTNode{}, err
+				}
+			}
+			args = append(args, expression)
+		}
+		if err := p.match(tRparen); err != nil {
+			return ASTNode{}, err
+		}
+		return ASTNode{
+			nodeType: ASTFunctionExpression,
+			value:    name,
+			children: args,
+		}, nil
+	case tFilter:
+		return p.parseFilter(node)
+	case tFlatten:
+		left := ASTNode{nodeType: ASTFlatten, children: []ASTNode{node}}
+		right, err := p.parseProjectionRHS(bindingPowers[tFlatten])
+		return ASTNode{
+			nodeType: ASTProjection,
+			children: []ASTNode{left, right},
+		}, err
+	case tEQ, tNE, tGT, tGTE, tLT, tLTE:
+		right, err := p.parseExpression(bindingPowers[tokenType])
+		if err != nil {
+			return ASTNode{}, err
+		}
+		return ASTNode{
+			nodeType: ASTComparator,
+			value:    tokenType,
+			children: []ASTNode{node, right},
+		}, nil
+	case tLbracket:
+		tokenType := p.current()
+		var right ASTNode
+		var err error
+		if tokenType == tNumber || tokenType == tColon {
+			right, err = p.parseIndexExpression()
+			if err != nil {
+				return ASTNode{}, err
+			}
+			return p.projectIfSlice(node, right)
+		}
+		// Otherwise this is a projection.
+		if err := p.match(tStar); err != nil {
+			return ASTNode{}, err
+		}
+		if err := p.match(tRbracket); err != nil {
+			return ASTNode{}, err
+		}
+		right, err = p.parseProjectionRHS(bindingPowers[tStar])
+		if err != nil {
+			return ASTNode{}, err
+		}
+		return ASTNode{
+			nodeType: ASTProjection,
+			children: []ASTNode{node, right},
+		}, nil
+	}
+	return ASTNode{}, p.syntaxError("Unexpected token: " + tokenType.String())
+}
+
+func (p *Parser) nud(token token) (ASTNode, error) {
+	switch token.tokenType {
+	case tJSONLiteral:
+		var parsed interface{}
+		err := json.Unmarshal([]byte(token.value), &parsed)
+		if err != nil {
+			return ASTNode{}, err
+		}
+		return ASTNode{nodeType: ASTLiteral, value: parsed}, nil
+	case tStringLiteral:
+		return ASTNode{nodeType: ASTLiteral, value: token.value}, nil
+	case tUnquotedIdentifier:
+		return ASTNode{
+			nodeType: ASTField,
+			value:    token.value,
+		}, nil
+	case tQuotedIdentifier:
+		node := ASTNode{nodeType: ASTField, value: token.value}
+		if p.current() == tLparen {
+			return ASTNode{}, p.syntaxErrorToken("Can't have quoted identifier as function name.", token)
+		}
+		return node, nil
+	case tStar:
+		left := ASTNode{nodeType: ASTIdentity}
+		var right ASTNode
+		var err error
+		if p.current() == tRbracket {
+			right = ASTNode{nodeType: ASTIdentity}
+		} else {
+			right, err = p.parseProjectionRHS(bindingPowers[tStar])
+		}
+		return ASTNode{nodeType: ASTValueProjection, children: []ASTNode{left, right}}, err
+	case tFilter:
+		return p.parseFilter(ASTNode{nodeType: ASTIdentity})
+	case tLbrace:
+		return p.parseMultiSelectHash()
+	case tFlatten:
+		left := ASTNode{
+			nodeType: ASTFlatten,
+			children: []ASTNode{{nodeType: ASTIdentity}},
+		}
+		right, err := p.parseProjectionRHS(bindingPowers[tFlatten])
+		if err != nil {
+			return ASTNode{}, err
+		}
+		return ASTNode{nodeType: ASTProjection, children: []ASTNode{left, right}}, nil
+	case tLbracket:
+		tokenType := p.current()
+		//var right ASTNode
+		if tokenType == tNumber || tokenType == tColon {
+			right, err := p.parseIndexExpression()
+			if err != nil {
+				return ASTNode{}, nil
+			}
+			return p.projectIfSlice(ASTNode{nodeType: ASTIdentity}, right)
+		} else if tokenType == tStar && p.lookahead(1) == tRbracket {
+			p.advance()
+			p.advance()
+			right, err := p.parseProjectionRHS(bindingPowers[tStar])
+			if err != nil {
+				return ASTNode{}, err
+			}
+			return ASTNode{
+				nodeType: ASTProjection,
+				children: []ASTNode{{nodeType: ASTIdentity}, right},
+			}, nil
+		} else {
+			return p.parseMultiSelectList()
+		}
+	case tCurrent:
+		return ASTNode{nodeType: ASTCurrentNode}, nil
+	case tExpref:
+		expression, err := p.parseExpression(bindingPowers[tExpref])
+		if err != nil {
+			return ASTNode{}, err
+		}
+		return ASTNode{nodeType: ASTExpRef, children: []ASTNode{expression}}, nil
+	case tNot:
+		expression, err := p.parseExpression(bindingPowers[tNot])
+		if err != nil {
+			return ASTNode{}, err
+		}
+		return ASTNode{nodeType: ASTNotExpression, children: []ASTNode{expression}}, nil
+	case tLparen:
+		expression, err := p.parseExpression(0)
+		if err != nil {
+			return ASTNode{}, err
+		}
+		if err := p.match(tRparen); err != nil {
+			return ASTNode{}, err
+		}
+		return expression, nil
+	case tEOF:
+		return ASTNode{}, p.syntaxErrorToken("Incomplete expression", token)
+	}
+
+	return ASTNode{}, p.syntaxErrorToken("Invalid token: "+token.tokenType.String(), token)
+}
+
+func (p *Parser) parseMultiSelectList() (ASTNode, error) {
+	var expressions []ASTNode
+	for {
+		expression, err := p.parseExpression(0)
+		if err != nil {
+			return ASTNode{}, err
+		}
+		expressions = append(expressions, expression)
+		if p.current() == tRbracket {
+			break
+		}
+		err = p.match(tComma)
+		if err != nil {
+			return ASTNode{}, err
+		}
+	}
+	err := p.match(tRbracket)
+	if err != nil {
+		return ASTNode{}, err
+	}
+	return ASTNode{
+		nodeType: ASTMultiSelectList,
+		children: expressions,
+	}, nil
+}
+
+func (p *Parser) parseMultiSelectHash() (ASTNode, error) {
+	var children []ASTNode
+	for {
+		keyToken := p.lookaheadToken(0)
+		if err := p.match(tUnquotedIdentifier); err != nil {
+			if err := p.match(tQuotedIdentifier); err != nil {
+				return ASTNode{}, p.syntaxError("Expected tQuotedIdentifier or tUnquotedIdentifier")
+			}
+		}
+		keyName := keyToken.value
+		err := p.match(tColon)
+		if err != nil {
+			return ASTNode{}, err
+		}
+		value, err := p.parseExpression(0)
+		if err != nil {
+			return ASTNode{}, err
+		}
+		node := ASTNode{
+			nodeType: ASTKeyValPair,
+			value:    keyName,
+			children: []ASTNode{value},
+		}
+		children = append(children, node)
+		if p.current() == tComma {
+			err := p.match(tComma)
+			if err != nil {
+				return ASTNode{}, nil
+			}
+		} else if p.current() == tRbrace {
+			err := p.match(tRbrace)
+			if err != nil {
+				return ASTNode{}, nil
+			}
+			break
+		}
+	}
+	return ASTNode{
+		nodeType: ASTMultiSelectHash,
+		children: children,
+	}, nil
+}
+
+func (p *Parser) projectIfSlice(left ASTNode, right ASTNode) (ASTNode, error) {
+	indexExpr := ASTNode{
+		nodeType: ASTIndexExpression,
+		children: []ASTNode{left, right},
+	}
+	if right.nodeType == ASTSlice {
+		right, err := p.parseProjectionRHS(bindingPowers[tStar])
+		return ASTNode{
+			nodeType: ASTProjection,
+			children: []ASTNode{indexExpr, right},
+		}, err
+	}
+	return indexExpr, nil
+}
+func (p *Parser) parseFilter(node ASTNode) (ASTNode, error) {
+	var right, condition ASTNode
+	var err error
+	condition, err = p.parseExpression(0)
+	if err != nil {
+		return ASTNode{}, err
+	}
+	if err := p.match(tRbracket); err != nil {
+		return ASTNode{}, err
+	}
+	if p.current() == tFlatten {
+		right = ASTNode{nodeType: ASTIdentity}
+	} else {
+		right, err = p.parseProjectionRHS(bindingPowers[tFilter])
+		if err != nil {
+			return ASTNode{}, err
+		}
+	}
+
+	return ASTNode{
+		nodeType: ASTFilterProjection,
+		children: []ASTNode{node, right, condition},
+	}, nil
+}
+
+func (p *Parser) parseDotRHS(bindingPower int) (ASTNode, error) {
+	lookahead := p.current()
+	if tokensOneOf([]tokType{tQuotedIdentifier, tUnquotedIdentifier, tStar}, lookahead) {
+		return p.parseExpression(bindingPower)
+	} else if lookahead == tLbracket {
+		if err := p.match(tLbracket); err != nil {
+			return ASTNode{}, err
+		}
+		return p.parseMultiSelectList()
+	} else if lookahead == tLbrace {
+		if err := p.match(tLbrace); err != nil {
+			return ASTNode{}, err
+		}
+		return p.parseMultiSelectHash()
+	}
+	return ASTNode{}, p.syntaxError("Expected identifier, lbracket, or lbrace")
+}
+
+func (p *Parser) parseProjectionRHS(bindingPower int) (ASTNode, error) {
+	current := p.current()
+	if bindingPowers[current] < 10 {
+		return ASTNode{nodeType: ASTIdentity}, nil
+	} else if current == tLbracket {
+		return p.parseExpression(bindingPower)
+	} else if current == tFilter {
+		return p.parseExpression(bindingPower)
+	} else if current == tDot {
+		err := p.match(tDot)
+		if err != nil {
+			return ASTNode{}, err
+		}
+		return p.parseDotRHS(bindingPower)
+	} else {
+		return ASTNode{}, p.syntaxError("Error")
+	}
+}
+
+func (p *Parser) lookahead(number int) tokType {
+	return p.lookaheadToken(number).tokenType
+}
+
+func (p *Parser) current() tokType {
+	return p.lookahead(0)
+}
+
+func (p *Parser) lookaheadToken(number int) token {
+	return p.tokens[p.index+number]
+}
+
+func (p *Parser) advance() {
+	p.index++
+}
+
+func tokensOneOf(elements []tokType, token tokType) bool {
+	for _, elem := range elements {
+		if elem == token {
+			return true
+		}
+	}
+	return false
+}
+
+func (p *Parser) syntaxError(msg string) SyntaxError {
+	return SyntaxError{
+		msg:        msg,
+		Expression: p.expression,
+		Offset:     p.lookaheadToken(0).position,
+	}
+}
+
+// Create a SyntaxError based on the provided token.
+// This differs from syntaxError() which creates a SyntaxError
+// based on the current lookahead token.
+func (p *Parser) syntaxErrorToken(msg string, t token) SyntaxError {
+	return SyntaxError{
+		msg:        msg,
+		Expression: p.expression,
+		Offset:     t.position,
+	}
+}
diff --git a/vendor/github.com/jmespath/go-jmespath/toktype_string.go b/vendor/github.com/jmespath/go-jmespath/toktype_string.go
new file mode 100644
index 000000000..dae79cbdf
--- /dev/null
+++ b/vendor/github.com/jmespath/go-jmespath/toktype_string.go
@@ -0,0 +1,16 @@
+// generated by stringer -type=tokType; DO NOT EDIT
+
+package jmespath
+
+import "fmt"
+
+const _tokType_name = "tUnknowntStartDottFiltertFlattentLparentRparentLbrackettRbrackettLbracetRbracetOrtPipetNumbertUnquotedIdentifiertQuotedIdentifiertCommatColontLTtLTEtGTtGTEtEQtNEtJSONLiteraltStringLiteraltCurrenttExpreftAndtNottEOF"
+
+var _tokType_index = [...]uint8{0, 8, 13, 17, 24, 32, 39, 46, 55, 64, 71, 78, 81, 86, 93, 112, 129, 135, 141, 144, 148, 151, 155, 158, 161, 173, 187, 195, 202, 206, 210, 214}
+
+func (i tokType) String() string {
+	if i < 0 || i >= tokType(len(_tokType_index)-1) {
+		return fmt.Sprintf("tokType(%d)", i)
+	}
+	return _tokType_name[_tokType_index[i]:_tokType_index[i+1]]
+}
diff --git a/vendor/github.com/jmespath/go-jmespath/util.go b/vendor/github.com/jmespath/go-jmespath/util.go
new file mode 100644
index 000000000..ddc1b7d7d
--- /dev/null
+++ b/vendor/github.com/jmespath/go-jmespath/util.go
@@ -0,0 +1,185 @@
+package jmespath
+
+import (
+	"errors"
+	"reflect"
+)
+
+// IsFalse determines if an object is false based on the JMESPath spec.
+// JMESPath defines false values to be any of:
+// - An empty string array, or hash.
+// - The boolean value false.
+// - nil
+func isFalse(value interface{}) bool {
+	switch v := value.(type) {
+	case bool:
+		return !v
+	case []interface{}:
+		return len(v) == 0
+	case map[string]interface{}:
+		return len(v) == 0
+	case string:
+		return len(v) == 0
+	case nil:
+		return true
+	}
+	// Try the reflection cases before returning false.
+	rv := reflect.ValueOf(value)
+	switch rv.Kind() {
+	case reflect.Struct:
+		// A struct type will never be false, even if
+		// all of its values are the zero type.
+		return false
+	case reflect.Slice, reflect.Map:
+		return rv.Len() == 0
+	case reflect.Ptr:
+		if rv.IsNil() {
+			return true
+		}
+		// If it's a pointer type, we'll try to deref the pointer
+		// and evaluate the pointer value for isFalse.
+		element := rv.Elem()
+		return isFalse(element.Interface())
+	}
+	return false
+}
+
+// ObjsEqual is a generic object equality check.
+// It will take two arbitrary objects and recursively determine
+// if they are equal.
+func objsEqual(left interface{}, right interface{}) bool {
+	return reflect.DeepEqual(left, right)
+}
+
+// SliceParam refers to a single part of a slice.
+// A slice consists of a start, a stop, and a step, similar to
+// python slices.
+type sliceParam struct {
+	N         int
+	Specified bool
+}
+
+// Slice supports [start:stop:step] style slicing that's supported in JMESPath.
+func slice(slice []interface{}, parts []sliceParam) ([]interface{}, error) {
+	computed, err := computeSliceParams(len(slice), parts)
+	if err != nil {
+		return nil, err
+	}
+	start, stop, step := computed[0], computed[1], computed[2]
+	result := []interface{}{}
+	if step > 0 {
+		for i := start; i < stop; i += step {
+			result = append(result, slice[i])
+		}
+	} else {
+		for i := start; i > stop; i += step {
+			result = append(result, slice[i])
+		}
+	}
+	return result, nil
+}
+
+func computeSliceParams(length int, parts []sliceParam) ([]int, error) {
+	var start, stop, step int
+	if !parts[2].Specified {
+		step = 1
+	} else if parts[2].N == 0 {
+		return nil, errors.New("Invalid slice, step cannot be 0")
+	} else {
+		step = parts[2].N
+	}
+	var stepValueNegative bool
+	if step < 0 {
+		stepValueNegative = true
+	} else {
+		stepValueNegative = false
+	}
+
+	if !parts[0].Specified {
+		if stepValueNegative {
+			start = length - 1
+		} else {
+			start = 0
+		}
+	} else {
+		start = capSlice(length, parts[0].N, step)
+	}
+
+	if !parts[1].Specified {
+		if stepValueNegative {
+			stop = -1
+		} else {
+			stop = length
+		}
+	} else {
+		stop = capSlice(length, parts[1].N, step)
+	}
+	return []int{start, stop, step}, nil
+}
+
+func capSlice(length int, actual int, step int) int {
+	if actual < 0 {
+		actual += length
+		if actual < 0 {
+			if step < 0 {
+				actual = -1
+			} else {
+				actual = 0
+			}
+		}
+	} else if actual >= length {
+		if step < 0 {
+			actual = length - 1
+		} else {
+			actual = length
+		}
+	}
+	return actual
+}
+
+// ToArrayNum converts an empty interface type to a slice of float64.
+// If any element in the array cannot be converted, then nil is returned
+// along with a second value of false.
+func toArrayNum(data interface{}) ([]float64, bool) {
+	// Is there a better way to do this with reflect?
+	if d, ok := data.([]interface{}); ok {
+		result := make([]float64, len(d))
+		for i, el := range d {
+			item, ok := el.(float64)
+			if !ok {
+				return nil, false
+			}
+			result[i] = item
+		}
+		return result, true
+	}
+	return nil, false
+}
+
+// ToArrayStr converts an empty interface type to a slice of strings.
+// If any element in the array cannot be converted, then nil is returned
+// along with a second value of false.  If the input data could be entirely
+// converted, then the converted data, along with a second value of true,
+// will be returned.
+func toArrayStr(data interface{}) ([]string, bool) {
+	// Is there a better way to do this with reflect?
+	if d, ok := data.([]interface{}); ok {
+		result := make([]string, len(d))
+		for i, el := range d {
+			item, ok := el.(string)
+			if !ok {
+				return nil, false
+			}
+			result[i] = item
+		}
+		return result, true
+	}
+	return nil, false
+}
+
+func isSliceType(v interface{}) bool {
+	if v == nil {
+		return false
+	}
+	return reflect.TypeOf(v).Kind() == reflect.Slice
+}
diff --git a/vendor/github.com/kardianos/osext/LICENSE b/vendor/github.com/kardianos/osext/LICENSE
new file mode 100644
index 000000000..744875676
--- /dev/null
+++ b/vendor/github.com/kardianos/osext/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2012 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/kardianos/osext/osext.go b/vendor/github.com/kardianos/osext/osext.go
new file mode 100644
index 000000000..17f380f0e
--- /dev/null
+++ b/vendor/github.com/kardianos/osext/osext.go
@@ -0,0 +1,33 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Extensions to the standard "os" package.
+package osext // import "github.com/kardianos/osext"
+
+import "path/filepath"
+
+var cx, ce = executableClean()
+
+func executableClean() (string, error) {
+	p, err := executable()
+	return filepath.Clean(p), err
+}
+
+// Executable returns an absolute path that can be used to
+// re-invoke the current program.
+// It may not be valid after the current program exits.
+func Executable() (string, error) {
+	return cx, ce
+}
+
+// Returns same path as Executable, returns just the folder
+// path. Excludes the executable name and any trailing slash.
+func ExecutableFolder() (string, error) {
+	p, err := Executable()
+	if err != nil {
+		return "", err
+	}
+
+	return filepath.Dir(p), nil
+}
diff --git a/vendor/github.com/kardianos/osext/osext_go18.go b/vendor/github.com/kardianos/osext/osext_go18.go
new file mode 100644
index 000000000..009d8a926
--- /dev/null
+++ b/vendor/github.com/kardianos/osext/osext_go18.go
@@ -0,0 +1,9 @@
+//+build go1.8,!openbsd
+
+package osext
+
+import "os"
+
+func executable() (string, error) {
+	return os.Executable()
+}
diff --git a/vendor/github.com/kardianos/osext/osext_plan9.go b/vendor/github.com/kardianos/osext/osext_plan9.go
new file mode 100644
index 000000000..95e237137
--- /dev/null
+++ b/vendor/github.com/kardianos/osext/osext_plan9.go
@@ -0,0 +1,22 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//+build !go1.8
+
+package osext
+
+import (
+	"os"
+	"strconv"
+	"syscall"
+)
+
+func executable() (string, error) {
+	f, err := os.Open("/proc/" + strconv.Itoa(os.Getpid()) + "/text")
+	if err != nil {
+		return "", err
+	}
+	defer f.Close()
+	return syscall.Fd2path(int(f.Fd()))
+}
diff --git a/vendor/github.com/kardianos/osext/osext_procfs.go b/vendor/github.com/kardianos/osext/osext_procfs.go
new file mode 100644
index 000000000..e1f16f885
--- /dev/null
+++ b/vendor/github.com/kardianos/osext/osext_procfs.go
@@ -0,0 +1,36 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.8,android !go1.8,linux !go1.8,netbsd !go1.8,solaris !go1.8,dragonfly
+
+package osext
+
+import (
+	"errors"
+	"fmt"
+	"os"
+	"runtime"
+	"strings"
+)
+
+func executable() (string, error) {
+	switch runtime.GOOS {
+	case "linux", "android":
+		const deletedTag = " (deleted)"
+		execpath, err := os.Readlink("/proc/self/exe")
+		if err != nil {
+			return execpath, err
+		}
+		execpath = strings.TrimSuffix(execpath, deletedTag)
+		execpath = strings.TrimPrefix(execpath, deletedTag)
+		return execpath, nil
+	case "netbsd":
+		return os.Readlink("/proc/curproc/exe")
+	case "dragonfly":
+		return os.Readlink("/proc/curproc/file")
+	case "solaris":
+		return os.Readlink(fmt.Sprintf("/proc/%d/path/a.out", os.Getpid()))
+	}
+	return "", errors.New("ExecPath not implemented for " + runtime.GOOS)
+}
diff --git a/vendor/github.com/kardianos/osext/osext_sysctl.go b/vendor/github.com/kardianos/osext/osext_sysctl.go
new file mode 100644
index 000000000..33cee2522
--- /dev/null
+++ b/vendor/github.com/kardianos/osext/osext_sysctl.go
@@ -0,0 +1,126 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.8,darwin !go1.8,freebsd openbsd
+
+package osext
+
+import (
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"syscall"
+	"unsafe"
+)
+
+var initCwd, initCwdErr = os.Getwd()
+
+func executable() (string, error) {
+	var mib [4]int32
+	switch runtime.GOOS {
+	case "freebsd":
+		mib = [4]int32{1 /* CTL_KERN */, 14 /* KERN_PROC */, 12 /* KERN_PROC_PATHNAME */, -1}
+	case "darwin":
+		mib = [4]int32{1 /* CTL_KERN */, 38 /* KERN_PROCARGS */, int32(os.Getpid()), -1}
+	case "openbsd":
+		mib = [4]int32{1 /* CTL_KERN */, 55 /* KERN_PROC_ARGS */, int32(os.Getpid()), 1 /* KERN_PROC_ARGV */}
+	}
+
+	n := uintptr(0)
+	// Get length.
+	_, _, errNum := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 4, 0, uintptr(unsafe.Pointer(&n)), 0, 0)
+	if errNum != 0 {
+		return "", errNum
+	}
+	if n == 0 { // This shouldn't happen.
+		return "", nil
+	}
+	buf := make([]byte, n)
+	_, _, errNum = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 4, uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&n)), 0, 0)
+	if errNum != 0 {
+		return "", errNum
+	}
+	if n == 0 { // This shouldn't happen.
+		return "", nil
+	}
+
+	var execPath string
+	switch runtime.GOOS {
+	case "openbsd":
+		// buf now contains **argv, with pointers to each of the C-style
+		// NULL terminated arguments.
+		var args []string
+		argv := uintptr(unsafe.Pointer(&buf[0]))
+	Loop:
+		for {
+			argp := *(**[1 << 20]byte)(unsafe.Pointer(argv))
+			if argp == nil {
+				break
+			}
+			for i := 0; uintptr(i) < n; i++ {
+				// we don't want the full arguments list
+				if string(argp[i]) == " " {
+					break Loop
+				}
+				if argp[i] != 0 {
+					continue
+				}
+				args = append(args, string(argp[:i]))
+				n -= uintptr(i)
+				break
+			}
+			if n < unsafe.Sizeof(argv) {
+				break
+			}
+			argv += unsafe.Sizeof(argv)
+			n -= unsafe.Sizeof(argv)
+		}
+		execPath = args[0]
+		// There is no canonical way to get an executable path on
+		// OpenBSD, so check PATH in case we are called directly
+		if execPath[0] != '/' && execPath[0] != '.' {
+			execIsInPath, err := exec.LookPath(execPath)
+			if err == nil {
+				execPath = execIsInPath
+			}
+		}
+	default:
+		for i, v := range buf {
+			if v == 0 {
+				buf = buf[:i]
+				break
+			}
+		}
+		execPath = string(buf)
+	}
+
+	var err error
+	// execPath will not be empty due to above checks.
+	// Try to get the absolute path if the execPath is not rooted.
+	if execPath[0] != '/' {
+		execPath, err = getAbs(execPath)
+		if err != nil {
+			return execPath, err
+		}
+	}
+	// For darwin KERN_PROCARGS may return the path to a symlink rather than the
+	// actual executable.
+	if runtime.GOOS == "darwin" {
+		if execPath, err = filepath.EvalSymlinks(execPath); err != nil {
+			return execPath, err
+		}
+	}
+	return execPath, nil
+}
+
+func getAbs(execPath string) (string, error) {
+	if initCwdErr != nil {
+		return execPath, initCwdErr
+	}
+	// The execPath may begin with a "../" or a "./" so clean it first.
+	// Join the two paths, trailing and starting slashes undetermined, so use
+	// the generic Join function.
+	return filepath.Join(initCwd, filepath.Clean(execPath)), nil
+}
diff --git a/vendor/github.com/kardianos/osext/osext_windows.go b/vendor/github.com/kardianos/osext/osext_windows.go
new file mode 100644
index 000000000..074b3b385
--- /dev/null
+++ b/vendor/github.com/kardianos/osext/osext_windows.go
@@ -0,0 +1,36 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//+build !go1.8
+
+package osext
+
+import (
+	"syscall"
+	"unicode/utf16"
+	"unsafe"
+)
+
+var (
+	kernel                = syscall.MustLoadDLL("kernel32.dll")
+	getModuleFileNameProc = kernel.MustFindProc("GetModuleFileNameW")
+)
+
+// GetModuleFileName() with hModule = NULL
+func executable() (exePath string, err error) {
+	return getModuleFileName()
+}
+
+func getModuleFileName() (string, error) {
+	var n uint32
+	b := make([]uint16, syscall.MAX_PATH)
+	size := uint32(len(b))
+
+	r0, _, e1 := getModuleFileNameProc.Call(0, uintptr(unsafe.Pointer(&b[0])), uintptr(size))
+	n = uint32(r0)
+	if n == 0 {
+		return "", e1
+	}
+	return string(utf16.Decode(b[0:n])), nil
+}
diff --git a/vendor/github.com/mitchellh/go-testing-interface/LICENSE b/vendor/github.com/mitchellh/go-testing-interface/LICENSE
new file mode 100644
index 000000000..a3866a291
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-testing-interface/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Mitchell Hashimoto
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/github.com/mitchellh/go-testing-interface/testing.go b/vendor/github.com/mitchellh/go-testing-interface/testing.go
new file mode 100644
index 000000000..204afb420
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-testing-interface/testing.go
@@ -0,0 +1,84 @@
+// +build !go1.9
+
+package testing
+
+import (
+	"fmt"
+	"log"
+)
+
+// T is the interface that mimics the standard library *testing.T.
+//
+// In unit tests you can just pass a *testing.T struct. At runtime, outside
+// of tests, you can pass in a RuntimeT struct from this package.
+type T interface {
+	Error(args ...interface{})
+	Errorf(format string, args ...interface{})
+	Fail()
+	FailNow()
+	Failed() bool
+	Fatal(args ...interface{})
+	Fatalf(format string, args ...interface{})
+	Log(args ...interface{})
+	Logf(format string, args ...interface{})
+	Name() string
+	Skip(args ...interface{})
+	SkipNow()
+	Skipf(format string, args ...interface{})
+	Skipped() bool
+}
+
+// RuntimeT implements T and can be instantiated and run at runtime to
+// mimic *testing.T behavior. Unlike *testing.T, this will simply panic
+// for calls to Fatal. For calls to Error, you'll have to check the errors
+// list to determine whether to exit yourself. Name and Skip methods are
+// unimplemented noops.
+type RuntimeT struct {
+	failed bool
+}
+
+func (t *RuntimeT) Error(args ...interface{}) {
+	log.Println(fmt.Sprintln(args...))
+	t.Fail()
+}
+
+func (t *RuntimeT) Errorf(format string, args ...interface{}) {
+	log.Println(fmt.Sprintf(format, args...))
+	t.Fail()
+}
+
+func (t *RuntimeT) Fatal(args ...interface{}) {
+	log.Println(fmt.Sprintln(args...))
+	t.FailNow()
+}
+
+func (t *RuntimeT) Fatalf(format string, args ...interface{}) {
+	log.Println(fmt.Sprintf(format, args...))
+	t.FailNow()
+}
+
+func (t *RuntimeT) Fail() {
+	t.failed = true
+}
+
+func (t *RuntimeT) FailNow() {
+	panic("testing.T failed, see logs for output (if any)")
+}
+
+func (t *RuntimeT) Failed() bool {
+	return t.failed
+}
+
+func (t *RuntimeT) Log(args ...interface{}) {
+	log.Println(fmt.Sprintln(args...))
+}
+
+func (t *RuntimeT) Logf(format string, args ...interface{}) {
+	log.Println(fmt.Sprintf(format, args...))
+}
+
+func (t *RuntimeT) Name() string                             { return "" }
+func (t *RuntimeT) Skip(args ...interface{})                 {}
+func (t *RuntimeT) SkipNow()                                 {}
+func (t *RuntimeT) Skipf(format string, args ...interface{}) {}
+func (t *RuntimeT) Skipped() bool                            { return false }
diff --git a/vendor/github.com/mitchellh/go-testing-interface/testing_go19.go b/vendor/github.com/mitchellh/go-testing-interface/testing_go19.go
new file mode 100644
index 000000000..31b42cadf
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-testing-interface/testing_go19.go
@@ -0,0 +1,108 @@
+// +build go1.9
+
+// NOTE: This is a temporary copy of testing.go for Go 1.9 with the addition
+// of "Helper" to the T interface. Go 1.9 at the time of typing is in RC
+// and is set for release shortly. We'll support this on master as the default
+// as soon as 1.9 is released.
+
+package testing
+
+import (
+	"fmt"
+	"log"
+)
+
+// T is the interface that mimics the standard library *testing.T.
+//
+// In unit tests you can just pass a *testing.T struct. At runtime, outside
+// of tests, you can pass in a RuntimeT struct from this package.
+type T interface {
+	Error(args ...interface{})
+	Errorf(format string, args ...interface{})
+	Fail()
+	FailNow()
+	Failed() bool
+	Fatal(args ...interface{})
+	Fatalf(format string, args ...interface{})
+	Log(args ...interface{})
+	Logf(format string, args ...interface{})
+	Name() string
+	Skip(args ...interface{})
+	SkipNow()
+	Skipf(format string, args ...interface{})
+	Skipped() bool
+	Helper()
+}
+
+// RuntimeT implements T and can be instantiated and run at runtime to
+// mimic *testing.T behavior. Unlike *testing.T, this will simply panic
+// for calls to Fatal. For calls to Error, you'll have to check the errors
+// list to determine whether to exit yourself.
+type RuntimeT struct {
+	skipped bool
+	failed  bool
+}
+
+func (t *RuntimeT) Error(args ...interface{}) {
+	log.Println(fmt.Sprintln(args...))
+	t.Fail()
+}
+
+func (t *RuntimeT) Errorf(format string, args ...interface{}) {
+	log.Printf(format, args...)
+	t.Fail()
+}
+
+func (t *RuntimeT) Fail() {
+	t.failed = true
+}
+
+func (t *RuntimeT) FailNow() {
+	panic("testing.T failed, see logs for output (if any)")
+}
+
+func (t *RuntimeT) Failed() bool {
+	return t.failed
+}
+
+func (t *RuntimeT) Fatal(args ...interface{}) {
+	log.Print(args...)
+	t.FailNow()
+}
+
+func (t *RuntimeT) Fatalf(format string, args ...interface{}) {
+	log.Printf(format, args...)
+	t.FailNow()
+}
+
+func (t *RuntimeT) Log(args ...interface{}) {
+	log.Println(fmt.Sprintln(args...))
+}
+
+func (t *RuntimeT) Logf(format string, args ...interface{}) {
+	log.Println(fmt.Sprintf(format, args...))
+}
+
+func (t *RuntimeT) Name() string {
+	return ""
+}
+
+func (t *RuntimeT) Skip(args ...interface{}) {
+	log.Print(args...)
+	t.SkipNow()
+}
+
+func (t *RuntimeT) SkipNow() {
+	t.skipped = true
+}
+
+func (t *RuntimeT) Skipf(format string, args ...interface{}) {
+	log.Printf(format, args...)
+	t.SkipNow()
+}
+
+func (t *RuntimeT) Skipped() bool {
+	return t.skipped
+}
+
+func (t *RuntimeT) Helper() {}
diff --git a/vendor/github.com/pkg/errors/LICENSE b/vendor/github.com/pkg/errors/LICENSE
new file mode 100644
index 000000000..835ba3e75
--- /dev/null
+++ b/vendor/github.com/pkg/errors/LICENSE
@@ -0,0 +1,23 @@
+Copyright (c) 2015, Dave Cheney 
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/pkg/errors/errors.go b/vendor/github.com/pkg/errors/errors.go
new file mode 100644
index 000000000..842ee8045
--- /dev/null
+++ b/vendor/github.com/pkg/errors/errors.go
@@ -0,0 +1,269 @@
+// Package errors provides simple error handling primitives.
+//
+// The traditional error handling idiom in Go is roughly akin to
+//
+//     if err != nil {
+//             return err
+//     }
+//
+// which applied recursively up the call stack results in error reports
+// without context or debugging information. The errors package allows
+// programmers to add context to the failure path in their code in a way
+// that does not destroy the original value of the error.
+//
+// Adding context to an error
+//
+// The errors.Wrap function returns a new error that adds context to the
+// original error by recording a stack trace at the point Wrap is called,
+// and the supplied message. For example
+//
+//     _, err := ioutil.ReadAll(r)
+//     if err != nil {
+//             return errors.Wrap(err, "read failed")
+//     }
+//
+// If additional control is required the errors.WithStack and errors.WithMessage
+// functions destructure errors.Wrap into its component operations of annotating
+// an error with a stack trace and an a message, respectively.
+//
+// Retrieving the cause of an error
+//
+// Using errors.Wrap constructs a stack of errors, adding context to the
+// preceding error. Depending on the nature of the error it may be necessary
+// to reverse the operation of errors.Wrap to retrieve the original error
+// for inspection. Any error value which implements this interface
+//
+//     type causer interface {
+//             Cause() error
+//     }
+//
+// can be inspected by errors.Cause. errors.Cause will recursively retrieve
+// the topmost error which does not implement causer, which is assumed to be
+// the original cause. For example:
+//
+//     switch err := errors.Cause(err).(type) {
+//     case *MyError:
+//             // handle specifically
+//     default:
+//             // unknown error
+//     }
+//
+// causer interface is not exported by this package, but is considered a part
+// of stable public API.
+//
+// Formatted printing of errors
+//
+// All error values returned from this package implement fmt.Formatter and can
+// be formatted by the fmt package. The following verbs are supported
+//
+//     %s    print the error. If the error has a Cause it will be
+//           printed recursively
+//     %v    see %s
+//     %+v   extended format. Each Frame of the error's StackTrace will
+//           be printed in detail.
+//
+// Retrieving the stack trace of an error or wrapper
+//
+// New, Errorf, Wrap, and Wrapf record a stack trace at the point they are
+// invoked. This information can be retrieved with the following interface.
+//
+//     type stackTracer interface {
+//             StackTrace() errors.StackTrace
+//     }
+//
+// Where errors.StackTrace is defined as
+//
+//     type StackTrace []Frame
+//
+// The Frame type represents a call site in the stack trace. Frame supports
+// the fmt.Formatter interface that can be used for printing information about
+// the stack trace of this error. For example:
+//
+//     if err, ok := err.(stackTracer); ok {
+//             for _, f := range err.StackTrace() {
+//                     fmt.Printf("%+s:%d", f)
+//             }
+//     }
+//
+// stackTracer interface is not exported by this package, but is considered a part
+// of stable public API.
+//
+// See the documentation for Frame.Format for more details.
+package errors
+
+import (
+	"fmt"
+	"io"
+)
+
+// New returns an error with the supplied message.
+// New also records the stack trace at the point it was called.
+func New(message string) error {
+	return &fundamental{
+		msg:   message,
+		stack: callers(),
+	}
+}
+
+// Errorf formats according to a format specifier and returns the string
+// as a value that satisfies error.
+// Errorf also records the stack trace at the point it was called.
+func Errorf(format string, args ...interface{}) error {
+	return &fundamental{
+		msg:   fmt.Sprintf(format, args...),
+		stack: callers(),
+	}
+}
+
+// fundamental is an error that has a message and a stack, but no caller.
+type fundamental struct {
+	msg string
+	*stack
+}
+
+func (f *fundamental) Error() string { return f.msg }
+
+func (f *fundamental) Format(s fmt.State, verb rune) {
+	switch verb {
+	case 'v':
+		if s.Flag('+') {
+			io.WriteString(s, f.msg)
+			f.stack.Format(s, verb)
+			return
+		}
+		fallthrough
+	case 's':
+		io.WriteString(s, f.msg)
+	case 'q':
+		fmt.Fprintf(s, "%q", f.msg)
+	}
+}
+
+// WithStack annotates err with a stack trace at the point WithStack was called.
+// If err is nil, WithStack returns nil.
+func WithStack(err error) error {
+	if err == nil {
+		return nil
+	}
+	return &withStack{
+		err,
+		callers(),
+	}
+}
+
+type withStack struct {
+	error
+	*stack
+}
+
+func (w *withStack) Cause() error { return w.error }
+
+func (w *withStack) Format(s fmt.State, verb rune) {
+	switch verb {
+	case 'v':
+		if s.Flag('+') {
+			fmt.Fprintf(s, "%+v", w.Cause())
+			w.stack.Format(s, verb)
+			return
+		}
+		fallthrough
+	case 's':
+		io.WriteString(s, w.Error())
+	case 'q':
+		fmt.Fprintf(s, "%q", w.Error())
+	}
+}
+
+// Wrap returns an error annotating err with a stack trace
+// at the point Wrap is called, and the supplied message.
+// If err is nil, Wrap returns nil.
+func Wrap(err error, message string) error {
+	if err == nil {
+		return nil
+	}
+	err = &withMessage{
+		cause: err,
+		msg:   message,
+	}
+	return &withStack{
+		err,
+		callers(),
+	}
+}
+
+// Wrapf returns an error annotating err with a stack trace
+// at the point Wrapf is call, and the format specifier.
+// If err is nil, Wrapf returns nil.
+func Wrapf(err error, format string, args ...interface{}) error {
+	if err == nil {
+		return nil
+	}
+	err = &withMessage{
+		cause: err,
+		msg:   fmt.Sprintf(format, args...),
+	}
+	return &withStack{
+		err,
+		callers(),
+	}
+}
+
+// WithMessage annotates err with a new message.
+// If err is nil, WithMessage returns nil.
+func WithMessage(err error, message string) error {
+	if err == nil {
+		return nil
+	}
+	return &withMessage{
+		cause: err,
+		msg:   message,
+	}
+}
+
+type withMessage struct {
+	cause error
+	msg   string
+}
+
+func (w *withMessage) Error() string { return w.msg + ": " + w.cause.Error() }
+func (w *withMessage) Cause() error  { return w.cause }
+
+func (w *withMessage) Format(s fmt.State, verb rune) {
+	switch verb {
+	case 'v':
+		if s.Flag('+') {
+			fmt.Fprintf(s, "%+v\n", w.Cause())
+			io.WriteString(s, w.msg)
+			return
+		}
+		fallthrough
+	case 's', 'q':
+		io.WriteString(s, w.Error())
+	}
+}
+
+// Cause returns the underlying cause of the error, if possible.
+// An error value has a cause if it implements the following
+// interface:
+//
+//     type causer interface {
+//            Cause() error
+//     }
+//
+// If the error does not implement Cause, the original error will
+// be returned. If the error is nil, nil will be returned without further
+// investigation.
+func Cause(err error) error {
+	type causer interface {
+		Cause() error
+	}
+
+	for err != nil {
+		cause, ok := err.(causer)
+		if !ok {
+			break
+		}
+		err = cause.Cause()
+	}
+	return err
+}
diff --git a/vendor/github.com/pkg/errors/stack.go b/vendor/github.com/pkg/errors/stack.go
new file mode 100644
index 000000000..6b1f2891a
--- /dev/null
+++ b/vendor/github.com/pkg/errors/stack.go
@@ -0,0 +1,178 @@
+package errors
+
+import (
+	"fmt"
+	"io"
+	"path"
+	"runtime"
+	"strings"
+)
+
+// Frame represents a program counter inside a stack frame.
+type Frame uintptr
+
+// pc returns the program counter for this frame;
+// multiple frames may have the same PC value.
+func (f Frame) pc() uintptr { return uintptr(f) - 1 }
+
+// file returns the full path to the file that contains the
+// function for this Frame's pc.
+func (f Frame) file() string {
+	fn := runtime.FuncForPC(f.pc())
+	if fn == nil {
+		return "unknown"
+	}
+	file, _ := fn.FileLine(f.pc())
+	return file
+}
+
+// line returns the line number of source code of the
+// function for this Frame's pc.
+func (f Frame) line() int {
+	fn := runtime.FuncForPC(f.pc())
+	if fn == nil {
+		return 0
+	}
+	_, line := fn.FileLine(f.pc())
+	return line
+}
+
+// Format formats the frame according to the fmt.Formatter interface.
+//
+//    %s    source file
+//    %d    source line
+//    %n    function name
+//    %v    equivalent to %s:%d
+//
+// Format accepts flags that alter the printing of some verbs, as follows:
+//
+//    %+s   path of source file relative to the compile time GOPATH
+//    %+v   equivalent to %+s:%d
+func (f Frame) Format(s fmt.State, verb rune) {
+	switch verb {
+	case 's':
+		switch {
+		case s.Flag('+'):
+			pc := f.pc()
+			fn := runtime.FuncForPC(pc)
+			if fn == nil {
+				io.WriteString(s, "unknown")
+			} else {
+				file, _ := fn.FileLine(pc)
+				fmt.Fprintf(s, "%s\n\t%s", fn.Name(), file)
+			}
+		default:
+			io.WriteString(s, path.Base(f.file()))
+		}
+	case 'd':
+		fmt.Fprintf(s, "%d", f.line())
+	case 'n':
+		name := runtime.FuncForPC(f.pc()).Name()
+		io.WriteString(s, funcname(name))
+	case 'v':
+		f.Format(s, 's')
+		io.WriteString(s, ":")
+		f.Format(s, 'd')
+	}
+}
+
+// StackTrace is stack of Frames from innermost (newest) to outermost (oldest).
+type StackTrace []Frame
+
+func (st StackTrace) Format(s fmt.State, verb rune) {
+	switch verb {
+	case 'v':
+		switch {
+		case s.Flag('+'):
+			for _, f := range st {
+				fmt.Fprintf(s, "\n%+v", f)
+			}
+		case s.Flag('#'):
+			fmt.Fprintf(s, "%#v", []Frame(st))
+		default:
+			fmt.Fprintf(s, "%v", []Frame(st))
+		}
+	case 's':
+		fmt.Fprintf(s, "%s", []Frame(st))
+	}
+}
+
+// stack represents a stack of program counters.
+type stack []uintptr
+
+func (s *stack) Format(st fmt.State, verb rune) {
+	switch verb {
+	case 'v':
+		switch {
+		case st.Flag('+'):
+			for _, pc := range *s {
+				f := Frame(pc)
+				fmt.Fprintf(st, "\n%+v", f)
+			}
+		}
+	}
+}
+
+func (s *stack) StackTrace() StackTrace {
+	f := make([]Frame, len(*s))
+	for i := 0; i < len(f); i++ {
+		f[i] = Frame((*s)[i])
+	}
+	return f
+}
+
+func callers() *stack {
+	const depth = 32
+	var pcs [depth]uintptr
+	n := runtime.Callers(3, pcs[:])
+	var st stack = pcs[0:n]
+	return &st
+}
+
+// funcname removes the path prefix component of a function's name reported by func.Name().
+func funcname(name string) string {
+	i := strings.LastIndex(name, "/")
+	name = name[i+1:]
+	i = strings.Index(name, ".")
+	return name[i+1:]
+}
+
+func trimGOPATH(name, file string) string {
+	// Here we want to get the source file path relative to the compile time
+	// GOPATH. As of Go 1.6.x there is no direct way to know the compiled
+	// GOPATH at runtime, but we can infer the number of path segments in the
+	// GOPATH. We note that fn.Name() returns the function name qualified by
+	// the import path, which does not include the GOPATH. Thus we can trim
+	// segments from the beginning of the file path until the number of path
+	// separators remaining is one more than the number of path separators in
+	// the function name. For example, given:
+	//
+	//    GOPATH     /home/user
+	//    file       /home/user/src/pkg/sub/file.go
+	//    fn.Name()  pkg/sub.Type.Method
+	//
+	// We want to produce:
+	//
+	//    pkg/sub/file.go
+	//
+	// From this we can easily see that fn.Name() has one less path separator
+	// than our desired output. We count separators from the end of the file
+	// path until it finds two more than in the function name and then move
+	// one character forward to preserve the initial path segment without a
+	// leading separator.
+	const sep = "/"
+	goal := strings.Count(name, sep) + 2
+	i := len(file)
+	for n := 0; n < goal; n++ {
+		i = strings.LastIndex(file[:i], sep)
+		if i == -1 {
+			// not enough separators found, set i so that the slice expression
+			// below leaves file unmodified
+			i = -len(sep)
+			break
+		}
+	}
+	// get back to 0 or trim the leading separator
+	file = file[i+len(sep):]
+	return file
+}
diff --git a/vendor/github.com/pmezard/go-difflib/LICENSE b/vendor/github.com/pmezard/go-difflib/LICENSE
new file mode 100644
index 000000000..c67dad612
--- /dev/null
+++ b/vendor/github.com/pmezard/go-difflib/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2013, Patrick Mezard
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+    Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+    The names of its contributors may not be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/pmezard/go-difflib/difflib/difflib.go b/vendor/github.com/pmezard/go-difflib/difflib/difflib.go
new file mode 100644
index 000000000..003e99fad
--- /dev/null
+++ b/vendor/github.com/pmezard/go-difflib/difflib/difflib.go
@@ -0,0 +1,772 @@
+// Package difflib is a partial port of Python difflib module.
+//
+// It provides tools to compare sequences of strings and generate textual diffs.
+//
+// The following class and functions have been ported:
+//
+// - SequenceMatcher
+//
+// - unified_diff
+//
+// - context_diff
+//
+// Getting unified diffs was the main goal of the port. Keep in mind this code
+// is mostly suitable to output text differences in a human friendly way, there
+// are no guarantees generated diffs are consumable by patch(1).
+package difflib
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io"
+	"strings"
+)
+
+func min(a, b int) int {
+	if a < b {
+		return a
+	}
+	return b
+}
+
+func max(a, b int) int {
+	if a > b {
+		return a
+	}
+	return b
+}
+
+func calculateRatio(matches, length int) float64 {
+	if length > 0 {
+		return 2.0 * float64(matches) / float64(length)
+	}
+	return 1.0
+}
+
+type Match struct {
+	A    int
+	B    int
+	Size int
+}
+
+type OpCode struct {
+	Tag byte
+	I1  int
+	I2  int
+	J1  int
+	J2  int
+}
+
+// SequenceMatcher compares sequence of strings. The basic
+// algorithm predates, and is a little fancier than, an algorithm
+// published in the late 1980's by Ratcliff and Obershelp under the
+// hyperbolic name "gestalt pattern matching".  The basic idea is to find
+// the longest contiguous matching subsequence that contains no "junk"
+// elements (R-O doesn't address junk).  The same idea is then applied
+// recursively to the pieces of the sequences to the left and to the right
+// of the matching subsequence.  This does not yield minimal edit
+// sequences, but does tend to yield matches that "look right" to people.
+//
+// SequenceMatcher tries to compute a "human-friendly diff" between two
+// sequences.  Unlike e.g. UNIX(tm) diff, the fundamental notion is the
+// longest *contiguous* & junk-free matching subsequence.  That's what
+// catches peoples' eyes.  The Windows(tm) windiff has another interesting
+// notion, pairing up elements that appear uniquely in each sequence.
+// That, and the method here, appear to yield more intuitive difference
+// reports than does diff.  This method appears to be the least vulnerable
+// to synching up on blocks of "junk lines", though (like blank lines in
+// ordinary text files, or maybe "

" lines in HTML files). That may be +// because this is the only method of the 3 that has a *concept* of +// "junk" . +// +// Timing: Basic R-O is cubic time worst case and quadratic time expected +// case. SequenceMatcher is quadratic time for the worst case and has +// expected-case behavior dependent in a complicated way on how many +// elements the sequences have in common; best case time is linear. +type SequenceMatcher struct { + a []string + b []string + b2j map[string][]int + IsJunk func(string) bool + autoJunk bool + bJunk map[string]struct{} + matchingBlocks []Match + fullBCount map[string]int + bPopular map[string]struct{} + opCodes []OpCode +} + +func NewMatcher(a, b []string) *SequenceMatcher { + m := SequenceMatcher{autoJunk: true} + m.SetSeqs(a, b) + return &m +} + +func NewMatcherWithJunk(a, b []string, autoJunk bool, + isJunk func(string) bool) *SequenceMatcher { + + m := SequenceMatcher{IsJunk: isJunk, autoJunk: autoJunk} + m.SetSeqs(a, b) + return &m +} + +// Set two sequences to be compared. +func (m *SequenceMatcher) SetSeqs(a, b []string) { + m.SetSeq1(a) + m.SetSeq2(b) +} + +// Set the first sequence to be compared. The second sequence to be compared is +// not changed. +// +// SequenceMatcher computes and caches detailed information about the second +// sequence, so if you want to compare one sequence S against many sequences, +// use .SetSeq2(s) once and call .SetSeq1(x) repeatedly for each of the other +// sequences. +// +// See also SetSeqs() and SetSeq2(). +func (m *SequenceMatcher) SetSeq1(a []string) { + if &a == &m.a { + return + } + m.a = a + m.matchingBlocks = nil + m.opCodes = nil +} + +// Set the second sequence to be compared. The first sequence to be compared is +// not changed. +func (m *SequenceMatcher) SetSeq2(b []string) { + if &b == &m.b { + return + } + m.b = b + m.matchingBlocks = nil + m.opCodes = nil + m.fullBCount = nil + m.chainB() +} + +func (m *SequenceMatcher) chainB() { + // Populate line -> index mapping + b2j := map[string][]int{} + for i, s := range m.b { + indices := b2j[s] + indices = append(indices, i) + b2j[s] = indices + } + + // Purge junk elements + m.bJunk = map[string]struct{}{} + if m.IsJunk != nil { + junk := m.bJunk + for s, _ := range b2j { + if m.IsJunk(s) { + junk[s] = struct{}{} + } + } + for s, _ := range junk { + delete(b2j, s) + } + } + + // Purge remaining popular elements + popular := map[string]struct{}{} + n := len(m.b) + if m.autoJunk && n >= 200 { + ntest := n/100 + 1 + for s, indices := range b2j { + if len(indices) > ntest { + popular[s] = struct{}{} + } + } + for s, _ := range popular { + delete(b2j, s) + } + } + m.bPopular = popular + m.b2j = b2j +} + +func (m *SequenceMatcher) isBJunk(s string) bool { + _, ok := m.bJunk[s] + return ok +} + +// Find longest matching block in a[alo:ahi] and b[blo:bhi]. +// +// If IsJunk is not defined: +// +// Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where +// alo <= i <= i+k <= ahi +// blo <= j <= j+k <= bhi +// and for all (i',j',k') meeting those conditions, +// k >= k' +// i <= i' +// and if i == i', j <= j' +// +// In other words, of all maximal matching blocks, return one that +// starts earliest in a, and of all those maximal matching blocks that +// start earliest in a, return the one that starts earliest in b. +// +// If IsJunk is defined, first the longest matching block is +// determined as above, but with the additional restriction that no +// junk element appears in the block. Then that block is extended as +// far as possible by matching (only) junk elements on both sides. So +// the resulting block never matches on junk except as identical junk +// happens to be adjacent to an "interesting" match. +// +// If no blocks match, return (alo, blo, 0). +func (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match { + // CAUTION: stripping common prefix or suffix would be incorrect. + // E.g., + // ab + // acab + // Longest matching block is "ab", but if common prefix is + // stripped, it's "a" (tied with "b"). UNIX(tm) diff does so + // strip, so ends up claiming that ab is changed to acab by + // inserting "ca" in the middle. That's minimal but unintuitive: + // "it's obvious" that someone inserted "ac" at the front. + // Windiff ends up at the same place as diff, but by pairing up + // the unique 'b's and then matching the first two 'a's. + besti, bestj, bestsize := alo, blo, 0 + + // find longest junk-free match + // during an iteration of the loop, j2len[j] = length of longest + // junk-free match ending with a[i-1] and b[j] + j2len := map[int]int{} + for i := alo; i != ahi; i++ { + // look at all instances of a[i] in b; note that because + // b2j has no junk keys, the loop is skipped if a[i] is junk + newj2len := map[int]int{} + for _, j := range m.b2j[m.a[i]] { + // a[i] matches b[j] + if j < blo { + continue + } + if j >= bhi { + break + } + k := j2len[j-1] + 1 + newj2len[j] = k + if k > bestsize { + besti, bestj, bestsize = i-k+1, j-k+1, k + } + } + j2len = newj2len + } + + // Extend the best by non-junk elements on each end. In particular, + // "popular" non-junk elements aren't in b2j, which greatly speeds + // the inner loop above, but also means "the best" match so far + // doesn't contain any junk *or* popular non-junk elements. + for besti > alo && bestj > blo && !m.isBJunk(m.b[bestj-1]) && + m.a[besti-1] == m.b[bestj-1] { + besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 + } + for besti+bestsize < ahi && bestj+bestsize < bhi && + !m.isBJunk(m.b[bestj+bestsize]) && + m.a[besti+bestsize] == m.b[bestj+bestsize] { + bestsize += 1 + } + + // Now that we have a wholly interesting match (albeit possibly + // empty!), we may as well suck up the matching junk on each + // side of it too. Can't think of a good reason not to, and it + // saves post-processing the (possibly considerable) expense of + // figuring out what to do with it. In the case of an empty + // interesting match, this is clearly the right thing to do, + // because no other kind of match is possible in the regions. + for besti > alo && bestj > blo && m.isBJunk(m.b[bestj-1]) && + m.a[besti-1] == m.b[bestj-1] { + besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 + } + for besti+bestsize < ahi && bestj+bestsize < bhi && + m.isBJunk(m.b[bestj+bestsize]) && + m.a[besti+bestsize] == m.b[bestj+bestsize] { + bestsize += 1 + } + + return Match{A: besti, B: bestj, Size: bestsize} +} + +// Return list of triples describing matching subsequences. +// +// Each triple is of the form (i, j, n), and means that +// a[i:i+n] == b[j:j+n]. The triples are monotonically increasing in +// i and in j. It's also guaranteed that if (i, j, n) and (i', j', n') are +// adjacent triples in the list, and the second is not the last triple in the +// list, then i+n != i' or j+n != j'. IOW, adjacent triples never describe +// adjacent equal blocks. +// +// The last triple is a dummy, (len(a), len(b), 0), and is the only +// triple with n==0. +func (m *SequenceMatcher) GetMatchingBlocks() []Match { + if m.matchingBlocks != nil { + return m.matchingBlocks + } + + var matchBlocks func(alo, ahi, blo, bhi int, matched []Match) []Match + matchBlocks = func(alo, ahi, blo, bhi int, matched []Match) []Match { + match := m.findLongestMatch(alo, ahi, blo, bhi) + i, j, k := match.A, match.B, match.Size + if match.Size > 0 { + if alo < i && blo < j { + matched = matchBlocks(alo, i, blo, j, matched) + } + matched = append(matched, match) + if i+k < ahi && j+k < bhi { + matched = matchBlocks(i+k, ahi, j+k, bhi, matched) + } + } + return matched + } + matched := matchBlocks(0, len(m.a), 0, len(m.b), nil) + + // It's possible that we have adjacent equal blocks in the + // matching_blocks list now. + nonAdjacent := []Match{} + i1, j1, k1 := 0, 0, 0 + for _, b := range matched { + // Is this block adjacent to i1, j1, k1? + i2, j2, k2 := b.A, b.B, b.Size + if i1+k1 == i2 && j1+k1 == j2 { + // Yes, so collapse them -- this just increases the length of + // the first block by the length of the second, and the first + // block so lengthened remains the block to compare against. + k1 += k2 + } else { + // Not adjacent. Remember the first block (k1==0 means it's + // the dummy we started with), and make the second block the + // new block to compare against. + if k1 > 0 { + nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) + } + i1, j1, k1 = i2, j2, k2 + } + } + if k1 > 0 { + nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) + } + + nonAdjacent = append(nonAdjacent, Match{len(m.a), len(m.b), 0}) + m.matchingBlocks = nonAdjacent + return m.matchingBlocks +} + +// Return list of 5-tuples describing how to turn a into b. +// +// Each tuple is of the form (tag, i1, i2, j1, j2). The first tuple +// has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the +// tuple preceding it, and likewise for j1 == the previous j2. +// +// The tags are characters, with these meanings: +// +// 'r' (replace): a[i1:i2] should be replaced by b[j1:j2] +// +// 'd' (delete): a[i1:i2] should be deleted, j1==j2 in this case. +// +// 'i' (insert): b[j1:j2] should be inserted at a[i1:i1], i1==i2 in this case. +// +// 'e' (equal): a[i1:i2] == b[j1:j2] +func (m *SequenceMatcher) GetOpCodes() []OpCode { + if m.opCodes != nil { + return m.opCodes + } + i, j := 0, 0 + matching := m.GetMatchingBlocks() + opCodes := make([]OpCode, 0, len(matching)) + for _, m := range matching { + // invariant: we've pumped out correct diffs to change + // a[:i] into b[:j], and the next matching block is + // a[ai:ai+size] == b[bj:bj+size]. So we need to pump + // out a diff to change a[i:ai] into b[j:bj], pump out + // the matching block, and move (i,j) beyond the match + ai, bj, size := m.A, m.B, m.Size + tag := byte(0) + if i < ai && j < bj { + tag = 'r' + } else if i < ai { + tag = 'd' + } else if j < bj { + tag = 'i' + } + if tag > 0 { + opCodes = append(opCodes, OpCode{tag, i, ai, j, bj}) + } + i, j = ai+size, bj+size + // the list of matching blocks is terminated by a + // sentinel with size 0 + if size > 0 { + opCodes = append(opCodes, OpCode{'e', ai, i, bj, j}) + } + } + m.opCodes = opCodes + return m.opCodes +} + +// Isolate change clusters by eliminating ranges with no changes. +// +// Return a generator of groups with up to n lines of context. +// Each group is in the same format as returned by GetOpCodes(). +func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode { + if n < 0 { + n = 3 + } + codes := m.GetOpCodes() + if len(codes) == 0 { + codes = []OpCode{OpCode{'e', 0, 1, 0, 1}} + } + // Fixup leading and trailing groups if they show no changes. + if codes[0].Tag == 'e' { + c := codes[0] + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + codes[0] = OpCode{c.Tag, max(i1, i2-n), i2, max(j1, j2-n), j2} + } + if codes[len(codes)-1].Tag == 'e' { + c := codes[len(codes)-1] + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + codes[len(codes)-1] = OpCode{c.Tag, i1, min(i2, i1+n), j1, min(j2, j1+n)} + } + nn := n + n + groups := [][]OpCode{} + group := []OpCode{} + for _, c := range codes { + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + // End the current group and start a new one whenever + // there is a large range with no changes. + if c.Tag == 'e' && i2-i1 > nn { + group = append(group, OpCode{c.Tag, i1, min(i2, i1+n), + j1, min(j2, j1+n)}) + groups = append(groups, group) + group = []OpCode{} + i1, j1 = max(i1, i2-n), max(j1, j2-n) + } + group = append(group, OpCode{c.Tag, i1, i2, j1, j2}) + } + if len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') { + groups = append(groups, group) + } + return groups +} + +// Return a measure of the sequences' similarity (float in [0,1]). +// +// Where T is the total number of elements in both sequences, and +// M is the number of matches, this is 2.0*M / T. +// Note that this is 1 if the sequences are identical, and 0 if +// they have nothing in common. +// +// .Ratio() is expensive to compute if you haven't already computed +// .GetMatchingBlocks() or .GetOpCodes(), in which case you may +// want to try .QuickRatio() or .RealQuickRation() first to get an +// upper bound. +func (m *SequenceMatcher) Ratio() float64 { + matches := 0 + for _, m := range m.GetMatchingBlocks() { + matches += m.Size + } + return calculateRatio(matches, len(m.a)+len(m.b)) +} + +// Return an upper bound on ratio() relatively quickly. +// +// This isn't defined beyond that it is an upper bound on .Ratio(), and +// is faster to compute. +func (m *SequenceMatcher) QuickRatio() float64 { + // viewing a and b as multisets, set matches to the cardinality + // of their intersection; this counts the number of matches + // without regard to order, so is clearly an upper bound + if m.fullBCount == nil { + m.fullBCount = map[string]int{} + for _, s := range m.b { + m.fullBCount[s] = m.fullBCount[s] + 1 + } + } + + // avail[x] is the number of times x appears in 'b' less the + // number of times we've seen it in 'a' so far ... kinda + avail := map[string]int{} + matches := 0 + for _, s := range m.a { + n, ok := avail[s] + if !ok { + n = m.fullBCount[s] + } + avail[s] = n - 1 + if n > 0 { + matches += 1 + } + } + return calculateRatio(matches, len(m.a)+len(m.b)) +} + +// Return an upper bound on ratio() very quickly. +// +// This isn't defined beyond that it is an upper bound on .Ratio(), and +// is faster to compute than either .Ratio() or .QuickRatio(). +func (m *SequenceMatcher) RealQuickRatio() float64 { + la, lb := len(m.a), len(m.b) + return calculateRatio(min(la, lb), la+lb) +} + +// Convert range to the "ed" format +func formatRangeUnified(start, stop int) string { + // Per the diff spec at http://www.unix.org/single_unix_specification/ + beginning := start + 1 // lines start numbering with one + length := stop - start + if length == 1 { + return fmt.Sprintf("%d", beginning) + } + if length == 0 { + beginning -= 1 // empty ranges begin at line just before the range + } + return fmt.Sprintf("%d,%d", beginning, length) +} + +// Unified diff parameters +type UnifiedDiff struct { + A []string // First sequence lines + FromFile string // First file name + FromDate string // First file time + B []string // Second sequence lines + ToFile string // Second file name + ToDate string // Second file time + Eol string // Headers end of line, defaults to LF + Context int // Number of context lines +} + +// Compare two sequences of lines; generate the delta as a unified diff. +// +// Unified diffs are a compact way of showing line changes and a few +// lines of context. The number of context lines is set by 'n' which +// defaults to three. +// +// By default, the diff control lines (those with ---, +++, or @@) are +// created with a trailing newline. This is helpful so that inputs +// created from file.readlines() result in diffs that are suitable for +// file.writelines() since both the inputs and outputs have trailing +// newlines. +// +// For inputs that do not have trailing newlines, set the lineterm +// argument to "" so that the output will be uniformly newline free. +// +// The unidiff format normally has a header for filenames and modification +// times. Any or all of these may be specified using strings for +// 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. +// The modification times are normally expressed in the ISO 8601 format. +func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error { + buf := bufio.NewWriter(writer) + defer buf.Flush() + wf := func(format string, args ...interface{}) error { + _, err := buf.WriteString(fmt.Sprintf(format, args...)) + return err + } + ws := func(s string) error { + _, err := buf.WriteString(s) + return err + } + + if len(diff.Eol) == 0 { + diff.Eol = "\n" + } + + started := false + m := NewMatcher(diff.A, diff.B) + for _, g := range m.GetGroupedOpCodes(diff.Context) { + if !started { + started = true + fromDate := "" + if len(diff.FromDate) > 0 { + fromDate = "\t" + diff.FromDate + } + toDate := "" + if len(diff.ToDate) > 0 { + toDate = "\t" + diff.ToDate + } + if diff.FromFile != "" || diff.ToFile != "" { + err := wf("--- %s%s%s", diff.FromFile, fromDate, diff.Eol) + if err != nil { + return err + } + err = wf("+++ %s%s%s", diff.ToFile, toDate, diff.Eol) + if err != nil { + return err + } + } + } + first, last := g[0], g[len(g)-1] + range1 := formatRangeUnified(first.I1, last.I2) + range2 := formatRangeUnified(first.J1, last.J2) + if err := wf("@@ -%s +%s @@%s", range1, range2, diff.Eol); err != nil { + return err + } + for _, c := range g { + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + if c.Tag == 'e' { + for _, line := range diff.A[i1:i2] { + if err := ws(" " + line); err != nil { + return err + } + } + continue + } + if c.Tag == 'r' || c.Tag == 'd' { + for _, line := range diff.A[i1:i2] { + if err := ws("-" + line); err != nil { + return err + } + } + } + if c.Tag == 'r' || c.Tag == 'i' { + for _, line := range diff.B[j1:j2] { + if err := ws("+" + line); err != nil { + return err + } + } + } + } + } + return nil +} + +// Like WriteUnifiedDiff but returns the diff a string. +func GetUnifiedDiffString(diff UnifiedDiff) (string, error) { + w := &bytes.Buffer{} + err := WriteUnifiedDiff(w, diff) + return string(w.Bytes()), err +} + +// Convert range to the "ed" format. +func formatRangeContext(start, stop int) string { + // Per the diff spec at http://www.unix.org/single_unix_specification/ + beginning := start + 1 // lines start numbering with one + length := stop - start + if length == 0 { + beginning -= 1 // empty ranges begin at line just before the range + } + if length <= 1 { + return fmt.Sprintf("%d", beginning) + } + return fmt.Sprintf("%d,%d", beginning, beginning+length-1) +} + +type ContextDiff UnifiedDiff + +// Compare two sequences of lines; generate the delta as a context diff. +// +// Context diffs are a compact way of showing line changes and a few +// lines of context. The number of context lines is set by diff.Context +// which defaults to three. +// +// By default, the diff control lines (those with *** or ---) are +// created with a trailing newline. +// +// For inputs that do not have trailing newlines, set the diff.Eol +// argument to "" so that the output will be uniformly newline free. +// +// The context diff format normally has a header for filenames and +// modification times. Any or all of these may be specified using +// strings for diff.FromFile, diff.ToFile, diff.FromDate, diff.ToDate. +// The modification times are normally expressed in the ISO 8601 format. +// If not specified, the strings default to blanks. +func WriteContextDiff(writer io.Writer, diff ContextDiff) error { + buf := bufio.NewWriter(writer) + defer buf.Flush() + var diffErr error + wf := func(format string, args ...interface{}) { + _, err := buf.WriteString(fmt.Sprintf(format, args...)) + if diffErr == nil && err != nil { + diffErr = err + } + } + ws := func(s string) { + _, err := buf.WriteString(s) + if diffErr == nil && err != nil { + diffErr = err + } + } + + if len(diff.Eol) == 0 { + diff.Eol = "\n" + } + + prefix := map[byte]string{ + 'i': "+ ", + 'd': "- ", + 'r': "! ", + 'e': " ", + } + + started := false + m := NewMatcher(diff.A, diff.B) + for _, g := range m.GetGroupedOpCodes(diff.Context) { + if !started { + started = true + fromDate := "" + if len(diff.FromDate) > 0 { + fromDate = "\t" + diff.FromDate + } + toDate := "" + if len(diff.ToDate) > 0 { + toDate = "\t" + diff.ToDate + } + if diff.FromFile != "" || diff.ToFile != "" { + wf("*** %s%s%s", diff.FromFile, fromDate, diff.Eol) + wf("--- %s%s%s", diff.ToFile, toDate, diff.Eol) + } + } + + first, last := g[0], g[len(g)-1] + ws("***************" + diff.Eol) + + range1 := formatRangeContext(first.I1, last.I2) + wf("*** %s ****%s", range1, diff.Eol) + for _, c := range g { + if c.Tag == 'r' || c.Tag == 'd' { + for _, cc := range g { + if cc.Tag == 'i' { + continue + } + for _, line := range diff.A[cc.I1:cc.I2] { + ws(prefix[cc.Tag] + line) + } + } + break + } + } + + range2 := formatRangeContext(first.J1, last.J2) + wf("--- %s ----%s", range2, diff.Eol) + for _, c := range g { + if c.Tag == 'r' || c.Tag == 'i' { + for _, cc := range g { + if cc.Tag == 'd' { + continue + } + for _, line := range diff.B[cc.J1:cc.J2] { + ws(prefix[cc.Tag] + line) + } + } + break + } + } + } + return diffErr +} + +// Like WriteContextDiff but returns the diff a string. +func GetContextDiffString(diff ContextDiff) (string, error) { + w := &bytes.Buffer{} + err := WriteContextDiff(w, diff) + return string(w.Bytes()), err +} + +// Split a string on "\n" while preserving them. The output can be used +// as input for UnifiedDiff and ContextDiff structures. +func SplitLines(s string) []string { + lines := strings.SplitAfter(s, "\n") + lines[len(lines)-1] += "\n" + return lines +} diff --git a/vendor/github.com/Sirupsen/logrus/LICENSE b/vendor/github.com/sirupsen/logrus/LICENSE similarity index 100% rename from vendor/github.com/Sirupsen/logrus/LICENSE rename to vendor/github.com/sirupsen/logrus/LICENSE diff --git a/vendor/github.com/Sirupsen/logrus/alt_exit.go b/vendor/github.com/sirupsen/logrus/alt_exit.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/alt_exit.go rename to vendor/github.com/sirupsen/logrus/alt_exit.go diff --git a/vendor/github.com/Sirupsen/logrus/doc.go b/vendor/github.com/sirupsen/logrus/doc.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/doc.go rename to vendor/github.com/sirupsen/logrus/doc.go diff --git a/vendor/github.com/Sirupsen/logrus/entry.go b/vendor/github.com/sirupsen/logrus/entry.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/entry.go rename to vendor/github.com/sirupsen/logrus/entry.go diff --git a/vendor/github.com/Sirupsen/logrus/exported.go b/vendor/github.com/sirupsen/logrus/exported.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/exported.go rename to vendor/github.com/sirupsen/logrus/exported.go diff --git a/vendor/github.com/Sirupsen/logrus/formatter.go b/vendor/github.com/sirupsen/logrus/formatter.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/formatter.go rename to vendor/github.com/sirupsen/logrus/formatter.go diff --git a/vendor/github.com/Sirupsen/logrus/hooks.go b/vendor/github.com/sirupsen/logrus/hooks.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/hooks.go rename to vendor/github.com/sirupsen/logrus/hooks.go diff --git a/vendor/github.com/Sirupsen/logrus/json_formatter.go b/vendor/github.com/sirupsen/logrus/json_formatter.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/json_formatter.go rename to vendor/github.com/sirupsen/logrus/json_formatter.go diff --git a/vendor/github.com/Sirupsen/logrus/logger.go b/vendor/github.com/sirupsen/logrus/logger.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/logger.go rename to vendor/github.com/sirupsen/logrus/logger.go diff --git a/vendor/github.com/Sirupsen/logrus/logrus.go b/vendor/github.com/sirupsen/logrus/logrus.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/logrus.go rename to vendor/github.com/sirupsen/logrus/logrus.go diff --git a/vendor/github.com/Sirupsen/logrus/terminal_bsd.go b/vendor/github.com/sirupsen/logrus/terminal_bsd.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/terminal_bsd.go rename to vendor/github.com/sirupsen/logrus/terminal_bsd.go diff --git a/vendor/github.com/Sirupsen/logrus/terminal_check_appengine.go b/vendor/github.com/sirupsen/logrus/terminal_check_appengine.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/terminal_check_appengine.go rename to vendor/github.com/sirupsen/logrus/terminal_check_appengine.go diff --git a/vendor/github.com/Sirupsen/logrus/terminal_check_notappengine.go b/vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/terminal_check_notappengine.go rename to vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go diff --git a/vendor/github.com/Sirupsen/logrus/terminal_linux.go b/vendor/github.com/sirupsen/logrus/terminal_linux.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/terminal_linux.go rename to vendor/github.com/sirupsen/logrus/terminal_linux.go diff --git a/vendor/github.com/Sirupsen/logrus/text_formatter.go b/vendor/github.com/sirupsen/logrus/text_formatter.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/text_formatter.go rename to vendor/github.com/sirupsen/logrus/text_formatter.go diff --git a/vendor/github.com/Sirupsen/logrus/writer.go b/vendor/github.com/sirupsen/logrus/writer.go similarity index 100% rename from vendor/github.com/Sirupsen/logrus/writer.go rename to vendor/github.com/sirupsen/logrus/writer.go diff --git a/vendor/github.com/spkg/bom/LICENSE.md b/vendor/github.com/spkg/bom/LICENSE.md new file mode 100644 index 000000000..931b189e4 --- /dev/null +++ b/vendor/github.com/spkg/bom/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 John Jeffery + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/spkg/bom/bom.go b/vendor/github.com/spkg/bom/bom.go new file mode 100644 index 000000000..93b811c6d --- /dev/null +++ b/vendor/github.com/spkg/bom/bom.go @@ -0,0 +1,39 @@ +// Package bom is used to clean up UTF-8 Byte Order Marks. +package bom + +import ( + "bufio" + "io" +) + +const ( + bom0 = 0xef + bom1 = 0xbb + bom2 = 0xbf +) + +// Clean returns b with the 3 byte BOM stripped off the front if it is present. +// If the BOM is not present, then b is returned. +func Clean(b []byte) []byte { + if len(b) >= 3 && + b[0] == bom0 && + b[1] == bom1 && + b[2] == bom2 { + return b[3:] + } + return b +} + +// NewReader returns an io.Reader that will skip over initial UTF-8 byte order marks. +func NewReader(r io.Reader) io.Reader { + buf := bufio.NewReader(r) + b, err := buf.Peek(3) + if err != nil { + // not enough bytes + return buf + } + if b[0] == bom0 && b[1] == bom1 && b[2] == bom2 { + discardBytes(buf, 3) + } + return buf +} diff --git a/vendor/github.com/spkg/bom/discard_go14.go b/vendor/github.com/spkg/bom/discard_go14.go new file mode 100644 index 000000000..782cd0624 --- /dev/null +++ b/vendor/github.com/spkg/bom/discard_go14.go @@ -0,0 +1,12 @@ +// +build !go1.5 + +package bom + +import "bufio" + +func discardBytes(buf *bufio.Reader, n int) { + // cannot use the buf.Discard method as it was introduced in Go 1.5 + for i := 0; i < n; i++ { + buf.ReadByte() + } +} diff --git a/vendor/github.com/spkg/bom/discard_go15.go b/vendor/github.com/spkg/bom/discard_go15.go new file mode 100644 index 000000000..2d17d5c5e --- /dev/null +++ b/vendor/github.com/spkg/bom/discard_go15.go @@ -0,0 +1,10 @@ +// +build go1.5 + +package bom + +import "bufio" + +func discardBytes(buf *bufio.Reader, n int) { + // the Discard method was introduced in Go 1.5 + buf.Discard(n) +} diff --git a/vendor/github.com/stretchr/testify/LICENSE b/vendor/github.com/stretchr/testify/LICENSE new file mode 100644 index 000000000..473b670a7 --- /dev/null +++ b/vendor/github.com/stretchr/testify/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell + +Please consider promoting this project if you find it useful. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT +OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/stretchr/testify/assert/assertion_format.go b/vendor/github.com/stretchr/testify/assert/assertion_format.go new file mode 100644 index 000000000..aa1c2b95c --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/assertion_format.go @@ -0,0 +1,484 @@ +/* +* CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen +* THIS FILE MUST NOT BE EDITED BY HAND + */ + +package assert + +import ( + http "net/http" + url "net/url" + time "time" +) + +// Conditionf uses a Comparison to assert a complex condition. +func Conditionf(t TestingT, comp Comparison, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Condition(t, comp, append([]interface{}{msg}, args...)...) +} + +// Containsf asserts that the specified string, list(array, slice...) or map contains the +// specified substring or element. +// +// assert.Containsf(t, "Hello World", "World", "error message %s", "formatted") +// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") +// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") +func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Contains(t, s, contains, append([]interface{}{msg}, args...)...) +} + +// DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists. +func DirExistsf(t TestingT, path string, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return DirExists(t, path, append([]interface{}{msg}, args...)...) +} + +// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified +// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, +// the number of appearances of each of them in both lists should match. +// +// assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted") +func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return ElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...) +} + +// Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// assert.Emptyf(t, obj, "error message %s", "formatted") +func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Empty(t, object, append([]interface{}{msg}, args...)...) +} + +// Equalf asserts that two objects are equal. +// +// assert.Equalf(t, 123, 123, "error message %s", "formatted") +// +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). Function equality +// cannot be determined and will always fail. +func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Equal(t, expected, actual, append([]interface{}{msg}, args...)...) +} + +// EqualErrorf asserts that a function returned an error (i.e. not `nil`) +// and that it is equal to the provided error. +// +// actualObj, err := SomeFunction() +// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") +func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return EqualError(t, theError, errString, append([]interface{}{msg}, args...)...) +} + +// EqualValuesf asserts that two objects are equal or convertable to the same types +// and equal. +// +// assert.EqualValuesf(t, uint32(123, "error message %s", "formatted"), int32(123)) +func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return EqualValues(t, expected, actual, append([]interface{}{msg}, args...)...) +} + +// Errorf asserts that a function returned an error (i.e. not `nil`). +// +// actualObj, err := SomeFunction() +// if assert.Errorf(t, err, "error message %s", "formatted") { +// assert.Equal(t, expectedErrorf, err) +// } +func Errorf(t TestingT, err error, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Error(t, err, append([]interface{}{msg}, args...)...) +} + +// Exactlyf asserts that two objects are equal in value and type. +// +// assert.Exactlyf(t, int32(123, "error message %s", "formatted"), int64(123)) +func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Exactly(t, expected, actual, append([]interface{}{msg}, args...)...) +} + +// Failf reports a failure through +func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Fail(t, failureMessage, append([]interface{}{msg}, args...)...) +} + +// FailNowf fails test +func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return FailNow(t, failureMessage, append([]interface{}{msg}, args...)...) +} + +// Falsef asserts that the specified value is false. +// +// assert.Falsef(t, myBool, "error message %s", "formatted") +func Falsef(t TestingT, value bool, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return False(t, value, append([]interface{}{msg}, args...)...) +} + +// FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file. +func FileExistsf(t TestingT, path string, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return FileExists(t, path, append([]interface{}{msg}, args...)...) +} + +// HTTPBodyContainsf asserts that a specified handler returns a +// body that contains a string. +// +// assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return HTTPBodyContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...) +} + +// HTTPBodyNotContainsf asserts that a specified handler returns a +// body that does not contain a string. +// +// assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return HTTPBodyNotContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...) +} + +// HTTPErrorf asserts that a specified handler returns an error status code. +// +// assert.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false). +func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return HTTPError(t, handler, method, url, values, append([]interface{}{msg}, args...)...) +} + +// HTTPRedirectf asserts that a specified handler returns a redirect status code. +// +// assert.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false). +func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return HTTPRedirect(t, handler, method, url, values, append([]interface{}{msg}, args...)...) +} + +// HTTPSuccessf asserts that a specified handler returns a success status code. +// +// assert.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return HTTPSuccess(t, handler, method, url, values, append([]interface{}{msg}, args...)...) +} + +// Implementsf asserts that an object is implemented by the specified interface. +// +// assert.Implementsf(t, (*MyInterface, "error message %s", "formatted")(nil), new(MyObject)) +func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Implements(t, interfaceObject, object, append([]interface{}{msg}, args...)...) +} + +// InDeltaf asserts that the two numerals are within delta of each other. +// +// assert.InDeltaf(t, math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01) +func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return InDelta(t, expected, actual, delta, append([]interface{}{msg}, args...)...) +} + +// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. +func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return InDeltaMapValues(t, expected, actual, delta, append([]interface{}{msg}, args...)...) +} + +// InDeltaSlicef is the same as InDelta, except it compares two slices. +func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return InDeltaSlice(t, expected, actual, delta, append([]interface{}{msg}, args...)...) +} + +// InEpsilonf asserts that expected and actual have a relative error less than epsilon +func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return InEpsilon(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...) +} + +// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices. +func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return InEpsilonSlice(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...) +} + +// IsTypef asserts that the specified objects are of the same type. +func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return IsType(t, expectedType, object, append([]interface{}{msg}, args...)...) +} + +// JSONEqf asserts that two JSON strings are equivalent. +// +// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") +func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return JSONEq(t, expected, actual, append([]interface{}{msg}, args...)...) +} + +// Lenf asserts that the specified object has specific length. +// Lenf also fails if the object has a type that len() not accept. +// +// assert.Lenf(t, mySlice, 3, "error message %s", "formatted") +func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Len(t, object, length, append([]interface{}{msg}, args...)...) +} + +// Nilf asserts that the specified object is nil. +// +// assert.Nilf(t, err, "error message %s", "formatted") +func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Nil(t, object, append([]interface{}{msg}, args...)...) +} + +// NoErrorf asserts that a function returned no error (i.e. `nil`). +// +// actualObj, err := SomeFunction() +// if assert.NoErrorf(t, err, "error message %s", "formatted") { +// assert.Equal(t, expectedObj, actualObj) +// } +func NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NoError(t, err, append([]interface{}{msg}, args...)...) +} + +// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the +// specified substring or element. +// +// assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted") +// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") +// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") +func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NotContains(t, s, contains, append([]interface{}{msg}, args...)...) +} + +// NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// if assert.NotEmptyf(t, obj, "error message %s", "formatted") { +// assert.Equal(t, "two", obj[1]) +// } +func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NotEmpty(t, object, append([]interface{}{msg}, args...)...) +} + +// NotEqualf asserts that the specified values are NOT equal. +// +// assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted") +// +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). +func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NotEqual(t, expected, actual, append([]interface{}{msg}, args...)...) +} + +// NotNilf asserts that the specified object is not nil. +// +// assert.NotNilf(t, err, "error message %s", "formatted") +func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NotNil(t, object, append([]interface{}{msg}, args...)...) +} + +// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. +// +// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") +func NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NotPanics(t, f, append([]interface{}{msg}, args...)...) +} + +// NotRegexpf asserts that a specified regexp does not match a string. +// +// assert.NotRegexpf(t, regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting") +// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") +func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NotRegexp(t, rx, str, append([]interface{}{msg}, args...)...) +} + +// NotSubsetf asserts that the specified list(array, slice...) contains not all +// elements given in the specified subset(array, slice...). +// +// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") +func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NotSubset(t, list, subset, append([]interface{}{msg}, args...)...) +} + +// NotZerof asserts that i is not the zero value for its type. +func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NotZero(t, i, append([]interface{}{msg}, args...)...) +} + +// Panicsf asserts that the code inside the specified PanicTestFunc panics. +// +// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") +func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Panics(t, f, append([]interface{}{msg}, args...)...) +} + +// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that +// the recovered panic value equals the expected panic value. +// +// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return PanicsWithValue(t, expected, f, append([]interface{}{msg}, args...)...) +} + +// Regexpf asserts that a specified regexp matches a string. +// +// assert.Regexpf(t, regexp.MustCompile("start", "error message %s", "formatted"), "it's starting") +// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") +func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Regexp(t, rx, str, append([]interface{}{msg}, args...)...) +} + +// Subsetf asserts that the specified list(array, slice...) contains all +// elements given in the specified subset(array, slice...). +// +// assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") +func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Subset(t, list, subset, append([]interface{}{msg}, args...)...) +} + +// Truef asserts that the specified value is true. +// +// assert.Truef(t, myBool, "error message %s", "formatted") +func Truef(t TestingT, value bool, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return True(t, value, append([]interface{}{msg}, args...)...) +} + +// WithinDurationf asserts that the two times are within duration delta of each other. +// +// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") +func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return WithinDuration(t, expected, actual, delta, append([]interface{}{msg}, args...)...) +} + +// Zerof asserts that i is the zero value for its type. +func Zerof(t TestingT, i interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Zero(t, i, append([]interface{}{msg}, args...)...) +} diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go b/vendor/github.com/stretchr/testify/assert/assertion_forward.go new file mode 100644 index 000000000..de39f794e --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/assertion_forward.go @@ -0,0 +1,956 @@ +/* +* CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen +* THIS FILE MUST NOT BE EDITED BY HAND + */ + +package assert + +import ( + http "net/http" + url "net/url" + time "time" +) + +// Condition uses a Comparison to assert a complex condition. +func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Condition(a.t, comp, msgAndArgs...) +} + +// Conditionf uses a Comparison to assert a complex condition. +func (a *Assertions) Conditionf(comp Comparison, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Conditionf(a.t, comp, msg, args...) +} + +// Contains asserts that the specified string, list(array, slice...) or map contains the +// specified substring or element. +// +// a.Contains("Hello World", "World") +// a.Contains(["Hello", "World"], "World") +// a.Contains({"Hello": "World"}, "Hello") +func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Contains(a.t, s, contains, msgAndArgs...) +} + +// Containsf asserts that the specified string, list(array, slice...) or map contains the +// specified substring or element. +// +// a.Containsf("Hello World", "World", "error message %s", "formatted") +// a.Containsf(["Hello", "World"], "World", "error message %s", "formatted") +// a.Containsf({"Hello": "World"}, "Hello", "error message %s", "formatted") +func (a *Assertions) Containsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Containsf(a.t, s, contains, msg, args...) +} + +// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists. +func (a *Assertions) DirExists(path string, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return DirExists(a.t, path, msgAndArgs...) +} + +// DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists. +func (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return DirExistsf(a.t, path, msg, args...) +} + +// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified +// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, +// the number of appearances of each of them in both lists should match. +// +// a.ElementsMatch([1, 3, 2, 3], [1, 3, 3, 2]) +func (a *Assertions) ElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return ElementsMatch(a.t, listA, listB, msgAndArgs...) +} + +// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified +// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, +// the number of appearances of each of them in both lists should match. +// +// a.ElementsMatchf([1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted") +func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return ElementsMatchf(a.t, listA, listB, msg, args...) +} + +// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// a.Empty(obj) +func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Empty(a.t, object, msgAndArgs...) +} + +// Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// a.Emptyf(obj, "error message %s", "formatted") +func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Emptyf(a.t, object, msg, args...) +} + +// Equal asserts that two objects are equal. +// +// a.Equal(123, 123) +// +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). Function equality +// cannot be determined and will always fail. +func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Equal(a.t, expected, actual, msgAndArgs...) +} + +// EqualError asserts that a function returned an error (i.e. not `nil`) +// and that it is equal to the provided error. +// +// actualObj, err := SomeFunction() +// a.EqualError(err, expectedErrorString) +func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return EqualError(a.t, theError, errString, msgAndArgs...) +} + +// EqualErrorf asserts that a function returned an error (i.e. not `nil`) +// and that it is equal to the provided error. +// +// actualObj, err := SomeFunction() +// a.EqualErrorf(err, expectedErrorString, "error message %s", "formatted") +func (a *Assertions) EqualErrorf(theError error, errString string, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return EqualErrorf(a.t, theError, errString, msg, args...) +} + +// EqualValues asserts that two objects are equal or convertable to the same types +// and equal. +// +// a.EqualValues(uint32(123), int32(123)) +func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return EqualValues(a.t, expected, actual, msgAndArgs...) +} + +// EqualValuesf asserts that two objects are equal or convertable to the same types +// and equal. +// +// a.EqualValuesf(uint32(123, "error message %s", "formatted"), int32(123)) +func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return EqualValuesf(a.t, expected, actual, msg, args...) +} + +// Equalf asserts that two objects are equal. +// +// a.Equalf(123, 123, "error message %s", "formatted") +// +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). Function equality +// cannot be determined and will always fail. +func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Equalf(a.t, expected, actual, msg, args...) +} + +// Error asserts that a function returned an error (i.e. not `nil`). +// +// actualObj, err := SomeFunction() +// if a.Error(err) { +// assert.Equal(t, expectedError, err) +// } +func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Error(a.t, err, msgAndArgs...) +} + +// Errorf asserts that a function returned an error (i.e. not `nil`). +// +// actualObj, err := SomeFunction() +// if a.Errorf(err, "error message %s", "formatted") { +// assert.Equal(t, expectedErrorf, err) +// } +func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Errorf(a.t, err, msg, args...) +} + +// Exactly asserts that two objects are equal in value and type. +// +// a.Exactly(int32(123), int64(123)) +func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Exactly(a.t, expected, actual, msgAndArgs...) +} + +// Exactlyf asserts that two objects are equal in value and type. +// +// a.Exactlyf(int32(123, "error message %s", "formatted"), int64(123)) +func (a *Assertions) Exactlyf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Exactlyf(a.t, expected, actual, msg, args...) +} + +// Fail reports a failure through +func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Fail(a.t, failureMessage, msgAndArgs...) +} + +// FailNow fails test +func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return FailNow(a.t, failureMessage, msgAndArgs...) +} + +// FailNowf fails test +func (a *Assertions) FailNowf(failureMessage string, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return FailNowf(a.t, failureMessage, msg, args...) +} + +// Failf reports a failure through +func (a *Assertions) Failf(failureMessage string, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Failf(a.t, failureMessage, msg, args...) +} + +// False asserts that the specified value is false. +// +// a.False(myBool) +func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return False(a.t, value, msgAndArgs...) +} + +// Falsef asserts that the specified value is false. +// +// a.Falsef(myBool, "error message %s", "formatted") +func (a *Assertions) Falsef(value bool, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Falsef(a.t, value, msg, args...) +} + +// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file. +func (a *Assertions) FileExists(path string, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return FileExists(a.t, path, msgAndArgs...) +} + +// FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file. +func (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return FileExistsf(a.t, path, msg, args...) +} + +// HTTPBodyContains asserts that a specified handler returns a +// body that contains a string. +// +// a.HTTPBodyContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return HTTPBodyContains(a.t, handler, method, url, values, str, msgAndArgs...) +} + +// HTTPBodyContainsf asserts that a specified handler returns a +// body that contains a string. +// +// a.HTTPBodyContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return HTTPBodyContainsf(a.t, handler, method, url, values, str, msg, args...) +} + +// HTTPBodyNotContains asserts that a specified handler returns a +// body that does not contain a string. +// +// a.HTTPBodyNotContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return HTTPBodyNotContains(a.t, handler, method, url, values, str, msgAndArgs...) +} + +// HTTPBodyNotContainsf asserts that a specified handler returns a +// body that does not contain a string. +// +// a.HTTPBodyNotContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return HTTPBodyNotContainsf(a.t, handler, method, url, values, str, msg, args...) +} + +// HTTPError asserts that a specified handler returns an error status code. +// +// a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return HTTPError(a.t, handler, method, url, values, msgAndArgs...) +} + +// HTTPErrorf asserts that a specified handler returns an error status code. +// +// a.HTTPErrorf(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false). +func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return HTTPErrorf(a.t, handler, method, url, values, msg, args...) +} + +// HTTPRedirect asserts that a specified handler returns a redirect status code. +// +// a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return HTTPRedirect(a.t, handler, method, url, values, msgAndArgs...) +} + +// HTTPRedirectf asserts that a specified handler returns a redirect status code. +// +// a.HTTPRedirectf(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false). +func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return HTTPRedirectf(a.t, handler, method, url, values, msg, args...) +} + +// HTTPSuccess asserts that a specified handler returns a success status code. +// +// a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return HTTPSuccess(a.t, handler, method, url, values, msgAndArgs...) +} + +// HTTPSuccessf asserts that a specified handler returns a success status code. +// +// a.HTTPSuccessf(myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return HTTPSuccessf(a.t, handler, method, url, values, msg, args...) +} + +// Implements asserts that an object is implemented by the specified interface. +// +// a.Implements((*MyInterface)(nil), new(MyObject)) +func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Implements(a.t, interfaceObject, object, msgAndArgs...) +} + +// Implementsf asserts that an object is implemented by the specified interface. +// +// a.Implementsf((*MyInterface, "error message %s", "formatted")(nil), new(MyObject)) +func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Implementsf(a.t, interfaceObject, object, msg, args...) +} + +// InDelta asserts that the two numerals are within delta of each other. +// +// a.InDelta(math.Pi, (22 / 7.0), 0.01) +func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return InDelta(a.t, expected, actual, delta, msgAndArgs...) +} + +// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. +func (a *Assertions) InDeltaMapValues(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return InDeltaMapValues(a.t, expected, actual, delta, msgAndArgs...) +} + +// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. +func (a *Assertions) InDeltaMapValuesf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return InDeltaMapValuesf(a.t, expected, actual, delta, msg, args...) +} + +// InDeltaSlice is the same as InDelta, except it compares two slices. +func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...) +} + +// InDeltaSlicef is the same as InDelta, except it compares two slices. +func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return InDeltaSlicef(a.t, expected, actual, delta, msg, args...) +} + +// InDeltaf asserts that the two numerals are within delta of each other. +// +// a.InDeltaf(math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01) +func (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return InDeltaf(a.t, expected, actual, delta, msg, args...) +} + +// InEpsilon asserts that expected and actual have a relative error less than epsilon +func (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...) +} + +// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. +func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...) +} + +// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices. +func (a *Assertions) InEpsilonSlicef(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return InEpsilonSlicef(a.t, expected, actual, epsilon, msg, args...) +} + +// InEpsilonf asserts that expected and actual have a relative error less than epsilon +func (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return InEpsilonf(a.t, expected, actual, epsilon, msg, args...) +} + +// IsType asserts that the specified objects are of the same type. +func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return IsType(a.t, expectedType, object, msgAndArgs...) +} + +// IsTypef asserts that the specified objects are of the same type. +func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return IsTypef(a.t, expectedType, object, msg, args...) +} + +// JSONEq asserts that two JSON strings are equivalent. +// +// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) +func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return JSONEq(a.t, expected, actual, msgAndArgs...) +} + +// JSONEqf asserts that two JSON strings are equivalent. +// +// a.JSONEqf(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") +func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return JSONEqf(a.t, expected, actual, msg, args...) +} + +// Len asserts that the specified object has specific length. +// Len also fails if the object has a type that len() not accept. +// +// a.Len(mySlice, 3) +func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Len(a.t, object, length, msgAndArgs...) +} + +// Lenf asserts that the specified object has specific length. +// Lenf also fails if the object has a type that len() not accept. +// +// a.Lenf(mySlice, 3, "error message %s", "formatted") +func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Lenf(a.t, object, length, msg, args...) +} + +// Nil asserts that the specified object is nil. +// +// a.Nil(err) +func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Nil(a.t, object, msgAndArgs...) +} + +// Nilf asserts that the specified object is nil. +// +// a.Nilf(err, "error message %s", "formatted") +func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Nilf(a.t, object, msg, args...) +} + +// NoError asserts that a function returned no error (i.e. `nil`). +// +// actualObj, err := SomeFunction() +// if a.NoError(err) { +// assert.Equal(t, expectedObj, actualObj) +// } +func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NoError(a.t, err, msgAndArgs...) +} + +// NoErrorf asserts that a function returned no error (i.e. `nil`). +// +// actualObj, err := SomeFunction() +// if a.NoErrorf(err, "error message %s", "formatted") { +// assert.Equal(t, expectedObj, actualObj) +// } +func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NoErrorf(a.t, err, msg, args...) +} + +// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the +// specified substring or element. +// +// a.NotContains("Hello World", "Earth") +// a.NotContains(["Hello", "World"], "Earth") +// a.NotContains({"Hello": "World"}, "Earth") +func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotContains(a.t, s, contains, msgAndArgs...) +} + +// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the +// specified substring or element. +// +// a.NotContainsf("Hello World", "Earth", "error message %s", "formatted") +// a.NotContainsf(["Hello", "World"], "Earth", "error message %s", "formatted") +// a.NotContainsf({"Hello": "World"}, "Earth", "error message %s", "formatted") +func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotContainsf(a.t, s, contains, msg, args...) +} + +// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// if a.NotEmpty(obj) { +// assert.Equal(t, "two", obj[1]) +// } +func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotEmpty(a.t, object, msgAndArgs...) +} + +// NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// if a.NotEmptyf(obj, "error message %s", "formatted") { +// assert.Equal(t, "two", obj[1]) +// } +func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotEmptyf(a.t, object, msg, args...) +} + +// NotEqual asserts that the specified values are NOT equal. +// +// a.NotEqual(obj1, obj2) +// +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). +func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotEqual(a.t, expected, actual, msgAndArgs...) +} + +// NotEqualf asserts that the specified values are NOT equal. +// +// a.NotEqualf(obj1, obj2, "error message %s", "formatted") +// +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). +func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotEqualf(a.t, expected, actual, msg, args...) +} + +// NotNil asserts that the specified object is not nil. +// +// a.NotNil(err) +func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotNil(a.t, object, msgAndArgs...) +} + +// NotNilf asserts that the specified object is not nil. +// +// a.NotNilf(err, "error message %s", "formatted") +func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotNilf(a.t, object, msg, args...) +} + +// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. +// +// a.NotPanics(func(){ RemainCalm() }) +func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotPanics(a.t, f, msgAndArgs...) +} + +// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. +// +// a.NotPanicsf(func(){ RemainCalm() }, "error message %s", "formatted") +func (a *Assertions) NotPanicsf(f PanicTestFunc, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotPanicsf(a.t, f, msg, args...) +} + +// NotRegexp asserts that a specified regexp does not match a string. +// +// a.NotRegexp(regexp.MustCompile("starts"), "it's starting") +// a.NotRegexp("^start", "it's not starting") +func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotRegexp(a.t, rx, str, msgAndArgs...) +} + +// NotRegexpf asserts that a specified regexp does not match a string. +// +// a.NotRegexpf(regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting") +// a.NotRegexpf("^start", "it's not starting", "error message %s", "formatted") +func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotRegexpf(a.t, rx, str, msg, args...) +} + +// NotSubset asserts that the specified list(array, slice...) contains not all +// elements given in the specified subset(array, slice...). +// +// a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") +func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotSubset(a.t, list, subset, msgAndArgs...) +} + +// NotSubsetf asserts that the specified list(array, slice...) contains not all +// elements given in the specified subset(array, slice...). +// +// a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") +func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotSubsetf(a.t, list, subset, msg, args...) +} + +// NotZero asserts that i is not the zero value for its type. +func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotZero(a.t, i, msgAndArgs...) +} + +// NotZerof asserts that i is not the zero value for its type. +func (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotZerof(a.t, i, msg, args...) +} + +// Panics asserts that the code inside the specified PanicTestFunc panics. +// +// a.Panics(func(){ GoCrazy() }) +func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Panics(a.t, f, msgAndArgs...) +} + +// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that +// the recovered panic value equals the expected panic value. +// +// a.PanicsWithValue("crazy error", func(){ GoCrazy() }) +func (a *Assertions) PanicsWithValue(expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return PanicsWithValue(a.t, expected, f, msgAndArgs...) +} + +// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that +// the recovered panic value equals the expected panic value. +// +// a.PanicsWithValuef("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +func (a *Assertions) PanicsWithValuef(expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return PanicsWithValuef(a.t, expected, f, msg, args...) +} + +// Panicsf asserts that the code inside the specified PanicTestFunc panics. +// +// a.Panicsf(func(){ GoCrazy() }, "error message %s", "formatted") +func (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Panicsf(a.t, f, msg, args...) +} + +// Regexp asserts that a specified regexp matches a string. +// +// a.Regexp(regexp.MustCompile("start"), "it's starting") +// a.Regexp("start...$", "it's not starting") +func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Regexp(a.t, rx, str, msgAndArgs...) +} + +// Regexpf asserts that a specified regexp matches a string. +// +// a.Regexpf(regexp.MustCompile("start", "error message %s", "formatted"), "it's starting") +// a.Regexpf("start...$", "it's not starting", "error message %s", "formatted") +func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Regexpf(a.t, rx, str, msg, args...) +} + +// Subset asserts that the specified list(array, slice...) contains all +// elements given in the specified subset(array, slice...). +// +// a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") +func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Subset(a.t, list, subset, msgAndArgs...) +} + +// Subsetf asserts that the specified list(array, slice...) contains all +// elements given in the specified subset(array, slice...). +// +// a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") +func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Subsetf(a.t, list, subset, msg, args...) +} + +// True asserts that the specified value is true. +// +// a.True(myBool) +func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return True(a.t, value, msgAndArgs...) +} + +// Truef asserts that the specified value is true. +// +// a.Truef(myBool, "error message %s", "formatted") +func (a *Assertions) Truef(value bool, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Truef(a.t, value, msg, args...) +} + +// WithinDuration asserts that the two times are within duration delta of each other. +// +// a.WithinDuration(time.Now(), time.Now(), 10*time.Second) +func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return WithinDuration(a.t, expected, actual, delta, msgAndArgs...) +} + +// WithinDurationf asserts that the two times are within duration delta of each other. +// +// a.WithinDurationf(time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") +func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return WithinDurationf(a.t, expected, actual, delta, msg, args...) +} + +// Zero asserts that i is the zero value for its type. +func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Zero(a.t, i, msgAndArgs...) +} + +// Zerof asserts that i is the zero value for its type. +func (a *Assertions) Zerof(i interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Zerof(a.t, i, msg, args...) +} diff --git a/vendor/github.com/stretchr/testify/assert/assertions.go b/vendor/github.com/stretchr/testify/assert/assertions.go new file mode 100644 index 000000000..5bdec56cd --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/assertions.go @@ -0,0 +1,1394 @@ +package assert + +import ( + "bufio" + "bytes" + "encoding/json" + "errors" + "fmt" + "math" + "os" + "reflect" + "regexp" + "runtime" + "strings" + "time" + "unicode" + "unicode/utf8" + + "github.com/davecgh/go-spew/spew" + "github.com/pmezard/go-difflib/difflib" +) + +//go:generate go run ../_codegen/main.go -output-package=assert -template=assertion_format.go.tmpl + +// TestingT is an interface wrapper around *testing.T +type TestingT interface { + Errorf(format string, args ...interface{}) +} + +// ComparisonAssertionFunc is a common function prototype when comparing two values. Can be useful +// for table driven tests. +type ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{}) bool + +// ValueAssertionFunc is a common function prototype when validating a single value. Can be useful +// for table driven tests. +type ValueAssertionFunc func(TestingT, interface{}, ...interface{}) bool + +// BoolAssertionFunc is a common function prototype when validating a bool value. Can be useful +// for table driven tests. +type BoolAssertionFunc func(TestingT, bool, ...interface{}) bool + +// ValuesAssertionFunc is a common function prototype when validating an error value. Can be useful +// for table driven tests. +type ErrorAssertionFunc func(TestingT, error, ...interface{}) bool + +// Comparison a custom function that returns true on success and false on failure +type Comparison func() (success bool) + +/* + Helper functions +*/ + +// ObjectsAreEqual determines if two objects are considered equal. +// +// This function does no assertion of any kind. +func ObjectsAreEqual(expected, actual interface{}) bool { + if expected == nil || actual == nil { + return expected == actual + } + + exp, ok := expected.([]byte) + if !ok { + return reflect.DeepEqual(expected, actual) + } + + act, ok := actual.([]byte) + if !ok { + return false + } + if exp == nil || act == nil { + return exp == nil && act == nil + } + return bytes.Equal(exp, act) +} + +// ObjectsAreEqualValues gets whether two objects are equal, or if their +// values are equal. +func ObjectsAreEqualValues(expected, actual interface{}) bool { + if ObjectsAreEqual(expected, actual) { + return true + } + + actualType := reflect.TypeOf(actual) + if actualType == nil { + return false + } + expectedValue := reflect.ValueOf(expected) + if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) { + // Attempt comparison after type conversion + return reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), actual) + } + + return false +} + +/* CallerInfo is necessary because the assert functions use the testing object +internally, causing it to print the file:line of the assert method, rather than where +the problem actually occurred in calling code.*/ + +// CallerInfo returns an array of strings containing the file and line number +// of each stack frame leading from the current test to the assert call that +// failed. +func CallerInfo() []string { + + pc := uintptr(0) + file := "" + line := 0 + ok := false + name := "" + + callers := []string{} + for i := 0; ; i++ { + pc, file, line, ok = runtime.Caller(i) + if !ok { + // The breaks below failed to terminate the loop, and we ran off the + // end of the call stack. + break + } + + // This is a huge edge case, but it will panic if this is the case, see #180 + if file == "" { + break + } + + f := runtime.FuncForPC(pc) + if f == nil { + break + } + name = f.Name() + + // testing.tRunner is the standard library function that calls + // tests. Subtests are called directly by tRunner, without going through + // the Test/Benchmark/Example function that contains the t.Run calls, so + // with subtests we should break when we hit tRunner, without adding it + // to the list of callers. + if name == "testing.tRunner" { + break + } + + parts := strings.Split(file, "/") + file = parts[len(parts)-1] + if len(parts) > 1 { + dir := parts[len(parts)-2] + if (dir != "assert" && dir != "mock" && dir != "require") || file == "mock_test.go" { + callers = append(callers, fmt.Sprintf("%s:%d", file, line)) + } + } + + // Drop the package + segments := strings.Split(name, ".") + name = segments[len(segments)-1] + if isTest(name, "Test") || + isTest(name, "Benchmark") || + isTest(name, "Example") { + break + } + } + + return callers +} + +// Stolen from the `go test` tool. +// isTest tells whether name looks like a test (or benchmark, according to prefix). +// It is a Test (say) if there is a character after Test that is not a lower-case letter. +// We don't want TesticularCancer. +func isTest(name, prefix string) bool { + if !strings.HasPrefix(name, prefix) { + return false + } + if len(name) == len(prefix) { // "Test" is ok + return true + } + rune, _ := utf8.DecodeRuneInString(name[len(prefix):]) + return !unicode.IsLower(rune) +} + +func messageFromMsgAndArgs(msgAndArgs ...interface{}) string { + if len(msgAndArgs) == 0 || msgAndArgs == nil { + return "" + } + if len(msgAndArgs) == 1 { + return msgAndArgs[0].(string) + } + if len(msgAndArgs) > 1 { + return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...) + } + return "" +} + +// Aligns the provided message so that all lines after the first line start at the same location as the first line. +// Assumes that the first line starts at the correct location (after carriage return, tab, label, spacer and tab). +// The longestLabelLen parameter specifies the length of the longest label in the output (required becaues this is the +// basis on which the alignment occurs). +func indentMessageLines(message string, longestLabelLen int) string { + outBuf := new(bytes.Buffer) + + for i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ { + // no need to align first line because it starts at the correct location (after the label) + if i != 0 { + // append alignLen+1 spaces to align with "{{longestLabel}}:" before adding tab + outBuf.WriteString("\n\t" + strings.Repeat(" ", longestLabelLen+1) + "\t") + } + outBuf.WriteString(scanner.Text()) + } + + return outBuf.String() +} + +type failNower interface { + FailNow() +} + +// FailNow fails test +func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + Fail(t, failureMessage, msgAndArgs...) + + // We cannot extend TestingT with FailNow() and + // maintain backwards compatibility, so we fallback + // to panicking when FailNow is not available in + // TestingT. + // See issue #263 + + if t, ok := t.(failNower); ok { + t.FailNow() + } else { + panic("test failed and t is missing `FailNow()`") + } + return false +} + +// Fail reports a failure through +func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + content := []labeledContent{ + {"Error Trace", strings.Join(CallerInfo(), "\n\t\t\t")}, + {"Error", failureMessage}, + } + + // Add test name if the Go version supports it + if n, ok := t.(interface { + Name() string + }); ok { + content = append(content, labeledContent{"Test", n.Name()}) + } + + message := messageFromMsgAndArgs(msgAndArgs...) + if len(message) > 0 { + content = append(content, labeledContent{"Messages", message}) + } + + t.Errorf("\n%s", ""+labeledOutput(content...)) + + return false +} + +type labeledContent struct { + label string + content string +} + +// labeledOutput returns a string consisting of the provided labeledContent. Each labeled output is appended in the following manner: +// +// \t{{label}}:{{align_spaces}}\t{{content}}\n +// +// The initial carriage return is required to undo/erase any padding added by testing.T.Errorf. The "\t{{label}}:" is for the label. +// If a label is shorter than the longest label provided, padding spaces are added to make all the labels match in length. Once this +// alignment is achieved, "\t{{content}}\n" is added for the output. +// +// If the content of the labeledOutput contains line breaks, the subsequent lines are aligned so that they start at the same location as the first line. +func labeledOutput(content ...labeledContent) string { + longestLabel := 0 + for _, v := range content { + if len(v.label) > longestLabel { + longestLabel = len(v.label) + } + } + var output string + for _, v := range content { + output += "\t" + v.label + ":" + strings.Repeat(" ", longestLabel-len(v.label)) + "\t" + indentMessageLines(v.content, longestLabel) + "\n" + } + return output +} + +// Implements asserts that an object is implemented by the specified interface. +// +// assert.Implements(t, (*MyInterface)(nil), new(MyObject)) +func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + interfaceType := reflect.TypeOf(interfaceObject).Elem() + + if object == nil { + return Fail(t, fmt.Sprintf("Cannot check if nil implements %v", interfaceType), msgAndArgs...) + } + if !reflect.TypeOf(object).Implements(interfaceType) { + return Fail(t, fmt.Sprintf("%T must implement %v", object, interfaceType), msgAndArgs...) + } + + return true +} + +// IsType asserts that the specified objects are of the same type. +func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) { + return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...) + } + + return true +} + +// Equal asserts that two objects are equal. +// +// assert.Equal(t, 123, 123) +// +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). Function equality +// cannot be determined and will always fail. +func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if err := validateEqualArgs(expected, actual); err != nil { + return Fail(t, fmt.Sprintf("Invalid operation: %#v == %#v (%s)", + expected, actual, err), msgAndArgs...) + } + + if !ObjectsAreEqual(expected, actual) { + diff := diff(expected, actual) + expected, actual = formatUnequalValues(expected, actual) + return Fail(t, fmt.Sprintf("Not equal: \n"+ + "expected: %s\n"+ + "actual : %s%s", expected, actual, diff), msgAndArgs...) + } + + return true + +} + +// formatUnequalValues takes two values of arbitrary types and returns string +// representations appropriate to be presented to the user. +// +// If the values are not of like type, the returned strings will be prefixed +// with the type name, and the value will be enclosed in parenthesis similar +// to a type conversion in the Go grammar. +func formatUnequalValues(expected, actual interface{}) (e string, a string) { + if reflect.TypeOf(expected) != reflect.TypeOf(actual) { + return fmt.Sprintf("%T(%#v)", expected, expected), + fmt.Sprintf("%T(%#v)", actual, actual) + } + + return fmt.Sprintf("%#v", expected), + fmt.Sprintf("%#v", actual) +} + +// EqualValues asserts that two objects are equal or convertable to the same types +// and equal. +// +// assert.EqualValues(t, uint32(123), int32(123)) +func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + if !ObjectsAreEqualValues(expected, actual) { + diff := diff(expected, actual) + expected, actual = formatUnequalValues(expected, actual) + return Fail(t, fmt.Sprintf("Not equal: \n"+ + "expected: %s\n"+ + "actual : %s%s", expected, actual, diff), msgAndArgs...) + } + + return true + +} + +// Exactly asserts that two objects are equal in value and type. +// +// assert.Exactly(t, int32(123), int64(123)) +func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + aType := reflect.TypeOf(expected) + bType := reflect.TypeOf(actual) + + if aType != bType { + return Fail(t, fmt.Sprintf("Types expected to match exactly\n\t%v != %v", aType, bType), msgAndArgs...) + } + + return Equal(t, expected, actual, msgAndArgs...) + +} + +// NotNil asserts that the specified object is not nil. +// +// assert.NotNil(t, err) +func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if !isNil(object) { + return true + } + return Fail(t, "Expected value not to be nil.", msgAndArgs...) +} + +// isNil checks if a specified object is nil or not, without Failing. +func isNil(object interface{}) bool { + if object == nil { + return true + } + + value := reflect.ValueOf(object) + kind := value.Kind() + if kind >= reflect.Chan && kind <= reflect.Slice && value.IsNil() { + return true + } + + return false +} + +// Nil asserts that the specified object is nil. +// +// assert.Nil(t, err) +func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if isNil(object) { + return true + } + return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...) +} + +// isEmpty gets whether the specified object is considered empty or not. +func isEmpty(object interface{}) bool { + + // get nil case out of the way + if object == nil { + return true + } + + objValue := reflect.ValueOf(object) + + switch objValue.Kind() { + // collection types are empty when they have no element + case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice: + return objValue.Len() == 0 + // pointers are empty if nil or if the value they point to is empty + case reflect.Ptr: + if objValue.IsNil() { + return true + } + deref := objValue.Elem().Interface() + return isEmpty(deref) + // for all other types, compare against the zero value + default: + zero := reflect.Zero(objValue.Type()) + return reflect.DeepEqual(object, zero.Interface()) + } +} + +// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// assert.Empty(t, obj) +func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + pass := isEmpty(object) + if !pass { + Fail(t, fmt.Sprintf("Should be empty, but was %v", object), msgAndArgs...) + } + + return pass + +} + +// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// if assert.NotEmpty(t, obj) { +// assert.Equal(t, "two", obj[1]) +// } +func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + pass := !isEmpty(object) + if !pass { + Fail(t, fmt.Sprintf("Should NOT be empty, but was %v", object), msgAndArgs...) + } + + return pass + +} + +// getLen try to get length of object. +// return (false, 0) if impossible. +func getLen(x interface{}) (ok bool, length int) { + v := reflect.ValueOf(x) + defer func() { + if e := recover(); e != nil { + ok = false + } + }() + return true, v.Len() +} + +// Len asserts that the specified object has specific length. +// Len also fails if the object has a type that len() not accept. +// +// assert.Len(t, mySlice, 3) +func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + ok, l := getLen(object) + if !ok { + return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...) + } + + if l != length { + return Fail(t, fmt.Sprintf("\"%s\" should have %d item(s), but has %d", object, length, l), msgAndArgs...) + } + return true +} + +// True asserts that the specified value is true. +// +// assert.True(t, myBool) +func True(t TestingT, value bool, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if h, ok := t.(interface { + Helper() + }); ok { + h.Helper() + } + + if value != true { + return Fail(t, "Should be true", msgAndArgs...) + } + + return true + +} + +// False asserts that the specified value is false. +// +// assert.False(t, myBool) +func False(t TestingT, value bool, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + if value != false { + return Fail(t, "Should be false", msgAndArgs...) + } + + return true + +} + +// NotEqual asserts that the specified values are NOT equal. +// +// assert.NotEqual(t, obj1, obj2) +// +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). +func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if err := validateEqualArgs(expected, actual); err != nil { + return Fail(t, fmt.Sprintf("Invalid operation: %#v != %#v (%s)", + expected, actual, err), msgAndArgs...) + } + + if ObjectsAreEqual(expected, actual) { + return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...) + } + + return true + +} + +// containsElement try loop over the list check if the list includes the element. +// return (false, false) if impossible. +// return (true, false) if element was not found. +// return (true, true) if element was found. +func includeElement(list interface{}, element interface{}) (ok, found bool) { + + listValue := reflect.ValueOf(list) + elementValue := reflect.ValueOf(element) + defer func() { + if e := recover(); e != nil { + ok = false + found = false + } + }() + + if reflect.TypeOf(list).Kind() == reflect.String { + return true, strings.Contains(listValue.String(), elementValue.String()) + } + + if reflect.TypeOf(list).Kind() == reflect.Map { + mapKeys := listValue.MapKeys() + for i := 0; i < len(mapKeys); i++ { + if ObjectsAreEqual(mapKeys[i].Interface(), element) { + return true, true + } + } + return true, false + } + + for i := 0; i < listValue.Len(); i++ { + if ObjectsAreEqual(listValue.Index(i).Interface(), element) { + return true, true + } + } + return true, false + +} + +// Contains asserts that the specified string, list(array, slice...) or map contains the +// specified substring or element. +// +// assert.Contains(t, "Hello World", "World") +// assert.Contains(t, ["Hello", "World"], "World") +// assert.Contains(t, {"Hello": "World"}, "Hello") +func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + ok, found := includeElement(s, contains) + if !ok { + return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...) + } + if !found { + return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", s, contains), msgAndArgs...) + } + + return true + +} + +// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the +// specified substring or element. +// +// assert.NotContains(t, "Hello World", "Earth") +// assert.NotContains(t, ["Hello", "World"], "Earth") +// assert.NotContains(t, {"Hello": "World"}, "Earth") +func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + ok, found := includeElement(s, contains) + if !ok { + return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...) + } + if found { + return Fail(t, fmt.Sprintf("\"%s\" should not contain \"%s\"", s, contains), msgAndArgs...) + } + + return true + +} + +// Subset asserts that the specified list(array, slice...) contains all +// elements given in the specified subset(array, slice...). +// +// assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") +func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if subset == nil { + return true // we consider nil to be equal to the nil set + } + + subsetValue := reflect.ValueOf(subset) + defer func() { + if e := recover(); e != nil { + ok = false + } + }() + + listKind := reflect.TypeOf(list).Kind() + subsetKind := reflect.TypeOf(subset).Kind() + + if listKind != reflect.Array && listKind != reflect.Slice { + return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...) + } + + if subsetKind != reflect.Array && subsetKind != reflect.Slice { + return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) + } + + for i := 0; i < subsetValue.Len(); i++ { + element := subsetValue.Index(i).Interface() + ok, found := includeElement(list, element) + if !ok { + return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...) + } + if !found { + return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", list, element), msgAndArgs...) + } + } + + return true +} + +// NotSubset asserts that the specified list(array, slice...) contains not all +// elements given in the specified subset(array, slice...). +// +// assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") +func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if subset == nil { + return Fail(t, fmt.Sprintf("nil is the empty set which is a subset of every set"), msgAndArgs...) + } + + subsetValue := reflect.ValueOf(subset) + defer func() { + if e := recover(); e != nil { + ok = false + } + }() + + listKind := reflect.TypeOf(list).Kind() + subsetKind := reflect.TypeOf(subset).Kind() + + if listKind != reflect.Array && listKind != reflect.Slice { + return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...) + } + + if subsetKind != reflect.Array && subsetKind != reflect.Slice { + return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) + } + + for i := 0; i < subsetValue.Len(); i++ { + element := subsetValue.Index(i).Interface() + ok, found := includeElement(list, element) + if !ok { + return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...) + } + if !found { + return true + } + } + + return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...) +} + +// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified +// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, +// the number of appearances of each of them in both lists should match. +// +// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2]) +func ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if isEmpty(listA) && isEmpty(listB) { + return true + } + + aKind := reflect.TypeOf(listA).Kind() + bKind := reflect.TypeOf(listB).Kind() + + if aKind != reflect.Array && aKind != reflect.Slice { + return Fail(t, fmt.Sprintf("%q has an unsupported type %s", listA, aKind), msgAndArgs...) + } + + if bKind != reflect.Array && bKind != reflect.Slice { + return Fail(t, fmt.Sprintf("%q has an unsupported type %s", listB, bKind), msgAndArgs...) + } + + aValue := reflect.ValueOf(listA) + bValue := reflect.ValueOf(listB) + + aLen := aValue.Len() + bLen := bValue.Len() + + if aLen != bLen { + return Fail(t, fmt.Sprintf("lengths don't match: %d != %d", aLen, bLen), msgAndArgs...) + } + + // Mark indexes in bValue that we already used + visited := make([]bool, bLen) + for i := 0; i < aLen; i++ { + element := aValue.Index(i).Interface() + found := false + for j := 0; j < bLen; j++ { + if visited[j] { + continue + } + if ObjectsAreEqual(bValue.Index(j).Interface(), element) { + visited[j] = true + found = true + break + } + } + if !found { + return Fail(t, fmt.Sprintf("element %s appears more times in %s than in %s", element, aValue, bValue), msgAndArgs...) + } + } + + return true +} + +// Condition uses a Comparison to assert a complex condition. +func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + result := comp() + if !result { + Fail(t, "Condition failed!", msgAndArgs...) + } + return result +} + +// PanicTestFunc defines a func that should be passed to the assert.Panics and assert.NotPanics +// methods, and represents a simple func that takes no arguments, and returns nothing. +type PanicTestFunc func() + +// didPanic returns true if the function passed to it panics. Otherwise, it returns false. +func didPanic(f PanicTestFunc) (bool, interface{}) { + + didPanic := false + var message interface{} + func() { + + defer func() { + if message = recover(); message != nil { + didPanic = true + } + }() + + // call the target function + f() + + }() + + return didPanic, message + +} + +// Panics asserts that the code inside the specified PanicTestFunc panics. +// +// assert.Panics(t, func(){ GoCrazy() }) +func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + if funcDidPanic, panicValue := didPanic(f); !funcDidPanic { + return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...) + } + + return true +} + +// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that +// the recovered panic value equals the expected panic value. +// +// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) +func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + funcDidPanic, panicValue := didPanic(f) + if !funcDidPanic { + return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...) + } + if panicValue != expected { + return Fail(t, fmt.Sprintf("func %#v should panic with value:\t%#v\n\tPanic value:\t%#v", f, expected, panicValue), msgAndArgs...) + } + + return true +} + +// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. +// +// assert.NotPanics(t, func(){ RemainCalm() }) +func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + if funcDidPanic, panicValue := didPanic(f); funcDidPanic { + return Fail(t, fmt.Sprintf("func %#v should not panic\n\tPanic value:\t%v", f, panicValue), msgAndArgs...) + } + + return true +} + +// WithinDuration asserts that the two times are within duration delta of each other. +// +// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) +func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + dt := expected.Sub(actual) + if dt < -delta || dt > delta { + return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...) + } + + return true +} + +func toFloat(x interface{}) (float64, bool) { + var xf float64 + xok := true + + switch xn := x.(type) { + case uint8: + xf = float64(xn) + case uint16: + xf = float64(xn) + case uint32: + xf = float64(xn) + case uint64: + xf = float64(xn) + case int: + xf = float64(xn) + case int8: + xf = float64(xn) + case int16: + xf = float64(xn) + case int32: + xf = float64(xn) + case int64: + xf = float64(xn) + case float32: + xf = float64(xn) + case float64: + xf = float64(xn) + case time.Duration: + xf = float64(xn) + default: + xok = false + } + + return xf, xok +} + +// InDelta asserts that the two numerals are within delta of each other. +// +// assert.InDelta(t, math.Pi, (22 / 7.0), 0.01) +func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + af, aok := toFloat(expected) + bf, bok := toFloat(actual) + + if !aok || !bok { + return Fail(t, fmt.Sprintf("Parameters must be numerical"), msgAndArgs...) + } + + if math.IsNaN(af) { + return Fail(t, fmt.Sprintf("Expected must not be NaN"), msgAndArgs...) + } + + if math.IsNaN(bf) { + return Fail(t, fmt.Sprintf("Expected %v with delta %v, but was NaN", expected, delta), msgAndArgs...) + } + + dt := af - bf + if dt < -delta || dt > delta { + return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...) + } + + return true +} + +// InDeltaSlice is the same as InDelta, except it compares two slices. +func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if expected == nil || actual == nil || + reflect.TypeOf(actual).Kind() != reflect.Slice || + reflect.TypeOf(expected).Kind() != reflect.Slice { + return Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...) + } + + actualSlice := reflect.ValueOf(actual) + expectedSlice := reflect.ValueOf(expected) + + for i := 0; i < actualSlice.Len(); i++ { + result := InDelta(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta, msgAndArgs...) + if !result { + return result + } + } + + return true +} + +// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. +func InDeltaMapValues(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if expected == nil || actual == nil || + reflect.TypeOf(actual).Kind() != reflect.Map || + reflect.TypeOf(expected).Kind() != reflect.Map { + return Fail(t, "Arguments must be maps", msgAndArgs...) + } + + expectedMap := reflect.ValueOf(expected) + actualMap := reflect.ValueOf(actual) + + if expectedMap.Len() != actualMap.Len() { + return Fail(t, "Arguments must have the same number of keys", msgAndArgs...) + } + + for _, k := range expectedMap.MapKeys() { + ev := expectedMap.MapIndex(k) + av := actualMap.MapIndex(k) + + if !ev.IsValid() { + return Fail(t, fmt.Sprintf("missing key %q in expected map", k), msgAndArgs...) + } + + if !av.IsValid() { + return Fail(t, fmt.Sprintf("missing key %q in actual map", k), msgAndArgs...) + } + + if !InDelta( + t, + ev.Interface(), + av.Interface(), + delta, + msgAndArgs..., + ) { + return false + } + } + + return true +} + +func calcRelativeError(expected, actual interface{}) (float64, error) { + af, aok := toFloat(expected) + if !aok { + return 0, fmt.Errorf("expected value %q cannot be converted to float", expected) + } + if af == 0 { + return 0, fmt.Errorf("expected value must have a value other than zero to calculate the relative error") + } + bf, bok := toFloat(actual) + if !bok { + return 0, fmt.Errorf("actual value %q cannot be converted to float", actual) + } + + return math.Abs(af-bf) / math.Abs(af), nil +} + +// InEpsilon asserts that expected and actual have a relative error less than epsilon +func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + actualEpsilon, err := calcRelativeError(expected, actual) + if err != nil { + return Fail(t, err.Error(), msgAndArgs...) + } + if actualEpsilon > epsilon { + return Fail(t, fmt.Sprintf("Relative error is too high: %#v (expected)\n"+ + " < %#v (actual)", epsilon, actualEpsilon), msgAndArgs...) + } + + return true +} + +// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. +func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if expected == nil || actual == nil || + reflect.TypeOf(actual).Kind() != reflect.Slice || + reflect.TypeOf(expected).Kind() != reflect.Slice { + return Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...) + } + + actualSlice := reflect.ValueOf(actual) + expectedSlice := reflect.ValueOf(expected) + + for i := 0; i < actualSlice.Len(); i++ { + result := InEpsilon(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), epsilon) + if !result { + return result + } + } + + return true +} + +/* + Errors +*/ + +// NoError asserts that a function returned no error (i.e. `nil`). +// +// actualObj, err := SomeFunction() +// if assert.NoError(t, err) { +// assert.Equal(t, expectedObj, actualObj) +// } +func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if err != nil { + return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...) + } + + return true +} + +// Error asserts that a function returned an error (i.e. not `nil`). +// +// actualObj, err := SomeFunction() +// if assert.Error(t, err) { +// assert.Equal(t, expectedError, err) +// } +func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + if err == nil { + return Fail(t, "An error is expected but got nil.", msgAndArgs...) + } + + return true +} + +// EqualError asserts that a function returned an error (i.e. not `nil`) +// and that it is equal to the provided error. +// +// actualObj, err := SomeFunction() +// assert.EqualError(t, err, expectedErrorString) +func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if !Error(t, theError, msgAndArgs...) { + return false + } + expected := errString + actual := theError.Error() + // don't need to use deep equals here, we know they are both strings + if expected != actual { + return Fail(t, fmt.Sprintf("Error message not equal:\n"+ + "expected: %q\n"+ + "actual : %q", expected, actual), msgAndArgs...) + } + return true +} + +// matchRegexp return true if a specified regexp matches a string. +func matchRegexp(rx interface{}, str interface{}) bool { + + var r *regexp.Regexp + if rr, ok := rx.(*regexp.Regexp); ok { + r = rr + } else { + r = regexp.MustCompile(fmt.Sprint(rx)) + } + + return (r.FindStringIndex(fmt.Sprint(str)) != nil) + +} + +// Regexp asserts that a specified regexp matches a string. +// +// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") +// assert.Regexp(t, "start...$", "it's not starting") +func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + match := matchRegexp(rx, str) + + if !match { + Fail(t, fmt.Sprintf("Expect \"%v\" to match \"%v\"", str, rx), msgAndArgs...) + } + + return match +} + +// NotRegexp asserts that a specified regexp does not match a string. +// +// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") +// assert.NotRegexp(t, "^start", "it's not starting") +func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + match := matchRegexp(rx, str) + + if match { + Fail(t, fmt.Sprintf("Expect \"%v\" to NOT match \"%v\"", str, rx), msgAndArgs...) + } + + return !match + +} + +// Zero asserts that i is the zero value for its type. +func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { + return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...) + } + return true +} + +// NotZero asserts that i is not the zero value for its type. +func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { + return Fail(t, fmt.Sprintf("Should not be zero, but was %v", i), msgAndArgs...) + } + return true +} + +// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file. +func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + info, err := os.Lstat(path) + if err != nil { + if os.IsNotExist(err) { + return Fail(t, fmt.Sprintf("unable to find file %q", path), msgAndArgs...) + } + return Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", path, err), msgAndArgs...) + } + if info.IsDir() { + return Fail(t, fmt.Sprintf("%q is a directory", path), msgAndArgs...) + } + return true +} + +// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists. +func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + info, err := os.Lstat(path) + if err != nil { + if os.IsNotExist(err) { + return Fail(t, fmt.Sprintf("unable to find file %q", path), msgAndArgs...) + } + return Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", path, err), msgAndArgs...) + } + if !info.IsDir() { + return Fail(t, fmt.Sprintf("%q is a file", path), msgAndArgs...) + } + return true +} + +// JSONEq asserts that two JSON strings are equivalent. +// +// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) +func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + var expectedJSONAsInterface, actualJSONAsInterface interface{} + + if err := json.Unmarshal([]byte(expected), &expectedJSONAsInterface); err != nil { + return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid json.\nJSON parsing error: '%s'", expected, err.Error()), msgAndArgs...) + } + + if err := json.Unmarshal([]byte(actual), &actualJSONAsInterface); err != nil { + return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid json.\nJSON parsing error: '%s'", actual, err.Error()), msgAndArgs...) + } + + return Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...) +} + +func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) { + t := reflect.TypeOf(v) + k := t.Kind() + + if k == reflect.Ptr { + t = t.Elem() + k = t.Kind() + } + return t, k +} + +// diff returns a diff of both values as long as both are of the same type and +// are a struct, map, slice or array. Otherwise it returns an empty string. +func diff(expected interface{}, actual interface{}) string { + if expected == nil || actual == nil { + return "" + } + + et, ek := typeAndKind(expected) + at, _ := typeAndKind(actual) + + if et != at { + return "" + } + + if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array && ek != reflect.String { + return "" + } + + var e, a string + if ek != reflect.String { + e = spewConfig.Sdump(expected) + a = spewConfig.Sdump(actual) + } else { + e = expected.(string) + a = actual.(string) + } + + diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ + A: difflib.SplitLines(e), + B: difflib.SplitLines(a), + FromFile: "Expected", + FromDate: "", + ToFile: "Actual", + ToDate: "", + Context: 1, + }) + + return "\n\nDiff:\n" + diff +} + +// validateEqualArgs checks whether provided arguments can be safely used in the +// Equal/NotEqual functions. +func validateEqualArgs(expected, actual interface{}) error { + if isFunction(expected) || isFunction(actual) { + return errors.New("cannot take func type as argument") + } + return nil +} + +func isFunction(arg interface{}) bool { + if arg == nil { + return false + } + return reflect.TypeOf(arg).Kind() == reflect.Func +} + +var spewConfig = spew.ConfigState{ + Indent: " ", + DisablePointerAddresses: true, + DisableCapacities: true, + SortKeys: true, +} + +type tHelper interface { + Helper() +} diff --git a/vendor/github.com/stretchr/testify/assert/doc.go b/vendor/github.com/stretchr/testify/assert/doc.go new file mode 100644 index 000000000..c9dccc4d6 --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/doc.go @@ -0,0 +1,45 @@ +// Package assert provides a set of comprehensive testing tools for use with the normal Go testing system. +// +// Example Usage +// +// The following is a complete example using assert in a standard test function: +// import ( +// "testing" +// "github.com/stretchr/testify/assert" +// ) +// +// func TestSomething(t *testing.T) { +// +// var a string = "Hello" +// var b string = "Hello" +// +// assert.Equal(t, a, b, "The two words should be the same.") +// +// } +// +// if you assert many times, use the format below: +// +// import ( +// "testing" +// "github.com/stretchr/testify/assert" +// ) +// +// func TestSomething(t *testing.T) { +// assert := assert.New(t) +// +// var a string = "Hello" +// var b string = "Hello" +// +// assert.Equal(a, b, "The two words should be the same.") +// } +// +// Assertions +// +// Assertions allow you to easily write test code, and are global funcs in the `assert` package. +// All assertion functions take, as the first argument, the `*testing.T` object provided by the +// testing framework. This allows the assertion funcs to write the failings and other details to +// the correct place. +// +// Every assertion function also takes an optional string message as the final argument, +// allowing custom error messages to be appended to the message the assertion method outputs. +package assert diff --git a/vendor/github.com/stretchr/testify/assert/errors.go b/vendor/github.com/stretchr/testify/assert/errors.go new file mode 100644 index 000000000..ac9dc9d1d --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/errors.go @@ -0,0 +1,10 @@ +package assert + +import ( + "errors" +) + +// AnError is an error instance useful for testing. If the code does not care +// about error specifics, and only needs to return the error for example, this +// error should be used to make the test code more readable. +var AnError = errors.New("assert.AnError general error for testing") diff --git a/vendor/github.com/stretchr/testify/assert/forward_assertions.go b/vendor/github.com/stretchr/testify/assert/forward_assertions.go new file mode 100644 index 000000000..9ad56851d --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/forward_assertions.go @@ -0,0 +1,16 @@ +package assert + +// Assertions provides assertion methods around the +// TestingT interface. +type Assertions struct { + t TestingT +} + +// New makes a new Assertions object for the specified TestingT. +func New(t TestingT) *Assertions { + return &Assertions{ + t: t, + } +} + +//go:generate go run ../_codegen/main.go -output-package=assert -template=assertion_forward.go.tmpl -include-format-funcs diff --git a/vendor/github.com/stretchr/testify/assert/http_assertions.go b/vendor/github.com/stretchr/testify/assert/http_assertions.go new file mode 100644 index 000000000..df46fa777 --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/http_assertions.go @@ -0,0 +1,143 @@ +package assert + +import ( + "fmt" + "net/http" + "net/http/httptest" + "net/url" + "strings" +) + +// httpCode is a helper that returns HTTP code of the response. It returns -1 and +// an error if building a new request fails. +func httpCode(handler http.HandlerFunc, method, url string, values url.Values) (int, error) { + w := httptest.NewRecorder() + req, err := http.NewRequest(method, url, nil) + if err != nil { + return -1, err + } + req.URL.RawQuery = values.Encode() + handler(w, req) + return w.Code, nil +} + +// HTTPSuccess asserts that a specified handler returns a success status code. +// +// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + code, err := httpCode(handler, method, url, values) + if err != nil { + Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err)) + return false + } + + isSuccessCode := code >= http.StatusOK && code <= http.StatusPartialContent + if !isSuccessCode { + Fail(t, fmt.Sprintf("Expected HTTP success status code for %q but received %d", url+"?"+values.Encode(), code)) + } + + return isSuccessCode +} + +// HTTPRedirect asserts that a specified handler returns a redirect status code. +// +// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + code, err := httpCode(handler, method, url, values) + if err != nil { + Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err)) + return false + } + + isRedirectCode := code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect + if !isRedirectCode { + Fail(t, fmt.Sprintf("Expected HTTP redirect status code for %q but received %d", url+"?"+values.Encode(), code)) + } + + return isRedirectCode +} + +// HTTPError asserts that a specified handler returns an error status code. +// +// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + code, err := httpCode(handler, method, url, values) + if err != nil { + Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err)) + return false + } + + isErrorCode := code >= http.StatusBadRequest + if !isErrorCode { + Fail(t, fmt.Sprintf("Expected HTTP error status code for %q but received %d", url+"?"+values.Encode(), code)) + } + + return isErrorCode +} + +// HTTPBody is a helper that returns HTTP body of the response. It returns +// empty string if building a new request fails. +func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) string { + w := httptest.NewRecorder() + req, err := http.NewRequest(method, url+"?"+values.Encode(), nil) + if err != nil { + return "" + } + handler(w, req) + return w.Body.String() +} + +// HTTPBodyContains asserts that a specified handler returns a +// body that contains a string. +// +// assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + body := HTTPBody(handler, method, url, values) + + contains := strings.Contains(body, fmt.Sprint(str)) + if !contains { + Fail(t, fmt.Sprintf("Expected response body for \"%s\" to contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body)) + } + + return contains +} + +// HTTPBodyNotContains asserts that a specified handler returns a +// body that does not contain a string. +// +// assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + body := HTTPBody(handler, method, url, values) + + contains := strings.Contains(body, fmt.Sprint(str)) + if contains { + Fail(t, fmt.Sprintf("Expected response body for \"%s\" to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body)) + } + + return !contains +} diff --git a/vendor/github.com/stvp/roll/LICENSE b/vendor/github.com/stvp/roll/LICENSE new file mode 100644 index 000000000..1235e06b5 --- /dev/null +++ b/vendor/github.com/stvp/roll/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2016 Stovepipe Studios + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/stvp/roll/client.go b/vendor/github.com/stvp/roll/client.go new file mode 100644 index 000000000..687343f2a --- /dev/null +++ b/vendor/github.com/stvp/roll/client.go @@ -0,0 +1,240 @@ +package roll + +import ( + "bytes" + "encoding/json" + "fmt" + "hash/adler32" + "io" + "io/ioutil" + "net/http" + "os" + "reflect" + "runtime" + "strings" + "time" +) + +const ( + // By default, all Rollbar API requests are sent to this endpoint. + endpoint = "https://api.rollbar.com/api/1/item/" + + // Identify this Rollbar client library to the Rollbar API. + clientName = "go-roll" + clientVersion = "0.2.0" + clientLanguage = "go" +) + +var ( + // Endpoint is the default HTTP(S) endpoint that all Rollbar API requests + // will be sent to. By default, this is Rollbar's "Items" API endpoint. If + // this is blank, no items will be sent to Rollbar. + Endpoint = endpoint + + // Rollbar access token for the global client. If this is blank, no items + // will be sent to Rollbar. + Token = "" + + // Environment for all items reported with the global client. + Environment = "development" +) + +type rollbarSuccess struct { + Result map[string]string `json:"result"` +} + +// Client reports items to a single Rollbar project. +type Client interface { + Critical(err error, custom map[string]string) (uuid string, e error) + CriticalStack(err error, ptrs []uintptr, custom map[string]string) (uuid string, e error) + Error(err error, custom map[string]string) (uuid string, e error) + ErrorStack(err error, ptrs []uintptr, custom map[string]string) (uuid string, e error) + Warning(err error, custom map[string]string) (uuid string, e error) + WarningStack(err error, ptrs []uintptr, custom map[string]string) (uuid string, e error) + Info(msg string, custom map[string]string) (uuid string, e error) + Debug(msg string, custom map[string]string) (uuid string, e error) +} + +type rollbarClient struct { + token string + env string +} + +// New creates a new Rollbar client that reports items to the given project +// token and with the given environment (eg. "production", "development", etc). +func New(token, env string) Client { + return &rollbarClient{token, env} +} + +func Critical(err error, custom map[string]string) (uuid string, e error) { + return CriticalStack(err, getCallers(2), custom) +} + +func CriticalStack(err error, ptrs []uintptr, custom map[string]string) (uuid string, e error) { + return New(Token, Environment).CriticalStack(err, ptrs, custom) +} + +func Error(err error, custom map[string]string) (uuid string, e error) { + return ErrorStack(err, getCallers(2), custom) +} + +func ErrorStack(err error, ptrs []uintptr, custom map[string]string) (uuid string, e error) { + return New(Token, Environment).ErrorStack(err, ptrs, custom) +} + +func Warning(err error, custom map[string]string) (uuid string, e error) { + return WarningStack(err, getCallers(2), custom) +} + +func WarningStack(err error, ptrs []uintptr, custom map[string]string) (uuid string, e error) { + return New(Token, Environment).WarningStack(err, ptrs, custom) +} + +func Info(msg string, custom map[string]string) (uuid string, e error) { + return New(Token, Environment).Info(msg, custom) +} + +func Debug(msg string, custom map[string]string) (uuid string, e error) { + return New(Token, Environment).Debug(msg, custom) +} + +func (c *rollbarClient) Critical(err error, custom map[string]string) (uuid string, e error) { + return c.CriticalStack(err, getCallers(2), custom) +} + +func (c *rollbarClient) CriticalStack(err error, callers []uintptr, custom map[string]string) (uuid string, e error) { + item := c.buildTraceItem("critical", err, callers, custom) + return c.send(item) +} + +func (c *rollbarClient) Error(err error, custom map[string]string) (uuid string, e error) { + return c.ErrorStack(err, getCallers(2), custom) +} + +func (c *rollbarClient) ErrorStack(err error, callers []uintptr, custom map[string]string) (uuid string, e error) { + item := c.buildTraceItem("error", err, callers, custom) + return c.send(item) +} + +func (c *rollbarClient) Warning(err error, custom map[string]string) (uuid string, e error) { + return c.WarningStack(err, getCallers(2), custom) +} + +func (c *rollbarClient) WarningStack(err error, callers []uintptr, custom map[string]string) (uuid string, e error) { + item := c.buildTraceItem("warning", err, callers, custom) + return c.send(item) +} + +func (c *rollbarClient) Info(msg string, custom map[string]string) (uuid string, e error) { + item := c.buildMessageItem("info", msg, custom) + return c.send(item) +} + +func (c *rollbarClient) Debug(msg string, custom map[string]string) (uuid string, e error) { + item := c.buildMessageItem("debug", msg, custom) + return c.send(item) +} + +func (c *rollbarClient) buildTraceItem(level string, err error, callers []uintptr, custom map[string]string) (item map[string]interface{}) { + stack := buildRollbarFrames(callers) + item = c.buildItem(level, err.Error(), custom) + itemData := item["data"].(map[string]interface{}) + itemData["fingerprint"] = stack.fingerprint() + itemData["body"] = map[string]interface{}{ + "trace": map[string]interface{}{ + "frames": stack, + "exception": map[string]interface{}{ + "class": errorClass(err), + "message": err.Error(), + }, + }, + } + + return item +} + +func (c *rollbarClient) buildMessageItem(level string, msg string, custom map[string]string) (item map[string]interface{}) { + item = c.buildItem(level, msg, custom) + itemData := item["data"].(map[string]interface{}) + itemData["body"] = map[string]interface{}{ + "message": map[string]interface{}{ + "body": msg, + }, + } + + return item +} + +func (c *rollbarClient) buildItem(level, title string, custom map[string]string) map[string]interface{} { + hostname, _ := os.Hostname() + + return map[string]interface{}{ + "access_token": c.token, + "data": map[string]interface{}{ + "environment": c.env, + "title": title, + "level": level, + "timestamp": time.Now().Unix(), + "platform": runtime.GOOS, + "language": clientLanguage, + "server": map[string]interface{}{ + "host": hostname, + }, + "notifier": map[string]interface{}{ + "name": clientName, + "version": clientVersion, + }, + "custom": custom, + }, + } +} + +// send reports the given item to Rollbar and returns either a UUID for the +// reported item or an error. +func (c *rollbarClient) send(item map[string]interface{}) (uuid string, err error) { + if len(c.token) == 0 || len(Endpoint) == 0 { + return "", nil + } + + jsonBody, err := json.Marshal(item) + if err != nil { + return "", err + } + + resp, err := http.Post(Endpoint, "application/json", bytes.NewReader(jsonBody)) + if err != nil { + return "", err + } + defer func() { + io.Copy(ioutil.Discard, resp.Body) + resp.Body.Close() + }() + + if resp.StatusCode != http.StatusOK { + return "", fmt.Errorf("Rollbar returned %s", resp.Status) + } + + // Extract UUID from JSON response + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", nil + } + success := rollbarSuccess{} + json.Unmarshal(body, &success) + + return success.Result["uuid"], nil +} + +// errorClass returns a class name for an error (eg. "ErrUnexpectedEOF"). For +// string errors, it returns an Adler-32 checksum of the error string. +func errorClass(err error) string { + class := reflect.TypeOf(err).String() + if class == "" { + return "panic" + } else if class == "*errors.errorString" { + checksum := adler32.Checksum([]byte(err.Error())) + return fmt.Sprintf("{%x}", checksum) + } else { + return strings.TrimPrefix(class, "*") + } +} diff --git a/vendor/github.com/stvp/roll/stack.go b/vendor/github.com/stvp/roll/stack.go new file mode 100644 index 000000000..c50425491 --- /dev/null +++ b/vendor/github.com/stvp/roll/stack.go @@ -0,0 +1,98 @@ +package roll + +import ( + "fmt" + "hash/crc32" + "os" + "runtime" + "strings" +) + +var ( + knownFilePathPatterns = []string{ + "github.com/", + "code.google.com/", + "bitbucket.org/", + "launchpad.net/", + "gopkg.in/", + } +) + +func getCallers(skip int) (pc []uintptr) { + pc = make([]uintptr, 1000) + i := runtime.Callers(skip+1, pc) + return pc[0:i] +} + +// -- rollbarFrames + +type rollbarFrame struct { + Filename string `json:"filename"` + Method string `json:"method"` + Line int `json:"lineno"` +} + +type rollbarFrames []rollbarFrame + +// buildRollbarFrames takes a slice of function pointers and returns a Rollbar +// API payload containing the filename, method name, and line number of each +// function. +func buildRollbarFrames(callers []uintptr) (frames rollbarFrames) { + frames = rollbarFrames{} + + // 2016-08-24 - runtime.CallersFrames was added in Go 1.7, which should + // replace the following code when roll is able to require Go 1.7+. + for _, caller := range callers { + frame := rollbarFrame{ + Filename: "???", + Method: "???", + } + if fn := runtime.FuncForPC(caller); fn != nil { + name, line := fn.FileLine(caller) + frame.Filename = scrubFile(name) + frame.Line = line + frame.Method = scrubFunction(fn.Name()) + } + frames = append(frames, frame) + } + + return frames +} + +// fingerprint returns a checksum that uniquely identifies a stacktrace by the +// filename, method name, and line number of every frame in the stack. +func (f rollbarFrames) fingerprint() string { + hash := crc32.NewIEEE() + for _, frame := range f { + fmt.Fprintf(hash, "%s%s%d", frame.Filename, frame.Method, frame.Line) + } + return fmt.Sprintf("%x", hash.Sum32()) +} + +// -- Helpers + +// scrubFile removes unneeded information from the path of a source file. This +// makes them shorter in Rollbar UI as well as making them the same, regardless +// of the machine the code was compiled on. +// +// Example: +// /home/foo/go/src/github.com/stvp/roll/rollbar.go -> github.com/stvp/roll/rollbar.go +func scrubFile(s string) string { + var i int + for _, pattern := range knownFilePathPatterns { + i = strings.Index(s, pattern) + if i != -1 { + return s[i:] + } + } + return s +} + +// scrubFunction removes unneeded information from the full name of a function. +// +// Example: +// github.com/stvp/roll.getCallers -> roll.getCallers +func scrubFunction(name string) string { + end := strings.LastIndex(name, string(os.PathSeparator)) + return name[end+1 : len(name)] +} diff --git a/vendor/github.com/ulikunitz/xz/LICENSE b/vendor/github.com/ulikunitz/xz/LICENSE new file mode 100644 index 000000000..58ebdc162 --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2014-2016 Ulrich Kunitz +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* My name, Ulrich Kunitz, may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/ulikunitz/xz/bits.go b/vendor/github.com/ulikunitz/xz/bits.go new file mode 100644 index 000000000..fadc1a594 --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/bits.go @@ -0,0 +1,74 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xz + +import ( + "errors" + "io" +) + +// putUint32LE puts the little-endian representation of x into the first +// four bytes of p. +func putUint32LE(p []byte, x uint32) { + p[0] = byte(x) + p[1] = byte(x >> 8) + p[2] = byte(x >> 16) + p[3] = byte(x >> 24) +} + +// putUint64LE puts the little-endian representation of x into the first +// eight bytes of p. +func putUint64LE(p []byte, x uint64) { + p[0] = byte(x) + p[1] = byte(x >> 8) + p[2] = byte(x >> 16) + p[3] = byte(x >> 24) + p[4] = byte(x >> 32) + p[5] = byte(x >> 40) + p[6] = byte(x >> 48) + p[7] = byte(x >> 56) +} + +// uint32LE converts a little endian representation to an uint32 value. +func uint32LE(p []byte) uint32 { + return uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | + uint32(p[3])<<24 +} + +// putUvarint puts a uvarint representation of x into the byte slice. +func putUvarint(p []byte, x uint64) int { + i := 0 + for x >= 0x80 { + p[i] = byte(x) | 0x80 + x >>= 7 + i++ + } + p[i] = byte(x) + return i + 1 +} + +// errOverflow indicates an overflow of the 64-bit unsigned integer. +var errOverflowU64 = errors.New("xz: uvarint overflows 64-bit unsigned integer") + +// readUvarint reads a uvarint from the given byte reader. +func readUvarint(r io.ByteReader) (x uint64, n int, err error) { + var s uint + i := 0 + for { + b, err := r.ReadByte() + if err != nil { + return x, i, err + } + i++ + if b < 0x80 { + if i > 10 || i == 10 && b > 1 { + return x, i, errOverflowU64 + } + return x | uint64(b)< 0 { + k = 4 - k + } + return k +} + +/*** Header ***/ + +// headerMagic stores the magic bytes for the header +var headerMagic = []byte{0xfd, '7', 'z', 'X', 'Z', 0x00} + +// HeaderLen provides the length of the xz file header. +const HeaderLen = 12 + +// Constants for the checksum methods supported by xz. +const ( + CRC32 byte = 0x1 + CRC64 = 0x4 + SHA256 = 0xa +) + +// errInvalidFlags indicates that flags are invalid. +var errInvalidFlags = errors.New("xz: invalid flags") + +// verifyFlags returns the error errInvalidFlags if the value is +// invalid. +func verifyFlags(flags byte) error { + switch flags { + case CRC32, CRC64, SHA256: + return nil + default: + return errInvalidFlags + } +} + +// flagstrings maps flag values to strings. +var flagstrings = map[byte]string{ + CRC32: "CRC-32", + CRC64: "CRC-64", + SHA256: "SHA-256", +} + +// flagString returns the string representation for the given flags. +func flagString(flags byte) string { + s, ok := flagstrings[flags] + if !ok { + return "invalid" + } + return s +} + +// newHashFunc returns a function that creates hash instances for the +// hash method encoded in flags. +func newHashFunc(flags byte) (newHash func() hash.Hash, err error) { + switch flags { + case CRC32: + newHash = newCRC32 + case CRC64: + newHash = newCRC64 + case SHA256: + newHash = sha256.New + default: + err = errInvalidFlags + } + return +} + +// header provides the actual content of the xz file header: the flags. +type header struct { + flags byte +} + +// Errors returned by readHeader. +var errHeaderMagic = errors.New("xz: invalid header magic bytes") + +// ValidHeader checks whether data is a correct xz file header. The +// length of data must be HeaderLen. +func ValidHeader(data []byte) bool { + var h header + err := h.UnmarshalBinary(data) + return err == nil +} + +// String returns a string representation of the flags. +func (h header) String() string { + return flagString(h.flags) +} + +// UnmarshalBinary reads header from the provided data slice. +func (h *header) UnmarshalBinary(data []byte) error { + // header length + if len(data) != HeaderLen { + return errors.New("xz: wrong file header length") + } + + // magic header + if !bytes.Equal(headerMagic, data[:6]) { + return errHeaderMagic + } + + // checksum + crc := crc32.NewIEEE() + crc.Write(data[6:8]) + if uint32LE(data[8:]) != crc.Sum32() { + return errors.New("xz: invalid checksum for file header") + } + + // stream flags + if data[6] != 0 { + return errInvalidFlags + } + flags := data[7] + if err := verifyFlags(flags); err != nil { + return err + } + + h.flags = flags + return nil +} + +// MarshalBinary generates the xz file header. +func (h *header) MarshalBinary() (data []byte, err error) { + if err = verifyFlags(h.flags); err != nil { + return nil, err + } + + data = make([]byte, 12) + copy(data, headerMagic) + data[7] = h.flags + + crc := crc32.NewIEEE() + crc.Write(data[6:8]) + putUint32LE(data[8:], crc.Sum32()) + + return data, nil +} + +/*** Footer ***/ + +// footerLen defines the length of the footer. +const footerLen = 12 + +// footerMagic contains the footer magic bytes. +var footerMagic = []byte{'Y', 'Z'} + +// footer represents the content of the xz file footer. +type footer struct { + indexSize int64 + flags byte +} + +// String prints a string representation of the footer structure. +func (f footer) String() string { + return fmt.Sprintf("%s index size %d", flagString(f.flags), f.indexSize) +} + +// Minimum and maximum for the size of the index (backward size). +const ( + minIndexSize = 4 + maxIndexSize = (1 << 32) * 4 +) + +// MarshalBinary converts footer values into an xz file footer. Note +// that the footer value is checked for correctness. +func (f *footer) MarshalBinary() (data []byte, err error) { + if err = verifyFlags(f.flags); err != nil { + return nil, err + } + if !(minIndexSize <= f.indexSize && f.indexSize <= maxIndexSize) { + return nil, errors.New("xz: index size out of range") + } + if f.indexSize%4 != 0 { + return nil, errors.New( + "xz: index size not aligned to four bytes") + } + + data = make([]byte, footerLen) + + // backward size (index size) + s := (f.indexSize / 4) - 1 + putUint32LE(data[4:], uint32(s)) + // flags + data[9] = f.flags + // footer magic + copy(data[10:], footerMagic) + + // CRC-32 + crc := crc32.NewIEEE() + crc.Write(data[4:10]) + putUint32LE(data, crc.Sum32()) + + return data, nil +} + +// UnmarshalBinary sets the footer value by unmarshalling an xz file +// footer. +func (f *footer) UnmarshalBinary(data []byte) error { + if len(data) != footerLen { + return errors.New("xz: wrong footer length") + } + + // magic bytes + if !bytes.Equal(data[10:], footerMagic) { + return errors.New("xz: footer magic invalid") + } + + // CRC-32 + crc := crc32.NewIEEE() + crc.Write(data[4:10]) + if uint32LE(data) != crc.Sum32() { + return errors.New("xz: footer checksum error") + } + + var g footer + // backward size (index size) + g.indexSize = (int64(uint32LE(data[4:])) + 1) * 4 + + // flags + if data[8] != 0 { + return errInvalidFlags + } + g.flags = data[9] + if err := verifyFlags(g.flags); err != nil { + return err + } + + *f = g + return nil +} + +/*** Block Header ***/ + +// blockHeader represents the content of an xz block header. +type blockHeader struct { + compressedSize int64 + uncompressedSize int64 + filters []filter +} + +// String converts the block header into a string. +func (h blockHeader) String() string { + var buf bytes.Buffer + first := true + if h.compressedSize >= 0 { + fmt.Fprintf(&buf, "compressed size %d", h.compressedSize) + first = false + } + if h.uncompressedSize >= 0 { + if !first { + buf.WriteString(" ") + } + fmt.Fprintf(&buf, "uncompressed size %d", h.uncompressedSize) + first = false + } + for _, f := range h.filters { + if !first { + buf.WriteString(" ") + } + fmt.Fprintf(&buf, "filter %s", f) + first = false + } + return buf.String() +} + +// Masks for the block flags. +const ( + filterCountMask = 0x03 + compressedSizePresent = 0x40 + uncompressedSizePresent = 0x80 + reservedBlockFlags = 0x3C +) + +// errIndexIndicator signals that an index indicator (0x00) has been found +// instead of an expected block header indicator. +var errIndexIndicator = errors.New("xz: found index indicator") + +// readBlockHeader reads the block header. +func readBlockHeader(r io.Reader) (h *blockHeader, n int, err error) { + var buf bytes.Buffer + buf.Grow(20) + + // block header size + z, err := io.CopyN(&buf, r, 1) + n = int(z) + if err != nil { + return nil, n, err + } + s := buf.Bytes()[0] + if s == 0 { + return nil, n, errIndexIndicator + } + + // read complete header + headerLen := (int(s) + 1) * 4 + buf.Grow(headerLen - 1) + z, err = io.CopyN(&buf, r, int64(headerLen-1)) + n += int(z) + if err != nil { + return nil, n, err + } + + // unmarshal block header + h = new(blockHeader) + if err = h.UnmarshalBinary(buf.Bytes()); err != nil { + return nil, n, err + } + + return h, n, nil +} + +// readSizeInBlockHeader reads the uncompressed or compressed size +// fields in the block header. The present value informs the function +// whether the respective field is actually present in the header. +func readSizeInBlockHeader(r io.ByteReader, present bool) (n int64, err error) { + if !present { + return -1, nil + } + x, _, err := readUvarint(r) + if err != nil { + return 0, err + } + if x >= 1<<63 { + return 0, errors.New("xz: size overflow in block header") + } + return int64(x), nil +} + +// UnmarshalBinary unmarshals the block header. +func (h *blockHeader) UnmarshalBinary(data []byte) error { + // Check header length + s := data[0] + if data[0] == 0 { + return errIndexIndicator + } + headerLen := (int(s) + 1) * 4 + if len(data) != headerLen { + return fmt.Errorf("xz: data length %d; want %d", len(data), + headerLen) + } + n := headerLen - 4 + + // Check CRC-32 + crc := crc32.NewIEEE() + crc.Write(data[:n]) + if crc.Sum32() != uint32LE(data[n:]) { + return errors.New("xz: checksum error for block header") + } + + // Block header flags + flags := data[1] + if flags&reservedBlockFlags != 0 { + return errors.New("xz: reserved block header flags set") + } + + r := bytes.NewReader(data[2:n]) + + // Compressed size + var err error + h.compressedSize, err = readSizeInBlockHeader( + r, flags&compressedSizePresent != 0) + if err != nil { + return err + } + + // Uncompressed size + h.uncompressedSize, err = readSizeInBlockHeader( + r, flags&uncompressedSizePresent != 0) + if err != nil { + return err + } + + h.filters, err = readFilters(r, int(flags&filterCountMask)+1) + if err != nil { + return err + } + + // Check padding + // Since headerLen is a multiple of 4 we don't need to check + // alignment. + k := r.Len() + // The standard spec says that the padding should have not more + // than 3 bytes. However we found paddings of 4 or 5 in the + // wild. See https://github.com/ulikunitz/xz/pull/11 and + // https://github.com/ulikunitz/xz/issues/15 + // + // The only reasonable approach seems to be to ignore the + // padding size. We still check that all padding bytes are zero. + if !allZeros(data[n-k : n]) { + return errPadding + } + return nil +} + +// MarshalBinary marshals the binary header. +func (h *blockHeader) MarshalBinary() (data []byte, err error) { + if !(minFilters <= len(h.filters) && len(h.filters) <= maxFilters) { + return nil, errors.New("xz: filter count wrong") + } + for i, f := range h.filters { + if i < len(h.filters)-1 { + if f.id() == lzmaFilterID { + return nil, errors.New( + "xz: LZMA2 filter is not the last") + } + } else { + // last filter + if f.id() != lzmaFilterID { + return nil, errors.New("xz: " + + "last filter must be the LZMA2 filter") + } + } + } + + var buf bytes.Buffer + // header size must set at the end + buf.WriteByte(0) + + // flags + flags := byte(len(h.filters) - 1) + if h.compressedSize >= 0 { + flags |= compressedSizePresent + } + if h.uncompressedSize >= 0 { + flags |= uncompressedSizePresent + } + buf.WriteByte(flags) + + p := make([]byte, 10) + if h.compressedSize >= 0 { + k := putUvarint(p, uint64(h.compressedSize)) + buf.Write(p[:k]) + } + if h.uncompressedSize >= 0 { + k := putUvarint(p, uint64(h.uncompressedSize)) + buf.Write(p[:k]) + } + + for _, f := range h.filters { + fp, err := f.MarshalBinary() + if err != nil { + return nil, err + } + buf.Write(fp) + } + + // padding + for i := padLen(int64(buf.Len())); i > 0; i-- { + buf.WriteByte(0) + } + + // crc place holder + buf.Write(p[:4]) + + data = buf.Bytes() + if len(data)%4 != 0 { + panic("data length not aligned") + } + s := len(data)/4 - 1 + if !(1 < s && s <= 255) { + panic("wrong block header size") + } + data[0] = byte(s) + + crc := crc32.NewIEEE() + crc.Write(data[:len(data)-4]) + putUint32LE(data[len(data)-4:], crc.Sum32()) + + return data, nil +} + +// Constants used for marshalling and unmarshalling filters in the xz +// block header. +const ( + minFilters = 1 + maxFilters = 4 + minReservedID = 1 << 62 +) + +// filter represents a filter in the block header. +type filter interface { + id() uint64 + UnmarshalBinary(data []byte) error + MarshalBinary() (data []byte, err error) + reader(r io.Reader, c *ReaderConfig) (fr io.Reader, err error) + writeCloser(w io.WriteCloser, c *WriterConfig) (fw io.WriteCloser, err error) + // filter must be last filter + last() bool +} + +// readFilter reads a block filter from the block header. At this point +// in time only the LZMA2 filter is supported. +func readFilter(r io.Reader) (f filter, err error) { + br := lzma.ByteReader(r) + + // index + id, _, err := readUvarint(br) + if err != nil { + return nil, err + } + + var data []byte + switch id { + case lzmaFilterID: + data = make([]byte, lzmaFilterLen) + data[0] = lzmaFilterID + if _, err = io.ReadFull(r, data[1:]); err != nil { + return nil, err + } + f = new(lzmaFilter) + default: + if id >= minReservedID { + return nil, errors.New( + "xz: reserved filter id in block stream header") + } + return nil, errors.New("xz: invalid filter id") + } + if err = f.UnmarshalBinary(data); err != nil { + return nil, err + } + return f, err +} + +// readFilters reads count filters. At this point in time only the count +// 1 is supported. +func readFilters(r io.Reader, count int) (filters []filter, err error) { + if count != 1 { + return nil, errors.New("xz: unsupported filter count") + } + f, err := readFilter(r) + if err != nil { + return nil, err + } + return []filter{f}, err +} + +// writeFilters writes the filters. +func writeFilters(w io.Writer, filters []filter) (n int, err error) { + for _, f := range filters { + p, err := f.MarshalBinary() + if err != nil { + return n, err + } + k, err := w.Write(p) + n += k + if err != nil { + return n, err + } + } + return n, nil +} + +/*** Index ***/ + +// record describes a block in the xz file index. +type record struct { + unpaddedSize int64 + uncompressedSize int64 +} + +// readRecord reads an index record. +func readRecord(r io.ByteReader) (rec record, n int, err error) { + u, k, err := readUvarint(r) + n += k + if err != nil { + return rec, n, err + } + rec.unpaddedSize = int64(u) + if rec.unpaddedSize < 0 { + return rec, n, errors.New("xz: unpadded size negative") + } + + u, k, err = readUvarint(r) + n += k + if err != nil { + return rec, n, err + } + rec.uncompressedSize = int64(u) + if rec.uncompressedSize < 0 { + return rec, n, errors.New("xz: uncompressed size negative") + } + + return rec, n, nil +} + +// MarshalBinary converts an index record in its binary encoding. +func (rec *record) MarshalBinary() (data []byte, err error) { + // maximum length of a uvarint is 10 + p := make([]byte, 20) + n := putUvarint(p, uint64(rec.unpaddedSize)) + n += putUvarint(p[n:], uint64(rec.uncompressedSize)) + return p[:n], nil +} + +// writeIndex writes the index, a sequence of records. +func writeIndex(w io.Writer, index []record) (n int64, err error) { + crc := crc32.NewIEEE() + mw := io.MultiWriter(w, crc) + + // index indicator + k, err := mw.Write([]byte{0}) + n += int64(k) + if err != nil { + return n, err + } + + // number of records + p := make([]byte, 10) + k = putUvarint(p, uint64(len(index))) + k, err = mw.Write(p[:k]) + n += int64(k) + if err != nil { + return n, err + } + + // list of records + for _, rec := range index { + p, err := rec.MarshalBinary() + if err != nil { + return n, err + } + k, err = mw.Write(p) + n += int64(k) + if err != nil { + return n, err + } + } + + // index padding + k, err = mw.Write(make([]byte, padLen(int64(n)))) + n += int64(k) + if err != nil { + return n, err + } + + // crc32 checksum + putUint32LE(p, crc.Sum32()) + k, err = w.Write(p[:4]) + n += int64(k) + + return n, err +} + +// readIndexBody reads the index from the reader. It assumes that the +// index indicator has already been read. +func readIndexBody(r io.Reader) (records []record, n int64, err error) { + crc := crc32.NewIEEE() + // index indicator + crc.Write([]byte{0}) + + br := lzma.ByteReader(io.TeeReader(r, crc)) + + // number of records + u, k, err := readUvarint(br) + n += int64(k) + if err != nil { + return nil, n, err + } + recLen := int(u) + if recLen < 0 || uint64(recLen) != u { + return nil, n, errors.New("xz: record number overflow") + } + + // list of records + records = make([]record, recLen) + for i := range records { + records[i], k, err = readRecord(br) + n += int64(k) + if err != nil { + return nil, n, err + } + } + + p := make([]byte, padLen(int64(n+1)), 4) + k, err = io.ReadFull(br.(io.Reader), p) + n += int64(k) + if err != nil { + return nil, n, err + } + if !allZeros(p) { + return nil, n, errors.New("xz: non-zero byte in index padding") + } + + // crc32 + s := crc.Sum32() + p = p[:4] + k, err = io.ReadFull(br.(io.Reader), p) + n += int64(k) + if err != nil { + return records, n, err + } + if uint32LE(p) != s { + return nil, n, errors.New("xz: wrong checksum for index") + } + + return records, n, nil +} diff --git a/vendor/github.com/ulikunitz/xz/internal/hash/cyclic_poly.go b/vendor/github.com/ulikunitz/xz/internal/hash/cyclic_poly.go new file mode 100644 index 000000000..a32887872 --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/internal/hash/cyclic_poly.go @@ -0,0 +1,181 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package hash + +// CyclicPoly provides a cyclic polynomial rolling hash. +type CyclicPoly struct { + h uint64 + p []uint64 + i int +} + +// ror rotates the unsigned 64-bit integer to right. The argument s must be +// less than 64. +func ror(x uint64, s uint) uint64 { + return (x >> s) | (x << (64 - s)) +} + +// NewCyclicPoly creates a new instance of the CyclicPoly structure. The +// argument n gives the number of bytes for which a hash will be executed. +// This number must be positive; the method panics if this isn't the case. +func NewCyclicPoly(n int) *CyclicPoly { + if n < 1 { + panic("argument n must be positive") + } + return &CyclicPoly{p: make([]uint64, 0, n)} +} + +// Len returns the length of the byte sequence for which a hash is generated. +func (r *CyclicPoly) Len() int { + return cap(r.p) +} + +// RollByte hashes the next byte and returns a hash value. The complete becomes +// available after at least Len() bytes have been hashed. +func (r *CyclicPoly) RollByte(x byte) uint64 { + y := hash[x] + if len(r.p) < cap(r.p) { + r.h = ror(r.h, 1) ^ y + r.p = append(r.p, y) + } else { + r.h ^= ror(r.p[r.i], uint(cap(r.p)-1)) + r.h = ror(r.h, 1) ^ y + r.p[r.i] = y + r.i = (r.i + 1) % cap(r.p) + } + return r.h +} + +// Stores the hash for the individual bytes. +var hash = [256]uint64{ + 0x2e4fc3f904065142, 0xc790984cfbc99527, + 0x879f95eb8c62f187, 0x3b61be86b5021ef2, + 0x65a896a04196f0a5, 0xc5b307b80470b59e, + 0xd3bff376a70df14b, 0xc332f04f0b3f1701, + 0x753b5f0e9abf3e0d, 0xb41538fdfe66ef53, + 0x1906a10c2c1c0208, 0xfb0c712a03421c0d, + 0x38be311a65c9552b, 0xfee7ee4ca6445c7e, + 0x71aadeded184f21e, 0xd73426fccda23b2d, + 0x29773fb5fb9600b5, 0xce410261cd32981a, + 0xfe2848b3c62dbc2d, 0x459eaaff6e43e11c, + 0xc13e35fc9c73a887, 0xf30ed5c201e76dbc, + 0xa5f10b3910482cea, 0x2945d59be02dfaad, + 0x06ee334ff70571b5, 0xbabf9d8070f44380, + 0xee3e2e9912ffd27c, 0x2a7118d1ea6b8ea7, + 0x26183cb9f7b1664c, 0xea71dac7da068f21, + 0xea92eca5bd1d0bb7, 0x415595862defcd75, + 0x248a386023c60648, 0x9cf021ab284b3c8a, + 0xfc9372df02870f6c, 0x2b92d693eeb3b3fc, + 0x73e799d139dc6975, 0x7b15ae312486363c, + 0xb70e5454a2239c80, 0x208e3fb31d3b2263, + 0x01f563cabb930f44, 0x2ac4533d2a3240d8, + 0x84231ed1064f6f7c, 0xa9f020977c2a6d19, + 0x213c227271c20122, 0x09fe8a9a0a03d07a, + 0x4236dc75bcaf910c, 0x460a8b2bead8f17e, + 0xd9b27be1aa07055f, 0xd202d5dc4b11c33e, + 0x70adb010543bea12, 0xcdae938f7ea6f579, + 0x3f3d870208672f4d, 0x8e6ccbce9d349536, + 0xe4c0871a389095ae, 0xf5f2a49152bca080, + 0x9a43f9b97269934e, 0xc17b3753cb6f475c, + 0xd56d941e8e206bd4, 0xac0a4f3e525eda00, + 0xa06d5a011912a550, 0x5537ed19537ad1df, + 0xa32fe713d611449d, 0x2a1d05b47c3b579f, + 0x991d02dbd30a2a52, 0x39e91e7e28f93eb0, + 0x40d06adb3e92c9ac, 0x9b9d3afde1c77c97, + 0x9a3f3f41c02c616f, 0x22ecd4ba00f60c44, + 0x0b63d5d801708420, 0x8f227ca8f37ffaec, + 0x0256278670887c24, 0x107e14877dbf540b, + 0x32c19f2786ac1c05, 0x1df5b12bb4bc9c61, + 0xc0cac129d0d4c4e2, 0x9fdb52ee9800b001, + 0x31f601d5d31c48c4, 0x72ff3c0928bcaec7, + 0xd99264421147eb03, 0x535a2d6d38aefcfe, + 0x6ba8b4454a916237, 0xfa39366eaae4719c, + 0x10f00fd7bbb24b6f, 0x5bd23185c76c84d4, + 0xb22c3d7e1b00d33f, 0x3efc20aa6bc830a8, + 0xd61c2503fe639144, 0x30ce625441eb92d3, + 0xe5d34cf359e93100, 0xa8e5aa13f2b9f7a5, + 0x5c2b8d851ca254a6, 0x68fb6c5e8b0d5fdf, + 0xc7ea4872c96b83ae, 0x6dd5d376f4392382, + 0x1be88681aaa9792f, 0xfef465ee1b6c10d9, + 0x1f98b65ed43fcb2e, 0x4d1ca11eb6e9a9c9, + 0x7808e902b3857d0b, 0x171c9c4ea4607972, + 0x58d66274850146df, 0x42b311c10d3981d1, + 0x647fa8c621c41a4c, 0xf472771c66ddfedc, + 0x338d27e3f847b46b, 0x6402ce3da97545ce, + 0x5162db616fc38638, 0x9c83be97bc22a50e, + 0x2d3d7478a78d5e72, 0xe621a9b938fd5397, + 0x9454614eb0f81c45, 0x395fb6e742ed39b6, + 0x77dd9179d06037bf, 0xc478d0fee4d2656d, + 0x35d9d6cb772007af, 0x83a56e92c883f0f6, + 0x27937453250c00a1, 0x27bd6ebc3a46a97d, + 0x9f543bf784342d51, 0xd158f38c48b0ed52, + 0x8dd8537c045f66b4, 0x846a57230226f6d5, + 0x6b13939e0c4e7cdf, 0xfca25425d8176758, + 0x92e5fc6cd52788e6, 0x9992e13d7a739170, + 0x518246f7a199e8ea, 0xf104c2a71b9979c7, + 0x86b3ffaabea4768f, 0x6388061cf3e351ad, + 0x09d9b5295de5bbb5, 0x38bf1638c2599e92, + 0x1d759846499e148d, 0x4c0ff015e5f96ef4, + 0xa41a94cfa270f565, 0x42d76f9cb2326c0b, + 0x0cf385dd3c9c23ba, 0x0508a6c7508d6e7a, + 0x337523aabbe6cf8d, 0x646bb14001d42b12, + 0xc178729d138adc74, 0xf900ef4491f24086, + 0xee1a90d334bb5ac4, 0x9755c92247301a50, + 0xb999bf7c4ff1b610, 0x6aeeb2f3b21e8fc9, + 0x0fa8084cf91ac6ff, 0x10d226cf136e6189, + 0xd302057a07d4fb21, 0x5f03800e20a0fcc3, + 0x80118d4ae46bd210, 0x58ab61a522843733, + 0x51edd575c5432a4b, 0x94ee6ff67f9197f7, + 0x765669e0e5e8157b, 0xa5347830737132f0, + 0x3ba485a69f01510c, 0x0b247d7b957a01c3, + 0x1b3d63449fd807dc, 0x0fdc4721c30ad743, + 0x8b535ed3829b2b14, 0xee41d0cad65d232c, + 0xe6a99ed97a6a982f, 0x65ac6194c202003d, + 0x692accf3a70573eb, 0xcc3c02c3e200d5af, + 0x0d419e8b325914a3, 0x320f160f42c25e40, + 0x00710d647a51fe7a, 0x3c947692330aed60, + 0x9288aa280d355a7a, 0xa1806a9b791d1696, + 0x5d60e38496763da1, 0x6c69e22e613fd0f4, + 0x977fc2a5aadffb17, 0xfb7bd063fc5a94ba, + 0x460c17992cbaece1, 0xf7822c5444d3297f, + 0x344a9790c69b74aa, 0xb80a42e6cae09dce, + 0x1b1361eaf2b1e757, 0xd84c1e758e236f01, + 0x88e0b7be347627cc, 0x45246009b7a99490, + 0x8011c6dd3fe50472, 0xc341d682bffb99d7, + 0x2511be93808e2d15, 0xd5bc13d7fd739840, + 0x2a3cd030679ae1ec, 0x8ad9898a4b9ee157, + 0x3245fef0a8eaf521, 0x3d6d8dbbb427d2b0, + 0x1ed146d8968b3981, 0x0c6a28bf7d45f3fc, + 0x4a1fd3dbcee3c561, 0x4210ff6a476bf67e, + 0xa559cce0d9199aac, 0xde39d47ef3723380, + 0xe5b69d848ce42e35, 0xefa24296f8e79f52, + 0x70190b59db9a5afc, 0x26f166cdb211e7bf, + 0x4deaf2df3c6b8ef5, 0xf171dbdd670f1017, + 0xb9059b05e9420d90, 0x2f0da855c9388754, + 0x611d5e9ab77949cc, 0x2912038ac01163f4, + 0x0231df50402b2fba, 0x45660fc4f3245f58, + 0xb91cc97c7c8dac50, 0xb72d2aafe4953427, + 0xfa6463f87e813d6b, 0x4515f7ee95d5c6a2, + 0x1310e1c1a48d21c3, 0xad48a7810cdd8544, + 0x4d5bdfefd5c9e631, 0xa43ed43f1fdcb7de, + 0xe70cfc8fe1ee9626, 0xef4711b0d8dda442, + 0xb80dd9bd4dab6c93, 0xa23be08d31ba4d93, + 0x9b37db9d0335a39c, 0x494b6f870f5cfebc, + 0x6d1b3c1149dda943, 0x372c943a518c1093, + 0xad27af45e77c09c4, 0x3b6f92b646044604, + 0xac2917909f5fcf4f, 0x2069a60e977e5557, + 0x353a469e71014de5, 0x24be356281f55c15, + 0x2b6d710ba8e9adea, 0x404ad1751c749c29, + 0xed7311bf23d7f185, 0xba4f6976b4acc43e, + 0x32d7198d2bc39000, 0xee667019014d6e01, + 0x494ef3e128d14c83, 0x1f95a152baecd6be, + 0x201648dff1f483a5, 0x68c28550c8384af6, + 0x5fc834a6824a7f48, 0x7cd06cb7365eaf28, + 0xd82bbd95e9b30909, 0x234f0d1694c53f6d, + 0xd2fb7f4a96d83f4a, 0xff0d5da83acac05e, + 0xf8f6b97f5585080a, 0x74236084be57b95b, + 0xa25e40c03bbc36ad, 0x6b6e5c14ce88465b, + 0x4378ffe93e1528c5, 0x94ca92a17118e2d2, +} diff --git a/vendor/github.com/ulikunitz/xz/internal/hash/doc.go b/vendor/github.com/ulikunitz/xz/internal/hash/doc.go new file mode 100644 index 000000000..f99ec2206 --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/internal/hash/doc.go @@ -0,0 +1,14 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package hash provides rolling hashes. + +Rolling hashes have to be used for maintaining the positions of n-byte +sequences in the dictionary buffer. + +The package provides currently the Rabin-Karp rolling hash and a Cyclic +Polynomial hash. Both support the Hashes method to be used with an interface. +*/ +package hash diff --git a/vendor/github.com/ulikunitz/xz/internal/hash/rabin_karp.go b/vendor/github.com/ulikunitz/xz/internal/hash/rabin_karp.go new file mode 100644 index 000000000..58635b113 --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/internal/hash/rabin_karp.go @@ -0,0 +1,66 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package hash + +// A is the default constant for Robin-Karp rolling hash. This is a random +// prime. +const A = 0x97b548add41d5da1 + +// RabinKarp supports the computation of a rolling hash. +type RabinKarp struct { + A uint64 + // a^n + aOldest uint64 + h uint64 + p []byte + i int +} + +// NewRabinKarp creates a new RabinKarp value. The argument n defines the +// length of the byte sequence to be hashed. The default constant will will be +// used. +func NewRabinKarp(n int) *RabinKarp { + return NewRabinKarpConst(n, A) +} + +// NewRabinKarpConst creates a new RabinKarp value. The argument n defines the +// length of the byte sequence to be hashed. The argument a provides the +// constant used to compute the hash. +func NewRabinKarpConst(n int, a uint64) *RabinKarp { + if n <= 0 { + panic("number of bytes n must be positive") + } + aOldest := uint64(1) + // There are faster methods. For the small n required by the LZMA + // compressor O(n) is sufficient. + for i := 0; i < n; i++ { + aOldest *= a + } + return &RabinKarp{ + A: a, aOldest: aOldest, + p: make([]byte, 0, n), + } +} + +// Len returns the length of the byte sequence. +func (r *RabinKarp) Len() int { + return cap(r.p) +} + +// RollByte computes the hash after x has been added. +func (r *RabinKarp) RollByte(x byte) uint64 { + if len(r.p) < cap(r.p) { + r.h += uint64(x) + r.h *= r.A + r.p = append(r.p, x) + } else { + r.h -= uint64(r.p[r.i]) * r.aOldest + r.h += uint64(x) + r.h *= r.A + r.p[r.i] = x + r.i = (r.i + 1) % cap(r.p) + } + return r.h +} diff --git a/vendor/github.com/ulikunitz/xz/internal/hash/roller.go b/vendor/github.com/ulikunitz/xz/internal/hash/roller.go new file mode 100644 index 000000000..ab6a19ca4 --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/internal/hash/roller.go @@ -0,0 +1,29 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package hash + +// Roller provides an interface for rolling hashes. The hash value will become +// valid after hash has been called Len times. +type Roller interface { + Len() int + RollByte(x byte) uint64 +} + +// Hashes computes all hash values for the array p. Note that the state of the +// roller is changed. +func Hashes(r Roller, p []byte) []uint64 { + n := r.Len() + if len(p) < n { + return nil + } + h := make([]uint64, len(p)-n+1) + for i := 0; i < n-1; i++ { + r.RollByte(p[i]) + } + for i := range h { + h[i] = r.RollByte(p[i+n-1]) + } + return h +} diff --git a/vendor/github.com/ulikunitz/xz/internal/xlog/xlog.go b/vendor/github.com/ulikunitz/xz/internal/xlog/xlog.go new file mode 100644 index 000000000..0ba45e8ff --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/internal/xlog/xlog.go @@ -0,0 +1,457 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package xlog provides a simple logging package that allows to disable +// certain message categories. It defines a type, Logger, with multiple +// methods for formatting output. The package has also a predefined +// 'standard' Logger accessible through helper function Print[f|ln], +// Fatal[f|ln], Panic[f|ln], Warn[f|ln], Print[f|ln] and Debug[f|ln] +// that are easier to use then creating a Logger manually. That logger +// writes to standard error and prints the date and time of each logged +// message, which can be configured using the function SetFlags. +// +// The Fatal functions call os.Exit(1) after the message is output +// unless not suppressed by the flags. The Panic functions call panic +// after the writing the log message unless suppressed. +package xlog + +import ( + "fmt" + "io" + "os" + "runtime" + "sync" + "time" +) + +// The flags define what information is prefixed to each log entry +// generated by the Logger. The Lno* versions allow the suppression of +// specific output. The bits are or'ed together to control what will be +// printed. There is no control over the order of the items printed and +// the format. The full format is: +// +// 2009-01-23 01:23:23.123123 /a/b/c/d.go:23: message +// +const ( + Ldate = 1 << iota // the date: 2009-01-23 + Ltime // the time: 01:23:23 + Lmicroseconds // microsecond resolution: 01:23:23.123123 + Llongfile // full file name and line number: /a/b/c/d.go:23 + Lshortfile // final file name element and line number: d.go:23 + Lnopanic // suppresses output from Panic[f|ln] but not the panic call + Lnofatal // suppresses output from Fatal[f|ln] but not the exit + Lnowarn // suppresses output from Warn[f|ln] + Lnoprint // suppresses output from Print[f|ln] + Lnodebug // suppresses output from Debug[f|ln] + // initial values for the standard logger + Lstdflags = Ldate | Ltime | Lnodebug +) + +// A Logger represents an active logging object that generates lines of +// output to an io.Writer. Each logging operation if not suppressed +// makes a single call to the Writer's Write method. A Logger can be +// used simultaneously from multiple goroutines; it guarantees to +// serialize access to the Writer. +type Logger struct { + mu sync.Mutex // ensures atomic writes; and protects the following + // fields + prefix string // prefix to write at beginning of each line + flag int // properties + out io.Writer // destination for output + buf []byte // for accumulating text to write +} + +// New creates a new Logger. The out argument sets the destination to +// which the log output will be written. The prefix appears at the +// beginning of each log line. The flag argument defines the logging +// properties. +func New(out io.Writer, prefix string, flag int) *Logger { + return &Logger{out: out, prefix: prefix, flag: flag} +} + +// std is the standard logger used by the package scope functions. +var std = New(os.Stderr, "", Lstdflags) + +// itoa converts the integer to ASCII. A negative widths will avoid +// zero-padding. The function supports only non-negative integers. +func itoa(buf *[]byte, i int, wid int) { + var u = uint(i) + if u == 0 && wid <= 1 { + *buf = append(*buf, '0') + return + } + var b [32]byte + bp := len(b) + for ; u > 0 || wid > 0; u /= 10 { + bp-- + wid-- + b[bp] = byte(u%10) + '0' + } + *buf = append(*buf, b[bp:]...) +} + +// formatHeader puts the header into the buf field of the buffer. +func (l *Logger) formatHeader(t time.Time, file string, line int) { + l.buf = append(l.buf, l.prefix...) + if l.flag&(Ldate|Ltime|Lmicroseconds) != 0 { + if l.flag&Ldate != 0 { + year, month, day := t.Date() + itoa(&l.buf, year, 4) + l.buf = append(l.buf, '-') + itoa(&l.buf, int(month), 2) + l.buf = append(l.buf, '-') + itoa(&l.buf, day, 2) + l.buf = append(l.buf, ' ') + } + if l.flag&(Ltime|Lmicroseconds) != 0 { + hour, min, sec := t.Clock() + itoa(&l.buf, hour, 2) + l.buf = append(l.buf, ':') + itoa(&l.buf, min, 2) + l.buf = append(l.buf, ':') + itoa(&l.buf, sec, 2) + if l.flag&Lmicroseconds != 0 { + l.buf = append(l.buf, '.') + itoa(&l.buf, t.Nanosecond()/1e3, 6) + } + l.buf = append(l.buf, ' ') + } + } + if l.flag&(Lshortfile|Llongfile) != 0 { + if l.flag&Lshortfile != 0 { + short := file + for i := len(file) - 1; i > 0; i-- { + if file[i] == '/' { + short = file[i+1:] + break + } + } + file = short + } + l.buf = append(l.buf, file...) + l.buf = append(l.buf, ':') + itoa(&l.buf, line, -1) + l.buf = append(l.buf, ": "...) + } +} + +func (l *Logger) output(calldepth int, now time.Time, s string) error { + var file string + var line int + if l.flag&(Lshortfile|Llongfile) != 0 { + l.mu.Unlock() + var ok bool + _, file, line, ok = runtime.Caller(calldepth) + if !ok { + file = "???" + line = 0 + } + l.mu.Lock() + } + l.buf = l.buf[:0] + l.formatHeader(now, file, line) + l.buf = append(l.buf, s...) + if len(s) == 0 || s[len(s)-1] != '\n' { + l.buf = append(l.buf, '\n') + } + _, err := l.out.Write(l.buf) + return err +} + +// Output writes the string s with the header controlled by the flags to +// the l.out writer. A newline will be appended if s doesn't end in a +// newline. Calldepth is used to recover the PC, although all current +// calls of Output use the call depth 2. Access to the function is serialized. +func (l *Logger) Output(calldepth, noflag int, v ...interface{}) error { + now := time.Now() + l.mu.Lock() + defer l.mu.Unlock() + if l.flag&noflag != 0 { + return nil + } + s := fmt.Sprint(v...) + return l.output(calldepth+1, now, s) +} + +// Outputf works like output but formats the output like Printf. +func (l *Logger) Outputf(calldepth int, noflag int, format string, v ...interface{}) error { + now := time.Now() + l.mu.Lock() + defer l.mu.Unlock() + if l.flag&noflag != 0 { + return nil + } + s := fmt.Sprintf(format, v...) + return l.output(calldepth+1, now, s) +} + +// Outputln works like output but formats the output like Println. +func (l *Logger) Outputln(calldepth int, noflag int, v ...interface{}) error { + now := time.Now() + l.mu.Lock() + defer l.mu.Unlock() + if l.flag&noflag != 0 { + return nil + } + s := fmt.Sprintln(v...) + return l.output(calldepth+1, now, s) +} + +// Panic prints the message like Print and calls panic. The printing +// might be suppressed by the flag Lnopanic. +func (l *Logger) Panic(v ...interface{}) { + l.Output(2, Lnopanic, v...) + s := fmt.Sprint(v...) + panic(s) +} + +// Panic prints the message like Print and calls panic. The printing +// might be suppressed by the flag Lnopanic. +func Panic(v ...interface{}) { + std.Output(2, Lnopanic, v...) + s := fmt.Sprint(v...) + panic(s) +} + +// Panicf prints the message like Printf and calls panic. The printing +// might be suppressed by the flag Lnopanic. +func (l *Logger) Panicf(format string, v ...interface{}) { + l.Outputf(2, Lnopanic, format, v...) + s := fmt.Sprintf(format, v...) + panic(s) +} + +// Panicf prints the message like Printf and calls panic. The printing +// might be suppressed by the flag Lnopanic. +func Panicf(format string, v ...interface{}) { + std.Outputf(2, Lnopanic, format, v...) + s := fmt.Sprintf(format, v...) + panic(s) +} + +// Panicln prints the message like Println and calls panic. The printing +// might be suppressed by the flag Lnopanic. +func (l *Logger) Panicln(v ...interface{}) { + l.Outputln(2, Lnopanic, v...) + s := fmt.Sprintln(v...) + panic(s) +} + +// Panicln prints the message like Println and calls panic. The printing +// might be suppressed by the flag Lnopanic. +func Panicln(v ...interface{}) { + std.Outputln(2, Lnopanic, v...) + s := fmt.Sprintln(v...) + panic(s) +} + +// Fatal prints the message like Print and calls os.Exit(1). The +// printing might be suppressed by the flag Lnofatal. +func (l *Logger) Fatal(v ...interface{}) { + l.Output(2, Lnofatal, v...) + os.Exit(1) +} + +// Fatal prints the message like Print and calls os.Exit(1). The +// printing might be suppressed by the flag Lnofatal. +func Fatal(v ...interface{}) { + std.Output(2, Lnofatal, v...) + os.Exit(1) +} + +// Fatalf prints the message like Printf and calls os.Exit(1). The +// printing might be suppressed by the flag Lnofatal. +func (l *Logger) Fatalf(format string, v ...interface{}) { + l.Outputf(2, Lnofatal, format, v...) + os.Exit(1) +} + +// Fatalf prints the message like Printf and calls os.Exit(1). The +// printing might be suppressed by the flag Lnofatal. +func Fatalf(format string, v ...interface{}) { + std.Outputf(2, Lnofatal, format, v...) + os.Exit(1) +} + +// Fatalln prints the message like Println and calls os.Exit(1). The +// printing might be suppressed by the flag Lnofatal. +func (l *Logger) Fatalln(format string, v ...interface{}) { + l.Outputln(2, Lnofatal, v...) + os.Exit(1) +} + +// Fatalln prints the message like Println and calls os.Exit(1). The +// printing might be suppressed by the flag Lnofatal. +func Fatalln(format string, v ...interface{}) { + std.Outputln(2, Lnofatal, v...) + os.Exit(1) +} + +// Warn prints the message like Print. The printing might be suppressed +// by the flag Lnowarn. +func (l *Logger) Warn(v ...interface{}) { + l.Output(2, Lnowarn, v...) +} + +// Warn prints the message like Print. The printing might be suppressed +// by the flag Lnowarn. +func Warn(v ...interface{}) { + std.Output(2, Lnowarn, v...) +} + +// Warnf prints the message like Printf. The printing might be suppressed +// by the flag Lnowarn. +func (l *Logger) Warnf(format string, v ...interface{}) { + l.Outputf(2, Lnowarn, format, v...) +} + +// Warnf prints the message like Printf. The printing might be suppressed +// by the flag Lnowarn. +func Warnf(format string, v ...interface{}) { + std.Outputf(2, Lnowarn, format, v...) +} + +// Warnln prints the message like Println. The printing might be suppressed +// by the flag Lnowarn. +func (l *Logger) Warnln(v ...interface{}) { + l.Outputln(2, Lnowarn, v...) +} + +// Warnln prints the message like Println. The printing might be suppressed +// by the flag Lnowarn. +func Warnln(v ...interface{}) { + std.Outputln(2, Lnowarn, v...) +} + +// Print prints the message like fmt.Print. The printing might be suppressed +// by the flag Lnoprint. +func (l *Logger) Print(v ...interface{}) { + l.Output(2, Lnoprint, v...) +} + +// Print prints the message like fmt.Print. The printing might be suppressed +// by the flag Lnoprint. +func Print(v ...interface{}) { + std.Output(2, Lnoprint, v...) +} + +// Printf prints the message like fmt.Printf. The printing might be suppressed +// by the flag Lnoprint. +func (l *Logger) Printf(format string, v ...interface{}) { + l.Outputf(2, Lnoprint, format, v...) +} + +// Printf prints the message like fmt.Printf. The printing might be suppressed +// by the flag Lnoprint. +func Printf(format string, v ...interface{}) { + std.Outputf(2, Lnoprint, format, v...) +} + +// Println prints the message like fmt.Println. The printing might be +// suppressed by the flag Lnoprint. +func (l *Logger) Println(v ...interface{}) { + l.Outputln(2, Lnoprint, v...) +} + +// Println prints the message like fmt.Println. The printing might be +// suppressed by the flag Lnoprint. +func Println(v ...interface{}) { + std.Outputln(2, Lnoprint, v...) +} + +// Debug prints the message like Print. The printing might be suppressed +// by the flag Lnodebug. +func (l *Logger) Debug(v ...interface{}) { + l.Output(2, Lnodebug, v...) +} + +// Debug prints the message like Print. The printing might be suppressed +// by the flag Lnodebug. +func Debug(v ...interface{}) { + std.Output(2, Lnodebug, v...) +} + +// Debugf prints the message like Printf. The printing might be suppressed +// by the flag Lnodebug. +func (l *Logger) Debugf(format string, v ...interface{}) { + l.Outputf(2, Lnodebug, format, v...) +} + +// Debugf prints the message like Printf. The printing might be suppressed +// by the flag Lnodebug. +func Debugf(format string, v ...interface{}) { + std.Outputf(2, Lnodebug, format, v...) +} + +// Debugln prints the message like Println. The printing might be suppressed +// by the flag Lnodebug. +func (l *Logger) Debugln(v ...interface{}) { + l.Outputln(2, Lnodebug, v...) +} + +// Debugln prints the message like Println. The printing might be suppressed +// by the flag Lnodebug. +func Debugln(v ...interface{}) { + std.Outputln(2, Lnodebug, v...) +} + +// Flags returns the current flags used by the logger. +func (l *Logger) Flags() int { + l.mu.Lock() + defer l.mu.Unlock() + return l.flag +} + +// Flags returns the current flags used by the standard logger. +func Flags() int { + return std.Flags() +} + +// SetFlags sets the flags of the logger. +func (l *Logger) SetFlags(flag int) { + l.mu.Lock() + defer l.mu.Unlock() + l.flag = flag +} + +// SetFlags sets the flags for the standard logger. +func SetFlags(flag int) { + std.SetFlags(flag) +} + +// Prefix returns the prefix used by the logger. +func (l *Logger) Prefix() string { + l.mu.Lock() + defer l.mu.Unlock() + return l.prefix +} + +// Prefix returns the prefix used by the standard logger of the package. +func Prefix() string { + return std.Prefix() +} + +// SetPrefix sets the prefix for the logger. +func (l *Logger) SetPrefix(prefix string) { + l.mu.Lock() + defer l.mu.Unlock() + l.prefix = prefix +} + +// SetPrefix sets the prefix of the standard logger of the package. +func SetPrefix(prefix string) { + std.SetPrefix(prefix) +} + +// SetOutput sets the output of the logger. +func (l *Logger) SetOutput(w io.Writer) { + l.mu.Lock() + defer l.mu.Unlock() + l.out = w +} + +// SetOutput sets the output for the standard logger of the package. +func SetOutput(w io.Writer) { + std.SetOutput(w) +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/bintree.go b/vendor/github.com/ulikunitz/xz/lzma/bintree.go new file mode 100644 index 000000000..a781bd195 --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/bintree.go @@ -0,0 +1,523 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import ( + "bufio" + "errors" + "fmt" + "io" + "unicode" +) + +// node represents a node in the binary tree. +type node struct { + // x is the search value + x uint32 + // p parent node + p uint32 + // l left child + l uint32 + // r right child + r uint32 +} + +// wordLen is the number of bytes represented by the v field of a node. +const wordLen = 4 + +// binTree supports the identification of the next operation based on a +// binary tree. +// +// Nodes will be identified by their index into the ring buffer. +type binTree struct { + dict *encoderDict + // ring buffer of nodes + node []node + // absolute offset of the entry for the next node. Position 4 + // byte larger. + hoff int64 + // front position in the node ring buffer + front uint32 + // index of the root node + root uint32 + // current x value + x uint32 + // preallocated array + data []byte +} + +// null represents the nonexistent index. We can't use zero because it +// would always exist or we would need to decrease the index for each +// reference. +const null uint32 = 1<<32 - 1 + +// newBinTree initializes the binTree structure. The capacity defines +// the size of the buffer and defines the maximum distance for which +// matches will be found. +func newBinTree(capacity int) (t *binTree, err error) { + if capacity < 1 { + return nil, errors.New( + "newBinTree: capacity must be larger than zero") + } + if int64(capacity) >= int64(null) { + return nil, errors.New( + "newBinTree: capacity must less 2^{32}-1") + } + t = &binTree{ + node: make([]node, capacity), + hoff: -int64(wordLen), + root: null, + data: make([]byte, maxMatchLen), + } + return t, nil +} + +func (t *binTree) SetDict(d *encoderDict) { t.dict = d } + +// WriteByte writes a single byte into the binary tree. +func (t *binTree) WriteByte(c byte) error { + t.x = (t.x << 8) | uint32(c) + t.hoff++ + if t.hoff < 0 { + return nil + } + v := t.front + if int64(v) < t.hoff { + // We are overwriting old nodes stored in the tree. + t.remove(v) + } + t.node[v].x = t.x + t.add(v) + t.front++ + if int64(t.front) >= int64(len(t.node)) { + t.front = 0 + } + return nil +} + +// Writes writes a sequence of bytes into the binTree structure. +func (t *binTree) Write(p []byte) (n int, err error) { + for _, c := range p { + t.WriteByte(c) + } + return len(p), nil +} + +// add puts the node v into the tree. The node must not be part of the +// tree before. +func (t *binTree) add(v uint32) { + vn := &t.node[v] + // Set left and right to null indices. + vn.l, vn.r = null, null + // If the binary tree is empty make v the root. + if t.root == null { + t.root = v + vn.p = null + return + } + x := vn.x + p := t.root + // Search for the right leave link and add the new node. + for { + pn := &t.node[p] + if x <= pn.x { + if pn.l == null { + pn.l = v + vn.p = p + return + } + p = pn.l + } else { + if pn.r == null { + pn.r = v + vn.p = p + return + } + p = pn.r + } + } +} + +// parent returns the parent node index of v and the pointer to v value +// in the parent. +func (t *binTree) parent(v uint32) (p uint32, ptr *uint32) { + if t.root == v { + return null, &t.root + } + p = t.node[v].p + if t.node[p].l == v { + ptr = &t.node[p].l + } else { + ptr = &t.node[p].r + } + return +} + +// Remove node v. +func (t *binTree) remove(v uint32) { + vn := &t.node[v] + p, ptr := t.parent(v) + l, r := vn.l, vn.r + if l == null { + // Move the right child up. + *ptr = r + if r != null { + t.node[r].p = p + } + return + } + if r == null { + // Move the left child up. + *ptr = l + t.node[l].p = p + return + } + + // Search the in-order predecessor u. + un := &t.node[l] + ur := un.r + if ur == null { + // In order predecessor is l. Move it up. + un.r = r + t.node[r].p = l + un.p = p + *ptr = l + return + } + var u uint32 + for { + // Look for the max value in the tree where l is root. + u = ur + ur = t.node[u].r + if ur == null { + break + } + } + // replace u with ul + un = &t.node[u] + ul := un.l + up := un.p + t.node[up].r = ul + if ul != null { + t.node[ul].p = up + } + + // replace v by u + un.l, un.r = l, r + t.node[l].p = u + t.node[r].p = u + *ptr = u + un.p = p +} + +// search looks for the node that have the value x or for the nodes that +// brace it. The node highest in the tree with the value x will be +// returned. All other nodes with the same value live in left subtree of +// the returned node. +func (t *binTree) search(v uint32, x uint32) (a, b uint32) { + a, b = null, null + if v == null { + return + } + for { + vn := &t.node[v] + if x <= vn.x { + if x == vn.x { + return v, v + } + b = v + if vn.l == null { + return + } + v = vn.l + } else { + a = v + if vn.r == null { + return + } + v = vn.r + } + } +} + +// max returns the node with maximum value in the subtree with v as +// root. +func (t *binTree) max(v uint32) uint32 { + if v == null { + return null + } + for { + r := t.node[v].r + if r == null { + return v + } + v = r + } +} + +// min returns the node with the minimum value in the subtree with v as +// root. +func (t *binTree) min(v uint32) uint32 { + if v == null { + return null + } + for { + l := t.node[v].l + if l == null { + return v + } + v = l + } +} + +// pred returns the in-order predecessor of node v. +func (t *binTree) pred(v uint32) uint32 { + if v == null { + return null + } + u := t.max(t.node[v].l) + if u != null { + return u + } + for { + p := t.node[v].p + if p == null { + return null + } + if t.node[p].r == v { + return p + } + v = p + } +} + +// succ returns the in-order successor of node v. +func (t *binTree) succ(v uint32) uint32 { + if v == null { + return null + } + u := t.min(t.node[v].r) + if u != null { + return u + } + for { + p := t.node[v].p + if p == null { + return null + } + if t.node[p].l == v { + return p + } + v = p + } +} + +// xval converts the first four bytes of a into an 32-bit unsigned +// integer in big-endian order. +func xval(a []byte) uint32 { + var x uint32 + switch len(a) { + default: + x |= uint32(a[3]) + fallthrough + case 3: + x |= uint32(a[2]) << 8 + fallthrough + case 2: + x |= uint32(a[1]) << 16 + fallthrough + case 1: + x |= uint32(a[0]) << 24 + case 0: + } + return x +} + +// dumpX converts value x into a four-letter string. +func dumpX(x uint32) string { + a := make([]byte, 4) + for i := 0; i < 4; i++ { + c := byte(x >> uint((3-i)*8)) + if unicode.IsGraphic(rune(c)) { + a[i] = c + } else { + a[i] = '.' + } + } + return string(a) +} + +// dumpNode writes a representation of the node v into the io.Writer. +func (t *binTree) dumpNode(w io.Writer, v uint32, indent int) { + if v == null { + return + } + + vn := &t.node[v] + + t.dumpNode(w, vn.r, indent+2) + + for i := 0; i < indent; i++ { + fmt.Fprint(w, " ") + } + if vn.p == null { + fmt.Fprintf(w, "node %d %q parent null\n", v, dumpX(vn.x)) + } else { + fmt.Fprintf(w, "node %d %q parent %d\n", v, dumpX(vn.x), vn.p) + } + + t.dumpNode(w, vn.l, indent+2) +} + +// dump prints a representation of the binary tree into the writer. +func (t *binTree) dump(w io.Writer) error { + bw := bufio.NewWriter(w) + t.dumpNode(bw, t.root, 0) + return bw.Flush() +} + +func (t *binTree) distance(v uint32) int { + dist := int(t.front) - int(v) + if dist <= 0 { + dist += len(t.node) + } + return dist +} + +type matchParams struct { + rep [4]uint32 + // length when match will be accepted + nAccept int + // nodes to check + check int + // finish if length get shorter + stopShorter bool +} + +func (t *binTree) match(m match, distIter func() (int, bool), p matchParams, +) (r match, checked int, accepted bool) { + buf := &t.dict.buf + for { + if checked >= p.check { + return m, checked, true + } + dist, ok := distIter() + if !ok { + return m, checked, false + } + checked++ + if m.n > 0 { + i := buf.rear - dist + m.n - 1 + if i < 0 { + i += len(buf.data) + } else if i >= len(buf.data) { + i -= len(buf.data) + } + if buf.data[i] != t.data[m.n-1] { + if p.stopShorter { + return m, checked, false + } + continue + } + } + n := buf.matchLen(dist, t.data) + switch n { + case 0: + if p.stopShorter { + return m, checked, false + } + continue + case 1: + if uint32(dist-minDistance) != p.rep[0] { + continue + } + } + if n < m.n || (n == m.n && int64(dist) >= m.distance) { + continue + } + m = match{int64(dist), n} + if n >= p.nAccept { + return m, checked, true + } + } +} + +func (t *binTree) NextOp(rep [4]uint32) operation { + // retrieve maxMatchLen data + n, _ := t.dict.buf.Peek(t.data[:maxMatchLen]) + if n == 0 { + panic("no data in buffer") + } + t.data = t.data[:n] + + var ( + m match + x, u, v uint32 + iterPred, iterSucc func() (int, bool) + ) + p := matchParams{ + rep: rep, + nAccept: maxMatchLen, + check: 32, + } + i := 4 + iterSmall := func() (dist int, ok bool) { + i-- + if i <= 0 { + return 0, false + } + return i, true + } + m, checked, accepted := t.match(m, iterSmall, p) + if accepted { + goto end + } + p.check -= checked + x = xval(t.data) + u, v = t.search(t.root, x) + if u == v && len(t.data) == 4 { + iter := func() (dist int, ok bool) { + if u == null { + return 0, false + } + dist = t.distance(u) + u, v = t.search(t.node[u].l, x) + if u != v { + u = null + } + return dist, true + } + m, _, _ = t.match(m, iter, p) + goto end + } + p.stopShorter = true + iterSucc = func() (dist int, ok bool) { + if v == null { + return 0, false + } + dist = t.distance(v) + v = t.succ(v) + return dist, true + } + m, checked, accepted = t.match(m, iterSucc, p) + if accepted { + goto end + } + p.check -= checked + iterPred = func() (dist int, ok bool) { + if u == null { + return 0, false + } + dist = t.distance(u) + u = t.pred(u) + return dist, true + } + m, _, _ = t.match(m, iterPred, p) +end: + if m.n == 0 { + return lit{t.data[0]} + } + return m +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/bitops.go b/vendor/github.com/ulikunitz/xz/lzma/bitops.go new file mode 100644 index 000000000..e9bab0199 --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/bitops.go @@ -0,0 +1,45 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +/* Naming conventions follows the CodeReviewComments in the Go Wiki. */ + +// ntz32Const is used by the functions NTZ and NLZ. +const ntz32Const = 0x04d7651f + +// ntz32Table is a helper table for de Bruijn algorithm by Danny Dubé. +// See Henry S. Warren, Jr. "Hacker's Delight" section 5-1 figure 5-26. +var ntz32Table = [32]int8{ + 0, 1, 2, 24, 3, 19, 6, 25, + 22, 4, 20, 10, 16, 7, 12, 26, + 31, 23, 18, 5, 21, 9, 15, 11, + 30, 17, 8, 14, 29, 13, 28, 27, +} + +// ntz32 computes the number of trailing zeros for an unsigned 32-bit integer. +func ntz32(x uint32) int { + if x == 0 { + return 32 + } + x = (x & -x) * ntz32Const + return int(ntz32Table[x>>27]) +} + +// nlz32 computes the number of leading zeros for an unsigned 32-bit integer. +func nlz32(x uint32) int { + // Smear left most bit to the right + x |= x >> 1 + x |= x >> 2 + x |= x >> 4 + x |= x >> 8 + x |= x >> 16 + // Use ntz mechanism to calculate nlz. + x++ + if x == 0 { + return 0 + } + x *= ntz32Const + return 32 - int(ntz32Table[x>>27]) +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/breader.go b/vendor/github.com/ulikunitz/xz/lzma/breader.go new file mode 100644 index 000000000..5350d814f --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/breader.go @@ -0,0 +1,39 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import ( + "errors" + "io" +) + +// breader provides the ReadByte function for a Reader. It doesn't read +// more data from the reader than absolutely necessary. +type breader struct { + io.Reader + // helper slice to save allocations + p []byte +} + +// ByteReader converts an io.Reader into an io.ByteReader. +func ByteReader(r io.Reader) io.ByteReader { + br, ok := r.(io.ByteReader) + if !ok { + return &breader{r, make([]byte, 1)} + } + return br +} + +// ReadByte read byte function. +func (r *breader) ReadByte() (c byte, err error) { + n, err := r.Reader.Read(r.p) + if n < 1 { + if err == nil { + err = errors.New("breader.ReadByte: no data") + } + return 0, err + } + return r.p[0], nil +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/buffer.go b/vendor/github.com/ulikunitz/xz/lzma/buffer.go new file mode 100644 index 000000000..50e0b6d57 --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/buffer.go @@ -0,0 +1,171 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import ( + "errors" +) + +// buffer provides a circular buffer of bytes. If the front index equals +// the rear index the buffer is empty. As a consequence front cannot be +// equal rear for a full buffer. So a full buffer has a length that is +// one byte less the the length of the data slice. +type buffer struct { + data []byte + front int + rear int +} + +// newBuffer creates a buffer with the given size. +func newBuffer(size int) *buffer { + return &buffer{data: make([]byte, size+1)} +} + +// Cap returns the capacity of the buffer. +func (b *buffer) Cap() int { + return len(b.data) - 1 +} + +// Resets the buffer. The front and rear index are set to zero. +func (b *buffer) Reset() { + b.front = 0 + b.rear = 0 +} + +// Buffered returns the number of bytes buffered. +func (b *buffer) Buffered() int { + delta := b.front - b.rear + if delta < 0 { + delta += len(b.data) + } + return delta +} + +// Available returns the number of bytes available for writing. +func (b *buffer) Available() int { + delta := b.rear - 1 - b.front + if delta < 0 { + delta += len(b.data) + } + return delta +} + +// addIndex adds a non-negative integer to the index i and returns the +// resulting index. The function takes care of wrapping the index as +// well as potential overflow situations. +func (b *buffer) addIndex(i int, n int) int { + // subtraction of len(b.data) prevents overflow + i += n - len(b.data) + if i < 0 { + i += len(b.data) + } + return i +} + +// Read reads bytes from the buffer into p and returns the number of +// bytes read. The function never returns an error but might return less +// data than requested. +func (b *buffer) Read(p []byte) (n int, err error) { + n, err = b.Peek(p) + b.rear = b.addIndex(b.rear, n) + return n, err +} + +// Peek reads bytes from the buffer into p without changing the buffer. +// Peek will never return an error but might return less data than +// requested. +func (b *buffer) Peek(p []byte) (n int, err error) { + m := b.Buffered() + n = len(p) + if m < n { + n = m + p = p[:n] + } + k := copy(p, b.data[b.rear:]) + if k < n { + copy(p[k:], b.data) + } + return n, nil +} + +// Discard skips the n next bytes to read from the buffer, returning the +// bytes discarded. +// +// If Discards skips fewer than n bytes, it returns an error. +func (b *buffer) Discard(n int) (discarded int, err error) { + if n < 0 { + return 0, errors.New("buffer.Discard: negative argument") + } + m := b.Buffered() + if m < n { + n = m + err = errors.New( + "buffer.Discard: discarded less bytes then requested") + } + b.rear = b.addIndex(b.rear, n) + return n, err +} + +// ErrNoSpace indicates that there is insufficient space for the Write +// operation. +var ErrNoSpace = errors.New("insufficient space") + +// Write puts data into the buffer. If less bytes are written than +// requested ErrNoSpace is returned. +func (b *buffer) Write(p []byte) (n int, err error) { + m := b.Available() + n = len(p) + if m < n { + n = m + p = p[:m] + err = ErrNoSpace + } + k := copy(b.data[b.front:], p) + if k < n { + copy(b.data, p[k:]) + } + b.front = b.addIndex(b.front, n) + return n, err +} + +// WriteByte writes a single byte into the buffer. The error ErrNoSpace +// is returned if no single byte is available in the buffer for writing. +func (b *buffer) WriteByte(c byte) error { + if b.Available() < 1 { + return ErrNoSpace + } + b.data[b.front] = c + b.front = b.addIndex(b.front, 1) + return nil +} + +// prefixLen returns the length of the common prefix of a and b. +func prefixLen(a, b []byte) int { + if len(a) > len(b) { + a, b = b, a + } + for i, c := range a { + if b[i] != c { + return i + } + } + return len(a) +} + +// matchLen returns the length of the common prefix for the given +// distance from the rear and the byte slice p. +func (b *buffer) matchLen(distance int, p []byte) int { + var n int + i := b.rear - distance + if i < 0 { + if n = prefixLen(p, b.data[len(b.data)+i:]); n < -i { + return n + } + p = p[n:] + i = 0 + } + n += prefixLen(p, b.data[i:]) + return n +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/bytewriter.go b/vendor/github.com/ulikunitz/xz/lzma/bytewriter.go new file mode 100644 index 000000000..a3696ba08 --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/bytewriter.go @@ -0,0 +1,37 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import ( + "errors" + "io" +) + +// ErrLimit indicates that the limit of the LimitedByteWriter has been +// reached. +var ErrLimit = errors.New("limit reached") + +// LimitedByteWriter provides a byte writer that can be written until a +// limit is reached. The field N provides the number of remaining +// bytes. +type LimitedByteWriter struct { + BW io.ByteWriter + N int64 +} + +// WriteByte writes a single byte to the limited byte writer. It returns +// ErrLimit if the limit has been reached. If the byte is successfully +// written the field N of the LimitedByteWriter will be decremented by +// one. +func (l *LimitedByteWriter) WriteByte(c byte) error { + if l.N <= 0 { + return ErrLimit + } + if err := l.BW.WriteByte(c); err != nil { + return err + } + l.N-- + return nil +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/decoder.go b/vendor/github.com/ulikunitz/xz/lzma/decoder.go new file mode 100644 index 000000000..16e14db39 --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/decoder.go @@ -0,0 +1,277 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import ( + "errors" + "fmt" + "io" +) + +// decoder decodes a raw LZMA stream without any header. +type decoder struct { + // dictionary; the rear pointer of the buffer will be used for + // reading the data. + Dict *decoderDict + // decoder state + State *state + // range decoder + rd *rangeDecoder + // start stores the head value of the dictionary for the LZMA + // stream + start int64 + // size of uncompressed data + size int64 + // end-of-stream encountered + eos bool + // EOS marker found + eosMarker bool +} + +// newDecoder creates a new decoder instance. The parameter size provides +// the expected byte size of the decompressed data. If the size is +// unknown use a negative value. In that case the decoder will look for +// a terminating end-of-stream marker. +func newDecoder(br io.ByteReader, state *state, dict *decoderDict, size int64) (d *decoder, err error) { + rd, err := newRangeDecoder(br) + if err != nil { + return nil, err + } + d = &decoder{ + State: state, + Dict: dict, + rd: rd, + size: size, + start: dict.pos(), + } + return d, nil +} + +// Reopen restarts the decoder with a new byte reader and a new size. Reopen +// resets the Decompressed counter to zero. +func (d *decoder) Reopen(br io.ByteReader, size int64) error { + var err error + if d.rd, err = newRangeDecoder(br); err != nil { + return err + } + d.start = d.Dict.pos() + d.size = size + d.eos = false + return nil +} + +// decodeLiteral decodes a single literal from the LZMA stream. +func (d *decoder) decodeLiteral() (op operation, err error) { + litState := d.State.litState(d.Dict.byteAt(1), d.Dict.head) + match := d.Dict.byteAt(int(d.State.rep[0]) + 1) + s, err := d.State.litCodec.Decode(d.rd, d.State.state, match, litState) + if err != nil { + return nil, err + } + return lit{s}, nil +} + +// errEOS indicates that an EOS marker has been found. +var errEOS = errors.New("EOS marker found") + +// readOp decodes the next operation from the compressed stream. It +// returns the operation. If an explicit end of stream marker is +// identified the eos error is returned. +func (d *decoder) readOp() (op operation, err error) { + // Value of the end of stream (EOS) marker + const eosDist = 1<<32 - 1 + + state, state2, posState := d.State.states(d.Dict.head) + + b, err := d.State.isMatch[state2].Decode(d.rd) + if err != nil { + return nil, err + } + if b == 0 { + // literal + op, err := d.decodeLiteral() + if err != nil { + return nil, err + } + d.State.updateStateLiteral() + return op, nil + } + b, err = d.State.isRep[state].Decode(d.rd) + if err != nil { + return nil, err + } + if b == 0 { + // simple match + d.State.rep[3], d.State.rep[2], d.State.rep[1] = + d.State.rep[2], d.State.rep[1], d.State.rep[0] + + d.State.updateStateMatch() + // The length decoder returns the length offset. + n, err := d.State.lenCodec.Decode(d.rd, posState) + if err != nil { + return nil, err + } + // The dist decoder returns the distance offset. The actual + // distance is 1 higher. + d.State.rep[0], err = d.State.distCodec.Decode(d.rd, n) + if err != nil { + return nil, err + } + if d.State.rep[0] == eosDist { + d.eosMarker = true + return nil, errEOS + } + op = match{n: int(n) + minMatchLen, + distance: int64(d.State.rep[0]) + minDistance} + return op, nil + } + b, err = d.State.isRepG0[state].Decode(d.rd) + if err != nil { + return nil, err + } + dist := d.State.rep[0] + if b == 0 { + // rep match 0 + b, err = d.State.isRepG0Long[state2].Decode(d.rd) + if err != nil { + return nil, err + } + if b == 0 { + d.State.updateStateShortRep() + op = match{n: 1, distance: int64(dist) + minDistance} + return op, nil + } + } else { + b, err = d.State.isRepG1[state].Decode(d.rd) + if err != nil { + return nil, err + } + if b == 0 { + dist = d.State.rep[1] + } else { + b, err = d.State.isRepG2[state].Decode(d.rd) + if err != nil { + return nil, err + } + if b == 0 { + dist = d.State.rep[2] + } else { + dist = d.State.rep[3] + d.State.rep[3] = d.State.rep[2] + } + d.State.rep[2] = d.State.rep[1] + } + d.State.rep[1] = d.State.rep[0] + d.State.rep[0] = dist + } + n, err := d.State.repLenCodec.Decode(d.rd, posState) + if err != nil { + return nil, err + } + d.State.updateStateRep() + op = match{n: int(n) + minMatchLen, distance: int64(dist) + minDistance} + return op, nil +} + +// apply takes the operation and transforms the decoder dictionary accordingly. +func (d *decoder) apply(op operation) error { + var err error + switch x := op.(type) { + case match: + err = d.Dict.writeMatch(x.distance, x.n) + case lit: + err = d.Dict.WriteByte(x.b) + default: + panic("op is neither a match nor a literal") + } + return err +} + +// decompress fills the dictionary unless no space for new data is +// available. If the end of the LZMA stream has been reached io.EOF will +// be returned. +func (d *decoder) decompress() error { + if d.eos { + return io.EOF + } + for d.Dict.Available() >= maxMatchLen { + op, err := d.readOp() + switch err { + case nil: + break + case errEOS: + d.eos = true + if !d.rd.possiblyAtEnd() { + return errDataAfterEOS + } + if d.size >= 0 && d.size != d.Decompressed() { + return errSize + } + return io.EOF + case io.EOF: + d.eos = true + return io.ErrUnexpectedEOF + default: + return err + } + if err = d.apply(op); err != nil { + return err + } + if d.size >= 0 && d.Decompressed() >= d.size { + d.eos = true + if d.Decompressed() > d.size { + return errSize + } + if !d.rd.possiblyAtEnd() { + switch _, err = d.readOp(); err { + case nil: + return errSize + case io.EOF: + return io.ErrUnexpectedEOF + case errEOS: + break + default: + return err + } + } + return io.EOF + } + } + return nil +} + +// Errors that may be returned while decoding data. +var ( + errDataAfterEOS = errors.New("lzma: data after end of stream marker") + errSize = errors.New("lzma: wrong uncompressed data size") +) + +// Read reads data from the buffer. If no more data is available io.EOF is +// returned. +func (d *decoder) Read(p []byte) (n int, err error) { + var k int + for { + // Read of decoder dict never returns an error. + k, err = d.Dict.Read(p[n:]) + if err != nil { + panic(fmt.Errorf("dictionary read error %s", err)) + } + if k == 0 && d.eos { + return n, io.EOF + } + n += k + if n >= len(p) { + return n, nil + } + if err = d.decompress(); err != nil && err != io.EOF { + return n, err + } + } +} + +// Decompressed returns the number of bytes decompressed by the decoder. +func (d *decoder) Decompressed() int64 { + return d.Dict.pos() - d.start +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/decoderdict.go b/vendor/github.com/ulikunitz/xz/lzma/decoderdict.go new file mode 100644 index 000000000..564a12b83 --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/decoderdict.go @@ -0,0 +1,135 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import ( + "errors" + "fmt" +) + +// decoderDict provides the dictionary for the decoder. The whole +// dictionary is used as reader buffer. +type decoderDict struct { + buf buffer + head int64 +} + +// newDecoderDict creates a new decoder dictionary. The whole dictionary +// will be used as reader buffer. +func newDecoderDict(dictCap int) (d *decoderDict, err error) { + // lower limit supports easy test cases + if !(1 <= dictCap && int64(dictCap) <= MaxDictCap) { + return nil, errors.New("lzma: dictCap out of range") + } + d = &decoderDict{buf: *newBuffer(dictCap)} + return d, nil +} + +// Reset clears the dictionary. The read buffer is not changed, so the +// buffered data can still be read. +func (d *decoderDict) Reset() { + d.head = 0 +} + +// WriteByte writes a single byte into the dictionary. It is used to +// write literals into the dictionary. +func (d *decoderDict) WriteByte(c byte) error { + if err := d.buf.WriteByte(c); err != nil { + return err + } + d.head++ + return nil +} + +// pos returns the position of the dictionary head. +func (d *decoderDict) pos() int64 { return d.head } + +// dictLen returns the actual length of the dictionary. +func (d *decoderDict) dictLen() int { + capacity := d.buf.Cap() + if d.head >= int64(capacity) { + return capacity + } + return int(d.head) +} + +// byteAt returns a byte stored in the dictionary. If the distance is +// non-positive or exceeds the current length of the dictionary the zero +// byte is returned. +func (d *decoderDict) byteAt(dist int) byte { + if !(0 < dist && dist <= d.dictLen()) { + return 0 + } + i := d.buf.front - dist + if i < 0 { + i += len(d.buf.data) + } + return d.buf.data[i] +} + +// writeMatch writes the match at the top of the dictionary. The given +// distance must point in the current dictionary and the length must not +// exceed the maximum length 273 supported in LZMA. +// +// The error value ErrNoSpace indicates that no space is available in +// the dictionary for writing. You need to read from the dictionary +// first. +func (d *decoderDict) writeMatch(dist int64, length int) error { + if !(0 < dist && dist <= int64(d.dictLen())) { + return errors.New("writeMatch: distance out of range") + } + if !(0 < length && length <= maxMatchLen) { + return errors.New("writeMatch: length out of range") + } + if length > d.buf.Available() { + return ErrNoSpace + } + d.head += int64(length) + + i := d.buf.front - int(dist) + if i < 0 { + i += len(d.buf.data) + } + for length > 0 { + var p []byte + if i >= d.buf.front { + p = d.buf.data[i:] + i = 0 + } else { + p = d.buf.data[i:d.buf.front] + i = d.buf.front + } + if len(p) > length { + p = p[:length] + } + if _, err := d.buf.Write(p); err != nil { + panic(fmt.Errorf("d.buf.Write returned error %s", err)) + } + length -= len(p) + } + return nil +} + +// Write writes the given bytes into the dictionary and advances the +// head. +func (d *decoderDict) Write(p []byte) (n int, err error) { + n, err = d.buf.Write(p) + d.head += int64(n) + return n, err +} + +// Available returns the number of available bytes for writing into the +// decoder dictionary. +func (d *decoderDict) Available() int { return d.buf.Available() } + +// Read reads data from the buffer contained in the decoder dictionary. +func (d *decoderDict) Read(p []byte) (n int, err error) { return d.buf.Read(p) } + +// Buffered returns the number of bytes currently buffered in the +// decoder dictionary. +func (d *decoderDict) buffered() int { return d.buf.Buffered() } + +// Peek gets data from the buffer without advancing the rear index. +func (d *decoderDict) peek(p []byte) (n int, err error) { return d.buf.Peek(p) } diff --git a/vendor/github.com/ulikunitz/xz/lzma/directcodec.go b/vendor/github.com/ulikunitz/xz/lzma/directcodec.go new file mode 100644 index 000000000..e08eb989f --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/directcodec.go @@ -0,0 +1,49 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import "fmt" + +// directCodec allows the encoding and decoding of values with a fixed number +// of bits. The number of bits must be in the range [1,32]. +type directCodec byte + +// makeDirectCodec creates a directCodec. The function panics if the number of +// bits is not in the range [1,32]. +func makeDirectCodec(bits int) directCodec { + if !(1 <= bits && bits <= 32) { + panic(fmt.Errorf("bits=%d out of range", bits)) + } + return directCodec(bits) +} + +// Bits returns the number of bits supported by this codec. +func (dc directCodec) Bits() int { + return int(dc) +} + +// Encode uses the range encoder to encode a value with the fixed number of +// bits. The most-significant bit is encoded first. +func (dc directCodec) Encode(e *rangeEncoder, v uint32) error { + for i := int(dc) - 1; i >= 0; i-- { + if err := e.DirectEncodeBit(v >> uint(i)); err != nil { + return err + } + } + return nil +} + +// Decode uses the range decoder to decode a value with the given number of +// given bits. The most-significant bit is decoded first. +func (dc directCodec) Decode(d *rangeDecoder) (v uint32, err error) { + for i := int(dc) - 1; i >= 0; i-- { + x, err := d.DirectDecodeBit() + if err != nil { + return 0, err + } + v = (v << 1) | x + } + return v, nil +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/distcodec.go b/vendor/github.com/ulikunitz/xz/lzma/distcodec.go new file mode 100644 index 000000000..b053a2dce --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/distcodec.go @@ -0,0 +1,156 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +// Constants used by the distance codec. +const ( + // minimum supported distance + minDistance = 1 + // maximum supported distance, value is used for the eos marker. + maxDistance = 1 << 32 + // number of the supported len states + lenStates = 4 + // start for the position models + startPosModel = 4 + // first index with align bits support + endPosModel = 14 + // bits for the position slots + posSlotBits = 6 + // number of align bits + alignBits = 4 + // maximum position slot + maxPosSlot = 63 +) + +// distCodec provides encoding and decoding of distance values. +type distCodec struct { + posSlotCodecs [lenStates]treeCodec + posModel [endPosModel - startPosModel]treeReverseCodec + alignCodec treeReverseCodec +} + +// deepcopy initializes dc as deep copy of the source. +func (dc *distCodec) deepcopy(src *distCodec) { + if dc == src { + return + } + for i := range dc.posSlotCodecs { + dc.posSlotCodecs[i].deepcopy(&src.posSlotCodecs[i]) + } + for i := range dc.posModel { + dc.posModel[i].deepcopy(&src.posModel[i]) + } + dc.alignCodec.deepcopy(&src.alignCodec) +} + +// distBits returns the number of bits required to encode dist. +func distBits(dist uint32) int { + if dist < startPosModel { + return 6 + } + // slot s > 3, dist d + // s = 2(bits(d)-1) + bit(d, bits(d)-2) + // s>>1 = bits(d)-1 + // bits(d) = 32-nlz32(d) + // s>>1=31-nlz32(d) + // n = 5 + (s>>1) = 36 - nlz32(d) + return 36 - nlz32(dist) +} + +// newDistCodec creates a new distance codec. +func (dc *distCodec) init() { + for i := range dc.posSlotCodecs { + dc.posSlotCodecs[i] = makeTreeCodec(posSlotBits) + } + for i := range dc.posModel { + posSlot := startPosModel + i + bits := (posSlot >> 1) - 1 + dc.posModel[i] = makeTreeReverseCodec(bits) + } + dc.alignCodec = makeTreeReverseCodec(alignBits) +} + +// lenState converts the value l to a supported lenState value. +func lenState(l uint32) uint32 { + if l >= lenStates { + l = lenStates - 1 + } + return l +} + +// Encode encodes the distance using the parameter l. Dist can have values from +// the full range of uint32 values. To get the distance offset the actual match +// distance has to be decreased by 1. A distance offset of 0xffffffff (eos) +// indicates the end of the stream. +func (dc *distCodec) Encode(e *rangeEncoder, dist uint32, l uint32) (err error) { + // Compute the posSlot using nlz32 + var posSlot uint32 + var bits uint32 + if dist < startPosModel { + posSlot = dist + } else { + bits = uint32(30 - nlz32(dist)) + posSlot = startPosModel - 2 + (bits << 1) + posSlot += (dist >> uint(bits)) & 1 + } + + if err = dc.posSlotCodecs[lenState(l)].Encode(e, posSlot); err != nil { + return + } + + switch { + case posSlot < startPosModel: + return nil + case posSlot < endPosModel: + tc := &dc.posModel[posSlot-startPosModel] + return tc.Encode(dist, e) + } + dic := directCodec(bits - alignBits) + if err = dic.Encode(e, dist>>alignBits); err != nil { + return + } + return dc.alignCodec.Encode(dist, e) +} + +// Decode decodes the distance offset using the parameter l. The dist value +// 0xffffffff (eos) indicates the end of the stream. Add one to the distance +// offset to get the actual match distance. +func (dc *distCodec) Decode(d *rangeDecoder, l uint32) (dist uint32, err error) { + posSlot, err := dc.posSlotCodecs[lenState(l)].Decode(d) + if err != nil { + return + } + + // posSlot equals distance + if posSlot < startPosModel { + return posSlot, nil + } + + // posSlot uses the individual models + bits := (posSlot >> 1) - 1 + dist = (2 | (posSlot & 1)) << bits + var u uint32 + if posSlot < endPosModel { + tc := &dc.posModel[posSlot-startPosModel] + if u, err = tc.Decode(d); err != nil { + return 0, err + } + dist += u + return dist, nil + } + + // posSlots use direct encoding and a single model for the four align + // bits. + dic := directCodec(bits - alignBits) + if u, err = dic.Decode(d); err != nil { + return 0, err + } + dist += u << alignBits + if u, err = dc.alignCodec.Decode(d); err != nil { + return 0, err + } + dist += u + return dist, nil +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/encoder.go b/vendor/github.com/ulikunitz/xz/lzma/encoder.go new file mode 100644 index 000000000..18ce00992 --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/encoder.go @@ -0,0 +1,268 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import ( + "fmt" + "io" +) + +// opLenMargin provides the upper limit of the number of bytes required +// to encode a single operation. +const opLenMargin = 10 + +// compressFlags control the compression process. +type compressFlags uint32 + +// Values for compressFlags. +const ( + // all data should be compressed, even if compression is not + // optimal. + all compressFlags = 1 << iota +) + +// encoderFlags provide the flags for an encoder. +type encoderFlags uint32 + +// Flags for the encoder. +const ( + // eosMarker requests an EOS marker to be written. + eosMarker encoderFlags = 1 << iota +) + +// Encoder compresses data buffered in the encoder dictionary and writes +// it into a byte writer. +type encoder struct { + dict *encoderDict + state *state + re *rangeEncoder + start int64 + // generate eos marker + marker bool + limit bool + margin int +} + +// newEncoder creates a new encoder. If the byte writer must be +// limited use LimitedByteWriter provided by this package. The flags +// argument supports the eosMarker flag, controlling whether a +// terminating end-of-stream marker must be written. +func newEncoder(bw io.ByteWriter, state *state, dict *encoderDict, + flags encoderFlags) (e *encoder, err error) { + + re, err := newRangeEncoder(bw) + if err != nil { + return nil, err + } + e = &encoder{ + dict: dict, + state: state, + re: re, + marker: flags&eosMarker != 0, + start: dict.Pos(), + margin: opLenMargin, + } + if e.marker { + e.margin += 5 + } + return e, nil +} + +// Write writes the bytes from p into the dictionary. If not enough +// space is available the data in the dictionary buffer will be +// compressed to make additional space available. If the limit of the +// underlying writer has been reached ErrLimit will be returned. +func (e *encoder) Write(p []byte) (n int, err error) { + for { + k, err := e.dict.Write(p[n:]) + n += k + if err == ErrNoSpace { + if err = e.compress(0); err != nil { + return n, err + } + continue + } + return n, err + } +} + +// Reopen reopens the encoder with a new byte writer. +func (e *encoder) Reopen(bw io.ByteWriter) error { + var err error + if e.re, err = newRangeEncoder(bw); err != nil { + return err + } + e.start = e.dict.Pos() + e.limit = false + return nil +} + +// writeLiteral writes a literal into the LZMA stream +func (e *encoder) writeLiteral(l lit) error { + var err error + state, state2, _ := e.state.states(e.dict.Pos()) + if err = e.state.isMatch[state2].Encode(e.re, 0); err != nil { + return err + } + litState := e.state.litState(e.dict.ByteAt(1), e.dict.Pos()) + match := e.dict.ByteAt(int(e.state.rep[0]) + 1) + err = e.state.litCodec.Encode(e.re, l.b, state, match, litState) + if err != nil { + return err + } + e.state.updateStateLiteral() + return nil +} + +// iverson implements the Iverson operator as proposed by Donald Knuth in his +// book Concrete Mathematics. +func iverson(ok bool) uint32 { + if ok { + return 1 + } + return 0 +} + +// writeMatch writes a repetition operation into the operation stream +func (e *encoder) writeMatch(m match) error { + var err error + if !(minDistance <= m.distance && m.distance <= maxDistance) { + panic(fmt.Errorf("match distance %d out of range", m.distance)) + } + dist := uint32(m.distance - minDistance) + if !(minMatchLen <= m.n && m.n <= maxMatchLen) && + !(dist == e.state.rep[0] && m.n == 1) { + panic(fmt.Errorf( + "match length %d out of range; dist %d rep[0] %d", + m.n, dist, e.state.rep[0])) + } + state, state2, posState := e.state.states(e.dict.Pos()) + if err = e.state.isMatch[state2].Encode(e.re, 1); err != nil { + return err + } + g := 0 + for ; g < 4; g++ { + if e.state.rep[g] == dist { + break + } + } + b := iverson(g < 4) + if err = e.state.isRep[state].Encode(e.re, b); err != nil { + return err + } + n := uint32(m.n - minMatchLen) + if b == 0 { + // simple match + e.state.rep[3], e.state.rep[2], e.state.rep[1], e.state.rep[0] = + e.state.rep[2], e.state.rep[1], e.state.rep[0], dist + e.state.updateStateMatch() + if err = e.state.lenCodec.Encode(e.re, n, posState); err != nil { + return err + } + return e.state.distCodec.Encode(e.re, dist, n) + } + b = iverson(g != 0) + if err = e.state.isRepG0[state].Encode(e.re, b); err != nil { + return err + } + if b == 0 { + // g == 0 + b = iverson(m.n != 1) + if err = e.state.isRepG0Long[state2].Encode(e.re, b); err != nil { + return err + } + if b == 0 { + e.state.updateStateShortRep() + return nil + } + } else { + // g in {1,2,3} + b = iverson(g != 1) + if err = e.state.isRepG1[state].Encode(e.re, b); err != nil { + return err + } + if b == 1 { + // g in {2,3} + b = iverson(g != 2) + err = e.state.isRepG2[state].Encode(e.re, b) + if err != nil { + return err + } + if b == 1 { + e.state.rep[3] = e.state.rep[2] + } + e.state.rep[2] = e.state.rep[1] + } + e.state.rep[1] = e.state.rep[0] + e.state.rep[0] = dist + } + e.state.updateStateRep() + return e.state.repLenCodec.Encode(e.re, n, posState) +} + +// writeOp writes a single operation to the range encoder. The function +// checks whether there is enough space available to close the LZMA +// stream. +func (e *encoder) writeOp(op operation) error { + if e.re.Available() < int64(e.margin) { + return ErrLimit + } + switch x := op.(type) { + case lit: + return e.writeLiteral(x) + case match: + return e.writeMatch(x) + default: + panic("unexpected operation") + } +} + +// compress compressed data from the dictionary buffer. If the flag all +// is set, all data in the dictionary buffer will be compressed. The +// function returns ErrLimit if the underlying writer has reached its +// limit. +func (e *encoder) compress(flags compressFlags) error { + n := 0 + if flags&all == 0 { + n = maxMatchLen - 1 + } + d := e.dict + m := d.m + for d.Buffered() > n { + op := m.NextOp(e.state.rep) + if err := e.writeOp(op); err != nil { + return err + } + d.Discard(op.Len()) + } + return nil +} + +// eosMatch is a pseudo operation that indicates the end of the stream. +var eosMatch = match{distance: maxDistance, n: minMatchLen} + +// Close terminates the LZMA stream. If requested the end-of-stream +// marker will be written. If the byte writer limit has been or will be +// reached during compression of the remaining data in the buffer the +// LZMA stream will be closed and data will remain in the buffer. +func (e *encoder) Close() error { + err := e.compress(all) + if err != nil && err != ErrLimit { + return err + } + if e.marker { + if err := e.writeMatch(eosMatch); err != nil { + return err + } + } + err = e.re.Close() + return err +} + +// Compressed returns the number bytes of the input data that been +// compressed. +func (e *encoder) Compressed() int64 { + return e.dict.Pos() - e.start +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/encoderdict.go b/vendor/github.com/ulikunitz/xz/lzma/encoderdict.go new file mode 100644 index 000000000..9d0fbc703 --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/encoderdict.go @@ -0,0 +1,149 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import ( + "errors" + "fmt" + "io" +) + +// matcher is an interface that supports the identification of the next +// operation. +type matcher interface { + io.Writer + SetDict(d *encoderDict) + NextOp(rep [4]uint32) operation +} + +// encoderDict provides the dictionary of the encoder. It includes an +// addtional buffer atop of the actual dictionary. +type encoderDict struct { + buf buffer + m matcher + head int64 + capacity int + // preallocated array + data [maxMatchLen]byte +} + +// newEncoderDict creates the encoder dictionary. The argument bufSize +// defines the size of the additional buffer. +func newEncoderDict(dictCap, bufSize int, m matcher) (d *encoderDict, err error) { + if !(1 <= dictCap && int64(dictCap) <= MaxDictCap) { + return nil, errors.New( + "lzma: dictionary capacity out of range") + } + if bufSize < 1 { + return nil, errors.New( + "lzma: buffer size must be larger than zero") + } + d = &encoderDict{ + buf: *newBuffer(dictCap + bufSize), + capacity: dictCap, + m: m, + } + m.SetDict(d) + return d, nil +} + +// Discard discards n bytes. Note that n must not be larger than +// MaxMatchLen. +func (d *encoderDict) Discard(n int) { + p := d.data[:n] + k, _ := d.buf.Read(p) + if k < n { + panic(fmt.Errorf("lzma: can't discard %d bytes", n)) + } + d.head += int64(n) + d.m.Write(p) +} + +// Len returns the data available in the encoder dictionary. +func (d *encoderDict) Len() int { + n := d.buf.Available() + if int64(n) > d.head { + return int(d.head) + } + return n +} + +// DictLen returns the actual length of data in the dictionary. +func (d *encoderDict) DictLen() int { + if d.head < int64(d.capacity) { + return int(d.head) + } + return d.capacity +} + +// Available returns the number of bytes that can be written by a +// following Write call. +func (d *encoderDict) Available() int { + return d.buf.Available() - d.DictLen() +} + +// Write writes data into the dictionary buffer. Note that the position +// of the dictionary head will not be moved. If there is not enough +// space in the buffer ErrNoSpace will be returned. +func (d *encoderDict) Write(p []byte) (n int, err error) { + m := d.Available() + if len(p) > m { + p = p[:m] + err = ErrNoSpace + } + var e error + if n, e = d.buf.Write(p); e != nil { + err = e + } + return n, err +} + +// Pos returns the position of the head. +func (d *encoderDict) Pos() int64 { return d.head } + +// ByteAt returns the byte at the given distance. +func (d *encoderDict) ByteAt(distance int) byte { + if !(0 < distance && distance <= d.Len()) { + return 0 + } + i := d.buf.rear - distance + if i < 0 { + i += len(d.buf.data) + } + return d.buf.data[i] +} + +// CopyN copies the last n bytes from the dictionary into the provided +// writer. This is used for copying uncompressed data into an +// uncompressed segment. +func (d *encoderDict) CopyN(w io.Writer, n int) (written int, err error) { + if n <= 0 { + return 0, nil + } + m := d.Len() + if n > m { + n = m + err = ErrNoSpace + } + i := d.buf.rear - n + var e error + if i < 0 { + i += len(d.buf.data) + if written, e = w.Write(d.buf.data[i:]); e != nil { + return written, e + } + i = 0 + } + var k int + k, e = w.Write(d.buf.data[i:d.buf.rear]) + written += k + if e != nil { + err = e + } + return written, err +} + +// Buffered returns the number of bytes in the buffer. +func (d *encoderDict) Buffered() int { return d.buf.Buffered() } diff --git a/vendor/github.com/ulikunitz/xz/lzma/hashtable.go b/vendor/github.com/ulikunitz/xz/lzma/hashtable.go new file mode 100644 index 000000000..d786a9745 --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/hashtable.go @@ -0,0 +1,309 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import ( + "errors" + "fmt" + + "github.com/ulikunitz/xz/internal/hash" +) + +/* For compression we need to find byte sequences that match the byte + * sequence at the dictionary head. A hash table is a simple method to + * provide this capability. + */ + +// maxMatches limits the number of matches requested from the Matches +// function. This controls the speed of the overall encoding. +const maxMatches = 16 + +// shortDists defines the number of short distances supported by the +// implementation. +const shortDists = 8 + +// The minimum is somehow arbitrary but the maximum is limited by the +// memory requirements of the hash table. +const ( + minTableExponent = 9 + maxTableExponent = 20 +) + +// newRoller contains the function used to create an instance of the +// hash.Roller. +var newRoller = func(n int) hash.Roller { return hash.NewCyclicPoly(n) } + +// hashTable stores the hash table including the rolling hash method. +// +// We implement chained hashing into a circular buffer. Each entry in +// the circular buffer stores the delta distance to the next position with a +// word that has the same hash value. +type hashTable struct { + dict *encoderDict + // actual hash table + t []int64 + // circular list data with the offset to the next word + data []uint32 + front int + // mask for computing the index for the hash table + mask uint64 + // hash offset; initial value is -int64(wordLen) + hoff int64 + // length of the hashed word + wordLen int + // hash roller for computing the hash values for the Write + // method + wr hash.Roller + // hash roller for computing arbitrary hashes + hr hash.Roller + // preallocated slices + p [maxMatches]int64 + distances [maxMatches + shortDists]int +} + +// hashTableExponent derives the hash table exponent from the dictionary +// capacity. +func hashTableExponent(n uint32) int { + e := 30 - nlz32(n) + switch { + case e < minTableExponent: + e = minTableExponent + case e > maxTableExponent: + e = maxTableExponent + } + return e +} + +// newHashTable creates a new hash table for words of length wordLen +func newHashTable(capacity int, wordLen int) (t *hashTable, err error) { + if !(0 < capacity) { + return nil, errors.New( + "newHashTable: capacity must not be negative") + } + exp := hashTableExponent(uint32(capacity)) + if !(1 <= wordLen && wordLen <= 4) { + return nil, errors.New("newHashTable: " + + "argument wordLen out of range") + } + n := 1 << uint(exp) + if n <= 0 { + panic("newHashTable: exponent is too large") + } + t = &hashTable{ + t: make([]int64, n), + data: make([]uint32, capacity), + mask: (uint64(1) << uint(exp)) - 1, + hoff: -int64(wordLen), + wordLen: wordLen, + wr: newRoller(wordLen), + hr: newRoller(wordLen), + } + return t, nil +} + +func (t *hashTable) SetDict(d *encoderDict) { t.dict = d } + +// buffered returns the number of bytes that are currently hashed. +func (t *hashTable) buffered() int { + n := t.hoff + 1 + switch { + case n <= 0: + return 0 + case n >= int64(len(t.data)): + return len(t.data) + } + return int(n) +} + +// addIndex adds n to an index ensuring that is stays inside the +// circular buffer for the hash chain. +func (t *hashTable) addIndex(i, n int) int { + i += n - len(t.data) + if i < 0 { + i += len(t.data) + } + return i +} + +// putDelta puts the delta instance at the current front of the circular +// chain buffer. +func (t *hashTable) putDelta(delta uint32) { + t.data[t.front] = delta + t.front = t.addIndex(t.front, 1) +} + +// putEntry puts a new entry into the hash table. If there is already a +// value stored it is moved into the circular chain buffer. +func (t *hashTable) putEntry(h uint64, pos int64) { + if pos < 0 { + return + } + i := h & t.mask + old := t.t[i] - 1 + t.t[i] = pos + 1 + var delta int64 + if old >= 0 { + delta = pos - old + if delta > 1<<32-1 || delta > int64(t.buffered()) { + delta = 0 + } + } + t.putDelta(uint32(delta)) +} + +// WriteByte converts a single byte into a hash and puts them into the hash +// table. +func (t *hashTable) WriteByte(b byte) error { + h := t.wr.RollByte(b) + t.hoff++ + t.putEntry(h, t.hoff) + return nil +} + +// Write converts the bytes provided into hash tables and stores the +// abbreviated offsets into the hash table. The method will never return an +// error. +func (t *hashTable) Write(p []byte) (n int, err error) { + for _, b := range p { + // WriteByte doesn't generate an error. + t.WriteByte(b) + } + return len(p), nil +} + +// getMatches the matches for a specific hash. The functions returns the +// number of positions found. +// +// TODO: Make a getDistances because that we are actually interested in. +func (t *hashTable) getMatches(h uint64, positions []int64) (n int) { + if t.hoff < 0 || len(positions) == 0 { + return 0 + } + buffered := t.buffered() + tailPos := t.hoff + 1 - int64(buffered) + rear := t.front - buffered + if rear >= 0 { + rear -= len(t.data) + } + // get the slot for the hash + pos := t.t[h&t.mask] - 1 + delta := pos - tailPos + for { + if delta < 0 { + return n + } + positions[n] = tailPos + delta + n++ + if n >= len(positions) { + return n + } + i := rear + int(delta) + if i < 0 { + i += len(t.data) + } + u := t.data[i] + if u == 0 { + return n + } + delta -= int64(u) + } +} + +// hash computes the rolling hash for the word stored in p. For correct +// results its length must be equal to t.wordLen. +func (t *hashTable) hash(p []byte) uint64 { + var h uint64 + for _, b := range p { + h = t.hr.RollByte(b) + } + return h +} + +// Matches fills the positions slice with potential matches. The +// functions returns the number of positions filled into positions. The +// byte slice p must have word length of the hash table. +func (t *hashTable) Matches(p []byte, positions []int64) int { + if len(p) != t.wordLen { + panic(fmt.Errorf( + "byte slice must have length %d", t.wordLen)) + } + h := t.hash(p) + return t.getMatches(h, positions) +} + +// NextOp identifies the next operation using the hash table. +// +// TODO: Use all repetitions to find matches. +func (t *hashTable) NextOp(rep [4]uint32) operation { + // get positions + data := t.dict.data[:maxMatchLen] + n, _ := t.dict.buf.Peek(data) + data = data[:n] + var p []int64 + if n < t.wordLen { + p = t.p[:0] + } else { + p = t.p[:maxMatches] + n = t.Matches(data[:t.wordLen], p) + p = p[:n] + } + + // convert positions in potential distances + head := t.dict.head + dists := append(t.distances[:0], 1, 2, 3, 4, 5, 6, 7, 8) + for _, pos := range p { + dis := int(head - pos) + if dis > shortDists { + dists = append(dists, dis) + } + } + + // check distances + var m match + dictLen := t.dict.DictLen() + for _, dist := range dists { + if dist > dictLen { + continue + } + + // Here comes a trick. We are only interested in matches + // that are longer than the matches we have been found + // before. So before we test the whole byte sequence at + // the given distance, we test the first byte that would + // make the match longer. If it doesn't match the byte + // to match, we don't to care any longer. + i := t.dict.buf.rear - dist + m.n + if i < 0 { + i += len(t.dict.buf.data) + } + if t.dict.buf.data[i] != data[m.n] { + // We can't get a longer match. Jump to the next + // distance. + continue + } + + n := t.dict.buf.matchLen(dist, data) + switch n { + case 0: + continue + case 1: + if uint32(dist-minDistance) != rep[0] { + continue + } + } + if n > m.n { + m = match{int64(dist), n} + if n == len(data) { + // No better match will be found. + break + } + } + } + + if m.n == 0 { + return lit{data[0]} + } + return m +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/header.go b/vendor/github.com/ulikunitz/xz/lzma/header.go new file mode 100644 index 000000000..bc708969f --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/header.go @@ -0,0 +1,167 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import ( + "errors" + "fmt" +) + +// uint32LE reads an uint32 integer from a byte slice +func uint32LE(b []byte) uint32 { + x := uint32(b[3]) << 24 + x |= uint32(b[2]) << 16 + x |= uint32(b[1]) << 8 + x |= uint32(b[0]) + return x +} + +// uint64LE converts the uint64 value stored as little endian to an uint64 +// value. +func uint64LE(b []byte) uint64 { + x := uint64(b[7]) << 56 + x |= uint64(b[6]) << 48 + x |= uint64(b[5]) << 40 + x |= uint64(b[4]) << 32 + x |= uint64(b[3]) << 24 + x |= uint64(b[2]) << 16 + x |= uint64(b[1]) << 8 + x |= uint64(b[0]) + return x +} + +// putUint32LE puts an uint32 integer into a byte slice that must have at least +// a length of 4 bytes. +func putUint32LE(b []byte, x uint32) { + b[0] = byte(x) + b[1] = byte(x >> 8) + b[2] = byte(x >> 16) + b[3] = byte(x >> 24) +} + +// putUint64LE puts the uint64 value into the byte slice as little endian +// value. The byte slice b must have at least place for 8 bytes. +func putUint64LE(b []byte, x uint64) { + b[0] = byte(x) + b[1] = byte(x >> 8) + b[2] = byte(x >> 16) + b[3] = byte(x >> 24) + b[4] = byte(x >> 32) + b[5] = byte(x >> 40) + b[6] = byte(x >> 48) + b[7] = byte(x >> 56) +} + +// noHeaderSize defines the value of the length field in the LZMA header. +const noHeaderSize uint64 = 1<<64 - 1 + +// HeaderLen provides the length of the LZMA file header. +const HeaderLen = 13 + +// header represents the header of an LZMA file. +type header struct { + properties Properties + dictCap int + // uncompressed size; negative value if no size is given + size int64 +} + +// marshalBinary marshals the header. +func (h *header) marshalBinary() (data []byte, err error) { + if err = h.properties.verify(); err != nil { + return nil, err + } + if !(0 <= h.dictCap && int64(h.dictCap) <= MaxDictCap) { + return nil, fmt.Errorf("lzma: DictCap %d out of range", + h.dictCap) + } + + data = make([]byte, 13) + + // property byte + data[0] = h.properties.Code() + + // dictionary capacity + putUint32LE(data[1:5], uint32(h.dictCap)) + + // uncompressed size + var s uint64 + if h.size > 0 { + s = uint64(h.size) + } else { + s = noHeaderSize + } + putUint64LE(data[5:], s) + + return data, nil +} + +// unmarshalBinary unmarshals the header. +func (h *header) unmarshalBinary(data []byte) error { + if len(data) != HeaderLen { + return errors.New("lzma.unmarshalBinary: data has wrong length") + } + + // properties + var err error + if h.properties, err = PropertiesForCode(data[0]); err != nil { + return err + } + + // dictionary capacity + h.dictCap = int(uint32LE(data[1:])) + if h.dictCap < 0 { + return errors.New( + "LZMA header: dictionary capacity exceeds maximum " + + "integer") + } + + // uncompressed size + s := uint64LE(data[5:]) + if s == noHeaderSize { + h.size = -1 + } else { + h.size = int64(s) + if h.size < 0 { + return errors.New( + "LZMA header: uncompressed size " + + "out of int64 range") + } + } + + return nil +} + +// validDictCap checks whether the dictionary capacity is correct. This +// is used to weed out wrong file headers. +func validDictCap(dictcap int) bool { + if int64(dictcap) == MaxDictCap { + return true + } + for n := uint(10); n < 32; n++ { + if dictcap == 1<= 10 or 2^32-1. If +// there is an explicit size it must not exceed 256 GiB. The length of +// the data argument must be HeaderLen. +func ValidHeader(data []byte) bool { + var h header + if err := h.unmarshalBinary(data); err != nil { + return false + } + if !validDictCap(h.dictCap) { + return false + } + return h.size < 0 || h.size <= 1<<38 +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/header2.go b/vendor/github.com/ulikunitz/xz/lzma/header2.go new file mode 100644 index 000000000..ac6a71a5a --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/header2.go @@ -0,0 +1,398 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import ( + "errors" + "fmt" + "io" +) + +const ( + // maximum size of compressed data in a chunk + maxCompressed = 1 << 16 + // maximum size of uncompressed data in a chunk + maxUncompressed = 1 << 21 +) + +// chunkType represents the type of an LZMA2 chunk. Note that this +// value is an internal representation and no actual encoding of a LZMA2 +// chunk header. +type chunkType byte + +// Possible values for the chunk type. +const ( + // end of stream + cEOS chunkType = iota + // uncompressed; reset dictionary + cUD + // uncompressed; no reset of dictionary + cU + // LZMA compressed; no reset + cL + // LZMA compressed; reset state + cLR + // LZMA compressed; reset state; new property value + cLRN + // LZMA compressed; reset state; new property value; reset dictionary + cLRND +) + +// chunkTypeStrings provide a string representation for the chunk types. +var chunkTypeStrings = [...]string{ + cEOS: "EOS", + cU: "U", + cUD: "UD", + cL: "L", + cLR: "LR", + cLRN: "LRN", + cLRND: "LRND", +} + +// String returns a string representation of the chunk type. +func (c chunkType) String() string { + if !(cEOS <= c && c <= cLRND) { + return "unknown" + } + return chunkTypeStrings[c] +} + +// Actual encodings for the chunk types in the value. Note that the high +// uncompressed size bits are stored in the header byte additionally. +const ( + hEOS = 0 + hUD = 1 + hU = 2 + hL = 1 << 7 + hLR = 1<<7 | 1<<5 + hLRN = 1<<7 | 1<<6 + hLRND = 1<<7 | 1<<6 | 1<<5 +) + +// errHeaderByte indicates an unsupported value for the chunk header +// byte. These bytes starts the variable-length chunk header. +var errHeaderByte = errors.New("lzma: unsupported chunk header byte") + +// headerChunkType converts the header byte into a chunk type. It +// ignores the uncompressed size bits in the chunk header byte. +func headerChunkType(h byte) (c chunkType, err error) { + if h&hL == 0 { + // no compression + switch h { + case hEOS: + c = cEOS + case hUD: + c = cUD + case hU: + c = cU + default: + return 0, errHeaderByte + } + return + } + switch h & hLRND { + case hL: + c = cL + case hLR: + c = cLR + case hLRN: + c = cLRN + case hLRND: + c = cLRND + default: + return 0, errHeaderByte + } + return +} + +// uncompressedHeaderLen provides the length of an uncompressed header +const uncompressedHeaderLen = 3 + +// headerLen returns the length of the LZMA2 header for a given chunk +// type. +func headerLen(c chunkType) int { + switch c { + case cEOS: + return 1 + case cU, cUD: + return uncompressedHeaderLen + case cL, cLR: + return 5 + case cLRN, cLRND: + return 6 + } + panic(fmt.Errorf("unsupported chunk type %d", c)) +} + +// chunkHeader represents the contents of a chunk header. +type chunkHeader struct { + ctype chunkType + uncompressed uint32 + compressed uint16 + props Properties +} + +// String returns a string representation of the chunk header. +func (h *chunkHeader) String() string { + return fmt.Sprintf("%s %d %d %s", h.ctype, h.uncompressed, + h.compressed, &h.props) +} + +// UnmarshalBinary reads the content of the chunk header from the data +// slice. The slice must have the correct length. +func (h *chunkHeader) UnmarshalBinary(data []byte) error { + if len(data) == 0 { + return errors.New("no data") + } + c, err := headerChunkType(data[0]) + if err != nil { + return err + } + + n := headerLen(c) + if len(data) < n { + return errors.New("incomplete data") + } + if len(data) > n { + return errors.New("invalid data length") + } + + *h = chunkHeader{ctype: c} + if c == cEOS { + return nil + } + + h.uncompressed = uint32(uint16BE(data[1:3])) + if c <= cU { + return nil + } + h.uncompressed |= uint32(data[0]&^hLRND) << 16 + + h.compressed = uint16BE(data[3:5]) + if c <= cLR { + return nil + } + + h.props, err = PropertiesForCode(data[5]) + return err +} + +// MarshalBinary encodes the chunk header value. The function checks +// whether the content of the chunk header is correct. +func (h *chunkHeader) MarshalBinary() (data []byte, err error) { + if h.ctype > cLRND { + return nil, errors.New("invalid chunk type") + } + if err = h.props.verify(); err != nil { + return nil, err + } + + data = make([]byte, headerLen(h.ctype)) + + switch h.ctype { + case cEOS: + return data, nil + case cUD: + data[0] = hUD + case cU: + data[0] = hU + case cL: + data[0] = hL + case cLR: + data[0] = hLR + case cLRN: + data[0] = hLRN + case cLRND: + data[0] = hLRND + } + + putUint16BE(data[1:3], uint16(h.uncompressed)) + if h.ctype <= cU { + return data, nil + } + data[0] |= byte(h.uncompressed>>16) &^ hLRND + + putUint16BE(data[3:5], h.compressed) + if h.ctype <= cLR { + return data, nil + } + + data[5] = h.props.Code() + return data, nil +} + +// readChunkHeader reads the chunk header from the IO reader. +func readChunkHeader(r io.Reader) (h *chunkHeader, err error) { + p := make([]byte, 1, 6) + if _, err = io.ReadFull(r, p); err != nil { + return + } + c, err := headerChunkType(p[0]) + if err != nil { + return + } + p = p[:headerLen(c)] + if _, err = io.ReadFull(r, p[1:]); err != nil { + return + } + h = new(chunkHeader) + if err = h.UnmarshalBinary(p); err != nil { + return nil, err + } + return h, nil +} + +// uint16BE converts a big-endian uint16 representation to an uint16 +// value. +func uint16BE(p []byte) uint16 { + return uint16(p[0])<<8 | uint16(p[1]) +} + +// putUint16BE puts the big-endian uint16 presentation into the given +// slice. +func putUint16BE(p []byte, x uint16) { + p[0] = byte(x >> 8) + p[1] = byte(x) +} + +// chunkState is used to manage the state of the chunks +type chunkState byte + +// start and stop define the initial and terminating state of the chunk +// state +const ( + start chunkState = 'S' + stop = 'T' +) + +// errors for the chunk state handling +var ( + errChunkType = errors.New("lzma: unexpected chunk type") + errState = errors.New("lzma: wrong chunk state") +) + +// next transitions state based on chunk type input +func (c *chunkState) next(ctype chunkType) error { + switch *c { + // start state + case 'S': + switch ctype { + case cEOS: + *c = 'T' + case cUD: + *c = 'R' + case cLRND: + *c = 'L' + default: + return errChunkType + } + // normal LZMA mode + case 'L': + switch ctype { + case cEOS: + *c = 'T' + case cUD: + *c = 'R' + case cU: + *c = 'U' + case cL, cLR, cLRN, cLRND: + break + default: + return errChunkType + } + // reset required + case 'R': + switch ctype { + case cEOS: + *c = 'T' + case cUD, cU: + break + case cLRN, cLRND: + *c = 'L' + default: + return errChunkType + } + // uncompressed + case 'U': + switch ctype { + case cEOS: + *c = 'T' + case cUD: + *c = 'R' + case cU: + break + case cL, cLR, cLRN, cLRND: + *c = 'L' + default: + return errChunkType + } + // terminal state + case 'T': + return errChunkType + default: + return errState + } + return nil +} + +// defaultChunkType returns the default chunk type for each chunk state. +func (c chunkState) defaultChunkType() chunkType { + switch c { + case 'S': + return cLRND + case 'L', 'U': + return cL + case 'R': + return cLRN + default: + // no error + return cEOS + } +} + +// maxDictCap defines the maximum dictionary capacity supported by the +// LZMA2 dictionary capacity encoding. +const maxDictCap = 1<<32 - 1 + +// maxDictCapCode defines the maximum dictionary capacity code. +const maxDictCapCode = 40 + +// The function decodes the dictionary capacity byte, but doesn't change +// for the correct range of the given byte. +func decodeDictCap(c byte) int64 { + return (2 | int64(c)&1) << (11 + (c>>1)&0x1f) +} + +// DecodeDictCap decodes the encoded dictionary capacity. The function +// returns an error if the code is out of range. +func DecodeDictCap(c byte) (n int64, err error) { + if c >= maxDictCapCode { + if c == maxDictCapCode { + return maxDictCap, nil + } + return 0, errors.New("lzma: invalid dictionary size code") + } + return decodeDictCap(c), nil +} + +// EncodeDictCap encodes a dictionary capacity. The function returns the +// code for the capacity that is greater or equal n. If n exceeds the +// maximum support dictionary capacity, the maximum value is returned. +func EncodeDictCap(n int64) byte { + a, b := byte(0), byte(40) + for a < b { + c := a + (b-a)>>1 + m := decodeDictCap(c) + if n <= m { + if n == m { + return c + } + b = c + } else { + a = c + 1 + } + } + return a +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/lengthcodec.go b/vendor/github.com/ulikunitz/xz/lzma/lengthcodec.go new file mode 100644 index 000000000..e51773092 --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/lengthcodec.go @@ -0,0 +1,129 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import "errors" + +// maxPosBits defines the number of bits of the position value that are used to +// to compute the posState value. The value is used to select the tree codec +// for length encoding and decoding. +const maxPosBits = 4 + +// minMatchLen and maxMatchLen give the minimum and maximum values for +// encoding and decoding length values. minMatchLen is also used as base +// for the encoded length values. +const ( + minMatchLen = 2 + maxMatchLen = minMatchLen + 16 + 256 - 1 +) + +// lengthCodec support the encoding of the length value. +type lengthCodec struct { + choice [2]prob + low [1 << maxPosBits]treeCodec + mid [1 << maxPosBits]treeCodec + high treeCodec +} + +// deepcopy initializes the lc value as deep copy of the source value. +func (lc *lengthCodec) deepcopy(src *lengthCodec) { + if lc == src { + return + } + lc.choice = src.choice + for i := range lc.low { + lc.low[i].deepcopy(&src.low[i]) + } + for i := range lc.mid { + lc.mid[i].deepcopy(&src.mid[i]) + } + lc.high.deepcopy(&src.high) +} + +// init initializes a new length codec. +func (lc *lengthCodec) init() { + for i := range lc.choice { + lc.choice[i] = probInit + } + for i := range lc.low { + lc.low[i] = makeTreeCodec(3) + } + for i := range lc.mid { + lc.mid[i] = makeTreeCodec(3) + } + lc.high = makeTreeCodec(8) +} + +// lBits gives the number of bits used for the encoding of the l value +// provided to the range encoder. +func lBits(l uint32) int { + switch { + case l < 8: + return 4 + case l < 16: + return 5 + default: + return 10 + } +} + +// Encode encodes the length offset. The length offset l can be compute by +// subtracting minMatchLen (2) from the actual length. +// +// l = length - minMatchLen +// +func (lc *lengthCodec) Encode(e *rangeEncoder, l uint32, posState uint32, +) (err error) { + if l > maxMatchLen-minMatchLen { + return errors.New("lengthCodec.Encode: l out of range") + } + if l < 8 { + if err = lc.choice[0].Encode(e, 0); err != nil { + return + } + return lc.low[posState].Encode(e, l) + } + if err = lc.choice[0].Encode(e, 1); err != nil { + return + } + if l < 16 { + if err = lc.choice[1].Encode(e, 0); err != nil { + return + } + return lc.mid[posState].Encode(e, l-8) + } + if err = lc.choice[1].Encode(e, 1); err != nil { + return + } + if err = lc.high.Encode(e, l-16); err != nil { + return + } + return nil +} + +// Decode reads the length offset. Add minMatchLen to compute the actual length +// to the length offset l. +func (lc *lengthCodec) Decode(d *rangeDecoder, posState uint32, +) (l uint32, err error) { + var b uint32 + if b, err = lc.choice[0].Decode(d); err != nil { + return + } + if b == 0 { + l, err = lc.low[posState].Decode(d) + return + } + if b, err = lc.choice[1].Decode(d); err != nil { + return + } + if b == 0 { + l, err = lc.mid[posState].Decode(d) + l += 8 + return + } + l, err = lc.high.Decode(d) + l += 16 + return +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/literalcodec.go b/vendor/github.com/ulikunitz/xz/lzma/literalcodec.go new file mode 100644 index 000000000..c949d6ebd --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/literalcodec.go @@ -0,0 +1,132 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +// literalCodec supports the encoding of literal. It provides 768 probability +// values per literal state. The upper 512 probabilities are used with the +// context of a match bit. +type literalCodec struct { + probs []prob +} + +// deepcopy initializes literal codec c as a deep copy of the source. +func (c *literalCodec) deepcopy(src *literalCodec) { + if c == src { + return + } + c.probs = make([]prob, len(src.probs)) + copy(c.probs, src.probs) +} + +// init initializes the literal codec. +func (c *literalCodec) init(lc, lp int) { + switch { + case !(minLC <= lc && lc <= maxLC): + panic("lc out of range") + case !(minLP <= lp && lp <= maxLP): + panic("lp out of range") + } + c.probs = make([]prob, 0x300<= 7 { + m := uint32(match) + for { + matchBit := (m >> 7) & 1 + m <<= 1 + bit := (r >> 7) & 1 + r <<= 1 + i := ((1 + matchBit) << 8) | symbol + if err = probs[i].Encode(e, bit); err != nil { + return + } + symbol = (symbol << 1) | bit + if matchBit != bit { + break + } + if symbol >= 0x100 { + break + } + } + } + for symbol < 0x100 { + bit := (r >> 7) & 1 + r <<= 1 + if err = probs[symbol].Encode(e, bit); err != nil { + return + } + symbol = (symbol << 1) | bit + } + return nil +} + +// Decode decodes a literal byte using the range decoder as well as the LZMA +// state, a match byte, and the literal state. +func (c *literalCodec) Decode(d *rangeDecoder, + state uint32, match byte, litState uint32, +) (s byte, err error) { + k := litState * 0x300 + probs := c.probs[k : k+0x300] + symbol := uint32(1) + if state >= 7 { + m := uint32(match) + for { + matchBit := (m >> 7) & 1 + m <<= 1 + i := ((1 + matchBit) << 8) | symbol + bit, err := d.DecodeBit(&probs[i]) + if err != nil { + return 0, err + } + symbol = (symbol << 1) | bit + if matchBit != bit { + break + } + if symbol >= 0x100 { + break + } + } + } + for symbol < 0x100 { + bit, err := d.DecodeBit(&probs[symbol]) + if err != nil { + return 0, err + } + symbol = (symbol << 1) | bit + } + s = byte(symbol - 0x100) + return s, nil +} + +// minLC and maxLC define the range for LC values. +const ( + minLC = 0 + maxLC = 8 +) + +// minLC and maxLC define the range for LP values. +const ( + minLP = 0 + maxLP = 4 +) + +// minState and maxState define a range for the state values stored in +// the State values. +const ( + minState = 0 + maxState = 11 +) diff --git a/vendor/github.com/ulikunitz/xz/lzma/matchalgorithm.go b/vendor/github.com/ulikunitz/xz/lzma/matchalgorithm.go new file mode 100644 index 000000000..4a244eb1a --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/matchalgorithm.go @@ -0,0 +1,52 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import "errors" + +// MatchAlgorithm identifies an algorithm to find matches in the +// dictionary. +type MatchAlgorithm byte + +// Supported matcher algorithms. +const ( + HashTable4 MatchAlgorithm = iota + BinaryTree +) + +// maStrings are used by the String method. +var maStrings = map[MatchAlgorithm]string{ + HashTable4: "HashTable4", + BinaryTree: "BinaryTree", +} + +// String returns a string representation of the Matcher. +func (a MatchAlgorithm) String() string { + if s, ok := maStrings[a]; ok { + return s + } + return "unknown" +} + +var errUnsupportedMatchAlgorithm = errors.New( + "lzma: unsupported match algorithm value") + +// verify checks whether the matcher value is supported. +func (a MatchAlgorithm) verify() error { + if _, ok := maStrings[a]; !ok { + return errUnsupportedMatchAlgorithm + } + return nil +} + +func (a MatchAlgorithm) new(dictCap int) (m matcher, err error) { + switch a { + case HashTable4: + return newHashTable(dictCap, 4) + case BinaryTree: + return newBinTree(dictCap) + } + return nil, errUnsupportedMatchAlgorithm +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/operation.go b/vendor/github.com/ulikunitz/xz/lzma/operation.go new file mode 100644 index 000000000..733bb99da --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/operation.go @@ -0,0 +1,80 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import ( + "errors" + "fmt" + "unicode" +) + +// operation represents an operation on the dictionary during encoding or +// decoding. +type operation interface { + Len() int +} + +// rep represents a repetition at the given distance and the given length +type match struct { + // supports all possible distance values, including the eos marker + distance int64 + // length + n int +} + +// verify checks whether the match is valid. If that is not the case an +// error is returned. +func (m match) verify() error { + if !(minDistance <= m.distance && m.distance <= maxDistance) { + return errors.New("distance out of range") + } + if !(1 <= m.n && m.n <= maxMatchLen) { + return errors.New("length out of range") + } + return nil +} + +// l return the l-value for the match, which is the difference of length +// n and 2. +func (m match) l() uint32 { + return uint32(m.n - minMatchLen) +} + +// dist returns the dist value for the match, which is one less of the +// distance stored in the match. +func (m match) dist() uint32 { + return uint32(m.distance - minDistance) +} + +// Len returns the number of bytes matched. +func (m match) Len() int { + return m.n +} + +// String returns a string representation for the repetition. +func (m match) String() string { + return fmt.Sprintf("M{%d,%d}", m.distance, m.n) +} + +// lit represents a single byte literal. +type lit struct { + b byte +} + +// Len returns 1 for the single byte literal. +func (l lit) Len() int { + return 1 +} + +// String returns a string representation for the literal. +func (l lit) String() string { + var c byte + if unicode.IsPrint(rune(l.b)) { + c = l.b + } else { + c = '.' + } + return fmt.Sprintf("L{%c/%02x}", c, l.b) +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/prob.go b/vendor/github.com/ulikunitz/xz/lzma/prob.go new file mode 100644 index 000000000..24d50ec68 --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/prob.go @@ -0,0 +1,53 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +// movebits defines the number of bits used for the updates of probability +// values. +const movebits = 5 + +// probbits defines the number of bits of a probability value. +const probbits = 11 + +// probInit defines 0.5 as initial value for prob values. +const probInit prob = 1 << (probbits - 1) + +// Type prob represents probabilities. The type can also be used to encode and +// decode single bits. +type prob uint16 + +// Dec decreases the probability. The decrease is proportional to the +// probability value. +func (p *prob) dec() { + *p -= *p >> movebits +} + +// Inc increases the probability. The Increase is proportional to the +// difference of 1 and the probability value. +func (p *prob) inc() { + *p += ((1 << probbits) - *p) >> movebits +} + +// Computes the new bound for a given range using the probability value. +func (p prob) bound(r uint32) uint32 { + return (r >> probbits) * uint32(p) +} + +// Bits returns 1. One is the number of bits that can be encoded or decoded +// with a single prob value. +func (p prob) Bits() int { + return 1 +} + +// Encode encodes the least-significant bit of v. Note that the p value will be +// changed. +func (p *prob) Encode(e *rangeEncoder, v uint32) error { + return e.EncodeBit(v, p) +} + +// Decode decodes a single bit. Note that the p value will change. +func (p *prob) Decode(d *rangeDecoder) (v uint32, err error) { + return d.DecodeBit(p) +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/properties.go b/vendor/github.com/ulikunitz/xz/lzma/properties.go new file mode 100644 index 000000000..23418e25d --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/properties.go @@ -0,0 +1,69 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import ( + "errors" + "fmt" +) + +// maximum and minimum values for the LZMA properties. +const ( + minPB = 0 + maxPB = 4 +) + +// maxPropertyCode is the possible maximum of a properties code byte. +const maxPropertyCode = (maxPB+1)*(maxLP+1)*(maxLC+1) - 1 + +// Properties contains the parameters LC, LP and PB. The parameter LC +// defines the number of literal context bits; parameter LP the number +// of literal position bits and PB the number of position bits. +type Properties struct { + LC int + LP int + PB int +} + +// String returns the properties in a string representation. +func (p *Properties) String() string { + return fmt.Sprintf("LC %d LP %d PB %d", p.LC, p.LP, p.PB) +} + +// PropertiesForCode converts a properties code byte into a Properties value. +func PropertiesForCode(code byte) (p Properties, err error) { + if code > maxPropertyCode { + return p, errors.New("lzma: invalid properties code") + } + p.LC = int(code % 9) + code /= 9 + p.LP = int(code % 5) + code /= 5 + p.PB = int(code % 5) + return p, err +} + +// verify checks the properties for correctness. +func (p *Properties) verify() error { + if p == nil { + return errors.New("lzma: properties are nil") + } + if !(minLC <= p.LC && p.LC <= maxLC) { + return errors.New("lzma: lc out of range") + } + if !(minLP <= p.LP && p.LP <= maxLP) { + return errors.New("lzma: lp out of range") + } + if !(minPB <= p.PB && p.PB <= maxPB) { + return errors.New("lzma: pb out of range") + } + return nil +} + +// Code converts the properties to a byte. The function assumes that +// the properties components are all in range. +func (p Properties) Code() byte { + return byte((p.PB*5+p.LP)*9 + p.LC) +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/rangecodec.go b/vendor/github.com/ulikunitz/xz/lzma/rangecodec.go new file mode 100644 index 000000000..6361c5e7c --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/rangecodec.go @@ -0,0 +1,248 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import ( + "errors" + "io" +) + +// rangeEncoder implements range encoding of single bits. The low value can +// overflow therefore we need uint64. The cache value is used to handle +// overflows. +type rangeEncoder struct { + lbw *LimitedByteWriter + nrange uint32 + low uint64 + cacheLen int64 + cache byte +} + +// maxInt64 provides the maximal value of the int64 type +const maxInt64 = 1<<63 - 1 + +// newRangeEncoder creates a new range encoder. +func newRangeEncoder(bw io.ByteWriter) (re *rangeEncoder, err error) { + lbw, ok := bw.(*LimitedByteWriter) + if !ok { + lbw = &LimitedByteWriter{BW: bw, N: maxInt64} + } + return &rangeEncoder{ + lbw: lbw, + nrange: 0xffffffff, + cacheLen: 1}, nil +} + +// Available returns the number of bytes that still can be written. The +// method takes the bytes that will be currently written by Close into +// account. +func (e *rangeEncoder) Available() int64 { + return e.lbw.N - (e.cacheLen + 4) +} + +// writeByte writes a single byte to the underlying writer. An error is +// returned if the limit is reached. The written byte will be counted if +// the underlying writer doesn't return an error. +func (e *rangeEncoder) writeByte(c byte) error { + if e.Available() < 1 { + return ErrLimit + } + return e.lbw.WriteByte(c) +} + +// DirectEncodeBit encodes the least-significant bit of b with probability 1/2. +func (e *rangeEncoder) DirectEncodeBit(b uint32) error { + e.nrange >>= 1 + e.low += uint64(e.nrange) & (0 - (uint64(b) & 1)) + + // normalize + const top = 1 << 24 + if e.nrange >= top { + return nil + } + e.nrange <<= 8 + return e.shiftLow() +} + +// EncodeBit encodes the least significant bit of b. The p value will be +// updated by the function depending on the bit encoded. +func (e *rangeEncoder) EncodeBit(b uint32, p *prob) error { + bound := p.bound(e.nrange) + if b&1 == 0 { + e.nrange = bound + p.inc() + } else { + e.low += uint64(bound) + e.nrange -= bound + p.dec() + } + + // normalize + const top = 1 << 24 + if e.nrange >= top { + return nil + } + e.nrange <<= 8 + return e.shiftLow() +} + +// Close writes a complete copy of the low value. +func (e *rangeEncoder) Close() error { + for i := 0; i < 5; i++ { + if err := e.shiftLow(); err != nil { + return err + } + } + return nil +} + +// shiftLow shifts the low value for 8 bit. The shifted byte is written into +// the byte writer. The cache value is used to handle overflows. +func (e *rangeEncoder) shiftLow() error { + if uint32(e.low) < 0xff000000 || (e.low>>32) != 0 { + tmp := e.cache + for { + err := e.writeByte(tmp + byte(e.low>>32)) + if err != nil { + return err + } + tmp = 0xff + e.cacheLen-- + if e.cacheLen <= 0 { + if e.cacheLen < 0 { + panic("negative cacheLen") + } + break + } + } + e.cache = byte(uint32(e.low) >> 24) + } + e.cacheLen++ + e.low = uint64(uint32(e.low) << 8) + return nil +} + +// rangeDecoder decodes single bits of the range encoding stream. +type rangeDecoder struct { + br io.ByteReader + nrange uint32 + code uint32 +} + +// init initializes the range decoder, by reading from the byte reader. +func (d *rangeDecoder) init() error { + d.nrange = 0xffffffff + d.code = 0 + + b, err := d.br.ReadByte() + if err != nil { + return err + } + if b != 0 { + return errors.New("newRangeDecoder: first byte not zero") + } + + for i := 0; i < 4; i++ { + if err = d.updateCode(); err != nil { + return err + } + } + + if d.code >= d.nrange { + return errors.New("newRangeDecoder: d.code >= d.nrange") + } + + return nil +} + +// newRangeDecoder initializes a range decoder. It reads five bytes from the +// reader and therefore may return an error. +func newRangeDecoder(br io.ByteReader) (d *rangeDecoder, err error) { + d = &rangeDecoder{br: br, nrange: 0xffffffff} + + b, err := d.br.ReadByte() + if err != nil { + return nil, err + } + if b != 0 { + return nil, errors.New("newRangeDecoder: first byte not zero") + } + + for i := 0; i < 4; i++ { + if err = d.updateCode(); err != nil { + return nil, err + } + } + + if d.code >= d.nrange { + return nil, errors.New("newRangeDecoder: d.code >= d.nrange") + } + + return d, nil +} + +// possiblyAtEnd checks whether the decoder may be at the end of the stream. +func (d *rangeDecoder) possiblyAtEnd() bool { + return d.code == 0 +} + +// DirectDecodeBit decodes a bit with probability 1/2. The return value b will +// contain the bit at the least-significant position. All other bits will be +// zero. +func (d *rangeDecoder) DirectDecodeBit() (b uint32, err error) { + d.nrange >>= 1 + d.code -= d.nrange + t := 0 - (d.code >> 31) + d.code += d.nrange & t + b = (t + 1) & 1 + + // d.code will stay less then d.nrange + + // normalize + // assume d.code < d.nrange + const top = 1 << 24 + if d.nrange >= top { + return b, nil + } + d.nrange <<= 8 + // d.code < d.nrange will be maintained + return b, d.updateCode() +} + +// decodeBit decodes a single bit. The bit will be returned at the +// least-significant position. All other bits will be zero. The probability +// value will be updated. +func (d *rangeDecoder) DecodeBit(p *prob) (b uint32, err error) { + bound := p.bound(d.nrange) + if d.code < bound { + d.nrange = bound + p.inc() + b = 0 + } else { + d.code -= bound + d.nrange -= bound + p.dec() + b = 1 + } + // normalize + // assume d.code < d.nrange + const top = 1 << 24 + if d.nrange >= top { + return b, nil + } + d.nrange <<= 8 + // d.code < d.nrange will be maintained + return b, d.updateCode() +} + +// updateCode reads a new byte into the code. +func (d *rangeDecoder) updateCode() error { + b, err := d.br.ReadByte() + if err != nil { + return err + } + d.code = (d.code << 8) | uint32(b) + return nil +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/reader.go b/vendor/github.com/ulikunitz/xz/lzma/reader.go new file mode 100644 index 000000000..2ef3dcaaa --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/reader.go @@ -0,0 +1,100 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package lzma supports the decoding and encoding of LZMA streams. +// Reader and Writer support the classic LZMA format. Reader2 and +// Writer2 support the decoding and encoding of LZMA2 streams. +// +// The package is written completely in Go and doesn't rely on any external +// library. +package lzma + +import ( + "errors" + "io" +) + +// ReaderConfig stores the parameters for the reader of the classic LZMA +// format. +type ReaderConfig struct { + DictCap int +} + +// fill converts the zero values of the configuration to the default values. +func (c *ReaderConfig) fill() { + if c.DictCap == 0 { + c.DictCap = 8 * 1024 * 1024 + } +} + +// Verify checks the reader configuration for errors. Zero values will +// be replaced by default values. +func (c *ReaderConfig) Verify() error { + c.fill() + if !(MinDictCap <= c.DictCap && int64(c.DictCap) <= MaxDictCap) { + return errors.New("lzma: dictionary capacity is out of range") + } + return nil +} + +// Reader provides a reader for LZMA files or streams. +type Reader struct { + lzma io.Reader + h header + d *decoder +} + +// NewReader creates a new reader for an LZMA stream using the classic +// format. NewReader reads and checks the header of the LZMA stream. +func NewReader(lzma io.Reader) (r *Reader, err error) { + return ReaderConfig{}.NewReader(lzma) +} + +// NewReader creates a new reader for an LZMA stream in the classic +// format. The function reads and verifies the the header of the LZMA +// stream. +func (c ReaderConfig) NewReader(lzma io.Reader) (r *Reader, err error) { + if err = c.Verify(); err != nil { + return nil, err + } + data := make([]byte, HeaderLen) + if _, err := io.ReadFull(lzma, data); err != nil { + if err == io.EOF { + return nil, errors.New("lzma: unexpected EOF") + } + return nil, err + } + r = &Reader{lzma: lzma} + if err = r.h.unmarshalBinary(data); err != nil { + return nil, err + } + if r.h.dictCap < MinDictCap { + return nil, errors.New("lzma: dictionary capacity too small") + } + dictCap := r.h.dictCap + if c.DictCap > dictCap { + dictCap = c.DictCap + } + + state := newState(r.h.properties) + dict, err := newDecoderDict(dictCap) + if err != nil { + return nil, err + } + r.d, err = newDecoder(ByteReader(lzma), state, dict, r.h.size) + if err != nil { + return nil, err + } + return r, nil +} + +// EOSMarker indicates that an EOS marker has been encountered. +func (r *Reader) EOSMarker() bool { + return r.d.eosMarker +} + +// Read returns uncompressed data. +func (r *Reader) Read(p []byte) (n int, err error) { + return r.d.Read(p) +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/reader2.go b/vendor/github.com/ulikunitz/xz/lzma/reader2.go new file mode 100644 index 000000000..a55cfaa4e --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/reader2.go @@ -0,0 +1,232 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import ( + "errors" + "io" + + "github.com/ulikunitz/xz/internal/xlog" +) + +// Reader2Config stores the parameters for the LZMA2 reader. +// format. +type Reader2Config struct { + DictCap int +} + +// fill converts the zero values of the configuration to the default values. +func (c *Reader2Config) fill() { + if c.DictCap == 0 { + c.DictCap = 8 * 1024 * 1024 + } +} + +// Verify checks the reader configuration for errors. Zero configuration values +// will be replaced by default values. +func (c *Reader2Config) Verify() error { + c.fill() + if !(MinDictCap <= c.DictCap && int64(c.DictCap) <= MaxDictCap) { + return errors.New("lzma: dictionary capacity is out of range") + } + return nil +} + +// Reader2 supports the reading of LZMA2 chunk sequences. Note that the +// first chunk should have a dictionary reset and the first compressed +// chunk a properties reset. The chunk sequence may not be terminated by +// an end-of-stream chunk. +type Reader2 struct { + r io.Reader + err error + + dict *decoderDict + ur *uncompressedReader + decoder *decoder + chunkReader io.Reader + + cstate chunkState + ctype chunkType +} + +// NewReader2 creates a reader for an LZMA2 chunk sequence. +func NewReader2(lzma2 io.Reader) (r *Reader2, err error) { + return Reader2Config{}.NewReader2(lzma2) +} + +// NewReader2 creates an LZMA2 reader using the given configuration. +func (c Reader2Config) NewReader2(lzma2 io.Reader) (r *Reader2, err error) { + if err = c.Verify(); err != nil { + return nil, err + } + r = &Reader2{r: lzma2, cstate: start} + r.dict, err = newDecoderDict(c.DictCap) + if err != nil { + return nil, err + } + if err = r.startChunk(); err != nil { + r.err = err + } + return r, nil +} + +// uncompressed tests whether the chunk type specifies an uncompressed +// chunk. +func uncompressed(ctype chunkType) bool { + return ctype == cU || ctype == cUD +} + +// startChunk parses a new chunk. +func (r *Reader2) startChunk() error { + r.chunkReader = nil + header, err := readChunkHeader(r.r) + if err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + return err + } + xlog.Debugf("chunk header %v", header) + if err = r.cstate.next(header.ctype); err != nil { + return err + } + if r.cstate == stop { + return io.EOF + } + if header.ctype == cUD || header.ctype == cLRND { + r.dict.Reset() + } + size := int64(header.uncompressed) + 1 + if uncompressed(header.ctype) { + if r.ur != nil { + r.ur.Reopen(r.r, size) + } else { + r.ur = newUncompressedReader(r.r, r.dict, size) + } + r.chunkReader = r.ur + return nil + } + br := ByteReader(io.LimitReader(r.r, int64(header.compressed)+1)) + if r.decoder == nil { + state := newState(header.props) + r.decoder, err = newDecoder(br, state, r.dict, size) + if err != nil { + return err + } + r.chunkReader = r.decoder + return nil + } + switch header.ctype { + case cLR: + r.decoder.State.Reset() + case cLRN, cLRND: + r.decoder.State = newState(header.props) + } + err = r.decoder.Reopen(br, size) + if err != nil { + return err + } + r.chunkReader = r.decoder + return nil +} + +// Read reads data from the LZMA2 chunk sequence. +func (r *Reader2) Read(p []byte) (n int, err error) { + if r.err != nil { + return 0, r.err + } + for n < len(p) { + var k int + k, err = r.chunkReader.Read(p[n:]) + n += k + if err != nil { + if err == io.EOF { + err = r.startChunk() + if err == nil { + continue + } + } + r.err = err + return n, err + } + if k == 0 { + r.err = errors.New("lzma: Reader2 doesn't get data") + return n, r.err + } + } + return n, nil +} + +// EOS returns whether the LZMA2 stream has been terminated by an +// end-of-stream chunk. +func (r *Reader2) EOS() bool { + return r.cstate == stop +} + +// uncompressedReader is used to read uncompressed chunks. +type uncompressedReader struct { + lr io.LimitedReader + Dict *decoderDict + eof bool + err error +} + +// newUncompressedReader initializes a new uncompressedReader. +func newUncompressedReader(r io.Reader, dict *decoderDict, size int64) *uncompressedReader { + ur := &uncompressedReader{ + lr: io.LimitedReader{R: r, N: size}, + Dict: dict, + } + return ur +} + +// Reopen reinitializes an uncompressed reader. +func (ur *uncompressedReader) Reopen(r io.Reader, size int64) { + ur.err = nil + ur.eof = false + ur.lr = io.LimitedReader{R: r, N: size} +} + +// fill reads uncompressed data into the dictionary. +func (ur *uncompressedReader) fill() error { + if !ur.eof { + n, err := io.CopyN(ur.Dict, &ur.lr, int64(ur.Dict.Available())) + if err != io.EOF { + return err + } + ur.eof = true + if n > 0 { + return nil + } + } + if ur.lr.N != 0 { + return io.ErrUnexpectedEOF + } + return io.EOF +} + +// Read reads uncompressed data from the limited reader. +func (ur *uncompressedReader) Read(p []byte) (n int, err error) { + if ur.err != nil { + return 0, ur.err + } + for { + var k int + k, err = ur.Dict.Read(p[n:]) + n += k + if n >= len(p) { + return n, nil + } + if err != nil { + break + } + err = ur.fill() + if err != nil { + break + } + } + ur.err = err + return n, err +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/state.go b/vendor/github.com/ulikunitz/xz/lzma/state.go new file mode 100644 index 000000000..502351052 --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/state.go @@ -0,0 +1,151 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +// states defines the overall state count +const states = 12 + +// State maintains the full state of the operation encoding or decoding +// process. +type state struct { + rep [4]uint32 + isMatch [states << maxPosBits]prob + isRepG0Long [states << maxPosBits]prob + isRep [states]prob + isRepG0 [states]prob + isRepG1 [states]prob + isRepG2 [states]prob + litCodec literalCodec + lenCodec lengthCodec + repLenCodec lengthCodec + distCodec distCodec + state uint32 + posBitMask uint32 + Properties Properties +} + +// initProbSlice initializes a slice of probabilities. +func initProbSlice(p []prob) { + for i := range p { + p[i] = probInit + } +} + +// Reset sets all state information to the original values. +func (s *state) Reset() { + p := s.Properties + *s = state{ + Properties: p, + // dict: s.dict, + posBitMask: (uint32(1) << uint(p.PB)) - 1, + } + initProbSlice(s.isMatch[:]) + initProbSlice(s.isRep[:]) + initProbSlice(s.isRepG0[:]) + initProbSlice(s.isRepG1[:]) + initProbSlice(s.isRepG2[:]) + initProbSlice(s.isRepG0Long[:]) + s.litCodec.init(p.LC, p.LP) + s.lenCodec.init() + s.repLenCodec.init() + s.distCodec.init() +} + +// initState initializes the state. +func initState(s *state, p Properties) { + *s = state{Properties: p} + s.Reset() +} + +// newState creates a new state from the give Properties. +func newState(p Properties) *state { + s := &state{Properties: p} + s.Reset() + return s +} + +// deepcopy initializes s as a deep copy of the source. +func (s *state) deepcopy(src *state) { + if s == src { + return + } + s.rep = src.rep + s.isMatch = src.isMatch + s.isRepG0Long = src.isRepG0Long + s.isRep = src.isRep + s.isRepG0 = src.isRepG0 + s.isRepG1 = src.isRepG1 + s.isRepG2 = src.isRepG2 + s.litCodec.deepcopy(&src.litCodec) + s.lenCodec.deepcopy(&src.lenCodec) + s.repLenCodec.deepcopy(&src.repLenCodec) + s.distCodec.deepcopy(&src.distCodec) + s.state = src.state + s.posBitMask = src.posBitMask + s.Properties = src.Properties +} + +// cloneState creates a new clone of the give state. +func cloneState(src *state) *state { + s := new(state) + s.deepcopy(src) + return s +} + +// updateStateLiteral updates the state for a literal. +func (s *state) updateStateLiteral() { + switch { + case s.state < 4: + s.state = 0 + return + case s.state < 10: + s.state -= 3 + return + } + s.state -= 6 +} + +// updateStateMatch updates the state for a match. +func (s *state) updateStateMatch() { + if s.state < 7 { + s.state = 7 + } else { + s.state = 10 + } +} + +// updateStateRep updates the state for a repetition. +func (s *state) updateStateRep() { + if s.state < 7 { + s.state = 8 + } else { + s.state = 11 + } +} + +// updateStateShortRep updates the state for a short repetition. +func (s *state) updateStateShortRep() { + if s.state < 7 { + s.state = 9 + } else { + s.state = 11 + } +} + +// states computes the states of the operation codec. +func (s *state) states(dictHead int64) (state1, state2, posState uint32) { + state1 = s.state + posState = uint32(dictHead) & s.posBitMask + state2 = (s.state << maxPosBits) | posState + return +} + +// litState computes the literal state. +func (s *state) litState(prev byte, dictHead int64) uint32 { + lp, lc := uint(s.Properties.LP), uint(s.Properties.LC) + litState := ((uint32(dictHead) & ((1 << lp) - 1)) << lc) | + (uint32(prev) >> (8 - lc)) + return litState +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/treecodecs.go b/vendor/github.com/ulikunitz/xz/lzma/treecodecs.go new file mode 100644 index 000000000..504b3d78e --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/treecodecs.go @@ -0,0 +1,133 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +// treeCodec encodes or decodes values with a fixed bit size. It is using a +// tree of probability value. The root of the tree is the most-significant bit. +type treeCodec struct { + probTree +} + +// makeTreeCodec makes a tree codec. The bits value must be inside the range +// [1,32]. +func makeTreeCodec(bits int) treeCodec { + return treeCodec{makeProbTree(bits)} +} + +// deepcopy initializes tc as a deep copy of the source. +func (tc *treeCodec) deepcopy(src *treeCodec) { + tc.probTree.deepcopy(&src.probTree) +} + +// Encode uses the range encoder to encode a fixed-bit-size value. +func (tc *treeCodec) Encode(e *rangeEncoder, v uint32) (err error) { + m := uint32(1) + for i := int(tc.bits) - 1; i >= 0; i-- { + b := (v >> uint(i)) & 1 + if err := e.EncodeBit(b, &tc.probs[m]); err != nil { + return err + } + m = (m << 1) | b + } + return nil +} + +// Decodes uses the range decoder to decode a fixed-bit-size value. Errors may +// be caused by the range decoder. +func (tc *treeCodec) Decode(d *rangeDecoder) (v uint32, err error) { + m := uint32(1) + for j := 0; j < int(tc.bits); j++ { + b, err := d.DecodeBit(&tc.probs[m]) + if err != nil { + return 0, err + } + m = (m << 1) | b + } + return m - (1 << uint(tc.bits)), nil +} + +// treeReverseCodec is another tree codec, where the least-significant bit is +// the start of the probability tree. +type treeReverseCodec struct { + probTree +} + +// deepcopy initializes the treeReverseCodec as a deep copy of the +// source. +func (tc *treeReverseCodec) deepcopy(src *treeReverseCodec) { + tc.probTree.deepcopy(&src.probTree) +} + +// makeTreeReverseCodec creates treeReverseCodec value. The bits argument must +// be in the range [1,32]. +func makeTreeReverseCodec(bits int) treeReverseCodec { + return treeReverseCodec{makeProbTree(bits)} +} + +// Encode uses range encoder to encode a fixed-bit-size value. The range +// encoder may cause errors. +func (tc *treeReverseCodec) Encode(v uint32, e *rangeEncoder) (err error) { + m := uint32(1) + for i := uint(0); i < uint(tc.bits); i++ { + b := (v >> i) & 1 + if err := e.EncodeBit(b, &tc.probs[m]); err != nil { + return err + } + m = (m << 1) | b + } + return nil +} + +// Decodes uses the range decoder to decode a fixed-bit-size value. Errors +// returned by the range decoder will be returned. +func (tc *treeReverseCodec) Decode(d *rangeDecoder) (v uint32, err error) { + m := uint32(1) + for j := uint(0); j < uint(tc.bits); j++ { + b, err := d.DecodeBit(&tc.probs[m]) + if err != nil { + return 0, err + } + m = (m << 1) | b + v |= b << j + } + return v, nil +} + +// probTree stores enough probability values to be used by the treeEncode and +// treeDecode methods of the range coder types. +type probTree struct { + probs []prob + bits byte +} + +// deepcopy initializes the probTree value as a deep copy of the source. +func (t *probTree) deepcopy(src *probTree) { + if t == src { + return + } + t.probs = make([]prob, len(src.probs)) + copy(t.probs, src.probs) + t.bits = src.bits +} + +// makeProbTree initializes a probTree structure. +func makeProbTree(bits int) probTree { + if !(1 <= bits && bits <= 32) { + panic("bits outside of range [1,32]") + } + t := probTree{ + bits: byte(bits), + probs: make([]prob, 1< 0 { + c.SizeInHeader = true + } + if !c.SizeInHeader { + c.EOSMarker = true + } +} + +// Verify checks WriterConfig for errors. Verify will replace zero +// values with default values. +func (c *WriterConfig) Verify() error { + c.fill() + var err error + if c == nil { + return errors.New("lzma: WriterConfig is nil") + } + if c.Properties == nil { + return errors.New("lzma: WriterConfig has no Properties set") + } + if err = c.Properties.verify(); err != nil { + return err + } + if !(MinDictCap <= c.DictCap && int64(c.DictCap) <= MaxDictCap) { + return errors.New("lzma: dictionary capacity is out of range") + } + if !(maxMatchLen <= c.BufSize) { + return errors.New("lzma: lookahead buffer size too small") + } + if c.SizeInHeader { + if c.Size < 0 { + return errors.New("lzma: negative size not supported") + } + } else if !c.EOSMarker { + return errors.New("lzma: EOS marker is required") + } + if err = c.Matcher.verify(); err != nil { + return err + } + + return nil +} + +// header returns the header structure for this configuration. +func (c *WriterConfig) header() header { + h := header{ + properties: *c.Properties, + dictCap: c.DictCap, + size: -1, + } + if c.SizeInHeader { + h.size = c.Size + } + return h +} + +// Writer writes an LZMA stream in the classic format. +type Writer struct { + h header + bw io.ByteWriter + buf *bufio.Writer + e *encoder +} + +// NewWriter creates a new LZMA writer for the classic format. The +// method will write the header to the underlying stream. +func (c WriterConfig) NewWriter(lzma io.Writer) (w *Writer, err error) { + if err = c.Verify(); err != nil { + return nil, err + } + w = &Writer{h: c.header()} + + var ok bool + w.bw, ok = lzma.(io.ByteWriter) + if !ok { + w.buf = bufio.NewWriter(lzma) + w.bw = w.buf + } + state := newState(w.h.properties) + m, err := c.Matcher.new(w.h.dictCap) + if err != nil { + return nil, err + } + dict, err := newEncoderDict(w.h.dictCap, c.BufSize, m) + if err != nil { + return nil, err + } + var flags encoderFlags + if c.EOSMarker { + flags = eosMarker + } + if w.e, err = newEncoder(w.bw, state, dict, flags); err != nil { + return nil, err + } + + if err = w.writeHeader(); err != nil { + return nil, err + } + return w, nil +} + +// NewWriter creates a new LZMA writer using the classic format. The +// function writes the header to the underlying stream. +func NewWriter(lzma io.Writer) (w *Writer, err error) { + return WriterConfig{}.NewWriter(lzma) +} + +// writeHeader writes the LZMA header into the stream. +func (w *Writer) writeHeader() error { + data, err := w.h.marshalBinary() + if err != nil { + return err + } + _, err = w.bw.(io.Writer).Write(data) + return err +} + +// Write puts data into the Writer. +func (w *Writer) Write(p []byte) (n int, err error) { + if w.h.size >= 0 { + m := w.h.size + m -= w.e.Compressed() + int64(w.e.dict.Buffered()) + if m < 0 { + m = 0 + } + if m < int64(len(p)) { + p = p[:m] + err = ErrNoSpace + } + } + var werr error + if n, werr = w.e.Write(p); werr != nil { + err = werr + } + return n, err +} + +// Close closes the writer stream. It ensures that all data from the +// buffer will be compressed and the LZMA stream will be finished. +func (w *Writer) Close() error { + if w.h.size >= 0 { + n := w.e.Compressed() + int64(w.e.dict.Buffered()) + if n != w.h.size { + return errSize + } + } + err := w.e.Close() + if w.buf != nil { + ferr := w.buf.Flush() + if err == nil { + err = ferr + } + } + return err +} diff --git a/vendor/github.com/ulikunitz/xz/lzma/writer2.go b/vendor/github.com/ulikunitz/xz/lzma/writer2.go new file mode 100644 index 000000000..7c1afe157 --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzma/writer2.go @@ -0,0 +1,305 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import ( + "bytes" + "errors" + "io" +) + +// Writer2Config is used to create a Writer2 using parameters. +type Writer2Config struct { + // The properties for the encoding. If the it is nil the value + // {LC: 3, LP: 0, PB: 2} will be chosen. + Properties *Properties + // The capacity of the dictionary. If DictCap is zero, the value + // 8 MiB will be chosen. + DictCap int + // Size of the lookahead buffer; value 0 indicates default size + // 4096 + BufSize int + // Match algorithm + Matcher MatchAlgorithm +} + +// fill replaces zero values with default values. +func (c *Writer2Config) fill() { + if c.Properties == nil { + c.Properties = &Properties{LC: 3, LP: 0, PB: 2} + } + if c.DictCap == 0 { + c.DictCap = 8 * 1024 * 1024 + } + if c.BufSize == 0 { + c.BufSize = 4096 + } +} + +// Verify checks the Writer2Config for correctness. Zero values will be +// replaced by default values. +func (c *Writer2Config) Verify() error { + c.fill() + var err error + if c == nil { + return errors.New("lzma: WriterConfig is nil") + } + if c.Properties == nil { + return errors.New("lzma: WriterConfig has no Properties set") + } + if err = c.Properties.verify(); err != nil { + return err + } + if !(MinDictCap <= c.DictCap && int64(c.DictCap) <= MaxDictCap) { + return errors.New("lzma: dictionary capacity is out of range") + } + if !(maxMatchLen <= c.BufSize) { + return errors.New("lzma: lookahead buffer size too small") + } + if c.Properties.LC+c.Properties.LP > 4 { + return errors.New("lzma: sum of lc and lp exceeds 4") + } + if err = c.Matcher.verify(); err != nil { + return err + } + return nil +} + +// Writer2 supports the creation of an LZMA2 stream. But note that +// written data is buffered, so call Flush or Close to write data to the +// underlying writer. The Close method writes the end-of-stream marker +// to the stream. So you may be able to concatenate the output of two +// writers as long the output of the first writer has only been flushed +// but not closed. +// +// Any change to the fields Properties, DictCap must be done before the +// first call to Write, Flush or Close. +type Writer2 struct { + w io.Writer + + start *state + encoder *encoder + + cstate chunkState + ctype chunkType + + buf bytes.Buffer + lbw LimitedByteWriter +} + +// NewWriter2 creates an LZMA2 chunk sequence writer with the default +// parameters and options. +func NewWriter2(lzma2 io.Writer) (w *Writer2, err error) { + return Writer2Config{}.NewWriter2(lzma2) +} + +// NewWriter2 creates a new LZMA2 writer using the given configuration. +func (c Writer2Config) NewWriter2(lzma2 io.Writer) (w *Writer2, err error) { + if err = c.Verify(); err != nil { + return nil, err + } + w = &Writer2{ + w: lzma2, + start: newState(*c.Properties), + cstate: start, + ctype: start.defaultChunkType(), + } + w.buf.Grow(maxCompressed) + w.lbw = LimitedByteWriter{BW: &w.buf, N: maxCompressed} + m, err := c.Matcher.new(c.DictCap) + if err != nil { + return nil, err + } + d, err := newEncoderDict(c.DictCap, c.BufSize, m) + if err != nil { + return nil, err + } + w.encoder, err = newEncoder(&w.lbw, cloneState(w.start), d, 0) + if err != nil { + return nil, err + } + return w, nil +} + +// written returns the number of bytes written to the current chunk +func (w *Writer2) written() int { + if w.encoder == nil { + return 0 + } + return int(w.encoder.Compressed()) + w.encoder.dict.Buffered() +} + +// errClosed indicates that the writer is closed. +var errClosed = errors.New("lzma: writer closed") + +// Writes data to LZMA2 stream. Note that written data will be buffered. +// Use Flush or Close to ensure that data is written to the underlying +// writer. +func (w *Writer2) Write(p []byte) (n int, err error) { + if w.cstate == stop { + return 0, errClosed + } + for n < len(p) { + m := maxUncompressed - w.written() + if m <= 0 { + panic("lzma: maxUncompressed reached") + } + var q []byte + if n+m < len(p) { + q = p[n : n+m] + } else { + q = p[n:] + } + k, err := w.encoder.Write(q) + n += k + if err != nil && err != ErrLimit { + return n, err + } + if err == ErrLimit || k == m { + if err = w.flushChunk(); err != nil { + return n, err + } + } + } + return n, nil +} + +// writeUncompressedChunk writes an uncompressed chunk to the LZMA2 +// stream. +func (w *Writer2) writeUncompressedChunk() error { + u := w.encoder.Compressed() + if u <= 0 { + return errors.New("lzma: can't write empty uncompressed chunk") + } + if u > maxUncompressed { + panic("overrun of uncompressed data limit") + } + switch w.ctype { + case cLRND: + w.ctype = cUD + default: + w.ctype = cU + } + w.encoder.state = w.start + + header := chunkHeader{ + ctype: w.ctype, + uncompressed: uint32(u - 1), + } + hdata, err := header.MarshalBinary() + if err != nil { + return err + } + if _, err = w.w.Write(hdata); err != nil { + return err + } + _, err = w.encoder.dict.CopyN(w.w, int(u)) + return err +} + +// writeCompressedChunk writes a compressed chunk to the underlying +// writer. +func (w *Writer2) writeCompressedChunk() error { + if w.ctype == cU || w.ctype == cUD { + panic("chunk type uncompressed") + } + + u := w.encoder.Compressed() + if u <= 0 { + return errors.New("writeCompressedChunk: empty chunk") + } + if u > maxUncompressed { + panic("overrun of uncompressed data limit") + } + c := w.buf.Len() + if c <= 0 { + panic("no compressed data") + } + if c > maxCompressed { + panic("overrun of compressed data limit") + } + header := chunkHeader{ + ctype: w.ctype, + uncompressed: uint32(u - 1), + compressed: uint16(c - 1), + props: w.encoder.state.Properties, + } + hdata, err := header.MarshalBinary() + if err != nil { + return err + } + if _, err = w.w.Write(hdata); err != nil { + return err + } + _, err = io.Copy(w.w, &w.buf) + return err +} + +// writes a single chunk to the underlying writer. +func (w *Writer2) writeChunk() error { + u := int(uncompressedHeaderLen + w.encoder.Compressed()) + c := headerLen(w.ctype) + w.buf.Len() + if u < c { + return w.writeUncompressedChunk() + } + return w.writeCompressedChunk() +} + +// flushChunk terminates the current chunk. The encoder will be reset +// to support the next chunk. +func (w *Writer2) flushChunk() error { + if w.written() == 0 { + return nil + } + var err error + if err = w.encoder.Close(); err != nil { + return err + } + if err = w.writeChunk(); err != nil { + return err + } + w.buf.Reset() + w.lbw.N = maxCompressed + if err = w.encoder.Reopen(&w.lbw); err != nil { + return err + } + if err = w.cstate.next(w.ctype); err != nil { + return err + } + w.ctype = w.cstate.defaultChunkType() + w.start = cloneState(w.encoder.state) + return nil +} + +// Flush writes all buffered data out to the underlying stream. This +// could result in multiple chunks to be created. +func (w *Writer2) Flush() error { + if w.cstate == stop { + return errClosed + } + for w.written() > 0 { + if err := w.flushChunk(); err != nil { + return err + } + } + return nil +} + +// Close terminates the LZMA2 stream with an EOS chunk. +func (w *Writer2) Close() error { + if w.cstate == stop { + return errClosed + } + if err := w.Flush(); err != nil { + return nil + } + // write zero byte EOS chunk + _, err := w.w.Write([]byte{0}) + if err != nil { + return err + } + w.cstate = stop + return nil +} diff --git a/vendor/github.com/ulikunitz/xz/lzmafilter.go b/vendor/github.com/ulikunitz/xz/lzmafilter.go new file mode 100644 index 000000000..69cf5f7c2 --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/lzmafilter.go @@ -0,0 +1,117 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xz + +import ( + "errors" + "fmt" + "io" + + "github.com/ulikunitz/xz/lzma" +) + +// LZMA filter constants. +const ( + lzmaFilterID = 0x21 + lzmaFilterLen = 3 +) + +// lzmaFilter declares the LZMA2 filter information stored in an xz +// block header. +type lzmaFilter struct { + dictCap int64 +} + +// String returns a representation of the LZMA filter. +func (f lzmaFilter) String() string { + return fmt.Sprintf("LZMA dict cap %#x", f.dictCap) +} + +// id returns the ID for the LZMA2 filter. +func (f lzmaFilter) id() uint64 { return lzmaFilterID } + +// MarshalBinary converts the lzmaFilter in its encoded representation. +func (f lzmaFilter) MarshalBinary() (data []byte, err error) { + c := lzma.EncodeDictCap(f.dictCap) + return []byte{lzmaFilterID, 1, c}, nil +} + +// UnmarshalBinary unmarshals the given data representation of the LZMA2 +// filter. +func (f *lzmaFilter) UnmarshalBinary(data []byte) error { + if len(data) != lzmaFilterLen { + return errors.New("xz: data for LZMA2 filter has wrong length") + } + if data[0] != lzmaFilterID { + return errors.New("xz: wrong LZMA2 filter id") + } + if data[1] != 1 { + return errors.New("xz: wrong LZMA2 filter size") + } + dc, err := lzma.DecodeDictCap(data[2]) + if err != nil { + return errors.New("xz: wrong LZMA2 dictionary size property") + } + + f.dictCap = dc + return nil +} + +// reader creates a new reader for the LZMA2 filter. +func (f lzmaFilter) reader(r io.Reader, c *ReaderConfig) (fr io.Reader, + err error) { + + config := new(lzma.Reader2Config) + if c != nil { + config.DictCap = c.DictCap + } + dc := int(f.dictCap) + if dc < 1 { + return nil, errors.New("xz: LZMA2 filter parameter " + + "dictionary capacity overflow") + } + if dc > config.DictCap { + config.DictCap = dc + } + + fr, err = config.NewReader2(r) + if err != nil { + return nil, err + } + return fr, nil +} + +// writeCloser creates a io.WriteCloser for the LZMA2 filter. +func (f lzmaFilter) writeCloser(w io.WriteCloser, c *WriterConfig, +) (fw io.WriteCloser, err error) { + config := new(lzma.Writer2Config) + if c != nil { + *config = lzma.Writer2Config{ + Properties: c.Properties, + DictCap: c.DictCap, + BufSize: c.BufSize, + Matcher: c.Matcher, + } + } + + dc := int(f.dictCap) + if dc < 1 { + return nil, errors.New("xz: LZMA2 filter parameter " + + "dictionary capacity overflow") + } + if dc > config.DictCap { + config.DictCap = dc + } + + fw, err = config.NewWriter2(w) + if err != nil { + return nil, err + } + return fw, nil +} + +// last returns true, because an LZMA2 filter must be the last filter in +// the filter list. +func (f lzmaFilter) last() bool { return true } diff --git a/vendor/github.com/ulikunitz/xz/reader.go b/vendor/github.com/ulikunitz/xz/reader.go new file mode 100644 index 000000000..0634c6bcc --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/reader.go @@ -0,0 +1,373 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package xz supports the compression and decompression of xz files. It +// supports version 1.0.4 of the specification without the non-LZMA2 +// filters. See http://tukaani.org/xz/xz-file-format-1.0.4.txt +package xz + +import ( + "bytes" + "errors" + "fmt" + "hash" + "io" + + "github.com/ulikunitz/xz/internal/xlog" + "github.com/ulikunitz/xz/lzma" +) + +// ReaderConfig defines the parameters for the xz reader. The +// SingleStream parameter requests the reader to assume that the +// underlying stream contains only a single stream. +type ReaderConfig struct { + DictCap int + SingleStream bool +} + +// fill replaces all zero values with their default values. +func (c *ReaderConfig) fill() { + if c.DictCap == 0 { + c.DictCap = 8 * 1024 * 1024 + } +} + +// Verify checks the reader parameters for Validity. Zero values will be +// replaced by default values. +func (c *ReaderConfig) Verify() error { + if c == nil { + return errors.New("xz: reader parameters are nil") + } + lc := lzma.Reader2Config{DictCap: c.DictCap} + if err := lc.Verify(); err != nil { + return err + } + return nil +} + +// Reader supports the reading of one or multiple xz streams. +type Reader struct { + ReaderConfig + + xz io.Reader + sr *streamReader +} + +// streamReader decodes a single xz stream +type streamReader struct { + ReaderConfig + + xz io.Reader + br *blockReader + newHash func() hash.Hash + h header + index []record +} + +// NewReader creates a new xz reader using the default parameters. +// The function reads and checks the header of the first XZ stream. The +// reader will process multiple streams including padding. +func NewReader(xz io.Reader) (r *Reader, err error) { + return ReaderConfig{}.NewReader(xz) +} + +// NewReader creates an xz stream reader. The created reader will be +// able to process multiple streams and padding unless a SingleStream +// has been set in the reader configuration c. +func (c ReaderConfig) NewReader(xz io.Reader) (r *Reader, err error) { + if err = c.Verify(); err != nil { + return nil, err + } + r = &Reader{ + ReaderConfig: c, + xz: xz, + } + if r.sr, err = c.newStreamReader(xz); err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + return nil, err + } + return r, nil +} + +var errUnexpectedData = errors.New("xz: unexpected data after stream") + +// Read reads uncompressed data from the stream. +func (r *Reader) Read(p []byte) (n int, err error) { + for n < len(p) { + if r.sr == nil { + if r.SingleStream { + data := make([]byte, 1) + _, err = io.ReadFull(r.xz, data) + if err != io.EOF { + return n, errUnexpectedData + } + return n, io.EOF + } + for { + r.sr, err = r.ReaderConfig.newStreamReader(r.xz) + if err != errPadding { + break + } + } + if err != nil { + return n, err + } + } + k, err := r.sr.Read(p[n:]) + n += k + if err != nil { + if err == io.EOF { + r.sr = nil + continue + } + return n, err + } + } + return n, nil +} + +var errPadding = errors.New("xz: padding (4 zero bytes) encountered") + +// newStreamReader creates a new xz stream reader using the given configuration +// parameters. NewReader reads and checks the header of the xz stream. +func (c ReaderConfig) newStreamReader(xz io.Reader) (r *streamReader, err error) { + if err = c.Verify(); err != nil { + return nil, err + } + data := make([]byte, HeaderLen) + if _, err := io.ReadFull(xz, data[:4]); err != nil { + return nil, err + } + if bytes.Equal(data[:4], []byte{0, 0, 0, 0}) { + return nil, errPadding + } + if _, err = io.ReadFull(xz, data[4:]); err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + return nil, err + } + r = &streamReader{ + ReaderConfig: c, + xz: xz, + index: make([]record, 0, 4), + } + if err = r.h.UnmarshalBinary(data); err != nil { + return nil, err + } + xlog.Debugf("xz header %s", r.h) + if r.newHash, err = newHashFunc(r.h.flags); err != nil { + return nil, err + } + return r, nil +} + +// errIndex indicates an error with the xz file index. +var errIndex = errors.New("xz: error in xz file index") + +// readTail reads the index body and the xz footer. +func (r *streamReader) readTail() error { + index, n, err := readIndexBody(r.xz) + if err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + return err + } + if len(index) != len(r.index) { + return fmt.Errorf("xz: index length is %d; want %d", + len(index), len(r.index)) + } + for i, rec := range r.index { + if rec != index[i] { + return fmt.Errorf("xz: record %d is %v; want %v", + i, rec, index[i]) + } + } + + p := make([]byte, footerLen) + if _, err = io.ReadFull(r.xz, p); err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + return err + } + var f footer + if err = f.UnmarshalBinary(p); err != nil { + return err + } + xlog.Debugf("xz footer %s", f) + if f.flags != r.h.flags { + return errors.New("xz: footer flags incorrect") + } + if f.indexSize != int64(n)+1 { + return errors.New("xz: index size in footer wrong") + } + return nil +} + +// Read reads actual data from the xz stream. +func (r *streamReader) Read(p []byte) (n int, err error) { + for n < len(p) { + if r.br == nil { + bh, hlen, err := readBlockHeader(r.xz) + if err != nil { + if err == errIndexIndicator { + if err = r.readTail(); err != nil { + return n, err + } + return n, io.EOF + } + return n, err + } + xlog.Debugf("block %v", *bh) + r.br, err = r.ReaderConfig.newBlockReader(r.xz, bh, + hlen, r.newHash()) + if err != nil { + return n, err + } + } + k, err := r.br.Read(p[n:]) + n += k + if err != nil { + if err == io.EOF { + r.index = append(r.index, r.br.record()) + r.br = nil + } else { + return n, err + } + } + } + return n, nil +} + +// countingReader is a reader that counts the bytes read. +type countingReader struct { + r io.Reader + n int64 +} + +// Read reads data from the wrapped reader and adds it to the n field. +func (lr *countingReader) Read(p []byte) (n int, err error) { + n, err = lr.r.Read(p) + lr.n += int64(n) + return n, err +} + +// blockReader supports the reading of a block. +type blockReader struct { + lxz countingReader + header *blockHeader + headerLen int + n int64 + hash hash.Hash + r io.Reader + err error +} + +// newBlockReader creates a new block reader. +func (c *ReaderConfig) newBlockReader(xz io.Reader, h *blockHeader, + hlen int, hash hash.Hash) (br *blockReader, err error) { + + br = &blockReader{ + lxz: countingReader{r: xz}, + header: h, + headerLen: hlen, + hash: hash, + } + + fr, err := c.newFilterReader(&br.lxz, h.filters) + if err != nil { + return nil, err + } + br.r = io.TeeReader(fr, br.hash) + + return br, nil +} + +// uncompressedSize returns the uncompressed size of the block. +func (br *blockReader) uncompressedSize() int64 { + return br.n +} + +// compressedSize returns the compressed size of the block. +func (br *blockReader) compressedSize() int64 { + return br.lxz.n +} + +// unpaddedSize computes the unpadded size for the block. +func (br *blockReader) unpaddedSize() int64 { + n := int64(br.headerLen) + n += br.compressedSize() + n += int64(br.hash.Size()) + return n +} + +// record returns the index record for the current block. +func (br *blockReader) record() record { + return record{br.unpaddedSize(), br.uncompressedSize()} +} + +// errBlockSize indicates that the size of the block in the block header +// is wrong. +var errBlockSize = errors.New("xz: wrong uncompressed size for block") + +// Read reads data from the block. +func (br *blockReader) Read(p []byte) (n int, err error) { + n, err = br.r.Read(p) + br.n += int64(n) + + u := br.header.uncompressedSize + if u >= 0 && br.uncompressedSize() > u { + return n, errors.New("xz: wrong uncompressed size for block") + } + c := br.header.compressedSize + if c >= 0 && br.compressedSize() > c { + return n, errors.New("xz: wrong compressed size for block") + } + if err != io.EOF { + return n, err + } + if br.uncompressedSize() < u || br.compressedSize() < c { + return n, io.ErrUnexpectedEOF + } + + s := br.hash.Size() + k := padLen(br.lxz.n) + q := make([]byte, k+s, k+2*s) + if _, err = io.ReadFull(br.lxz.r, q); err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + return n, err + } + if !allZeros(q[:k]) { + return n, errors.New("xz: non-zero block padding") + } + checkSum := q[k:] + computedSum := br.hash.Sum(checkSum[s:]) + if !bytes.Equal(checkSum, computedSum) { + return n, errors.New("xz: checksum error for block") + } + return n, io.EOF +} + +func (c *ReaderConfig) newFilterReader(r io.Reader, f []filter) (fr io.Reader, + err error) { + + if err = verifyFilters(f); err != nil { + return nil, err + } + + fr = r + for i := len(f) - 1; i >= 0; i-- { + fr, err = f[i].reader(fr, c) + if err != nil { + return nil, err + } + } + return fr, nil +} diff --git a/vendor/github.com/ulikunitz/xz/writer.go b/vendor/github.com/ulikunitz/xz/writer.go new file mode 100644 index 000000000..c126f7099 --- /dev/null +++ b/vendor/github.com/ulikunitz/xz/writer.go @@ -0,0 +1,386 @@ +// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xz + +import ( + "errors" + "hash" + "io" + + "github.com/ulikunitz/xz/lzma" +) + +// WriterConfig describe the parameters for an xz writer. +type WriterConfig struct { + Properties *lzma.Properties + DictCap int + BufSize int + BlockSize int64 + // checksum method: CRC32, CRC64 or SHA256 + CheckSum byte + // match algorithm + Matcher lzma.MatchAlgorithm +} + +// fill replaces zero values with default values. +func (c *WriterConfig) fill() { + if c.Properties == nil { + c.Properties = &lzma.Properties{LC: 3, LP: 0, PB: 2} + } + if c.DictCap == 0 { + c.DictCap = 8 * 1024 * 1024 + } + if c.BufSize == 0 { + c.BufSize = 4096 + } + if c.BlockSize == 0 { + c.BlockSize = maxInt64 + } + if c.CheckSum == 0 { + c.CheckSum = CRC64 + } +} + +// Verify checks the configuration for errors. Zero values will be +// replaced by default values. +func (c *WriterConfig) Verify() error { + if c == nil { + return errors.New("xz: writer configuration is nil") + } + c.fill() + lc := lzma.Writer2Config{ + Properties: c.Properties, + DictCap: c.DictCap, + BufSize: c.BufSize, + Matcher: c.Matcher, + } + if err := lc.Verify(); err != nil { + return err + } + if c.BlockSize <= 0 { + return errors.New("xz: block size out of range") + } + if err := verifyFlags(c.CheckSum); err != nil { + return err + } + return nil +} + +// filters creates the filter list for the given parameters. +func (c *WriterConfig) filters() []filter { + return []filter{&lzmaFilter{int64(c.DictCap)}} +} + +// maxInt64 defines the maximum 64-bit signed integer. +const maxInt64 = 1<<63 - 1 + +// verifyFilters checks the filter list for the length and the right +// sequence of filters. +func verifyFilters(f []filter) error { + if len(f) == 0 { + return errors.New("xz: no filters") + } + if len(f) > 4 { + return errors.New("xz: more than four filters") + } + for _, g := range f[:len(f)-1] { + if g.last() { + return errors.New("xz: last filter is not last") + } + } + if !f[len(f)-1].last() { + return errors.New("xz: wrong last filter") + } + return nil +} + +// newFilterWriteCloser converts a filter list into a WriteCloser that +// can be used by a blockWriter. +func (c *WriterConfig) newFilterWriteCloser(w io.Writer, f []filter) (fw io.WriteCloser, err error) { + if err = verifyFilters(f); err != nil { + return nil, err + } + fw = nopWriteCloser(w) + for i := len(f) - 1; i >= 0; i-- { + fw, err = f[i].writeCloser(fw, c) + if err != nil { + return nil, err + } + } + return fw, nil +} + +// nopWCloser implements a WriteCloser with a Close method not doing +// anything. +type nopWCloser struct { + io.Writer +} + +// Close returns nil and doesn't do anything else. +func (c nopWCloser) Close() error { + return nil +} + +// nopWriteCloser converts the Writer into a WriteCloser with a Close +// function that does nothing beside returning nil. +func nopWriteCloser(w io.Writer) io.WriteCloser { + return nopWCloser{w} +} + +// Writer compresses data written to it. It is an io.WriteCloser. +type Writer struct { + WriterConfig + + xz io.Writer + bw *blockWriter + newHash func() hash.Hash + h header + index []record + closed bool +} + +// newBlockWriter creates a new block writer writes the header out. +func (w *Writer) newBlockWriter() error { + var err error + w.bw, err = w.WriterConfig.newBlockWriter(w.xz, w.newHash()) + if err != nil { + return err + } + if err = w.bw.writeHeader(w.xz); err != nil { + return err + } + return nil +} + +// closeBlockWriter closes a block writer and records the sizes in the +// index. +func (w *Writer) closeBlockWriter() error { + var err error + if err = w.bw.Close(); err != nil { + return err + } + w.index = append(w.index, w.bw.record()) + return nil +} + +// NewWriter creates a new xz writer using default parameters. +func NewWriter(xz io.Writer) (w *Writer, err error) { + return WriterConfig{}.NewWriter(xz) +} + +// NewWriter creates a new Writer using the given configuration parameters. +func (c WriterConfig) NewWriter(xz io.Writer) (w *Writer, err error) { + if err = c.Verify(); err != nil { + return nil, err + } + w = &Writer{ + WriterConfig: c, + xz: xz, + h: header{c.CheckSum}, + index: make([]record, 0, 4), + } + if w.newHash, err = newHashFunc(c.CheckSum); err != nil { + return nil, err + } + data, err := w.h.MarshalBinary() + if _, err = xz.Write(data); err != nil { + return nil, err + } + if err = w.newBlockWriter(); err != nil { + return nil, err + } + return w, nil + +} + +// Write compresses the uncompressed data provided. +func (w *Writer) Write(p []byte) (n int, err error) { + if w.closed { + return 0, errClosed + } + for { + k, err := w.bw.Write(p[n:]) + n += k + if err != errNoSpace { + return n, err + } + if err = w.closeBlockWriter(); err != nil { + return n, err + } + if err = w.newBlockWriter(); err != nil { + return n, err + } + } +} + +// Close closes the writer and adds the footer to the Writer. Close +// doesn't close the underlying writer. +func (w *Writer) Close() error { + if w.closed { + return errClosed + } + w.closed = true + var err error + if err = w.closeBlockWriter(); err != nil { + return err + } + + f := footer{flags: w.h.flags} + if f.indexSize, err = writeIndex(w.xz, w.index); err != nil { + return err + } + data, err := f.MarshalBinary() + if err != nil { + return err + } + if _, err = w.xz.Write(data); err != nil { + return err + } + return nil +} + +// countingWriter is a writer that counts all data written to it. +type countingWriter struct { + w io.Writer + n int64 +} + +// Write writes data to the countingWriter. +func (cw *countingWriter) Write(p []byte) (n int, err error) { + n, err = cw.w.Write(p) + cw.n += int64(n) + if err == nil && cw.n < 0 { + return n, errors.New("xz: counter overflow") + } + return +} + +// blockWriter is writes a single block. +type blockWriter struct { + cxz countingWriter + // mw combines io.WriteCloser w and the hash. + mw io.Writer + w io.WriteCloser + n int64 + blockSize int64 + closed bool + headerLen int + + filters []filter + hash hash.Hash +} + +// newBlockWriter creates a new block writer. +func (c *WriterConfig) newBlockWriter(xz io.Writer, hash hash.Hash) (bw *blockWriter, err error) { + bw = &blockWriter{ + cxz: countingWriter{w: xz}, + blockSize: c.BlockSize, + filters: c.filters(), + hash: hash, + } + bw.w, err = c.newFilterWriteCloser(&bw.cxz, bw.filters) + if err != nil { + return nil, err + } + bw.mw = io.MultiWriter(bw.w, bw.hash) + return bw, nil +} + +// writeHeader writes the header. If the function is called after Close +// the commpressedSize and uncompressedSize fields will be filled. +func (bw *blockWriter) writeHeader(w io.Writer) error { + h := blockHeader{ + compressedSize: -1, + uncompressedSize: -1, + filters: bw.filters, + } + if bw.closed { + h.compressedSize = bw.compressedSize() + h.uncompressedSize = bw.uncompressedSize() + } + data, err := h.MarshalBinary() + if err != nil { + return err + } + if _, err = w.Write(data); err != nil { + return err + } + bw.headerLen = len(data) + return nil +} + +// compressed size returns the amount of data written to the underlying +// stream. +func (bw *blockWriter) compressedSize() int64 { + return bw.cxz.n +} + +// uncompressedSize returns the number of data written to the +// blockWriter +func (bw *blockWriter) uncompressedSize() int64 { + return bw.n +} + +// unpaddedSize returns the sum of the header length, the uncompressed +// size of the block and the hash size. +func (bw *blockWriter) unpaddedSize() int64 { + if bw.headerLen <= 0 { + panic("xz: block header not written") + } + n := int64(bw.headerLen) + n += bw.compressedSize() + n += int64(bw.hash.Size()) + return n +} + +// record returns the record for the current stream. Call Close before +// calling this method. +func (bw *blockWriter) record() record { + return record{bw.unpaddedSize(), bw.uncompressedSize()} +} + +var errClosed = errors.New("xz: writer already closed") + +var errNoSpace = errors.New("xz: no space") + +// Write writes uncompressed data to the block writer. +func (bw *blockWriter) Write(p []byte) (n int, err error) { + if bw.closed { + return 0, errClosed + } + + t := bw.blockSize - bw.n + if int64(len(p)) > t { + err = errNoSpace + p = p[:t] + } + + var werr error + n, werr = bw.mw.Write(p) + bw.n += int64(n) + if werr != nil { + return n, werr + } + return n, err +} + +// Close closes the writer. +func (bw *blockWriter) Close() error { + if bw.closed { + return errClosed + } + bw.closed = true + if err := bw.w.Close(); err != nil { + return err + } + s := bw.hash.Size() + k := padLen(bw.cxz.n) + p := make([]byte, k+s) + bw.hash.Sum(p[k:k]) + if _, err := bw.cxz.w.Write(p); err != nil { + return err + } + return nil +}