Description: Vendor go-openapi runtime module to break circular depdency
 To complete the upload of both the go-openapi runtime and validate
 modules it's necessary to vendor the runtime module for the initial
 upload. Once both packages are in the archive this patch will be removed.
Author: Tim Potter <tpot@hpe.com>
Forwarded: no
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/.drone.sec
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/.drone.sec
@@ -0,0 +1 @@
+eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.LWdLoZr7D0nRXsFIC4Wfr_xX-1Evh5MQIakeOV4aXVqvMGMYWjAbLyXaWT0Wmwkl8ZGXzyVJGxCEJhAPiCXG-XKdxZrLjqpPc4eWuajF0CFoCoBeDNkGINmx8_4Vjq2D6C0bE2UN2lBqpUpexobdFWNVFcl7K3v-rGELr3VKa29Yp4dGkf0kjgOiaf7x6dJDXOdSo4ioNN08sfHaH1W7TYe9dl64GrSduKj_IKnLB6aA3Ckk6zOHf9AMQVpPAq-fKAMWQJgiiUGzpOPewAxmqdNZfMAt0FX_J5Jy8Rl76-rj2J8qMzKkHuWDVooS3kFHk4pEy5CVNQ2ee6PnXrhkuA.xuTULIjAQ3BCYx-9.lQ8tTXWaltPSileqAWwAPsm0ThSbIQB7bAKPN86dcm0Yq2SoStqFOH96Ut6_kGwk5S_0iO81fEybma-Xh508dTcy1IkQUaSUZ8At-GHJ69XH_r46V4hb6DbiMKBHu8pSOKuKehrEA2vr9CgHU7R_7opRrvwUJ0cQnpG_UQGSzckAowxFvgqv05ckFncTSNqRI-no7rIaPpq3ijCmvHaEfGFsmdB0i1Sy7eDMECn50qs9g88jLXQogcnZ7Dt5UUlvb9zXBt1rzAoFJiA6lrhTi9gv3CH2x1MA8X_6O4t4ob114vZmOH3R1YG4F94Yo7thd9jNivl6vu54pJRyIX1zPILHW_-KHqH6RRyywCuTU-ka0alLOlz4f9RCNBZDEZC0rk8Nf9BP8GfOO8EYMS4LgyiFv45HQzTLEvXTkkwdNKSVJfalZmMTEfFlxYcO3F9HvPpdTQjf6zB0BI9iUgMYow9seoSwPZhgo5HFffcCPME5L7pvvuSoEf7uJtDbYp46QhWIT6gTQ_GGL4z_K187Hgrqv8zddYtTqJuPQCvvddccPGLzxlA1RyUZdyrwvDII_Gwn2kChg0EM_uLMTbSee16eUaSAtx0eRnmJ0i6oPVJNIKZZHsZ7YMMwufNS6ec4fvE.VwKOnyCMKTr_b8EQdCe7Ng
\ No newline at end of file
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/.drone.yml
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/.drone.yml
@@ -0,0 +1,42 @@
+clone:
+  path: github.com/go-openapi/runtime
+
+matrix:
+  GO_VERSION:
+    - "1.6"
+
+build:
+  integration:
+    image: golang:$$GO_VERSION
+    pull: true
+    commands:
+      - go get -u github.com/axw/gocov/gocov
+      - go get -u gopkg.in/matm/v1/gocov-html
+      - go get -u github.com/cee-dub/go-junit-report
+      - go get -u github.com/stretchr/testify/assert
+      - go get -u golang.org/x/net/context
+      - go get -u gopkg.in/yaml.v2
+      - go get -u github.com/gorilla/context
+      - go get -u github.com/go-openapi/analysis
+      - go get -u github.com/go-openapi/errors
+      - go get -u github.com/go-openapi/loads
+      - go get -u github.com/go-openapi/strfmt
+      - mkdir -p /drone/src/github.com/go-openapi/validate
+      - git clone https://github.com/go-openapi/validate /drone/src/github.com/go-openapi/validate
+      - ./hack/build-drone.sh
+
+notify:
+  slack:
+    channel: bots
+    webhook_url: $$SLACK_URL
+    username: drone
+
+publish:
+  coverage:
+    server: https://coverage.vmware.run
+    token: $$GITHUB_TOKEN
+    # threshold: 70
+    # must_increase: true
+    when:
+      matrix:
+        GO_VERSION: "1.6"
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/.github/CONTRIBUTING.md
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/.github/CONTRIBUTING.md
@@ -0,0 +1,117 @@
+## Contribution Guidelines
+
+### Pull requests are always welcome
+
+We are always thrilled to receive pull requests, and do our best to
+process them as fast as possible. Not sure if that typo is worth a pull
+request? Do it! We will appreciate it.
+
+If your pull request is not accepted on the first try, don't be
+discouraged! If there's a problem with the implementation, hopefully you
+received feedback on what to improve.
+
+We're trying very hard to keep go-swagger lean and focused. We don't want it
+to do everything for everybody. This means that we might decide against
+incorporating a new feature. However, there might be a way to implement
+that feature *on top of* go-swagger.
+
+
+### Conventions
+
+Fork the repo and make changes on your fork in a feature branch:
+
+- If it's a bugfix branch, name it XXX-something where XXX is the number of the
+  issue
+- If it's a feature branch, create an enhancement issue to announce your
+  intentions, and name it XXX-something where XXX is the number of the issue.
+
+Submit unit tests for your changes.  Go has a great test framework built in; use
+it! Take a look at existing tests for inspiration. Run the full test suite on
+your branch before submitting a pull request.
+
+Update the documentation when creating or modifying features. Test
+your documentation changes for clarity, concision, and correctness, as
+well as a clean documentation build. See ``docs/README.md`` for more
+information on building the docs and how docs get released.
+
+Write clean code. Universally formatted code promotes ease of writing, reading,
+and maintenance. Always run `gofmt -s -w file.go` on each changed file before
+committing your changes. Most editors have plugins that do this automatically.
+
+Pull requests descriptions should be as clear as possible and include a
+reference to all the issues that they address.
+
+Pull requests must not contain commits from other users or branches.
+
+Commit messages must start with a capitalized and short summary (max. 50
+chars) written in the imperative, followed by an optional, more detailed
+explanatory text which is separated from the summary by an empty line.
+
+Code review comments may be added to your pull request. Discuss, then make the
+suggested modifications and push additional commits to your feature branch. Be
+sure to post a comment after pushing. The new commits will show up in the pull
+request automatically, but the reviewers will not be notified unless you
+comment.
+
+Before the pull request is merged, make sure that you squash your commits into
+logical units of work using `git rebase -i` and `git push -f`. After every
+commit the test suite should be passing. Include documentation changes in the
+same commit so that a revert would remove all traces of the feature or fix.
+
+Commits that fix or close an issue should include a reference like `Closes #XXX`
+or `Fixes #XXX`, which will automatically close the issue when merged.
+
+### Sign your work
+
+The sign-off is a simple line at the end of the explanation for the
+patch, which certifies that you wrote it or otherwise have the right to
+pass it on as an open-source patch.  The rules are pretty simple: if you
+can certify the below (from
+[developercertificate.org](http://developercertificate.org/)):
+
+```
+Developer Certificate of Origin
+Version 1.1
+
+Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
+660 York Street, Suite 102,
+San Francisco, CA 94110 USA
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+
+
+Developer's Certificate of Origin 1.1
+
+By making a contribution to this project, I certify that:
+
+(a) The contribution was created in whole or in part by me and I
+    have the right to submit it under the open source license
+    indicated in the file; or
+
+(b) The contribution is based upon previous work that, to the best
+    of my knowledge, is covered under an appropriate open source
+    license and I have the right under that license to submit that
+    work with modifications, whether created in whole or in part
+    by me, under the same open source license (unless I am
+    permitted to submit under a different license), as indicated
+    in the file; or
+
+(c) The contribution was provided directly to me by some other
+    person who certified (a), (b) or (c) and I have not modified
+    it.
+
+(d) I understand and agree that this project and the contribution
+    are public and that a record of the contribution (including all
+    personal information I submit with it, including my sign-off) is
+    maintained indefinitely and may be redistributed consistent with
+    this project or the open source license(s) involved.
+```
+
+then you just add a line to every git commit message:
+
+    Signed-off-by: Joe Smith <joe@gmail.com>
+
+using your real name (sorry, no pseudonyms or anonymous contributions.)
+
+You can add the sign off when creating the git commit via `git commit -s`.
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/.gitignore
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/.gitignore
@@ -0,0 +1 @@
+.pc
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/.pc/.quilt_patches
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/.pc/.quilt_patches
@@ -0,0 +1 @@
+debian/patches
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/.pc/.quilt_series
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/.pc/.quilt_series
@@ -0,0 +1 @@
+series
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/.pc/.version
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/.pc/.version
@@ -0,0 +1 @@
+2
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/.pullapprove.yml
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/.pullapprove.yml
@@ -0,0 +1,13 @@
+approve_by_comment: true
+approve_regex: '^(:shipit:|:\+1:|\+1|LGTM|lgtm|Approved)'
+reject_regex: ^[Rr]ejected
+reset_on_push: false
+reviewers:
+  members:
+  - casualjim
+  - chancez
+  - frapposelli
+  - vburenin
+  - pytlesk4
+  name: pullapprove
+  required: 1
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/CODE_OF_CONDUCT.md
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/CODE_OF_CONDUCT.md
@@ -0,0 +1,74 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, gender identity and expression, level of experience,
+nationality, personal appearance, race, religion, or sexual identity and
+orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic
+  address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+  professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or
+reject comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any contributor for other behaviors that they deem inappropriate,
+threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. Examples of
+representing a project or community include using an official project e-mail
+address, posting via an official social media account, or acting as an appointed
+representative at an online or offline event. Representation of a project may be
+further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting the project team at ivan+abuse@flanders.co.nz. All
+complaints will be reviewed and investigated and will result in a response that
+is deemed necessary and appropriate to the circumstances. The project team is
+obligated to maintain confidentiality with regard to the reporter of an incident.
+Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good
+faith may face temporary or permanent repercussions as determined by other
+members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
+available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/LICENSE
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/LICENSE
@@ -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.
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/README.md
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/README.md
@@ -0,0 +1,5 @@
+# runtime [![Build Status](https://ci.vmware.run/api/badges/go-openapi/runtime/status.svg)](https://ci.vmware.run/go-openapi/runtime) [![Coverage](https://coverage.vmware.run/badges/go-openapi/runtime/coverage.svg)](https://coverage.vmware.run/go-openapi/runtime) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
+
+[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/runtime/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/runtime?status.svg)](http://godoc.org/github.com/go-openapi/runtime)
+
+The runtime component for use in codegeneration or as untyped usage.
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/authinfo_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/authinfo_test.go
@@ -0,0 +1,33 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 runtime
+
+import (
+	"testing"
+
+	"github.com/go-openapi/strfmt"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestAuthInfoWriter(t *testing.T) {
+	hand := ClientAuthInfoWriterFunc(func(r ClientRequest, _ strfmt.Registry) error {
+		r.SetHeaderParam("authorization", "Bearer the-token-goes-here")
+		return nil
+	})
+
+	tr := new(trw)
+	hand.AuthenticateRequest(tr, nil)
+	assert.Equal(t, "Bearer the-token-goes-here", tr.Headers.Get("Authorization"))
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/bytestream.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/bytestream.go
@@ -0,0 +1,45 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 runtime
+
+import (
+	"errors"
+	"io"
+)
+
+// ByteStreamConsumer creates a consmer for byte streams, takes a writer and reads from the provided reader
+func ByteStreamConsumer() Consumer {
+	return ConsumerFunc(func(r io.Reader, v interface{}) error {
+		wrtr, ok := v.(io.Writer)
+		if !ok {
+			return errors.New("ByteStreamConsumer can only deal with io.Writer")
+		}
+
+		_, err := io.Copy(wrtr, r)
+		return err
+	})
+}
+
+// ByteStreamProducer creates a producer for byte streams, takes a reader, writes to a writer (essentially a pipe)
+func ByteStreamProducer() Producer {
+	return ProducerFunc(func(w io.Writer, v interface{}) error {
+		rdr, ok := v.(io.Reader)
+		if !ok {
+			return errors.New("ByteStreamProducer can only deal with io.Reader")
+		}
+		_, err := io.Copy(w, rdr)
+		return err
+	})
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/bytestream_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/bytestream_test.go
@@ -0,0 +1,30 @@
+package runtime
+
+import (
+	"bytes"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestByteStreamConsumer(t *testing.T) {
+	cons := ByteStreamConsumer()
+	expected := "the data for the stream to be sent over the wire"
+	rdr := bytes.NewBufferString(expected)
+	var in bytes.Buffer
+
+	if assert.NoError(t, cons.Consume(rdr, &in)) {
+		assert.Equal(t, expected, in.String())
+	}
+}
+
+func TestByteStreamProducer(t *testing.T) {
+	cons := ByteStreamProducer()
+	var wrtr bytes.Buffer
+	expected := "the data for the stream to be sent over the wire"
+	out := bytes.NewBufferString(expected)
+
+	if assert.NoError(t, cons.Produce(&wrtr, out)) {
+		assert.Equal(t, expected, wrtr.String())
+	}
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client/auth_info.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client/auth_info.go
@@ -0,0 +1,57 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 client
+
+import (
+	"encoding/base64"
+
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/strfmt"
+)
+
+// BasicAuth provides a basic auth info writer
+func BasicAuth(username, password string) runtime.ClientAuthInfoWriter {
+	return runtime.ClientAuthInfoWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
+		encoded := base64.StdEncoding.EncodeToString([]byte(username + ":" + password))
+		r.SetHeaderParam("Authorization", "Basic "+encoded)
+		return nil
+	})
+}
+
+// APIKeyAuth provides an API key auth info writer
+func APIKeyAuth(name, in, value string) runtime.ClientAuthInfoWriter {
+	if in == "query" {
+		return runtime.ClientAuthInfoWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
+			r.SetQueryParam(name, value)
+			return nil
+		})
+	}
+
+	if in == "header" {
+		return runtime.ClientAuthInfoWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
+			r.SetHeaderParam(name, value)
+			return nil
+		})
+	}
+	return nil
+}
+
+// BearerToken provides a header based oauth2 bearer access token auth info writer
+func BearerToken(token string) runtime.ClientAuthInfoWriter {
+	return runtime.ClientAuthInfoWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
+		r.SetHeaderParam("Authorization", "Bearer "+token)
+		return nil
+	})
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client/auth_info_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client/auth_info_test.go
@@ -0,0 +1,65 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 client
+
+import (
+	"net/http"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestBasicAuth(t *testing.T) {
+	r, _ := newRequest("GET", "/", nil)
+
+	writer := BasicAuth("someone", "with a password")
+	writer.AuthenticateRequest(r, nil)
+
+	req := new(http.Request)
+	req.Header = make(http.Header)
+	req.Header.Set("Authorization", r.header.Get("Authorization"))
+	usr, pw, ok := req.BasicAuth()
+	if assert.True(t, ok) {
+		assert.Equal(t, "someone", usr)
+		assert.Equal(t, "with a password", pw)
+	}
+}
+
+func TestAPIKeyAuth_Query(t *testing.T) {
+	r, _ := newRequest("GET", "/", nil)
+
+	writer := APIKeyAuth("api_key", "query", "the-shared-key")
+	writer.AuthenticateRequest(r, nil)
+
+	assert.Equal(t, "the-shared-key", r.query.Get("api_key"))
+}
+
+func TestAPIKeyAuth_Header(t *testing.T) {
+	r, _ := newRequest("GET", "/", nil)
+
+	writer := APIKeyAuth("x-api-token", "header", "the-shared-key")
+	writer.AuthenticateRequest(r, nil)
+
+	assert.Equal(t, "the-shared-key", r.header.Get("x-api-token"))
+}
+
+func TestBearerTokenAuth(t *testing.T) {
+	r, _ := newRequest("GET", "/", nil)
+
+	writer := BearerToken("the-shared-token")
+	writer.AuthenticateRequest(r, nil)
+
+	assert.Equal(t, "Bearer the-shared-token", r.header.Get("Authorization"))
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client/request.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client/request.go
@@ -0,0 +1,270 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 client
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"log"
+	"mime/multipart"
+	"net/http"
+	"net/url"
+	"os"
+	"path/filepath"
+	"strings"
+	"time"
+
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/strfmt"
+)
+
+// NewRequest creates a new swagger http client request
+func newRequest(method, pathPattern string, writer runtime.ClientRequestWriter) (*request, error) {
+	return &request{
+		pathPattern: pathPattern,
+		method:      method,
+		writer:      writer,
+		header:      make(http.Header),
+		query:       make(url.Values),
+		timeout:     DefaultTimeout,
+	}, nil
+}
+
+// Request represents a swagger client request.
+//
+// This Request struct converts to a HTTP request.
+// There might be others that convert to other transports.
+// There is no error checking here, it is assumed to be used after a spec has been validated.
+// so impossible combinations should not arise (hopefully).
+//
+// The main purpose of this struct is to hide the machinery of adding params to a transport request.
+// The generated code only implements what is necessary to turn a param into a valid value for these methods.
+type request struct {
+	pathPattern string
+	method      string
+	writer      runtime.ClientRequestWriter
+
+	pathParams map[string]string
+	header     http.Header
+	query      url.Values
+	formFields url.Values
+	fileFields map[string]*os.File
+	payload    interface{}
+	timeout    time.Duration
+}
+
+var (
+	// ensure interface compliance
+	_ runtime.ClientRequest = new(request)
+)
+
+// BuildHTTP creates a new http request based on the data from the params
+func (r *request) BuildHTTP(mediaType string, producers map[string]runtime.Producer, registry strfmt.Registry) (*http.Request, error) {
+	// build the data
+	if err := r.writer.WriteToRequest(r, registry); err != nil {
+		return nil, err
+	}
+
+	// create http request
+	path := r.pathPattern
+	for k, v := range r.pathParams {
+		path = strings.Replace(path, "{"+k+"}", v, -1)
+	}
+
+	var body io.ReadCloser
+	var pr *io.PipeReader
+	var pw *io.PipeWriter
+	buf := bytes.NewBuffer(nil)
+	body = ioutil.NopCloser(buf)
+	if r.fileFields != nil {
+		pr, pw = io.Pipe()
+		body = pr
+	}
+	req, err := http.NewRequest(r.method, path, body)
+	if err != nil {
+		return nil, err
+	}
+	req.URL.RawQuery = r.query.Encode()
+	req.Header = r.header
+
+	// check if this is a form type request
+	if len(r.formFields) > 0 || len(r.fileFields) > 0 {
+		// check if this is multipart
+		if len(r.fileFields) > 0 {
+			mp := multipart.NewWriter(pw)
+			req.Header.Set(runtime.HeaderContentType, mp.FormDataContentType())
+
+			go func() {
+				defer func() {
+					mp.Close()
+					pw.Close()
+				}()
+
+				for fn, v := range r.formFields {
+					if len(v) > 0 {
+						if err := mp.WriteField(fn, v[0]); err != nil {
+							pw.CloseWithError(err)
+							log.Fatal(err)
+						}
+					}
+				}
+
+				for fn, f := range r.fileFields {
+					wrtr, err := mp.CreateFormFile(fn, filepath.Base(f.Name()))
+					if err != nil {
+						pw.CloseWithError(err)
+						log.Fatal(err)
+					}
+					defer func() {
+						for _, ff := range r.fileFields {
+							ff.Close()
+						}
+
+					}()
+					if _, err := io.Copy(wrtr, f); err != nil {
+						pw.CloseWithError(err)
+						log.Fatal(err)
+					}
+				}
+
+			}()
+			return req, nil
+		} else {
+			req.Header.Set(runtime.HeaderContentType, mediaType)
+			// write the form values as the body
+			buf.WriteString(r.formFields.Encode())
+			return req, nil
+		}
+	}
+
+	// if there is payload, use the producer to write the payload, and then
+	// set the header to the content-type appropriate for the payload produced
+	if r.payload != nil {
+		// TODO: infer most appropriate content type based on the producer used,
+		// and the `consumers` section of the spec/operation
+		req.Header.Set(runtime.HeaderContentType, mediaType)
+		if rdr, ok := r.payload.(io.ReadCloser); ok {
+			req.Body = rdr
+			return req, nil
+		}
+
+		if rdr, ok := r.payload.(io.Reader); ok {
+			req.Body = ioutil.NopCloser(rdr)
+			return req, nil
+		}
+
+		// set the content length of the request or else a chunked transfer is
+		// declared, and this corrupts outgoing JSON payloads. the content's
+		// length must be set prior to the body being written per the spec at
+		// https://golang.org/pkg/net/http
+		//
+		//     If Body is present, Content-Length is <= 0 and TransferEncoding
+		//     hasn't been set to "identity", Write adds
+		//     "Transfer-Encoding: chunked" to the header. Body is closed
+		//     after it is sent.
+		//
+		// to that end a temporary buffer, b, is created to produce the payload
+		// body, and then its size is used to set the request's content length
+		var b bytes.Buffer
+		producer := producers[mediaType]
+		if err := producer.Produce(&b, r.payload); err != nil {
+			return nil, err
+		}
+		req.ContentLength = int64(b.Len())
+		if _, err := buf.Write(b.Bytes()); err != nil {
+			return nil, err
+		}
+	}
+	return req, nil
+}
+
+// SetHeaderParam adds a header param to the request
+// when there is only 1 value provided for the varargs, it will set it.
+// when there are several values provided for the varargs it will add it (no overriding)
+func (r *request) SetHeaderParam(name string, values ...string) error {
+	if r.header == nil {
+		r.header = make(http.Header)
+	}
+	r.header[http.CanonicalHeaderKey(name)] = values
+	return nil
+}
+
+// SetQueryParam adds a query param to the request
+// when there is only 1 value provided for the varargs, it will set it.
+// when there are several values provided for the varargs it will add it (no overriding)
+func (r *request) SetQueryParam(name string, values ...string) error {
+	if r.header == nil {
+		r.query = make(url.Values)
+	}
+	r.query[name] = values
+	return nil
+}
+
+// SetFormParam adds a forn param to the request
+// when there is only 1 value provided for the varargs, it will set it.
+// when there are several values provided for the varargs it will add it (no overriding)
+func (r *request) SetFormParam(name string, values ...string) error {
+	if r.formFields == nil {
+		r.formFields = make(url.Values)
+	}
+	r.formFields[name] = values
+	return nil
+}
+
+// SetPathParam adds a path param to the request
+func (r *request) SetPathParam(name string, value string) error {
+	if r.pathParams == nil {
+		r.pathParams = make(map[string]string)
+	}
+
+	r.pathParams[name] = value
+	return nil
+}
+
+// SetFileParam adds a file param to the request
+func (r *request) SetFileParam(name string, file *os.File) error {
+	fi, err := os.Stat(file.Name())
+	if err != nil {
+		return err
+	}
+	if fi.IsDir() {
+		return fmt.Errorf("%q is a directory, only files are supported", file.Name())
+	}
+
+	if r.fileFields == nil {
+		r.fileFields = make(map[string]*os.File)
+	}
+	if r.formFields == nil {
+		r.formFields = make(url.Values)
+	}
+
+	r.fileFields[name] = file
+	return nil
+}
+
+// SetBodyParam sets a body parameter on the request.
+// This does not yet serialze the object, this happens as late as possible.
+func (r *request) SetBodyParam(payload interface{}) error {
+	r.payload = payload
+	return nil
+}
+
+// SetTimeout sets the timeout for a request
+func (r *request) SetTimeout(timeout time.Duration) error {
+	r.timeout = timeout
+	return nil
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client/request_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client/request_test.go
@@ -0,0 +1,244 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 client
+
+import (
+	"encoding/json"
+	"encoding/xml"
+	"io/ioutil"
+	"mime"
+	"mime/multipart"
+	"os"
+	"path/filepath"
+	"testing"
+
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/strfmt"
+	"github.com/stretchr/testify/assert"
+)
+
+var testProducers = map[string]runtime.Producer{
+	runtime.JSONMime: runtime.JSONProducer(),
+	runtime.XMLMime:  runtime.XMLProducer(),
+	runtime.TextMime: runtime.TextProducer(),
+}
+
+func TestBuildRequest_SetHeaders(t *testing.T) {
+	r, _ := newRequest("GET", "/flats/{id}/", nil)
+	// single value
+	r.SetHeaderParam("X-Rate-Limit", "500")
+	assert.Equal(t, "500", r.header.Get("X-Rate-Limit"))
+	r.SetHeaderParam("X-Rate-Limit", "400")
+	assert.Equal(t, "400", r.header.Get("X-Rate-Limit"))
+
+	// multi value
+	r.SetHeaderParam("X-Accepts", "json", "xml", "yaml")
+	assert.EqualValues(t, []string{"json", "xml", "yaml"}, r.header["X-Accepts"])
+}
+
+func TestBuildRequest_SetPath(t *testing.T) {
+	r, _ := newRequest("GET", "/flats/{id}/?hello=world", nil)
+
+	r.SetPathParam("id", "1345")
+	assert.Equal(t, "1345", r.pathParams["id"])
+}
+
+func TestBuildRequest_SetQuery(t *testing.T) {
+	r, _ := newRequest("GET", "/flats/{id}/", nil)
+
+	// single value
+	r.SetQueryParam("hello", "there")
+	assert.Equal(t, "there", r.query.Get("hello"))
+
+	// multi value
+	r.SetQueryParam("goodbye", "cruel", "world")
+	assert.Equal(t, []string{"cruel", "world"}, r.query["goodbye"])
+}
+
+func TestBuildRequest_SetForm(t *testing.T) {
+	// non-multipart
+	r, _ := newRequest("POST", "/flats", nil)
+	r.SetFormParam("hello", "world")
+	assert.Equal(t, "world", r.formFields.Get("hello"))
+	r.SetFormParam("goodbye", "cruel", "world")
+	assert.Equal(t, []string{"cruel", "world"}, r.formFields["goodbye"])
+}
+
+func TestBuildRequest_SetFile(t *testing.T) {
+	// needs to convert form to multipart
+	r, _ := newRequest("POST", "/flats/{id}/image", nil)
+	// error if it isn't there
+	err := r.SetFileParam("not there", os.NewFile(0, "./i-dont-exist"))
+	assert.Error(t, err)
+	// error if it isn't a file
+	err = r.SetFileParam("directory", os.NewFile(0, "../client"))
+	assert.Error(t, err)
+	// success adds it to the map
+	err = r.SetFileParam("file", mustGetFile("./runtime.go"))
+	if assert.NoError(t, err) {
+		fl, ok := r.fileFields["file"]
+		if assert.True(t, ok) {
+			assert.Equal(t, "runtime.go", filepath.Base(fl.Name()))
+		}
+	}
+}
+
+func mustGetFile(path string) *os.File {
+	f, err := os.Open(path)
+	if err != nil {
+		panic(err)
+	}
+	return f
+}
+
+func TestBuildRequest_SetBody(t *testing.T) {
+	r, _ := newRequest("GET", "/flats/{id}/?hello=world", nil)
+	bd := []struct{ Name, Hobby string }{{"Tom", "Organ trail"}, {"John", "Bird watching"}}
+
+	r.SetBodyParam(bd)
+	assert.Equal(t, bd, r.payload)
+}
+
+func TestBuildRequest_BuildHTTP_Payload(t *testing.T) {
+	bd := []struct{ Name, Hobby string }{{"Tom", "Organ trail"}, {"John", "Bird watching"}}
+	reqWrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
+		req.SetBodyParam(bd)
+		req.SetQueryParam("hello", "world")
+		req.SetPathParam("id", "1234")
+		req.SetHeaderParam("X-Rate-Limit", "200")
+		return nil
+	})
+	r, _ := newRequest("GET", "/flats/{id}/", reqWrtr)
+	r.SetHeaderParam(runtime.HeaderContentType, runtime.JSONMime)
+
+	req, err := r.BuildHTTP(runtime.JSONMime, testProducers, nil)
+	if assert.NoError(t, err) && assert.NotNil(t, req) {
+		assert.Equal(t, "200", req.Header.Get("x-rate-limit"))
+		assert.Equal(t, "world", req.URL.Query().Get("hello"))
+		assert.Equal(t, "/flats/1234/", req.URL.Path)
+		expectedBody, _ := json.Marshal(bd)
+		actualBody, _ := ioutil.ReadAll(req.Body)
+		assert.Equal(t, append(expectedBody, '\n'), actualBody)
+	}
+}
+
+func TestBuildRequest_BuildHTTP_XMLPayload(t *testing.T) {
+	bd := []struct {
+		XMLName xml.Name `xml:"person"`
+		Name    string   `xml:"name"`
+		Hobby   string   `xml:"hobby"`
+	}{{xml.Name{}, "Tom", "Organ trail"}, {xml.Name{}, "John", "Bird watching"}}
+	reqWrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
+		req.SetBodyParam(bd)
+		req.SetQueryParam("hello", "world")
+		req.SetPathParam("id", "1234")
+		req.SetHeaderParam("X-Rate-Limit", "200")
+		return nil
+	})
+	r, _ := newRequest("GET", "/flats/{id}/", reqWrtr)
+	r.SetHeaderParam(runtime.HeaderContentType, runtime.XMLMime)
+
+	req, err := r.BuildHTTP(runtime.XMLMime, testProducers, nil)
+	if assert.NoError(t, err) && assert.NotNil(t, req) {
+		assert.Equal(t, "200", req.Header.Get("x-rate-limit"))
+		assert.Equal(t, "world", req.URL.Query().Get("hello"))
+		assert.Equal(t, "/flats/1234/", req.URL.Path)
+		expectedBody, _ := xml.Marshal(bd)
+		actualBody, _ := ioutil.ReadAll(req.Body)
+		assert.Equal(t, expectedBody, actualBody)
+	}
+}
+
+func TestBuildRequest_BuildHTTP_TextPayload(t *testing.T) {
+	bd := "Tom: Organ trail; John: Bird watching"
+	reqWrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
+		req.SetBodyParam(bd)
+		req.SetQueryParam("hello", "world")
+		req.SetPathParam("id", "1234")
+		req.SetHeaderParam("X-Rate-Limit", "200")
+		return nil
+	})
+	r, _ := newRequest("GET", "/flats/{id}/", reqWrtr)
+	r.SetHeaderParam(runtime.HeaderContentType, runtime.TextMime)
+
+	req, err := r.BuildHTTP(runtime.TextMime, testProducers, nil)
+	if assert.NoError(t, err) && assert.NotNil(t, req) {
+		assert.Equal(t, "200", req.Header.Get("x-rate-limit"))
+		assert.Equal(t, "world", req.URL.Query().Get("hello"))
+		assert.Equal(t, "/flats/1234/", req.URL.Path)
+		expectedBody := []byte(bd)
+		actualBody, _ := ioutil.ReadAll(req.Body)
+		assert.Equal(t, expectedBody, actualBody)
+	}
+}
+
+func TestBuildRequest_BuildHTTP_Form(t *testing.T) {
+	reqWrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
+		req.SetFormParam("something", "some value")
+		req.SetQueryParam("hello", "world")
+		req.SetPathParam("id", "1234")
+		req.SetHeaderParam("X-Rate-Limit", "200")
+		return nil
+	})
+	r, _ := newRequest("GET", "/flats/{id}/", reqWrtr)
+	r.SetHeaderParam(runtime.HeaderContentType, runtime.JSONMime)
+
+	req, err := r.BuildHTTP(runtime.JSONMime, testProducers, nil)
+	if assert.NoError(t, err) && assert.NotNil(t, req) {
+		assert.Equal(t, "200", req.Header.Get("x-rate-limit"))
+		assert.Equal(t, "world", req.URL.Query().Get("hello"))
+		assert.Equal(t, "/flats/1234/", req.URL.Path)
+		expected := []byte("something=some+value")
+		actual, _ := ioutil.ReadAll(req.Body)
+		assert.Equal(t, expected, actual)
+	}
+}
+
+func TestBuildRequest_BuildHTTP_Files(t *testing.T) {
+	cont, _ := ioutil.ReadFile("./runtime.go")
+	reqWrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
+		req.SetFormParam("something", "some value")
+		req.SetFileParam("file", mustGetFile("./runtime.go"))
+		req.SetQueryParam("hello", "world")
+		req.SetPathParam("id", "1234")
+		req.SetHeaderParam("X-Rate-Limit", "200")
+		return nil
+	})
+	r, _ := newRequest("GET", "/flats/{id}/", reqWrtr)
+	r.SetHeaderParam(runtime.HeaderContentType, runtime.JSONMime)
+	req, err := r.BuildHTTP(runtime.JSONMime, testProducers, nil)
+	if assert.NoError(t, err) && assert.NotNil(t, req) {
+		assert.Equal(t, "200", req.Header.Get("x-rate-limit"))
+		assert.Equal(t, "world", req.URL.Query().Get("hello"))
+		assert.Equal(t, "/flats/1234/", req.URL.Path)
+		mediaType, params, err := mime.ParseMediaType(req.Header.Get(runtime.HeaderContentType))
+		if assert.NoError(t, err) {
+			assert.Equal(t, runtime.MultipartFormMime, mediaType)
+			boundary := params["boundary"]
+			mr := multipart.NewReader(req.Body, boundary)
+			defer req.Body.Close()
+			frm, err := mr.ReadForm(1 << 20)
+			if assert.NoError(t, err) {
+				assert.Equal(t, "some value", frm.Value["something"][0])
+				mpff := frm.File["file"][0]
+				mpf, _ := mpff.Open()
+				defer mpf.Close()
+				assert.Equal(t, "runtime.go", mpff.Filename)
+				actual, _ := ioutil.ReadAll(mpf)
+				assert.Equal(t, cont, actual)
+			}
+		}
+	}
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client/response.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client/response.go
@@ -0,0 +1,44 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 client
+
+import (
+	"io"
+	"net/http"
+
+	"github.com/go-openapi/runtime"
+)
+
+var _ runtime.ClientResponse = response{}
+
+type response struct {
+	resp *http.Response
+}
+
+func (r response) Code() int {
+	return r.resp.StatusCode
+}
+
+func (r response) Message() string {
+	return r.resp.Status
+}
+
+func (r response) GetHeader(name string) string {
+	return r.resp.Header.Get(name)
+}
+
+func (r response) Body() io.ReadCloser {
+	return r.resp.Body
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client/response_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client/response_test.go
@@ -0,0 +1,40 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 client
+
+import (
+	"bytes"
+	"io/ioutil"
+	"net/http"
+	"testing"
+
+	"github.com/go-openapi/runtime"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestResponse(t *testing.T) {
+	under := new(http.Response)
+	under.Status = "the status message"
+	under.StatusCode = 392
+	under.Header = make(http.Header)
+	under.Header.Set("Blah", "blah blah")
+	under.Body = ioutil.NopCloser(bytes.NewBufferString("some content"))
+
+	var resp runtime.ClientResponse = response{under}
+	assert.EqualValues(t, under.StatusCode, resp.Code())
+	assert.Equal(t, under.Status, resp.Message())
+	assert.Equal(t, "blah blah", resp.GetHeader("blah"))
+	assert.Equal(t, under.Body, resp.Body())
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client/runtime.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client/runtime.go
@@ -0,0 +1,219 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 client
+
+import (
+	"fmt"
+	"mime"
+	"net/http"
+	"net/http/httputil"
+	"os"
+	"path"
+	"strings"
+	"sync"
+	"time"
+
+	"golang.org/x/net/context"
+	"golang.org/x/net/context/ctxhttp"
+
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/strfmt"
+)
+
+// DefaultTimeout the default request timeout
+var DefaultTimeout = 30 * time.Second
+
+// Runtime represents an API client that uses the transport
+// to make http requests based on a swagger specification.
+type Runtime struct {
+	DefaultMediaType      string
+	DefaultAuthentication runtime.ClientAuthInfoWriter
+	Consumers             map[string]runtime.Consumer
+	Producers             map[string]runtime.Producer
+
+	Transport http.RoundTripper
+	Jar       http.CookieJar
+	//Spec      *spec.Document
+	Host     string
+	BasePath string
+	Formats  strfmt.Registry
+	Debug    bool
+	Context  context.Context
+
+	clientOnce *sync.Once
+	client     *http.Client
+	schemes    []string
+}
+
+// New creates a new default runtime for a swagger api runtime.Client
+func New(host, basePath string, schemes []string) *Runtime {
+	var rt Runtime
+	rt.DefaultMediaType = runtime.JSONMime
+
+	// TODO: actually infer this stuff from the spec
+	rt.Consumers = map[string]runtime.Consumer{
+		runtime.JSONMime: runtime.JSONConsumer(),
+		runtime.XMLMime:  runtime.XMLConsumer(),
+		runtime.TextMime: runtime.TextConsumer(),
+	}
+	rt.Producers = map[string]runtime.Producer{
+		runtime.JSONMime: runtime.JSONProducer(),
+		runtime.XMLMime:  runtime.XMLProducer(),
+		runtime.TextMime: runtime.TextProducer(),
+	}
+	rt.Transport = http.DefaultTransport
+	rt.Jar = nil
+	rt.Host = host
+	rt.BasePath = basePath
+	rt.Context = context.Background()
+	rt.clientOnce = new(sync.Once)
+	if !strings.HasPrefix(rt.BasePath, "/") {
+		rt.BasePath = "/" + rt.BasePath
+	}
+	rt.Debug = os.Getenv("DEBUG") == "1"
+	if len(schemes) > 0 {
+		rt.schemes = schemes
+	}
+	return &rt
+}
+
+func (r *Runtime) pickScheme(schemes []string) string {
+	if v := r.selectScheme(r.schemes); v != "" {
+		return v
+	}
+	if v := r.selectScheme(schemes); v != "" {
+		return v
+	}
+	return "http"
+}
+
+func (r *Runtime) selectScheme(schemes []string) string {
+	schLen := len(schemes)
+	if schLen == 0 {
+		return ""
+	}
+
+	scheme := schemes[0]
+	// prefer https, but skip when not possible
+	if scheme != "https" && schLen > 1 {
+		for _, sch := range schemes {
+			if sch == "https" {
+				scheme = sch
+				break
+			}
+		}
+	}
+	return scheme
+}
+
+// Submit a request and when there is a body on success it will turn that into the result
+// all other things are turned into an api error for swagger which retains the status code
+func (r *Runtime) Submit(operation *runtime.ClientOperation) (interface{}, error) {
+	params, readResponse, auth := operation.Params, operation.Reader, operation.AuthInfo
+
+	request, err := newRequest(operation.Method, operation.PathPattern, params)
+	if err != nil {
+		return nil, err
+	}
+
+	var accept []string
+	for _, mimeType := range operation.ProducesMediaTypes {
+		accept = append(accept, mimeType)
+	}
+	request.SetHeaderParam(runtime.HeaderAccept, accept...)
+
+	if auth == nil && r.DefaultAuthentication != nil {
+		auth = r.DefaultAuthentication
+	}
+	if auth != nil {
+		if err := auth.AuthenticateRequest(request, r.Formats); err != nil {
+			return nil, err
+		}
+	}
+
+	// TODO: pick appropriate media type
+	cmt := r.DefaultMediaType
+	if len(operation.ConsumesMediaTypes) > 0 {
+		cmt = operation.ConsumesMediaTypes[0]
+	}
+
+	req, err := request.BuildHTTP(cmt, r.Producers, r.Formats)
+	if err != nil {
+		return nil, err
+	}
+	req.URL.Scheme = r.pickScheme(operation.Schemes)
+	req.URL.Host = r.Host
+	var reinstateSlash bool
+	if req.URL.Path != "" && req.URL.Path != "/" && req.URL.Path[len(req.URL.Path)-1] == '/' {
+		reinstateSlash = true
+	}
+	req.URL.Path = path.Join(r.BasePath, req.URL.Path)
+	if reinstateSlash {
+		req.URL.Path = req.URL.Path + "/"
+	}
+
+	r.clientOnce.Do(func() {
+		r.client = &http.Client{
+			Transport: r.Transport,
+			Jar:       r.Jar,
+		}
+	})
+
+	if r.Debug {
+		b, err2 := httputil.DumpRequestOut(req, true)
+		if err2 != nil {
+			return nil, err2
+		}
+		fmt.Println(string(b))
+	}
+
+	pctx := r.Context
+	if pctx == nil {
+		pctx = context.Background()
+	}
+	ctx, cancel := context.WithTimeout(pctx, request.timeout)
+	defer cancel()
+
+	res, err := ctxhttp.Do(ctx, r.client, req) // make requests, by default follows 10 redirects before failing
+	if err != nil {
+		return nil, err
+	}
+	defer res.Body.Close()
+
+	if r.Debug {
+		b, err2 := httputil.DumpResponse(res, true)
+		if err2 != nil {
+			return nil, err2
+		}
+		fmt.Println(string(b))
+	}
+
+	ct := res.Header.Get(runtime.HeaderContentType)
+	if ct == "" { // this should really really never occur
+		ct = r.DefaultMediaType
+	}
+
+	mt, _, err := mime.ParseMediaType(ct)
+	if err != nil {
+		return nil, fmt.Errorf("parse content type: %s", err)
+	}
+
+	cons, ok := r.Consumers[mt]
+	if !ok {
+		// scream about not knowing what to do
+		return nil, fmt.Errorf("no consumer: %q", ct)
+	}
+	return readResponse.ReadResponse(response{res}, cons)
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client/runtime_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client/runtime_test.go
@@ -0,0 +1,630 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 client
+
+import (
+	"bytes"
+	"encoding/json"
+	"encoding/xml"
+	"errors"
+	"io/ioutil"
+	"net/http"
+	"net/http/cookiejar"
+	"net/http/httptest"
+	"net/url"
+	"testing"
+	"time"
+
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/strfmt"
+	"github.com/stretchr/testify/assert"
+)
+
+// task This describes a task. Tasks require a content property to be set.
+type task struct {
+
+	// Completed
+	Completed bool `json:"completed" xml:"completed"`
+
+	// Content Task content can contain [GFM](https://help.github.com/articles/github-flavored-markdown/).
+	Content string `json:"content" xml:"content"`
+
+	// ID This id property is autogenerated when a task is created.
+	ID int64 `json:"id" xml:"id"`
+}
+
+func TestRuntime_Concurrent(t *testing.T) {
+	// test that it can make a simple request
+	// and get the response for it.
+	// defaults all the way down
+	result := []task{
+		{false, "task 1 content", 1},
+		{false, "task 2 content", 2},
+	}
+	server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
+		rw.Header().Add(runtime.HeaderContentType, runtime.JSONMime)
+		rw.WriteHeader(http.StatusOK)
+		jsongen := json.NewEncoder(rw)
+		jsongen.Encode(result)
+	}))
+	defer server.Close()
+
+	rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
+		return nil
+	})
+
+	hu, _ := url.Parse(server.URL)
+	rt := New(hu.Host, "/", []string{"http"})
+	resCC := make(chan interface{})
+	errCC := make(chan error)
+	var res interface{}
+	var err error
+
+	for j := 0; j < 6; j++ {
+		go func() {
+			resC := make(chan interface{})
+			errC := make(chan error)
+
+			go func() {
+				var resp interface{}
+				var errp error
+				for i := 0; i < 3; i++ {
+					resp, errp = rt.Submit(&runtime.ClientOperation{
+						ID:          "getTasks",
+						Method:      "GET",
+						PathPattern: "/",
+						Params:      rwrtr,
+						Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
+							if response.Code() == 200 {
+								var result []task
+								if err := consumer.Consume(response.Body(), &result); err != nil {
+									return nil, err
+								}
+								return result, nil
+							}
+							return nil, errors.New("Generic error")
+						}),
+					})
+					<-time.After(100 * time.Millisecond)
+				}
+				resC <- resp
+				errC <- errp
+			}()
+			resCC <- <-resC
+			errCC <- <-errC
+		}()
+	}
+
+	c := 6
+	for c > 0 {
+		res = <-resCC
+		err = <-errCC
+		c--
+	}
+
+	if assert.NoError(t, err) {
+		assert.IsType(t, []task{}, res)
+		actual := res.([]task)
+		assert.EqualValues(t, result, actual)
+	}
+}
+
+func TestRuntime_Canary(t *testing.T) {
+	// test that it can make a simple request
+	// and get the response for it.
+	// defaults all the way down
+	result := []task{
+		{false, "task 1 content", 1},
+		{false, "task 2 content", 2},
+	}
+	server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
+		rw.Header().Add(runtime.HeaderContentType, runtime.JSONMime)
+		rw.WriteHeader(http.StatusOK)
+		jsongen := json.NewEncoder(rw)
+		jsongen.Encode(result)
+	}))
+	defer server.Close()
+
+	rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
+		return nil
+	})
+
+	hu, _ := url.Parse(server.URL)
+	rt := New(hu.Host, "/", []string{"http"})
+	res, err := rt.Submit(&runtime.ClientOperation{
+		ID:          "getTasks",
+		Method:      "GET",
+		PathPattern: "/",
+		Params:      rwrtr,
+		Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
+			if response.Code() == 200 {
+				var result []task
+				if err := consumer.Consume(response.Body(), &result); err != nil {
+					return nil, err
+				}
+				return result, nil
+			}
+			return nil, errors.New("Generic error")
+		}),
+	})
+
+	if assert.NoError(t, err) {
+		assert.IsType(t, []task{}, res)
+		actual := res.([]task)
+		assert.EqualValues(t, result, actual)
+	}
+}
+
+type tasks struct {
+	Tasks []task `xml:"task"`
+}
+
+func TestRuntime_XMLCanary(t *testing.T) {
+	// test that it can make a simple XML request
+	// and get the response for it.
+	result := tasks{
+		Tasks: []task{
+			{false, "task 1 content", 1},
+			{false, "task 2 content", 2},
+		},
+	}
+	server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
+		rw.Header().Add(runtime.HeaderContentType, runtime.XMLMime)
+		rw.WriteHeader(http.StatusOK)
+		xmlgen := xml.NewEncoder(rw)
+		xmlgen.Encode(result)
+	}))
+	defer server.Close()
+
+	rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
+		return nil
+	})
+
+	hu, _ := url.Parse(server.URL)
+	rt := New(hu.Host, "/", []string{"http"})
+	res, err := rt.Submit(&runtime.ClientOperation{
+		ID:          "getTasks",
+		Method:      "GET",
+		PathPattern: "/",
+		Params:      rwrtr,
+		Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
+			if response.Code() == 200 {
+				var result tasks
+				if err := consumer.Consume(response.Body(), &result); err != nil {
+					return nil, err
+				}
+				return result, nil
+			}
+			return nil, errors.New("Generic error")
+		}),
+	})
+
+	if assert.NoError(t, err) {
+		assert.IsType(t, tasks{}, res)
+		actual := res.(tasks)
+		assert.EqualValues(t, result, actual)
+	}
+}
+
+func TestRuntime_TextCanary(t *testing.T) {
+	// test that it can make a simple text request
+	// and get the response for it.
+	result := "1: task 1 content; 2: task 2 content"
+	server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
+		rw.Header().Add(runtime.HeaderContentType, runtime.TextMime)
+		rw.WriteHeader(http.StatusOK)
+		rw.Write([]byte(result))
+	}))
+	defer server.Close()
+
+	rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
+		return nil
+	})
+
+	hu, _ := url.Parse(server.URL)
+	rt := New(hu.Host, "/", []string{"http"})
+	res, err := rt.Submit(&runtime.ClientOperation{
+		ID:          "getTasks",
+		Method:      "GET",
+		PathPattern: "/",
+		Params:      rwrtr,
+		Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
+			if response.Code() == 200 {
+				var result string
+				if err := consumer.Consume(response.Body(), &result); err != nil {
+					return nil, err
+				}
+				return result, nil
+			}
+			return nil, errors.New("Generic error")
+		}),
+	})
+
+	if assert.NoError(t, err) {
+		assert.IsType(t, "", res)
+		actual := res.(string)
+		assert.EqualValues(t, result, actual)
+	}
+}
+
+type roundTripperFunc func(*http.Request) (*http.Response, error)
+
+func (fn roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error) {
+	return fn(req)
+}
+
+func TestRuntime_CustomTransport(t *testing.T) {
+	rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
+		return nil
+	})
+	result := []task{
+		{false, "task 1 content", 1},
+		{false, "task 2 content", 2},
+	}
+
+	rt := New("localhost:3245", "/", []string{"ws", "wss", "https"})
+	rt.Transport = roundTripperFunc(func(req *http.Request) (*http.Response, error) {
+		if req.URL.Scheme != "https" {
+			return nil, errors.New("this was not a https request")
+		}
+		var resp http.Response
+		resp.StatusCode = 200
+		resp.Header = make(http.Header)
+		resp.Header.Set("content-type", "application/json")
+		buf := bytes.NewBuffer(nil)
+		enc := json.NewEncoder(buf)
+		enc.Encode(result)
+		resp.Body = ioutil.NopCloser(buf)
+		return &resp, nil
+	})
+
+	res, err := rt.Submit(&runtime.ClientOperation{
+		ID:          "getTasks",
+		Method:      "GET",
+		PathPattern: "/",
+		Schemes:     []string{"ws", "wss", "https"},
+		Params:      rwrtr,
+		Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
+			if response.Code() == 200 {
+				var result []task
+				if err := consumer.Consume(response.Body(), &result); err != nil {
+					return nil, err
+				}
+				return result, nil
+			}
+			return nil, errors.New("Generic error")
+		}),
+	})
+
+	if assert.NoError(t, err) {
+		assert.IsType(t, []task{}, res)
+		actual := res.([]task)
+		assert.EqualValues(t, result, actual)
+	}
+}
+
+func TestRuntime_CustomCookieJar(t *testing.T) {
+	server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
+		authenticated := false
+		for _, cookie := range req.Cookies() {
+			if cookie.Name == "sessionid" && cookie.Value == "abc" {
+				authenticated = true
+			}
+		}
+		if !authenticated {
+			username, password, ok := req.BasicAuth()
+			if ok && username == "username" && password == "password" {
+				authenticated = true
+				http.SetCookie(rw, &http.Cookie{Name: "sessionid", Value: "abc"})
+			}
+		}
+		if authenticated {
+			rw.Header().Add(runtime.HeaderContentType, runtime.JSONMime)
+			rw.WriteHeader(http.StatusOK)
+			jsongen := json.NewEncoder(rw)
+			jsongen.Encode([]task{})
+		} else {
+			rw.WriteHeader(http.StatusUnauthorized)
+		}
+	}))
+	defer server.Close()
+
+	rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
+		return nil
+	})
+
+	hu, _ := url.Parse(server.URL)
+	rt := New(hu.Host, "/", []string{"http"})
+	rt.Jar, _ = cookiejar.New(nil)
+
+	submit := func(authInfo runtime.ClientAuthInfoWriter) {
+		_, err := rt.Submit(&runtime.ClientOperation{
+			ID:          "getTasks",
+			Method:      "GET",
+			PathPattern: "/",
+			Params:      rwrtr,
+			AuthInfo:    authInfo,
+			Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
+				if response.Code() == 200 {
+					return nil, nil
+				}
+				return nil, errors.New("Generic error")
+			}),
+		})
+
+		assert.NoError(t, err)
+	}
+
+	submit(BasicAuth("username", "password"))
+	submit(nil)
+}
+
+func TestRuntime_AuthCanary(t *testing.T) {
+	// test that it can make a simple request
+	// and get the response for it.
+	// defaults all the way down
+	result := []task{
+		{false, "task 1 content", 1},
+		{false, "task 2 content", 2},
+	}
+	server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
+		if req.Header.Get("Authorization") != "Bearer the-super-secret-token" {
+			rw.WriteHeader(400)
+			return
+		}
+		rw.Header().Add(runtime.HeaderContentType, runtime.JSONMime)
+		rw.WriteHeader(http.StatusOK)
+		jsongen := json.NewEncoder(rw)
+		jsongen.Encode(result)
+	}))
+	defer server.Close()
+
+	rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
+		return nil
+	})
+
+	hu, _ := url.Parse(server.URL)
+
+	rt := New(hu.Host, "/", []string{"http"})
+	res, err := rt.Submit(&runtime.ClientOperation{
+		ID:     "getTasks",
+		Params: rwrtr,
+		Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
+			if response.Code() == 200 {
+				var result []task
+				if err := consumer.Consume(response.Body(), &result); err != nil {
+					return nil, err
+				}
+				return result, nil
+			}
+			return nil, errors.New("Generic error")
+		}),
+		AuthInfo: BearerToken("the-super-secret-token"),
+	})
+
+	if assert.NoError(t, err) {
+		assert.IsType(t, []task{}, res)
+		actual := res.([]task)
+		assert.EqualValues(t, result, actual)
+	}
+}
+
+func TestRuntime_PickConsumer(t *testing.T) {
+	result := []task{
+		{false, "task 1 content", 1},
+		{false, "task 2 content", 2},
+	}
+	server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
+		if req.Header.Get("Content-Type") != "application/octet-stream" {
+			rw.Header().Add(runtime.HeaderContentType, runtime.JSONMime+";charset=utf-8")
+			rw.WriteHeader(400)
+			return
+		}
+		rw.Header().Add(runtime.HeaderContentType, runtime.JSONMime+";charset=utf-8")
+		rw.WriteHeader(http.StatusOK)
+		jsongen := json.NewEncoder(rw)
+		jsongen.Encode(result)
+	}))
+	defer server.Close()
+
+	rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
+		req.SetBodyParam(bytes.NewBufferString("hello"))
+		return nil
+	})
+
+	hu, _ := url.Parse(server.URL)
+	rt := New(hu.Host, "/", []string{"http"})
+	res, err := rt.Submit(&runtime.ClientOperation{
+		ID:                 "getTasks",
+		Method:             "POST",
+		PathPattern:        "/",
+		Schemes:            []string{"http"},
+		ConsumesMediaTypes: []string{"application/octet-stream"},
+		Params:             rwrtr,
+		Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
+			if response.Code() == 200 {
+				var result []task
+				if err := consumer.Consume(response.Body(), &result); err != nil {
+					return nil, err
+				}
+				return result, nil
+			}
+			return nil, errors.New("Generic error")
+		}),
+		AuthInfo: BearerToken("the-super-secret-token"),
+	})
+
+	if assert.NoError(t, err) {
+		assert.IsType(t, []task{}, res)
+		actual := res.([]task)
+		assert.EqualValues(t, result, actual)
+	}
+}
+
+func TestRuntime_ContentTypeCanary(t *testing.T) {
+	// test that it can make a simple request
+	// and get the response for it.
+	// defaults all the way down
+	result := []task{
+		{false, "task 1 content", 1},
+		{false, "task 2 content", 2},
+	}
+	server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
+		if req.Header.Get("Authorization") != "Bearer the-super-secret-token" {
+			rw.WriteHeader(400)
+			return
+		}
+		rw.Header().Add(runtime.HeaderContentType, runtime.JSONMime+";charset=utf-8")
+		rw.WriteHeader(http.StatusOK)
+		jsongen := json.NewEncoder(rw)
+		jsongen.Encode(result)
+	}))
+	defer server.Close()
+
+	rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
+		return nil
+	})
+
+	hu, _ := url.Parse(server.URL)
+	rt := New(hu.Host, "/", []string{"http"})
+	res, err := rt.Submit(&runtime.ClientOperation{
+		ID:          "getTasks",
+		Method:      "GET",
+		PathPattern: "/",
+		Schemes:     []string{"http"},
+		Params:      rwrtr,
+		Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
+			if response.Code() == 200 {
+				var result []task
+				if err := consumer.Consume(response.Body(), &result); err != nil {
+					return nil, err
+				}
+				return result, nil
+			}
+			return nil, errors.New("Generic error")
+		}),
+		AuthInfo: BearerToken("the-super-secret-token"),
+	})
+
+	if assert.NoError(t, err) {
+		assert.IsType(t, []task{}, res)
+		actual := res.([]task)
+		assert.EqualValues(t, result, actual)
+	}
+}
+
+func TestRuntime_ChunkedResponse(t *testing.T) {
+	// test that it can make a simple request
+	// and get the response for it.
+	// defaults all the way down
+	result := []task{
+		{false, "task 1 content", 1},
+		{false, "task 2 content", 2},
+	}
+	server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
+		if req.Header.Get("Authorization") != "Bearer the-super-secret-token" {
+			rw.WriteHeader(400)
+			return
+		}
+		rw.Header().Add(runtime.HeaderTransferEncoding, "chunked")
+		rw.Header().Add(runtime.HeaderContentType, runtime.JSONMime+";charset=utf-8")
+		rw.WriteHeader(http.StatusOK)
+		jsongen := json.NewEncoder(rw)
+		jsongen.Encode(result)
+	}))
+	defer server.Close()
+
+	rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
+		return nil
+	})
+
+	//specDoc, err := spec.Load("../../fixtures/codegen/todolist.simple.yml")
+	hu, _ := url.Parse(server.URL)
+
+	rt := New(hu.Host, "/", []string{"http"})
+	res, err := rt.Submit(&runtime.ClientOperation{
+		ID:          "getTasks",
+		Method:      "GET",
+		PathPattern: "/",
+		Schemes:     []string{"http"},
+		Params:      rwrtr,
+		Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
+			if response.Code() == 200 {
+				var result []task
+				if err := consumer.Consume(response.Body(), &result); err != nil {
+					return nil, err
+				}
+				return result, nil
+			}
+			return nil, errors.New("Generic error")
+		}),
+		AuthInfo: BearerToken("the-super-secret-token"),
+	})
+
+	if assert.NoError(t, err) {
+		assert.IsType(t, []task{}, res)
+		actual := res.([]task)
+		assert.EqualValues(t, result, actual)
+	}
+}
+
+func TestRuntime_OverrideScheme(t *testing.T) {
+	runtime := New("", "/", []string{"https"})
+	sch := runtime.pickScheme([]string{"http"})
+	assert.Equal(t, "https", sch)
+}
+
+func TestRuntime_PreserveTrailingSlash(t *testing.T) {
+	var redirected bool
+
+	server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
+		rw.Header().Add(runtime.HeaderContentType, runtime.JSONMime+";charset=utf-8")
+
+		if req.URL.Path == "/api/tasks" {
+			redirected = true
+			return
+		}
+		if req.URL.Path == "/api/tasks/" {
+			rw.WriteHeader(http.StatusOK)
+		}
+	}))
+	defer server.Close()
+
+	hu, _ := url.Parse(server.URL)
+
+	rt := New(hu.Host, "/", []string{"http"})
+
+	rwrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
+		return nil
+	})
+
+	_, err := rt.Submit(&runtime.ClientOperation{
+		ID:          "getTasks",
+		Method:      "GET",
+		PathPattern: "/api/tasks/",
+		Params:      rwrtr,
+		Reader: runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
+			if redirected {
+				return nil, errors.New("expected Submit to preserve trailing slashes - this caused a redirect")
+			}
+			if response.Code() == http.StatusOK {
+				return nil, nil
+			}
+			return nil, errors.New("Generic error")
+		}),
+	})
+
+	assert.NoError(t, err)
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client_auth_info.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client_auth_info.go
@@ -0,0 +1,30 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 runtime
+
+import "github.com/go-openapi/strfmt"
+
+// A ClientAuthInfoWriterFunc converts a function to a request writer interface
+type ClientAuthInfoWriterFunc func(ClientRequest, strfmt.Registry) error
+
+// AuthenticateRequest adds authentication data to the request
+func (fn ClientAuthInfoWriterFunc) AuthenticateRequest(req ClientRequest, reg strfmt.Registry) error {
+	return fn(req, reg)
+}
+
+// A ClientAuthInfoWriter implementor knows how to write authentication info to a request
+type ClientAuthInfoWriter interface {
+	AuthenticateRequest(ClientRequest, strfmt.Registry) error
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client_operation.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client_operation.go
@@ -0,0 +1,34 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 runtime
+
+// ClientOperation represents the context for a swagger operation to be submitted to the transport
+type ClientOperation struct {
+	ID                 string
+	Method             string
+	PathPattern        string
+	ProducesMediaTypes []string
+	ConsumesMediaTypes []string
+	Schemes            []string
+	AuthInfo           ClientAuthInfoWriter
+	Params             ClientRequestWriter
+	Reader             ClientResponseReader
+}
+
+// A ClientTransport implementor knows how to submit Request objects to some destination
+type ClientTransport interface {
+	//Submit(string, RequestWriter, ResponseReader, AuthInfoWriter) (interface{}, error)
+	Submit(*ClientOperation) (interface{}, error)
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client_request.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client_request.go
@@ -0,0 +1,53 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 runtime
+
+import (
+	"os"
+	"time"
+
+	"github.com/go-openapi/strfmt"
+)
+
+// ClientRequestWriterFunc converts a function to a request writer interface
+type ClientRequestWriterFunc func(ClientRequest, strfmt.Registry) error
+
+// WriteToRequest adds data to the request
+func (fn ClientRequestWriterFunc) WriteToRequest(req ClientRequest, reg strfmt.Registry) error {
+	return fn(req, reg)
+}
+
+// ClientRequestWriter is an interface for things that know how to write to a request
+type ClientRequestWriter interface {
+	WriteToRequest(ClientRequest, strfmt.Registry) error
+}
+
+// ClientRequest is an interface for things that know how to
+// add information to a swagger client request
+type ClientRequest interface {
+	SetHeaderParam(string, ...string) error
+
+	SetQueryParam(string, ...string) error
+
+	SetFormParam(string, ...string) error
+
+	SetPathParam(string, string) error
+
+	SetFileParam(string, *os.File) error
+
+	SetBodyParam(interface{}) error
+
+	SetTimeout(time.Duration) error
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client_request_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client_request_test.go
@@ -0,0 +1,69 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 runtime
+
+import (
+	"net/http"
+	"os"
+	"testing"
+	"time"
+
+	"github.com/go-openapi/strfmt"
+	"github.com/stretchr/testify/assert"
+)
+
+type trw struct {
+	Headers http.Header
+	Body    interface{}
+}
+
+func (t *trw) SetHeaderParam(name string, values ...string) error {
+	if t.Headers == nil {
+		t.Headers = make(http.Header)
+	}
+	t.Headers.Set(name, values[0])
+	return nil
+}
+
+func (t *trw) SetQueryParam(_ string, _ ...string) error { return nil }
+
+func (t *trw) SetFormParam(_ string, _ ...string) error { return nil }
+
+func (t *trw) SetPathParam(_ string, _ string) error { return nil }
+
+func (t *trw) SetFileParam(_ string, _ *os.File) error { return nil }
+
+func (t *trw) SetBodyParam(body interface{}) error {
+	t.Body = body
+	return nil
+}
+
+func (t *trw) SetTimeout(timeout time.Duration) error {
+	return nil
+}
+
+func TestRequestWriterFunc(t *testing.T) {
+
+	hand := ClientRequestWriterFunc(func(r ClientRequest, reg strfmt.Registry) error {
+		r.SetHeaderParam("blah", "blah blah")
+		r.SetBodyParam(struct{ Name string }{"Adriana"})
+		return nil
+	})
+
+	tr := new(trw)
+	hand.WriteToRequest(tr, nil)
+	assert.Equal(t, "blah blah", tr.Headers.Get("blah"))
+	assert.Equal(t, "Adriana", tr.Body.(struct{ Name string }).Name)
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client_response.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client_response.go
@@ -0,0 +1,63 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 runtime
+
+import (
+	"fmt"
+	"io"
+)
+
+// A ClientResponse represents a client response
+// This bridges between responses obtained from different transports
+type ClientResponse interface {
+	Code() int
+	Message() string
+	GetHeader(string) string
+	Body() io.ReadCloser
+}
+
+// A ClientResponseReaderFunc turns a function into a ClientResponseReader interface implementation
+type ClientResponseReaderFunc func(ClientResponse, Consumer) (interface{}, error)
+
+// ReadResponse reads the response
+func (read ClientResponseReaderFunc) ReadResponse(resp ClientResponse, consumer Consumer) (interface{}, error) {
+	return read(resp, consumer)
+}
+
+// A ClientResponseReader is an interface for things want to read a response.
+// An application of this is to create structs from response values
+type ClientResponseReader interface {
+	ReadResponse(ClientResponse, Consumer) (interface{}, error)
+}
+
+// NewAPIError creates a new API error
+func NewAPIError(opName string, payload interface{}, code int) *APIError {
+	return &APIError{
+		OperationName: opName,
+		Response:      payload,
+		Code:          code,
+	}
+}
+
+// APIError wraps an error model and captures the status code
+type APIError struct {
+	OperationName string
+	Response      interface{}
+	Code          int
+}
+
+func (a *APIError) Error() string {
+	return fmt.Sprintf("%s (status %d): %+v ", a.OperationName, a.Code, a.Response)
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client_response_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/client_response_test.go
@@ -0,0 +1,60 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 runtime
+
+import (
+	"bytes"
+	"io"
+	"io/ioutil"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+type response struct {
+}
+
+func (r response) Code() int {
+	return 490
+}
+func (r response) Message() string {
+	return "the message"
+}
+func (r response) GetHeader(_ string) string {
+	return "the header"
+}
+func (r response) Body() io.ReadCloser {
+	return ioutil.NopCloser(bytes.NewBufferString("the content"))
+}
+
+func TestResponseReaderFunc(t *testing.T) {
+	var actual struct {
+		Header, Message, Body string
+		Code                  int
+	}
+	reader := ClientResponseReaderFunc(func(r ClientResponse, _ Consumer) (interface{}, error) {
+		b, _ := ioutil.ReadAll(r.Body())
+		actual.Body = string(b)
+		actual.Code = r.Code()
+		actual.Message = r.Message()
+		actual.Header = r.GetHeader("blah")
+		return actual, nil
+	})
+	reader.ReadResponse(response{}, nil)
+	assert.Equal(t, "the content", actual.Body)
+	assert.Equal(t, "the message", actual.Message)
+	assert.Equal(t, "the header", actual.Header)
+	assert.Equal(t, 490, actual.Code)
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/constants.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/constants.go
@@ -0,0 +1,41 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 runtime
+
+const (
+	// HeaderContentType represents a http content-type header, it's value is supposed to be a mime type
+	HeaderContentType = "Content-Type"
+
+	// HeaderTransferEncoding represents a http transfer-encoding header.
+	HeaderTransferEncoding = "Transfer-Encoding"
+
+	// HeaderAccept the Accept header
+	HeaderAccept = "Accept"
+
+	charsetKey = "charset"
+
+	// DefaultMime the default fallback mime type
+	DefaultMime = "application/octet-stream"
+	// JSONMime the json mime type
+	JSONMime = "application/json"
+	// YAMLMime the yaml mime type
+	YAMLMime = "application/x-yaml"
+	// XMLMime the xml mime type
+	XMLMime = "application/xml"
+	// TextMime the text mime type
+	TextMime = "text/plain"
+	// MultipartFormMime the multipart form mime type
+	MultipartFormMime = "multipart/form-data"
+)
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/discard.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/discard.go
@@ -0,0 +1,9 @@
+package runtime
+
+import "io"
+
+// DiscardConsumer does absolutely nothing, it's a black hole.
+var DiscardConsumer = ConsumerFunc(func(_ io.Reader, _ interface{}) error { return nil })
+
+// DiscardProducer does absolutely nothing, it's a black hole.
+var DiscardProducer = ProducerFunc(func(_ io.Writer, _ interface{}) error { return nil })
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/fixtures/bugs/264/swagger.yml
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/fixtures/bugs/264/swagger.yml
@@ -0,0 +1,21 @@
+swagger: '2.0'
+info:
+  version: 1.0.0
+  title: 'Test'
+schemes:
+  - http
+produces:
+  - application/json
+consumes:
+  - application/json
+paths:
+  /key/{id}:
+    delete:
+      parameters:
+        - name: id
+          in: path
+          type: integer
+          required: true
+      responses:
+        '200':
+          description: OK
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/hack/build-drone.sh
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/hack/build-drone.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+set -e -o pipefail
+
+ mkdir -p /drone/{testresults,coverage,dist}
+ go test -race -timeout 20m -v ./... | go-junit-report -dir /drone/testresults
+
+# Run test coverage on each subdirectories and merge the coverage profile.
+echo "mode: ${GOCOVMODE-count}" > profile.cov
+
+# Standard go tooling behavior is to ignore dirs with leading underscores
+# skip generator for race detection and coverage
+for dir in $(go list ./...)
+do
+  pth="$GOPATH/src/$dir"
+  go test -covermode=${GOCOVMODE-count} -coverprofile=${pth}/profile.out $dir
+  if [ -f $pth/profile.out ]
+  then
+      cat $pth/profile.out | tail -n +2 >> profile.cov
+      # rm $pth/profile.out
+  fi
+done
+
+go tool cover -func profile.cov
+gocov convert profile.cov | gocov report
+gocov convert profile.cov | gocov-html > /drone/coverage/coverage-${CI_BUILD_NUM-"0"}.html
\ No newline at end of file
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/headers.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/headers.go
@@ -0,0 +1,45 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 runtime
+
+import (
+	"mime"
+	"net/http"
+
+	"github.com/go-openapi/errors"
+)
+
+// ContentType parses a content type header
+func ContentType(headers http.Header) (string, string, error) {
+	ct := headers.Get(HeaderContentType)
+	orig := ct
+	if ct == "" {
+		ct = DefaultMime
+	}
+	if ct == "" {
+		return "", "", nil
+	}
+
+	mt, opts, err := mime.ParseMediaType(ct)
+	if err != nil {
+		return "", "", errors.NewParseError(HeaderContentType, "header", orig, err)
+	}
+
+	if cs, ok := opts[charsetKey]; ok {
+		return mt, cs, nil
+	}
+
+	return mt, "", nil
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/headers_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/headers_test.go
@@ -0,0 +1,61 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 runtime
+
+import (
+	"mime"
+	"net/http"
+	"testing"
+
+	"github.com/go-openapi/errors"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestParseContentType(t *testing.T) {
+	_, _, reason1 := mime.ParseMediaType("application(")
+	_, _, reason2 := mime.ParseMediaType("application/json;char*")
+	data := []struct {
+		hdr, mt, cs string
+		err         *errors.ParseError
+	}{
+		{"application/json", "application/json", "", nil},
+		{"text/html; charset=utf-8", "text/html", "utf-8", nil},
+		{"text/html;charset=utf-8", "text/html", "utf-8", nil},
+		{"", "application/octet-stream", "", nil},
+		{"text/html;           charset=utf-8", "text/html", "utf-8", nil},
+		{"application(", "", "", errors.NewParseError("Content-Type", "header", "application(", reason1)},
+		{"application/json;char*", "", "", errors.NewParseError("Content-Type", "header", "application/json;char*", reason2)},
+	}
+
+	headers := http.Header(map[string][]string{})
+	for _, v := range data {
+		if v.hdr != "" {
+			headers.Set("Content-Type", v.hdr)
+		} else {
+			headers.Del("Content-Type")
+		}
+		ct, cs, err := ContentType(headers)
+		if v.err == nil {
+			assert.NoError(t, err, "input: %q, err: %v", v.hdr, err)
+		} else {
+			assert.Error(t, err, "input: %q", v.hdr)
+			assert.IsType(t, &errors.ParseError{}, err, "input: %q", v.hdr)
+			assert.Equal(t, v.err.Error(), err.Error(), "input: %q", v.hdr)
+		}
+		assert.Equal(t, v.mt, ct, "input: %q", v.hdr)
+		assert.Equal(t, v.cs, cs, "input: %q", v.hdr)
+	}
+
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/interfaces.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/interfaces.go
@@ -0,0 +1,94 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 runtime
+
+import (
+	"io"
+	"mime/multipart"
+
+	"github.com/go-openapi/strfmt"
+)
+
+// File represents an uploaded file.
+type File struct {
+	Data   multipart.File
+	Header *multipart.FileHeader
+}
+
+// OperationHandlerFunc an adapter for a function to the OperationHandler interface
+type OperationHandlerFunc func(interface{}) (interface{}, error)
+
+// Handle implements the operation handler interface
+func (s OperationHandlerFunc) Handle(data interface{}) (interface{}, error) {
+	return s(data)
+}
+
+// OperationHandler a handler for a swagger operation
+type OperationHandler interface {
+	Handle(interface{}) (interface{}, error)
+}
+
+// ConsumerFunc represents a function that can be used as a consumer
+type ConsumerFunc func(io.Reader, interface{}) error
+
+// Consume consumes the reader into the data parameter
+func (fn ConsumerFunc) Consume(reader io.Reader, data interface{}) error {
+	return fn(reader, data)
+}
+
+// Consumer implementations know how to bind the values on the provided interface to
+// data provided by the request body
+type Consumer interface {
+	// Consume performs the binding of request values
+	Consume(io.Reader, interface{}) error
+}
+
+// ProducerFunc represents a function that can be used as a producer
+type ProducerFunc func(io.Writer, interface{}) error
+
+// Produce produces the response for the provided data
+func (f ProducerFunc) Produce(writer io.Writer, data interface{}) error {
+	return f(writer, data)
+}
+
+// Producer implementations know how to turn the provided interface into a valid
+// HTTP response
+type Producer interface {
+	// Produce writes to the http response
+	Produce(io.Writer, interface{}) error
+}
+
+// AuthenticatorFunc turns a function into an authenticator
+type AuthenticatorFunc func(interface{}) (bool, interface{}, error)
+
+// Authenticate authenticates the request with the provided data
+func (f AuthenticatorFunc) Authenticate(params interface{}) (bool, interface{}, error) {
+	return f(params)
+}
+
+// Authenticator represents an authentication strategy
+// implementations of Authenticator know how to authenticate the
+// request data and translate that into a valid principal object or an error
+type Authenticator interface {
+	Authenticate(interface{}) (bool, interface{}, error)
+}
+
+// Validatable types implementing this interface allow customizing their validation
+// this will be used instead of the reflective valditation based on the spec document.
+// the implementations are assumed to have been generated by the swagger tool so they should
+// contain all the validations obtained from the spec
+type Validatable interface {
+	Validate(strfmt.Registry) error
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/internal/testing/data.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/internal/testing/data.go
@@ -0,0 +1,811 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 testing
+
+import (
+	"encoding/json"
+)
+
+// PetStore20YAML yaml doc for swagger 2.0 pet store
+const PetStore20YAML = `swagger: '2.0'
+info:
+  version: '1.0.0'
+  title: Swagger Petstore
+  description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification
+  termsOfService: http://helloreverb.com/terms/
+  contact:
+    name: Swagger API team
+    email: foo@example.com
+    url: http://swagger.io
+  license:
+    name: MIT
+    url: http://opensource.org/licenses/MIT
+host: petstore.swagger.wordnik.com
+basePath: /api
+schemes:
+  - http
+consumes:
+  - application/json
+produces:
+  - application/json
+paths:
+  /pets:
+    get:
+      description: Returns all pets from the system that the user has access to
+      operationId: findPets
+      produces:
+        - application/json
+        - application/xml
+        - text/xml
+        - text/html
+      parameters:
+        - name: tags
+          in: query
+          description: tags to filter by
+          required: false
+          type: array
+          items:
+            type: string
+          collectionFormat: csv
+        - name: limit
+          in: query
+          description: maximum number of results to return
+          required: false
+          type: integer
+          format: int32
+      responses:
+        '200':
+          description: pet response
+          schema:
+            type: array
+            items:
+              $ref: '#/definitions/pet'
+        default:
+          description: unexpected error
+          schema:
+            $ref: '#/definitions/errorModel'
+    post:
+      description: Creates a new pet in the store.  Duplicates are allowed
+      operationId: addPet
+      produces:
+        - application/json
+      parameters:
+        - name: pet
+          in: body
+          description: Pet to add to the store
+          required: true
+          schema:
+            $ref: '#/definitions/newPet'
+      responses:
+        '200':
+          description: pet response
+          schema:
+            $ref: '#/definitions/pet'
+        default:
+          description: unexpected error
+          schema:
+            $ref: '#/definitions/errorModel'
+  /pets/{id}:
+    get:
+      description: Returns a user based on a single ID, if the user does not have access to the pet
+      operationId: findPetById
+      produces:
+        - application/json
+        - application/xml
+        - text/xml
+        - text/html
+      parameters:
+        - name: id
+          in: path
+          description: ID of pet to fetch
+          required: true
+          type: integer
+          format: int64
+      responses:
+        '200':
+          description: pet response
+          schema:
+            $ref: '#/definitions/pet'
+        default:
+          description: unexpected error
+          schema:
+            $ref: '#/definitions/errorModel'
+    delete:
+      description: deletes a single pet based on the ID supplied
+      operationId: deletePet
+      parameters:
+        - name: id
+          in: path
+          description: ID of pet to delete
+          required: true
+          type: integer
+          format: int64
+      responses:
+        '204':
+          description: pet deleted
+        default:
+          description: unexpected error
+          schema:
+            $ref: '#/definitions/errorModel'
+definitions:
+  pet:
+    required:
+      - id
+      - name
+    properties:
+      id:
+        type: integer
+        format: int64
+      name:
+        type: string
+      tag:
+        type: string
+  newPet:
+    allOf:
+      - $ref: '#/definitions/pet'
+      - required:
+          - name
+        properties:
+          id:
+            type: integer
+            format: int64
+          name:
+            type: string
+  errorModel:
+    required:
+      - code
+      - message
+    properties:
+      code:
+        type: integer
+        format: int32
+      message:
+        type: string
+`
+
+// PetStore20 json doc for swagger 2.0 pet store
+const PetStore20 = `{
+  "swagger": "2.0",
+  "info": {
+    "version": "1.0.0",
+    "title": "Swagger Petstore",
+    "contact": {
+      "name": "Wordnik API Team",
+      "url": "http://developer.wordnik.com"
+    },
+    "license": {
+      "name": "Creative Commons 4.0 International",
+      "url": "http://creativecommons.org/licenses/by/4.0/"
+    }
+  },
+  "host": "petstore.swagger.wordnik.com",
+  "basePath": "/api",
+  "schemes": [
+    "http"
+  ],
+  "paths": {
+    "/pets": {
+      "get": {
+        "security": [
+          {
+            "basic": []
+          }
+        ],
+        "tags": [ "Pet Operations" ],
+        "operationId": "getAllPets",
+        "parameters": [
+          {
+            "name": "status",
+            "in": "query",
+            "description": "The status to filter by",
+            "type": "string"
+          },
+          {
+            "name": "limit",
+            "in": "query",
+            "description": "The maximum number of results to return",
+            "type": "integer",
+						"format": "int64"
+          }
+        ],
+        "summary": "Finds all pets in the system",
+        "responses": {
+          "200": {
+            "description": "Pet response",
+            "schema": {
+              "type": "array",
+              "items": {
+                "$ref": "#/definitions/Pet"
+              }
+            }
+          },
+          "default": {
+            "description": "Unexpected error",
+            "schema": {
+              "$ref": "#/definitions/Error"
+            }
+          }
+        }
+      },
+      "post": {
+        "security": [
+          {
+            "basic": []
+          }
+        ],
+        "tags": [ "Pet Operations" ],
+        "operationId": "createPet",
+        "summary": "Creates a new pet",
+        "consumes": ["application/x-yaml"],
+        "produces": ["application/x-yaml"],
+        "parameters": [
+          {
+            "name": "pet",
+            "in": "body",
+            "description": "The Pet to create",
+            "required": true,
+            "schema": {
+              "$ref": "#/definitions/newPet"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "Created Pet response",
+            "schema": {
+              "$ref": "#/definitions/Pet"
+            }
+          },
+          "default": {
+            "description": "Unexpected error",
+            "schema": {
+              "$ref": "#/definitions/Error"
+            }
+          }
+        }
+      }
+    },
+    "/pets/{id}": {
+      "delete": {
+        "security": [
+          {
+            "apiKey": []
+          }
+        ],
+        "description": "Deletes the Pet by id",
+        "operationId": "deletePet",
+        "parameters": [
+          {
+            "name": "id",
+            "in": "path",
+            "description": "ID of pet to delete",
+            "required": true,
+            "type": "integer",
+            "format": "int64"
+          }
+        ],
+        "responses": {
+          "204": {
+            "description": "pet deleted"
+          },
+          "default": {
+            "description": "unexpected error",
+            "schema": {
+              "$ref": "#/definitions/Error"
+            }
+          }
+        }
+      },
+      "get": {
+        "tags": [ "Pet Operations" ],
+        "operationId": "getPetById",
+        "summary": "Finds the pet by id",
+        "responses": {
+          "200": {
+            "description": "Pet response",
+            "schema": {
+              "$ref": "#/definitions/Pet"
+            }
+          },
+          "default": {
+            "description": "Unexpected error",
+            "schema": {
+              "$ref": "#/definitions/Error"
+            }
+          }
+        }
+      },
+      "parameters": [
+        {
+          "name": "id",
+          "in": "path",
+          "description": "ID of pet",
+          "required": true,
+          "type": "integer",
+          "format": "int64"
+        }
+      ]
+    }
+  },
+  "definitions": {
+    "Category": {
+      "id": "Category",
+      "properties": {
+        "id": {
+          "format": "int64",
+          "type": "integer"
+        },
+        "name": {
+          "type": "string"
+        }
+      }
+    },
+    "Pet": {
+      "id": "Pet",
+      "properties": {
+        "category": {
+          "$ref": "#/definitions/Category"
+        },
+        "id": {
+          "description": "unique identifier for the pet",
+          "format": "int64",
+          "maximum": 100.0,
+          "minimum": 0.0,
+          "type": "integer"
+        },
+        "name": {
+          "type": "string"
+        },
+        "photoUrls": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "status": {
+          "description": "pet status in the store",
+          "enum": [
+            "available",
+            "pending",
+            "sold"
+          ],
+          "type": "string"
+        },
+        "tags": {
+          "items": {
+            "$ref": "#/definitions/Tag"
+          },
+          "type": "array"
+        }
+      },
+      "required": [
+        "id",
+        "name"
+      ]
+    },
+    "newPet": {
+      "anyOf": [
+        {
+          "$ref": "#/definitions/Pet"
+        },
+        {
+          "required": [
+            "name"
+          ]
+        }
+      ]
+    },
+    "Tag": {
+      "id": "Tag",
+      "properties": {
+        "id": {
+          "format": "int64",
+          "type": "integer"
+        },
+        "name": {
+          "type": "string"
+        }
+      }
+    },
+    "Error": {
+      "required": [
+        "code",
+        "message"
+      ],
+      "properties": {
+        "code": {
+          "type": "integer",
+          "format": "int32"
+        },
+        "message": {
+          "type": "string"
+        }
+      }
+    }
+  },
+  "consumes": [
+    "application/json",
+    "application/xml"
+  ],
+  "produces": [
+    "application/json",
+    "application/xml",
+    "text/plain",
+    "text/html"
+  ],
+  "securityDefinitions": {
+    "basic": {
+      "type": "basic"
+    },
+    "apiKey": {
+      "type": "apiKey",
+      "in": "header",
+      "name": "X-API-KEY"
+    }
+  }
+}
+`
+
+// RootPetStore20 json doc for swagger 2.0 pet store at /
+const RootPetStore20 = `{
+  "swagger": "2.0",
+  "info": {
+    "version": "1.0.0",
+    "title": "Swagger Petstore",
+    "contact": {
+      "name": "Wordnik API Team",
+      "url": "http://developer.wordnik.com"
+    },
+    "license": {
+      "name": "Creative Commons 4.0 International",
+      "url": "http://creativecommons.org/licenses/by/4.0/"
+    }
+  },
+  "host": "petstore.swagger.wordnik.com",
+  "basePath": "/",
+  "schemes": [
+    "http"
+  ],
+  "paths": {
+    "/pets": {
+      "get": {
+        "security": [
+          {
+            "basic": []
+          }
+        ],
+        "tags": [ "Pet Operations" ],
+        "operationId": "getAllPets",
+        "parameters": [
+          {
+            "name": "status",
+            "in": "query",
+            "description": "The status to filter by",
+            "type": "string"
+          }
+        ],
+        "summary": "Finds all pets in the system",
+        "responses": {
+          "200": {
+            "description": "Pet response",
+            "schema": {
+              "type": "array",
+              "items": {
+                "$ref": "#/definitions/Pet"
+              }
+            }
+          },
+          "default": {
+            "description": "Unexpected error",
+            "schema": {
+              "$ref": "#/definitions/Error"
+            }
+          }
+        }
+      },
+      "post": {
+        "security": [
+          {
+            "basic": []
+          }
+        ],
+        "tags": [ "Pet Operations" ],
+        "operationId": "createPet",
+        "summary": "Creates a new pet",
+        "consumes": ["application/x-yaml"],
+        "produces": ["application/x-yaml"],
+        "parameters": [
+          {
+            "name": "pet",
+            "in": "body",
+            "description": "The Pet to create",
+            "required": true,
+            "schema": {
+              "$ref": "#/definitions/newPet"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "Created Pet response",
+            "schema": {
+              "$ref": "#/definitions/Pet"
+            }
+          },
+          "default": {
+            "description": "Unexpected error",
+            "schema": {
+              "$ref": "#/definitions/Error"
+            }
+          }
+        }
+      }
+    },
+    "/pets/{id}": {
+      "delete": {
+        "security": [
+          {
+            "apiKey": []
+          }
+        ],
+        "description": "Deletes the Pet by id",
+        "operationId": "deletePet",
+        "parameters": [
+          {
+            "name": "id",
+            "in": "path",
+            "description": "ID of pet to delete",
+            "required": true,
+            "type": "integer",
+            "format": "int64"
+          }
+        ],
+        "responses": {
+          "204": {
+            "description": "pet deleted"
+          },
+          "default": {
+            "description": "unexpected error",
+            "schema": {
+              "$ref": "#/definitions/Error"
+            }
+          }
+        }
+      },
+      "get": {
+        "tags": [ "Pet Operations" ],
+        "operationId": "getPetById",
+        "summary": "Finds the pet by id",
+        "responses": {
+          "200": {
+            "description": "Pet response",
+            "schema": {
+              "$ref": "#/definitions/Pet"
+            }
+          },
+          "default": {
+            "description": "Unexpected error",
+            "schema": {
+              "$ref": "#/definitions/Error"
+            }
+          }
+        }
+      },
+      "parameters": [
+        {
+          "name": "id",
+          "in": "path",
+          "description": "ID of pet",
+          "required": true,
+          "type": "integer",
+          "format": "int64"
+        }
+      ]
+    }
+  },
+  "definitions": {
+    "Category": {
+      "id": "Category",
+      "properties": {
+        "id": {
+          "format": "int64",
+          "type": "integer"
+        },
+        "name": {
+          "type": "string"
+        }
+      }
+    },
+    "Pet": {
+      "id": "Pet",
+      "properties": {
+        "category": {
+          "$ref": "#/definitions/Category"
+        },
+        "id": {
+          "description": "unique identifier for the pet",
+          "format": "int64",
+          "maximum": 100.0,
+          "minimum": 0.0,
+          "type": "integer"
+        },
+        "name": {
+          "type": "string"
+        },
+        "photoUrls": {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        "status": {
+          "description": "pet status in the store",
+          "enum": [
+            "available",
+            "pending",
+            "sold"
+          ],
+          "type": "string"
+        },
+        "tags": {
+          "items": {
+            "$ref": "#/definitions/Tag"
+          },
+          "type": "array"
+        }
+      },
+      "required": [
+        "id",
+        "name"
+      ]
+    },
+    "newPet": {
+      "anyOf": [
+        {
+          "$ref": "#/definitions/Pet"
+        },
+        {
+          "required": [
+            "name"
+          ]
+        }
+      ]
+    },
+    "Tag": {
+      "id": "Tag",
+      "properties": {
+        "id": {
+          "format": "int64",
+          "type": "integer"
+        },
+        "name": {
+          "type": "string"
+        }
+      }
+    },
+    "Error": {
+      "required": [
+        "code",
+        "message"
+      ],
+      "properties": {
+        "code": {
+          "type": "integer",
+          "format": "int32"
+        },
+        "message": {
+          "type": "string"
+        }
+      }
+    }
+  },
+  "consumes": [
+    "application/json",
+    "application/xml"
+  ],
+  "produces": [
+    "application/json",
+    "application/xml",
+    "text/plain",
+    "text/html"
+  ],
+  "securityDefinitions": {
+    "basic": {
+      "type": "basic"
+    },
+    "apiKey": {
+      "type": "apiKey",
+      "in": "header",
+      "name": "X-API-KEY"
+    }
+  }
+}
+`
+
+// PetStoreJSONMessage json raw message for Petstore20
+var PetStoreJSONMessage = json.RawMessage([]byte(PetStore20))
+
+// RootPetStoreJSONMessage json raw message for Petstore20
+var RootPetStoreJSONMessage = json.RawMessage([]byte(RootPetStore20))
+
+// InvalidJSON invalid swagger 2.0 spec in JSON
+const InvalidJSON = `{
+  "apiVersion": "1.0.0",
+  "apis": [
+    {
+      "description": "Operations about pets",
+      "path": "/pet"
+    },
+    {
+      "description": "Operations about user",
+      "path": "/user"
+    },
+    {
+      "description": "Operations about store",
+      "path": "/store"
+    }
+  ],
+  "authorizations": {
+    "oauth2": {
+      "grantTypes": {
+        "authorization_code": {
+          "tokenEndpoint": {
+            "tokenName": "auth_code",
+            "url": "http://petstore.swagger.wordnik.com/oauth/token"
+          },
+          "tokenRequestEndpoint": {
+            "clientIdName": "client_id",
+            "clientSecretName": "client_secret",
+            "url": "http://petstore.swagger.wordnik.com/oauth/requestToken"
+          }
+        },
+        "implicit": {
+          "loginEndpoint": {
+            "url": "http://petstore.swagger.wordnik.com/oauth/dialog"
+          },
+          "tokenName": "access_token"
+        }
+      },
+      "scopes": [
+        {
+          "description": "Modify pets in your account",
+          "scope": "write:pets"
+        },
+        {
+          "description": "Read your pets",
+          "scope": "read:pets"
+        },
+        {
+          "description": "Anything (testing)",
+          "scope": "test:anything"
+        }
+      ],
+      "type": "oauth2"
+    }
+  },
+  "info": {
+    "contact": "apiteam@wordnik.com",
+    "description": "This is a sample server Petstore server.  You can find out more about Swagger \n  at <a href=\"http://swagger.wordnik.com\">http://swagger.wordnik.com</a> or on irc.freenode.net, #swagger.  For this sample,\n  you can use the api key \"special-key\" to test the authorization filters",
+    "license": "Apache 2.0",
+    "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.html",
+    "termsOfServiceUrl": "http://helloreverb.com/terms/",
+    "title": "Swagger Sample App"
+  },
+  "swaggerVersion": "1.2"
+}
+`
+
+// InvalidJSONMessage json raw message for invalid json
+var InvalidJSONMessage = json.RawMessage([]byte(InvalidJSON))
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/internal/testing/petstore/api.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/internal/testing/petstore/api.go
@@ -0,0 +1,147 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 petstore
+
+import (
+	"io"
+	gotest "testing"
+
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/loads"
+	"github.com/go-openapi/runtime"
+	testingutil "github.com/go-openapi/runtime/internal/testing"
+	"github.com/go-openapi/runtime/middleware/untyped"
+	"github.com/go-openapi/runtime/security"
+	"github.com/go-openapi/runtime/yamlpc"
+	"github.com/stretchr/testify/assert"
+)
+
+// NewAPI registers a stub api for the pet store
+func NewAPI(t gotest.TB) (*loads.Document, *untyped.API) {
+	spec, err := loads.Analyzed(testingutil.PetStoreJSONMessage, "")
+	assert.NoError(t, err)
+	api := untyped.NewAPI(spec)
+
+	api.RegisterConsumer("application/json", runtime.JSONConsumer())
+	api.RegisterProducer("application/json", runtime.JSONProducer())
+	api.RegisterConsumer("application/xml", new(stubConsumer))
+	api.RegisterProducer("application/xml", new(stubProducer))
+	api.RegisterProducer("text/plain", new(stubProducer))
+	api.RegisterProducer("text/html", new(stubProducer))
+	api.RegisterConsumer("application/x-yaml", yamlpc.YAMLConsumer())
+	api.RegisterProducer("application/x-yaml", yamlpc.YAMLProducer())
+
+	api.RegisterAuth("basic", security.BasicAuth(func(username, password string) (interface{}, error) {
+		if username == "admin" && password == "admin" {
+			return "admin", nil
+		}
+		return nil, errors.Unauthenticated("basic")
+	}))
+	api.RegisterAuth("apiKey", security.APIKeyAuth("X-API-KEY", "header", func(token string) (interface{}, error) {
+		if token == "token123" {
+			return "admin", nil
+		}
+		return nil, errors.Unauthenticated("token")
+	}))
+	api.RegisterOperation("get", "/pets", new(stubOperationHandler))
+	api.RegisterOperation("post", "/pets", new(stubOperationHandler))
+	api.RegisterOperation("delete", "/pets/{id}", new(stubOperationHandler))
+	api.RegisterOperation("get", "/pets/{id}", new(stubOperationHandler))
+
+	api.Models["pet"] = func() interface{} { return new(Pet) }
+	api.Models["newPet"] = func() interface{} { return new(Pet) }
+	api.Models["tag"] = func() interface{} { return new(Tag) }
+
+	return spec, api
+}
+
+// NewRootAPI registers a stub api for the pet store
+func NewRootAPI(t gotest.TB) (*loads.Document, *untyped.API) {
+	spec, err := loads.Analyzed(testingutil.RootPetStoreJSONMessage, "")
+	assert.NoError(t, err)
+	api := untyped.NewAPI(spec)
+
+	api.RegisterConsumer("application/json", runtime.JSONConsumer())
+	api.RegisterProducer("application/json", runtime.JSONProducer())
+	api.RegisterConsumer("application/xml", new(stubConsumer))
+	api.RegisterProducer("application/xml", new(stubProducer))
+	api.RegisterProducer("text/plain", new(stubProducer))
+	api.RegisterProducer("text/html", new(stubProducer))
+	api.RegisterConsumer("application/x-yaml", yamlpc.YAMLConsumer())
+	api.RegisterProducer("application/x-yaml", yamlpc.YAMLProducer())
+
+	api.RegisterAuth("basic", security.BasicAuth(func(username, password string) (interface{}, error) {
+		if username == "admin" && password == "admin" {
+			return "admin", nil
+		}
+		return nil, errors.Unauthenticated("basic")
+	}))
+	api.RegisterAuth("apiKey", security.APIKeyAuth("X-API-KEY", "header", func(token string) (interface{}, error) {
+		if token == "token123" {
+			return "admin", nil
+		}
+		return nil, errors.Unauthenticated("token")
+	}))
+	api.RegisterOperation("get", "/pets", new(stubOperationHandler))
+	api.RegisterOperation("post", "/pets", new(stubOperationHandler))
+	api.RegisterOperation("delete", "/pets/{id}", new(stubOperationHandler))
+	api.RegisterOperation("get", "/pets/{id}", new(stubOperationHandler))
+
+	api.Models["pet"] = func() interface{} { return new(Pet) }
+	api.Models["newPet"] = func() interface{} { return new(Pet) }
+	api.Models["tag"] = func() interface{} { return new(Tag) }
+
+	return spec, api
+}
+
+// Tag the tag model
+type Tag struct {
+	ID   int64
+	Name string
+}
+
+// Pet the pet model
+type Pet struct {
+	ID        int64
+	Name      string
+	PhotoURLs []string
+	Status    string
+	Tags      []Tag
+}
+
+type stubConsumer struct {
+}
+
+func (s *stubConsumer) Consume(_ io.Reader, _ interface{}) error {
+	return nil
+}
+
+type stubProducer struct {
+}
+
+func (s *stubProducer) Produce(_ io.Writer, _ interface{}) error {
+	return nil
+}
+
+type stubOperationHandler struct {
+}
+
+func (s *stubOperationHandler) ParameterModel() interface{} {
+	return nil
+}
+
+func (s *stubOperationHandler) Handle(params interface{}) (interface{}, error) {
+	return nil, nil
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/internal/testing/simplepetstore/api.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/internal/testing/simplepetstore/api.go
@@ -0,0 +1,348 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 simplepetstore
+
+import (
+	"encoding/json"
+	"net/http"
+	"sync"
+	"sync/atomic"
+
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/loads"
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/runtime/middleware"
+	"github.com/go-openapi/runtime/middleware/untyped"
+)
+
+// NewPetstore creates a new petstore api handler
+func NewPetstore() (http.Handler, error) {
+	spec, err := loads.Analyzed(json.RawMessage([]byte(swaggerJSON)), "")
+	if err != nil {
+		return nil, err
+	}
+	api := untyped.NewAPI(spec)
+
+	api.RegisterOperation("get", "/pets", getAllPets)
+	api.RegisterOperation("post", "/pets", createPet)
+	api.RegisterOperation("delete", "/pets/{id}", deletePet)
+	api.RegisterOperation("get", "/pets/{id}", getPetByID)
+
+	return middleware.Serve(spec, api), nil
+}
+
+var getAllPets = runtime.OperationHandlerFunc(func(data interface{}) (interface{}, error) {
+	return pets, nil
+})
+
+var createPet = runtime.OperationHandlerFunc(func(data interface{}) (interface{}, error) {
+	body := data.(map[string]interface{})["pet"].(map[string]interface{})
+	return addPet(Pet{
+		Name:   body["name"].(string),
+		Status: body["status"].(string),
+	}), nil
+})
+
+var deletePet = runtime.OperationHandlerFunc(func(data interface{}) (interface{}, error) {
+	id := data.(map[string]interface{})["id"].(int64)
+	removePet(id)
+	return nil, nil
+})
+
+var getPetByID = runtime.OperationHandlerFunc(func(data interface{}) (interface{}, error) {
+	id := data.(map[string]interface{})["id"].(int64)
+	return petByID(id)
+})
+
+// Tag the tag model
+type Tag struct {
+	ID   int64
+	Name string
+}
+
+// Pet the pet model
+type Pet struct {
+	ID        int64    `json:"id"`
+	Name      string   `json:"name"`
+	PhotoURLs []string `json:"photoUrls,omitempty"`
+	Status    string   `json:"status,omitempty"`
+	Tags      []Tag    `json:"tags,omitempty"`
+}
+
+var pets = []Pet{
+	{1, "Dog", []string{}, "available", nil},
+	{2, "Cat", []string{}, "pending", nil},
+}
+
+var petsLock = &sync.Mutex{}
+var lastPetID int64 = 2
+
+func newPetID() int64 {
+	return atomic.AddInt64(&lastPetID, 1)
+}
+
+func addPet(pet Pet) Pet {
+	petsLock.Lock()
+	defer petsLock.Unlock()
+	pet.ID = newPetID()
+	pets = append(pets, pet)
+	return pet
+}
+
+func removePet(id int64) {
+	petsLock.Lock()
+	defer petsLock.Unlock()
+	var newPets []Pet
+	for _, pet := range pets {
+		if pet.ID != id {
+			newPets = append(newPets, pet)
+		}
+	}
+	pets = newPets
+}
+
+func petByID(id int64) (*Pet, error) {
+	for _, pet := range pets {
+		if pet.ID == id {
+			return &pet, nil
+		}
+	}
+	return nil, errors.NotFound("not found: pet %d", id)
+}
+
+var swaggerJSON = `{
+  "swagger": "2.0",
+  "info": {
+    "version": "1.0.0",
+    "title": "Swagger Petstore",
+    "description": "A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification",
+    "termsOfService": "http://helloreverb.com/terms/",
+    "contact": {
+      "name": "Wordnik API Team"
+    },
+    "license": {
+      "name": "MIT"
+    }
+  },
+  "host": "localhost:8344",
+  "basePath": "/api",
+  "schemes": [
+    "http"
+  ],
+  "consumes": [
+    "application/json"
+  ],
+  "produces": [
+    "application/json"
+  ],
+  "paths": {
+    "/pets": {
+      "get": {
+        "description": "Returns all pets from the system that the user has access to",
+        "operationId": "findPets",
+        "produces": [
+          "application/json",
+          "application/xml",
+          "text/xml",
+          "text/html"
+        ],
+        "parameters": [
+          {
+            "name": "tags",
+            "in": "query",
+            "description": "tags to filter by",
+            "required": false,
+            "type": "array",
+            "items": {
+              "type": "string"
+            },
+            "collectionFormat": "csv"
+          },
+          {
+            "name": "limit",
+            "in": "query",
+            "description": "maximum number of results to return",
+            "required": false,
+            "type": "integer",
+            "format": "int32"
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "pet response",
+            "schema": {
+              "type": "array",
+              "items": {
+                "$ref": "#/definitions/pet"
+              }
+            }
+          },
+          "default": {
+            "description": "unexpected error",
+            "schema": {
+              "$ref": "#/definitions/errorModel"
+            }
+          }
+        }
+      },
+      "post": {
+        "description": "Creates a new pet in the store.  Duplicates are allowed",
+        "operationId": "addPet",
+        "produces": [
+          "application/json"
+        ],
+        "parameters": [
+          {
+            "name": "pet",
+            "in": "body",
+            "description": "Pet to add to the store",
+            "required": true,
+            "schema": {
+              "$ref": "#/definitions/petInput"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "pet response",
+            "schema": {
+              "$ref": "#/definitions/pet"
+            }
+          },
+          "default": {
+            "description": "unexpected error",
+            "schema": {
+              "$ref": "#/definitions/errorModel"
+            }
+          }
+        }
+      }
+    },
+    "/pets/{id}": {
+      "get": {
+        "description": "Returns a user based on a single ID, if the user does not have access to the pet",
+        "operationId": "findPetById",
+        "produces": [
+          "application/json",
+          "application/xml",
+          "text/xml",
+          "text/html"
+        ],
+        "parameters": [
+          {
+            "name": "id",
+            "in": "path",
+            "description": "ID of pet to fetch",
+            "required": true,
+            "type": "integer",
+            "format": "int64"
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "pet response",
+            "schema": {
+              "$ref": "#/definitions/pet"
+            }
+          },
+          "default": {
+            "description": "unexpected error",
+            "schema": {
+              "$ref": "#/definitions/errorModel"
+            }
+          }
+        }
+      },
+      "delete": {
+        "description": "deletes a single pet based on the ID supplied",
+        "operationId": "deletePet",
+        "parameters": [
+          {
+            "name": "id",
+            "in": "path",
+            "description": "ID of pet to delete",
+            "required": true,
+            "type": "integer",
+            "format": "int64"
+          }
+        ],
+        "responses": {
+          "204": {
+            "description": "pet deleted"
+          },
+          "default": {
+            "description": "unexpected error",
+            "schema": {
+              "$ref": "#/definitions/errorModel"
+            }
+          }
+        }
+      }
+    }
+  },
+  "definitions": {
+    "pet": {
+      "required": [
+        "id",
+        "name"
+      ],
+      "properties": {
+        "id": {
+          "type": "integer",
+          "format": "int64"
+        },
+        "name": {
+          "type": "string"
+        },
+        "tag": {
+          "type": "string"
+        }
+      }
+    },
+    "petInput": {
+      "allOf": [
+        {
+          "$ref": "pet"
+        },
+        {
+          "required": [
+            "name"
+          ],
+          "properties": {
+            "id": {
+              "type": "integer",
+              "format": "int64"
+            }
+          }
+        }
+      ]
+    },
+    "errorModel": {
+      "required": [
+        "code",
+        "message"
+      ],
+      "properties": {
+        "code": {
+          "type": "integer",
+          "format": "int32"
+        },
+        "message": {
+          "type": "string"
+        }
+      }
+    }
+  }
+}`
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/internal/testing/simplepetstore/api_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/internal/testing/simplepetstore/api_test.go
@@ -0,0 +1,81 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 simplepetstore
+
+import (
+	"bytes"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/go-openapi/runtime"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestSimplePetstoreSpec(t *testing.T) {
+	handler, _ := NewPetstore()
+	// Serves swagger spec document
+	r, _ := runtime.JSONRequest("GET", "/swagger.json", nil)
+	rw := httptest.NewRecorder()
+	handler.ServeHTTP(rw, r)
+	assert.Equal(t, 200, rw.Code)
+	assert.Equal(t, swaggerJSON, rw.Body.String())
+}
+
+func TestSimplePetstoreAllPets(t *testing.T) {
+	handler, _ := NewPetstore()
+	// Serves swagger spec document
+	r, _ := runtime.JSONRequest("GET", "/api/pets", nil)
+	rw := httptest.NewRecorder()
+	handler.ServeHTTP(rw, r)
+	assert.Equal(t, 200, rw.Code)
+	assert.Equal(t, "[{\"id\":1,\"name\":\"Dog\",\"status\":\"available\"},{\"id\":2,\"name\":\"Cat\",\"status\":\"pending\"}]\n", rw.Body.String())
+}
+
+func TestSimplePetstorePetByID(t *testing.T) {
+	handler, _ := NewPetstore()
+
+	// Serves swagger spec document
+	r, _ := runtime.JSONRequest("GET", "/api/pets/1", nil)
+	rw := httptest.NewRecorder()
+	handler.ServeHTTP(rw, r)
+	assert.Equal(t, 200, rw.Code)
+	assert.Equal(t, "{\"id\":1,\"name\":\"Dog\",\"status\":\"available\"}\n", rw.Body.String())
+}
+
+func TestSimplePetstoreAddPet(t *testing.T) {
+	handler, _ := NewPetstore()
+	// Serves swagger spec document
+	r, _ := runtime.JSONRequest("POST", "/api/pets", bytes.NewBuffer([]byte(`{"name": "Fish","status": "available"}`)))
+	rw := httptest.NewRecorder()
+	handler.ServeHTTP(rw, r)
+	assert.Equal(t, 200, rw.Code)
+	assert.Equal(t, "{\"id\":3,\"name\":\"Fish\",\"status\":\"available\"}\n", rw.Body.String())
+}
+
+func TestSimplePetstoreDeletePet(t *testing.T) {
+	handler, _ := NewPetstore()
+	// Serves swagger spec document
+	r, _ := runtime.JSONRequest("DELETE", "/api/pets/1", nil)
+	rw := httptest.NewRecorder()
+	handler.ServeHTTP(rw, r)
+	assert.Equal(t, 204, rw.Code)
+	assert.Equal(t, "", rw.Body.String())
+
+	r, _ = runtime.JSONRequest("GET", "/api/pets/1", nil)
+	rw = httptest.NewRecorder()
+	handler.ServeHTTP(rw, r)
+	assert.Equal(t, 404, rw.Code)
+	assert.Equal(t, "{\"code\":404,\"message\":\"not found: pet 1\"}", rw.Body.String())
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/json.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/json.go
@@ -0,0 +1,37 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 runtime
+
+import (
+	"encoding/json"
+	"io"
+)
+
+// JSONConsumer creates a new JSON consumer
+func JSONConsumer() Consumer {
+	return ConsumerFunc(func(reader io.Reader, data interface{}) error {
+		dec := json.NewDecoder(reader)
+		dec.UseNumber() // preserve number formats
+		return dec.Decode(data)
+	})
+}
+
+// JSONProducer creates a new JSON producer
+func JSONProducer() Producer {
+	return ProducerFunc(func(writer io.Writer, data interface{}) error {
+		enc := json.NewEncoder(writer)
+		return enc.Encode(data)
+	})
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/json_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/json_test.go
@@ -0,0 +1,62 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 runtime
+
+import (
+	"bytes"
+	"io"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+var consProdJSON = `{"name":"Somebody","id":1}`
+
+type eofRdr struct {
+}
+
+func (r *eofRdr) Read(d []byte) (int, error) {
+	return 0, io.EOF
+}
+
+func TestJSONConsumer(t *testing.T) {
+	cons := JSONConsumer()
+	var data struct {
+		Name string
+		ID   int
+	}
+	err := cons.Consume(bytes.NewBuffer([]byte(consProdJSON)), &data)
+	if assert.NoError(t, err) {
+		assert.Equal(t, "Somebody", data.Name)
+		assert.Equal(t, 1, data.ID)
+
+		err = cons.Consume(new(eofRdr), &data)
+		assert.Error(t, err)
+	}
+}
+
+func TestJSONProducer(t *testing.T) {
+	prod := JSONProducer()
+	data := struct {
+		Name string `json:"name"`
+		ID   int    `json:"id"`
+	}{Name: "Somebody", ID: 1}
+
+	rw := httptest.NewRecorder()
+	err := prod.Produce(rw, data)
+	assert.NoError(t, err)
+	assert.Equal(t, consProdJSON+"\n", rw.Body.String())
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/body_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/body_test.go
@@ -0,0 +1,100 @@
+package middleware
+
+import (
+	"io"
+	"net/http"
+	"testing"
+
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/runtime/internal/testing/petstore"
+	"github.com/stretchr/testify/assert"
+)
+
+type eofReader struct {
+}
+
+func (r *eofReader) Read(b []byte) (int, error) {
+	return 0, io.EOF
+}
+
+func (r *eofReader) Close() error {
+	return nil
+}
+
+type rbn func(*http.Request, *MatchedRoute) error
+
+func (b rbn) BindRequest(r *http.Request, rr *MatchedRoute) error {
+	return b(r, rr)
+}
+
+func TestBindRequest_BodyValidation(t *testing.T) {
+	spec, api := petstore.NewAPI(t)
+	ctx := NewContext(spec, api, nil)
+	api.DefaultConsumes = runtime.JSONMime
+	ctx.router = DefaultRouter(spec, ctx.api)
+
+	req, err := http.NewRequest("GET", "/pets", new(eofReader))
+	if assert.NoError(t, err) {
+		req.Header.Set("Content-Type", runtime.JSONMime)
+
+		ri, ok := ctx.RouteInfo(req)
+		if assert.True(t, ok) {
+
+			err := ctx.BindValidRequest(req, ri, rbn(func(r *http.Request, rr *MatchedRoute) error {
+				defer r.Body.Close()
+				var data interface{}
+				err := runtime.JSONConsumer().Consume(r.Body, &data)
+				_ = data
+				return err
+			}))
+
+			assert.Error(t, err)
+			assert.Equal(t, io.EOF, err)
+		}
+	}
+}
+
+func TestBindRequest_DeleteNoBody(t *testing.T) {
+	spec, api := petstore.NewAPI(t)
+	ctx := NewContext(spec, api, nil)
+	api.DefaultConsumes = runtime.JSONMime
+	ctx.router = DefaultRouter(spec, ctx.api)
+
+	req, err := http.NewRequest("DELETE", "/pets/123", new(eofReader))
+	if assert.NoError(t, err) {
+		req.Header.Set("Accept", "*/*")
+
+		ri, ok := ctx.RouteInfo(req)
+		if assert.True(t, ok) {
+
+			err := ctx.BindValidRequest(req, ri, rbn(func(r *http.Request, rr *MatchedRoute) error {
+				return nil
+			}))
+
+			assert.NoError(t, err)
+			//assert.Equal(t, io.EOF, err)
+		}
+	}
+
+	req, err = http.NewRequest("DELETE", "/pets/123", new(eofReader))
+	if assert.NoError(t, err) {
+		req.Header.Set("Accept", "*/*")
+		req.Header.Set("Content-Type", runtime.JSONMime)
+		req.ContentLength = 1
+
+		ri, ok := ctx.RouteInfo(req)
+		if assert.True(t, ok) {
+
+			err := ctx.BindValidRequest(req, ri, rbn(func(r *http.Request, rr *MatchedRoute) error {
+				defer r.Body.Close()
+				var data interface{}
+				err := runtime.JSONConsumer().Consume(r.Body, &data)
+				_ = data
+				return err
+			}))
+
+			assert.Error(t, err)
+			assert.Equal(t, io.EOF, err)
+		}
+	}
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/context.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/context.go
@@ -0,0 +1,477 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 middleware
+
+import (
+	"net/http"
+	"strings"
+
+	"github.com/go-openapi/analysis"
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/loads"
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/runtime/middleware/untyped"
+	"github.com/go-openapi/runtime/security"
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/strfmt"
+	"github.com/gorilla/context"
+)
+
+// A Builder can create middlewares
+type Builder func(http.Handler) http.Handler
+
+// PassthroughBuilder returns the handler, aka the builder identity function
+func PassthroughBuilder(handler http.Handler) http.Handler { return handler }
+
+// RequestBinder is an interface for types to implement
+// when they want to be able to bind from a request
+type RequestBinder interface {
+	BindRequest(*http.Request, *MatchedRoute) error
+}
+
+// Responder is an interface for types to implement
+// when they want to be considered for writing HTTP responses
+type Responder interface {
+	WriteResponse(http.ResponseWriter, runtime.Producer)
+}
+
+// ResponderFunc wraps a func as a Responder interface
+type ResponderFunc func(http.ResponseWriter, runtime.Producer)
+
+// WriteResponse writes to the response
+func (fn ResponderFunc) WriteResponse(rw http.ResponseWriter, pr runtime.Producer) {
+	fn(rw, pr)
+}
+
+// Context is a type safe wrapper around an untyped request context
+// used throughout to store request context with the gorilla context module
+type Context struct {
+	spec     *loads.Document
+	analyzer *analysis.Spec
+	api      RoutableAPI
+	router   Router
+	formats  strfmt.Registry
+}
+
+type routableUntypedAPI struct {
+	api             *untyped.API
+	handlers        map[string]map[string]http.Handler
+	defaultConsumes string
+	defaultProduces string
+}
+
+func newRoutableUntypedAPI(spec *loads.Document, api *untyped.API, context *Context) *routableUntypedAPI {
+	var handlers map[string]map[string]http.Handler
+	if spec == nil || api == nil {
+		return nil
+	}
+	analyzer := analysis.New(spec.Spec())
+	for method, hls := range analyzer.Operations() {
+		um := strings.ToUpper(method)
+		for path, op := range hls {
+			schemes := analyzer.SecurityDefinitionsFor(op)
+
+			if oh, ok := api.OperationHandlerFor(method, path); ok {
+				if handlers == nil {
+					handlers = make(map[string]map[string]http.Handler)
+				}
+				if b, ok := handlers[um]; !ok || b == nil {
+					handlers[um] = make(map[string]http.Handler)
+				}
+
+				handlers[um][path] = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+					// lookup route info in the context
+					route, _ := context.RouteInfo(r)
+
+					// bind and validate the request using reflection
+					bound, validation := context.BindAndValidate(r, route)
+					if validation != nil {
+						context.Respond(w, r, route.Produces, route, validation)
+						return
+					}
+
+					// actually handle the request
+					result, err := oh.Handle(bound)
+					if err != nil {
+						// respond with failure
+						context.Respond(w, r, route.Produces, route, err)
+						return
+					}
+
+					// respond with success
+					context.Respond(w, r, route.Produces, route, result)
+				})
+
+				if len(schemes) > 0 {
+					handlers[um][path] = newSecureAPI(context, handlers[um][path])
+				}
+			}
+		}
+	}
+
+	return &routableUntypedAPI{
+		api:             api,
+		handlers:        handlers,
+		defaultProduces: api.DefaultProduces,
+		defaultConsumes: api.DefaultConsumes,
+	}
+}
+
+func (r *routableUntypedAPI) HandlerFor(method, path string) (http.Handler, bool) {
+	paths, ok := r.handlers[strings.ToUpper(method)]
+	if !ok {
+		return nil, false
+	}
+	handler, ok := paths[path]
+	return handler, ok
+}
+func (r *routableUntypedAPI) ServeErrorFor(operationID string) func(http.ResponseWriter, *http.Request, error) {
+	return r.api.ServeError
+}
+func (r *routableUntypedAPI) ConsumersFor(mediaTypes []string) map[string]runtime.Consumer {
+	return r.api.ConsumersFor(mediaTypes)
+}
+func (r *routableUntypedAPI) ProducersFor(mediaTypes []string) map[string]runtime.Producer {
+	return r.api.ProducersFor(mediaTypes)
+}
+func (r *routableUntypedAPI) AuthenticatorsFor(schemes map[string]spec.SecurityScheme) map[string]runtime.Authenticator {
+	return r.api.AuthenticatorsFor(schemes)
+}
+func (r *routableUntypedAPI) Formats() strfmt.Registry {
+	return r.api.Formats()
+}
+
+func (r *routableUntypedAPI) DefaultProduces() string {
+	return r.defaultProduces
+}
+
+func (r *routableUntypedAPI) DefaultConsumes() string {
+	return r.defaultConsumes
+}
+
+// NewRoutableContext creates a new context for a routable API
+func NewRoutableContext(spec *loads.Document, routableAPI RoutableAPI, routes Router) *Context {
+	var an *analysis.Spec
+	if spec != nil {
+		an = analysis.New(spec.Spec())
+	}
+	ctx := &Context{spec: spec, api: routableAPI, analyzer: an}
+	return ctx
+}
+
+// NewContext creates a new context wrapper
+func NewContext(spec *loads.Document, api *untyped.API, routes Router) *Context {
+	var an *analysis.Spec
+	if spec != nil {
+		an = analysis.New(spec.Spec())
+	}
+	ctx := &Context{spec: spec, analyzer: an}
+	ctx.api = newRoutableUntypedAPI(spec, api, ctx)
+	return ctx
+}
+
+// Serve serves the specified spec with the specified api registrations as a http.Handler
+func Serve(spec *loads.Document, api *untyped.API) http.Handler {
+	return ServeWithBuilder(spec, api, PassthroughBuilder)
+}
+
+// ServeWithBuilder serves the specified spec with the specified api registrations as a http.Handler that is decorated
+// by the Builder
+func ServeWithBuilder(spec *loads.Document, api *untyped.API, builder Builder) http.Handler {
+	context := NewContext(spec, api, nil)
+	return context.APIHandler(builder)
+}
+
+type contextKey int8
+
+const (
+	_ contextKey = iota
+	ctxContentType
+	ctxResponseFormat
+	ctxMatchedRoute
+	ctxAllowedMethods
+	ctxBoundParams
+	ctxSecurityPrincipal
+	ctxSecurityScopes
+
+	ctxConsumer
+)
+
+type contentTypeValue struct {
+	MediaType string
+	Charset   string
+}
+
+// BasePath returns the base path for this API
+func (c *Context) BasePath() string {
+	return c.spec.BasePath()
+}
+
+// RequiredProduces returns the accepted content types for responses
+func (c *Context) RequiredProduces() []string {
+	return c.analyzer.RequiredProduces()
+}
+
+// BindValidRequest binds a params object to a request but only when the request is valid
+// if the request is not valid an error will be returned
+func (c *Context) BindValidRequest(request *http.Request, route *MatchedRoute, binder RequestBinder) error {
+	var res []error
+
+	requestContentType := "*/*"
+	// check and validate content type, select consumer
+	if runtime.HasBody(request) {
+		ct, _, err := runtime.ContentType(request.Header)
+		if err != nil {
+			res = append(res, err)
+		} else {
+			if err := validateContentType(route.Consumes, ct); err != nil {
+				res = append(res, err)
+			}
+			if len(res) == 0 {
+				cons, ok := route.Consumers[ct]
+				if !ok {
+					res = append(res, errors.New(500, "no consumer registered for %s", ct))
+				} else {
+					route.Consumer = cons
+					requestContentType = ct
+				}
+			}
+		}
+	}
+
+	// check and validate the response format
+	if len(res) == 0 && runtime.HasBody(request) {
+		if str := NegotiateContentType(request, route.Produces, requestContentType); str == "" {
+			res = append(res, errors.InvalidResponseFormat(request.Header.Get(runtime.HeaderAccept), route.Produces))
+		}
+	}
+
+	// now bind the request with the provided binder
+	// it's assumed the binder will also validate the request and return an error if the
+	// request is invalid
+	if binder != nil && len(res) == 0 {
+		if err := binder.BindRequest(request, route); err != nil {
+			return err
+		}
+	}
+
+	if len(res) > 0 {
+		return errors.CompositeValidationError(res...)
+	}
+	return nil
+}
+
+// ContentType gets the parsed value of a content type
+func (c *Context) ContentType(request *http.Request) (string, string, error) {
+	if v, ok := context.GetOk(request, ctxContentType); ok {
+		if val, ok := v.(*contentTypeValue); ok {
+			return val.MediaType, val.Charset, nil
+		}
+	}
+
+	mt, cs, err := runtime.ContentType(request.Header)
+	if err != nil {
+		return "", "", err
+	}
+	context.Set(request, ctxContentType, &contentTypeValue{mt, cs})
+	return mt, cs, nil
+}
+
+// LookupRoute looks a route up and returns true when it is found
+func (c *Context) LookupRoute(request *http.Request) (*MatchedRoute, bool) {
+	if route, ok := c.router.Lookup(request.Method, request.URL.Path); ok {
+		return route, ok
+	}
+	return nil, false
+}
+
+// RouteInfo tries to match a route for this request
+func (c *Context) RouteInfo(request *http.Request) (*MatchedRoute, bool) {
+	if v, ok := context.GetOk(request, ctxMatchedRoute); ok {
+		if val, ok := v.(*MatchedRoute); ok {
+			return val, ok
+		}
+	}
+
+	if route, ok := c.LookupRoute(request); ok {
+		context.Set(request, ctxMatchedRoute, route)
+		return route, ok
+	}
+
+	return nil, false
+}
+
+// ResponseFormat negotiates the response content type
+func (c *Context) ResponseFormat(r *http.Request, offers []string) string {
+	if v, ok := context.GetOk(r, ctxResponseFormat); ok {
+		if val, ok := v.(string); ok {
+			return val
+		}
+	}
+
+	format := NegotiateContentType(r, offers, "")
+	if format != "" {
+		context.Set(r, ctxResponseFormat, format)
+	}
+	return format
+}
+
+// AllowedMethods gets the allowed methods for the path of this request
+func (c *Context) AllowedMethods(request *http.Request) []string {
+	return c.router.OtherMethods(request.Method, request.URL.Path)
+}
+
+// Authorize authorizes the request
+func (c *Context) Authorize(request *http.Request, route *MatchedRoute) (interface{}, error) {
+	if len(route.Authenticators) == 0 {
+		return nil, nil
+	}
+	if v, ok := context.GetOk(request, ctxSecurityPrincipal); ok {
+		return v, nil
+	}
+
+	for scheme, authenticator := range route.Authenticators {
+		applies, usr, err := authenticator.Authenticate(&security.ScopedAuthRequest{
+			Request:        request,
+			RequiredScopes: route.Scopes[scheme],
+		})
+		if !applies || err != nil || usr == nil {
+			continue
+		}
+		context.Set(request, ctxSecurityPrincipal, usr)
+		context.Set(request, ctxSecurityScopes, route.Scopes[scheme])
+		return usr, nil
+	}
+
+	return nil, errors.Unauthenticated("invalid credentials")
+}
+
+// BindAndValidate binds and validates the request
+func (c *Context) BindAndValidate(request *http.Request, matched *MatchedRoute) (interface{}, error) {
+	if v, ok := context.GetOk(request, ctxBoundParams); ok {
+		if val, ok := v.(*validation); ok {
+			if len(val.result) > 0 {
+				return val.bound, errors.CompositeValidationError(val.result...)
+			}
+			return val.bound, nil
+		}
+	}
+	result := validateRequest(c, request, matched)
+	if result != nil {
+		context.Set(request, ctxBoundParams, result)
+	}
+	if len(result.result) > 0 {
+		return result.bound, errors.CompositeValidationError(result.result...)
+	}
+	return result.bound, nil
+}
+
+// NotFound the default not found responder for when no route has been matched yet
+func (c *Context) NotFound(rw http.ResponseWriter, r *http.Request) {
+	c.Respond(rw, r, []string{c.api.DefaultProduces()}, nil, errors.NotFound("not found"))
+}
+
+// Respond renders the response after doing some content negotiation
+func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []string, route *MatchedRoute, data interface{}) {
+	offers := []string{}
+	for _, mt := range produces {
+		if mt != c.api.DefaultProduces() {
+			offers = append(offers, mt)
+		}
+	}
+	// the default producer is last so more specific producers take precedence
+	offers = append(offers, c.api.DefaultProduces())
+
+	format := c.ResponseFormat(r, offers)
+	rw.Header().Set(runtime.HeaderContentType, format)
+
+	if resp, ok := data.(Responder); ok {
+		producers := route.Producers
+		prod, ok := producers[format]
+		if !ok {
+			prods := c.api.ProducersFor([]string{c.api.DefaultProduces()})
+			pr, ok := prods[c.api.DefaultProduces()]
+			if !ok {
+				panic(errors.New(http.StatusInternalServerError, "can't find a producer for "+format))
+			}
+			prod = pr
+		}
+		resp.WriteResponse(rw, prod)
+		return
+	}
+
+	if err, ok := data.(error); ok {
+		if format == "" {
+			rw.Header().Set(runtime.HeaderContentType, runtime.JSONMime)
+		}
+		if route == nil || route.Operation == nil {
+			c.api.ServeErrorFor("")(rw, r, err)
+			return
+		}
+		c.api.ServeErrorFor(route.Operation.ID)(rw, r, err)
+		return
+	}
+
+	if route == nil || route.Operation == nil {
+		rw.WriteHeader(200)
+		if r.Method == "HEAD" {
+			return
+		}
+		producers := c.api.ProducersFor(offers)
+		prod, ok := producers[format]
+		if !ok {
+			panic(errors.New(http.StatusInternalServerError, "can't find a producer for "+format))
+		}
+		if err := prod.Produce(rw, data); err != nil {
+			panic(err) // let the recovery middleware deal with this
+		}
+		return
+	}
+
+	if _, code, ok := route.Operation.SuccessResponse(); ok {
+		rw.WriteHeader(code)
+		if code == 204 || r.Method == "HEAD" {
+			return
+		}
+
+		producers := route.Producers
+		prod, ok := producers[format]
+		if !ok {
+			if !ok {
+				prods := c.api.ProducersFor([]string{c.api.DefaultProduces()})
+				pr, ok := prods[c.api.DefaultProduces()]
+				if !ok {
+					panic(errors.New(http.StatusInternalServerError, "can't find a producer for "+format))
+				}
+				prod = pr
+			}
+		}
+		if err := prod.Produce(rw, data); err != nil {
+			panic(err) // let the recovery middleware deal with this
+		}
+		return
+	}
+
+	c.api.ServeErrorFor(route.Operation.ID)(rw, r, errors.New(http.StatusInternalServerError, "can't produce response"))
+}
+
+// APIHandler returns a handler to serve
+func (c *Context) APIHandler(builder Builder) http.Handler {
+	b := builder
+	if b == nil {
+		b = PassthroughBuilder
+	}
+	return specMiddleware(c, newRouter(c, b(newOperationExecutor(c))))
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/context_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/context_test.go
@@ -0,0 +1,395 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 middleware
+
+import (
+	"errors"
+	"net/http"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/go-openapi/loads"
+	"github.com/go-openapi/loads/fmts"
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/runtime/internal/testing/petstore"
+	"github.com/go-openapi/runtime/middleware/untyped"
+	"github.com/gorilla/context"
+	"github.com/stretchr/testify/assert"
+)
+
+type stubOperationHandler struct {
+}
+
+func (s *stubOperationHandler) ParameterModel() interface{} {
+	return nil
+}
+
+func (s *stubOperationHandler) Handle(params interface{}) (interface{}, error) {
+	return nil, nil
+}
+
+type testBinder struct {
+}
+
+func (t *testBinder) BindRequest(r *http.Request, m *MatchedRoute) error {
+	return nil
+}
+
+func init() {
+	loads.AddLoader(fmts.YAMLMatcher, fmts.YAMLDoc)
+}
+
+func TestContentType_Issue264(t *testing.T) {
+	swspec, err := loads.Spec("../fixtures/bugs/264/swagger.yml")
+	if assert.NoError(t, err) {
+		api := untyped.NewAPI(swspec)
+		api.RegisterConsumer("application/json", runtime.JSONConsumer())
+		api.RegisterProducer("application/json", runtime.JSONProducer())
+		api.RegisterOperation("delete", "/key/{id}", new(stubOperationHandler))
+
+		handler := Serve(swspec, api)
+		request, _ := http.NewRequest("DELETE", "/key/1", nil)
+		recorder := httptest.NewRecorder()
+		handler.ServeHTTP(recorder, request)
+		assert.Equal(t, 200, recorder.Code)
+	}
+}
+
+func TestServe(t *testing.T) {
+	spec, api := petstore.NewAPI(t)
+	handler := Serve(spec, api)
+
+	// serve spec document
+	request, _ := http.NewRequest("GET", "http://localhost:8080/swagger.json", nil)
+	request.Header.Add("Content-Type", runtime.JSONMime)
+	request.Header.Add("Accept", runtime.JSONMime)
+	recorder := httptest.NewRecorder()
+
+	handler.ServeHTTP(recorder, request)
+	assert.Equal(t, 200, recorder.Code)
+
+	request, _ = http.NewRequest("GET", "http://localhost:8080/swagger-ui", nil)
+	recorder = httptest.NewRecorder()
+
+	handler.ServeHTTP(recorder, request)
+	assert.Equal(t, 404, recorder.Code)
+}
+
+func TestContextAuthorize(t *testing.T) {
+	spec, api := petstore.NewAPI(t)
+	ctx := NewContext(spec, api, nil)
+	ctx.router = DefaultRouter(spec, ctx.api)
+
+	request, _ := runtime.JSONRequest("GET", "/pets", nil)
+
+	v, ok := context.GetOk(request, ctxSecurityPrincipal)
+	assert.False(t, ok)
+	assert.Nil(t, v)
+
+	ri, ok := ctx.RouteInfo(request)
+	assert.True(t, ok)
+	p, err := ctx.Authorize(request, ri)
+	assert.Error(t, err)
+	assert.Nil(t, p)
+
+	v, ok = context.GetOk(request, ctxSecurityPrincipal)
+	assert.False(t, ok)
+	assert.Nil(t, v)
+
+	request.SetBasicAuth("wrong", "wrong")
+	p, err = ctx.Authorize(request, ri)
+	assert.Error(t, err)
+	assert.Nil(t, p)
+
+	v, ok = context.GetOk(request, ctxSecurityPrincipal)
+	assert.False(t, ok)
+	assert.Nil(t, v)
+
+	request.SetBasicAuth("admin", "admin")
+	p, err = ctx.Authorize(request, ri)
+	assert.NoError(t, err)
+	assert.Equal(t, "admin", p)
+
+	v, ok = context.GetOk(request, ctxSecurityPrincipal)
+	assert.True(t, ok)
+	assert.Equal(t, "admin", v)
+
+	request.SetBasicAuth("doesn't matter", "doesn't")
+	pp, rr := ctx.Authorize(request, ri)
+	assert.Equal(t, p, pp)
+	assert.Equal(t, err, rr)
+}
+
+func TestContextNegotiateContentType(t *testing.T) {
+	spec, api := petstore.NewAPI(t)
+	ctx := NewContext(spec, api, nil)
+	ctx.router = DefaultRouter(spec, ctx.api)
+
+	request, _ := http.NewRequest("POST", "/pets", nil)
+	// request.Header.Add("Accept", "*/*")
+	request.Header.Add("content-type", "text/html")
+
+	v, ok := context.GetOk(request, ctxBoundParams)
+	assert.False(t, ok)
+	assert.Nil(t, v)
+
+	ri, _ := ctx.RouteInfo(request)
+
+	res := NegotiateContentType(request, ri.Produces, "")
+	assert.Equal(t, "", res)
+
+	res2 := NegotiateContentType(request, ri.Produces, "text/plain")
+	assert.Equal(t, "text/plain", res2)
+}
+
+func TestContextBindAndValidate(t *testing.T) {
+	spec, api := petstore.NewAPI(t)
+	ctx := NewContext(spec, api, nil)
+	ctx.router = DefaultRouter(spec, ctx.api)
+
+	request, _ := http.NewRequest("POST", "/pets", nil)
+	request.Header.Add("Accept", "*/*")
+	request.Header.Add("content-type", "text/html")
+	request.ContentLength = 1
+
+	v, ok := context.GetOk(request, ctxBoundParams)
+	assert.False(t, ok)
+	assert.Nil(t, v)
+
+	ri, _ := ctx.RouteInfo(request)
+	data, result := ctx.BindAndValidate(request, ri) // this requires a much more thorough test
+	assert.NotNil(t, data)
+	assert.NotNil(t, result)
+
+	v, ok = context.GetOk(request, ctxBoundParams)
+	assert.True(t, ok)
+	assert.NotNil(t, v)
+
+	dd, rr := ctx.BindAndValidate(request, ri)
+	assert.Equal(t, data, dd)
+	assert.Equal(t, result, rr)
+}
+
+func TestContextRender(t *testing.T) {
+	ct := runtime.JSONMime
+	spec, api := petstore.NewAPI(t)
+
+	assert.NotNil(t, spec)
+	assert.NotNil(t, api)
+	ctx := NewContext(spec, api, nil)
+	ctx.router = DefaultRouter(spec, ctx.api)
+
+	request, _ := http.NewRequest("GET", "pets", nil)
+	request.Header.Set(runtime.HeaderAccept, ct)
+	ri, _ := ctx.RouteInfo(request)
+
+	recorder := httptest.NewRecorder()
+	ctx.Respond(recorder, request, []string{ct}, ri, map[string]interface{}{"name": "hello"})
+	assert.Equal(t, 200, recorder.Code)
+	assert.Equal(t, "{\"name\":\"hello\"}\n", recorder.Body.String())
+
+	recorder = httptest.NewRecorder()
+	ctx.Respond(recorder, request, []string{ct}, ri, errors.New("this went wrong"))
+	assert.Equal(t, 500, recorder.Code)
+
+	recorder = httptest.NewRecorder()
+	assert.Panics(t, func() { ctx.Respond(recorder, request, []string{ct}, ri, map[int]interface{}{1: "hello"}) })
+
+	recorder = httptest.NewRecorder()
+	request, _ = http.NewRequest("GET", "pets", nil)
+	assert.Panics(t, func() { ctx.Respond(recorder, request, []string{}, ri, map[string]interface{}{"name": "hello"}) })
+
+	request, _ = http.NewRequest("GET", "/pets", nil)
+	request.Header.Set(runtime.HeaderAccept, ct)
+	ri, _ = ctx.RouteInfo(request)
+
+	recorder = httptest.NewRecorder()
+	ctx.Respond(recorder, request, []string{ct}, ri, map[string]interface{}{"name": "hello"})
+	assert.Equal(t, 200, recorder.Code)
+	assert.Equal(t, "{\"name\":\"hello\"}\n", recorder.Body.String())
+
+	recorder = httptest.NewRecorder()
+	ctx.Respond(recorder, request, []string{ct}, ri, errors.New("this went wrong"))
+	assert.Equal(t, 500, recorder.Code)
+
+	recorder = httptest.NewRecorder()
+	assert.Panics(t, func() { ctx.Respond(recorder, request, []string{ct}, ri, map[int]interface{}{1: "hello"}) })
+
+	// recorder = httptest.NewRecorder()
+	// request, _ = http.NewRequest("GET", "/pets", nil)
+	// assert.Panics(t, func() { ctx.Respond(recorder, request, []string{}, ri, map[string]interface{}{"name": "hello"}) })
+
+	recorder = httptest.NewRecorder()
+	request, _ = http.NewRequest("DELETE", "/pets/1", nil)
+	ri, _ = ctx.RouteInfo(request)
+	ctx.Respond(recorder, request, ri.Produces, ri, nil)
+	assert.Equal(t, 204, recorder.Code)
+}
+
+func TestContextValidResponseFormat(t *testing.T) {
+	ct := "application/json"
+	spec, api := petstore.NewAPI(t)
+	ctx := NewContext(spec, api, nil)
+	ctx.router = DefaultRouter(spec, ctx.api)
+
+	request, _ := http.NewRequest("GET", "http://localhost:8080", nil)
+	request.Header.Set(runtime.HeaderAccept, ct)
+
+	// check there's nothing there
+	cached, ok := context.GetOk(request, ctxResponseFormat)
+	assert.False(t, ok)
+	assert.Empty(t, cached)
+
+	// trigger the parse
+	mt := ctx.ResponseFormat(request, []string{ct})
+	assert.Equal(t, ct, mt)
+
+	// check it was cached
+	cached, ok = context.GetOk(request, ctxResponseFormat)
+	assert.True(t, ok)
+	assert.Equal(t, ct, cached)
+
+	// check if the cast works and fetch from cache too
+	mt = ctx.ResponseFormat(request, []string{ct})
+	assert.Equal(t, ct, mt)
+}
+
+func TestContextInvalidResponseFormat(t *testing.T) {
+	ct := "application/x-yaml"
+	other := "application/sgml"
+	spec, api := petstore.NewAPI(t)
+	ctx := NewContext(spec, api, nil)
+	ctx.router = DefaultRouter(spec, ctx.api)
+
+	request, _ := http.NewRequest("GET", "http://localhost:8080", nil)
+	request.Header.Set(runtime.HeaderAccept, ct)
+
+	// check there's nothing there
+	cached, ok := context.GetOk(request, ctxResponseFormat)
+	assert.False(t, ok)
+	assert.Empty(t, cached)
+
+	// trigger the parse
+	mt := ctx.ResponseFormat(request, []string{other})
+	assert.Empty(t, mt)
+
+	// check it was cached
+	cached, ok = context.GetOk(request, ctxResponseFormat)
+	assert.False(t, ok)
+	assert.Empty(t, cached)
+
+	// check if the cast works and fetch from cache too
+	mt = ctx.ResponseFormat(request, []string{other})
+	assert.Empty(t, mt)
+}
+
+func TestContextValidRoute(t *testing.T) {
+	spec, api := petstore.NewAPI(t)
+	ctx := NewContext(spec, api, nil)
+	ctx.router = DefaultRouter(spec, ctx.api)
+
+	request, _ := http.NewRequest("GET", "/pets", nil)
+
+	// check there's nothing there
+	_, ok := context.GetOk(request, ctxMatchedRoute)
+	assert.False(t, ok)
+
+	matched, ok := ctx.RouteInfo(request)
+	assert.True(t, ok)
+	assert.NotNil(t, matched)
+
+	// check it was cached
+	_, ok = context.GetOk(request, ctxMatchedRoute)
+	assert.True(t, ok)
+
+	matched, ok = ctx.RouteInfo(request)
+	assert.True(t, ok)
+	assert.NotNil(t, matched)
+}
+
+func TestContextInvalidRoute(t *testing.T) {
+	spec, api := petstore.NewAPI(t)
+	ctx := NewContext(spec, api, nil)
+	ctx.router = DefaultRouter(spec, ctx.api)
+
+	request, _ := http.NewRequest("DELETE", "pets", nil)
+
+	// check there's nothing there
+	_, ok := context.GetOk(request, ctxMatchedRoute)
+	assert.False(t, ok)
+
+	matched, ok := ctx.RouteInfo(request)
+	assert.False(t, ok)
+	assert.Nil(t, matched)
+
+	// check it was cached
+	_, ok = context.GetOk(request, ctxMatchedRoute)
+	assert.False(t, ok)
+
+	matched, ok = ctx.RouteInfo(request)
+	assert.False(t, ok)
+	assert.Nil(t, matched)
+}
+
+func TestContextValidContentType(t *testing.T) {
+	ct := "application/json"
+	ctx := NewContext(nil, nil, nil)
+
+	request, _ := http.NewRequest("GET", "http://localhost:8080", nil)
+	request.Header.Set(runtime.HeaderContentType, ct)
+
+	// check there's nothing there
+	_, ok := context.GetOk(request, ctxContentType)
+	assert.False(t, ok)
+
+	// trigger the parse
+	mt, _, err := ctx.ContentType(request)
+	assert.NoError(t, err)
+	assert.Equal(t, ct, mt)
+
+	// check it was cached
+	_, ok = context.GetOk(request, ctxContentType)
+	assert.True(t, ok)
+
+	// check if the cast works and fetch from cache too
+	mt, _, err = ctx.ContentType(request)
+	assert.NoError(t, err)
+	assert.Equal(t, ct, mt)
+}
+
+func TestContextInvalidContentType(t *testing.T) {
+	ct := "application("
+	ctx := NewContext(nil, nil, nil)
+
+	request, _ := http.NewRequest("GET", "http://localhost:8080", nil)
+	request.Header.Set(runtime.HeaderContentType, ct)
+
+	// check there's nothing there
+	_, ok := context.GetOk(request, ctxContentType)
+	assert.False(t, ok)
+
+	// trigger the parse
+	mt, _, err := ctx.ContentType(request)
+	assert.Error(t, err)
+	assert.Empty(t, mt)
+
+	// check it was not cached
+	_, ok = context.GetOk(request, ctxContentType)
+	assert.False(t, ok)
+
+	// check if the failure continues
+	_, _, err = ctx.ContentType(request)
+	assert.Error(t, err)
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/denco/LICENSE
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/denco/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2014 Naoya Inada <naoina@kuune.org>
+
+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.
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/denco/README.md
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/denco/README.md
@@ -0,0 +1,180 @@
+# Denco [![Build Status](https://travis-ci.org/naoina/denco.png?branch=master)](https://travis-ci.org/naoina/denco)
+
+The fast and flexible HTTP request router for [Go](http://golang.org).
+
+Denco is based on Double-Array implementation of [Kocha-urlrouter](https://github.com/naoina/kocha-urlrouter).
+However, Denco is optimized and some features added.
+
+## Features
+
+* Fast (See [go-http-routing-benchmark](https://github.com/naoina/go-http-routing-benchmark))
+* [URL patterns](#url-patterns) (`/foo/:bar` and `/foo/*wildcard`)
+* Small (but enough) URL router API
+* HTTP request multiplexer like `http.ServeMux`
+
+## Installation
+
+    go get -u github.com/go-openapi/runtime/middleware/denco
+
+## Using as HTTP request multiplexer
+
+```go
+package main
+
+import (
+    "fmt"
+    "log"
+    "net/http"
+
+    "github.com/go-openapi/runtime/middleware/denco"
+)
+
+func Index(w http.ResponseWriter, r *http.Request, params denco.Params) {
+    fmt.Fprintf(w, "Welcome to Denco!\n")
+}
+
+func User(w http.ResponseWriter, r *http.Request, params denco.Params) {
+    fmt.Fprintf(w, "Hello %s!\n", params.Get("name"))
+}
+
+func main() {
+    mux := denco.NewMux()
+    handler, err := mux.Build([]denco.Handler{
+        mux.GET("/", Index),
+        mux.GET("/user/:name", User),
+        mux.POST("/user/:name", User),
+    })
+    if err != nil {
+        panic(err)
+    }
+    log.Fatal(http.ListenAndServe(":8080", handler))
+}
+```
+
+## Using as URL router
+
+```go
+package main
+
+import (
+	"fmt"
+
+	"github.com/go-openapi/runtime/middleware/denco"
+)
+
+type route struct {
+	name string
+}
+
+func main() {
+	router := denco.New()
+	router.Build([]denco.Record{
+		{"/", &route{"root"}},
+		{"/user/:id", &route{"user"}},
+		{"/user/:name/:id", &route{"username"}},
+		{"/static/*filepath", &route{"static"}},
+	})
+
+	data, params, found := router.Lookup("/")
+	// print `&main.route{name:"root"}, denco.Params(nil), true`.
+	fmt.Printf("%#v, %#v, %#v\n", data, params, found)
+
+	data, params, found = router.Lookup("/user/hoge")
+	// print `&main.route{name:"user"}, denco.Params{denco.Param{Name:"id", Value:"hoge"}}, true`.
+	fmt.Printf("%#v, %#v, %#v\n", data, params, found)
+
+	data, params, found = router.Lookup("/user/hoge/7")
+	// print `&main.route{name:"username"}, denco.Params{denco.Param{Name:"name", Value:"hoge"}, denco.Param{Name:"id", Value:"7"}}, true`.
+	fmt.Printf("%#v, %#v, %#v\n", data, params, found)
+
+	data, params, found = router.Lookup("/static/path/to/file")
+	// print `&main.route{name:"static"}, denco.Params{denco.Param{Name:"filepath", Value:"path/to/file"}}, true`.
+	fmt.Printf("%#v, %#v, %#v\n", data, params, found)
+}
+```
+
+See [Godoc](http://godoc.org/github.com/go-openapi/runtime/middleware/denco) for more details.
+
+## Getting the value of path parameter
+
+You can get the value of path parameter by 2 ways.
+
+1. Using [`denco.Params.Get`](http://godoc.org/github.com/go-openapi/runtime/middleware/denco#Params.Get) method
+2. Find by loop
+
+```go
+package main
+
+import (
+    "fmt"
+
+    "github.com/go-openapi/runtime/middleware/denco"
+)
+
+func main() {
+    router := denco.New()
+    if err := router.Build([]denco.Record{
+        {"/user/:name/:id", "route1"},
+    }); err != nil {
+        panic(err)
+    }
+
+    // 1. Using denco.Params.Get method.
+    _, params, _ := router.Lookup("/user/alice/1")
+    name := params.Get("name")
+    if name != "" {
+        fmt.Printf("Hello %s.\n", name) // prints "Hello alice.".
+    }
+
+    // 2. Find by loop.
+    for _, param := range params {
+        if param.Name == "name" {
+            fmt.Printf("Hello %s.\n", name) // prints "Hello alice.".
+        }
+    }
+}
+```
+
+## URL patterns
+
+Denco's route matching strategy is "most nearly matching".
+
+When routes `/:name` and `/alice` have been built, URI `/alice` matches the route `/alice`, not `/:name`.
+Because URI `/alice` is more match with the route `/alice` than `/:name`.
+
+For more example, when routes below have been built:
+
+```
+/user/alice
+/user/:name
+/user/:name/:id
+/user/alice/:id
+/user/:id/bob
+```
+
+Routes matching are:
+
+```
+/user/alice      => "/user/alice" (no match with "/user/:name")
+/user/bob        => "/user/:name"
+/user/naoina/1   => "/user/:name/1"
+/user/alice/1    => "/user/alice/:id" (no match with "/user/:name/:id")
+/user/1/bob      => "/user/:id/bob"   (no match with "/user/:name/:id")
+/user/alice/bob  => "/user/alice/:id" (no match with "/user/:name/:id" and "/user/:id/bob")
+```
+
+## Limitation
+
+Denco has some limitations below.
+
+* Number of param records (such as `/:name`) must be less than 2^22
+* Number of elements of internal slice must be less than 2^22
+
+## Benchmarks
+
+    cd $GOPATH/github.com/go-openapi/runtime/middleware/denco
+    go test -bench . -benchmem
+
+## License
+
+Denco is licensed under the MIT License.
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/denco/router.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/denco/router.go
@@ -0,0 +1,452 @@
+// Package denco provides fast URL router.
+package denco
+
+import (
+	"fmt"
+	"sort"
+	"strings"
+)
+
+const (
+	// ParamCharacter is a special character for path parameter.
+	ParamCharacter = ':'
+
+	// WildcardCharacter is a special character for wildcard path parameter.
+	WildcardCharacter = '*'
+
+	// TerminationCharacter is a special character for end of path.
+	TerminationCharacter = '#'
+
+	// MaxSize is max size of records and internal slice.
+	MaxSize = (1 << 22) - 1
+)
+
+// Router represents a URL router.
+type Router struct {
+	// SizeHint expects the maximum number of path parameters in records to Build.
+	// SizeHint will be used to determine the capacity of the memory to allocate.
+	// By default, SizeHint will be determined from given records to Build.
+	SizeHint int
+
+	static map[string]interface{}
+	param  *doubleArray
+}
+
+// New returns a new Router.
+func New() *Router {
+	return &Router{
+		SizeHint: -1,
+		static:   make(map[string]interface{}),
+		param:    newDoubleArray(),
+	}
+}
+
+// Lookup returns data and path parameters that associated with path.
+// params is a slice of the Param that arranged in the order in which parameters appeared.
+// e.g. when built routing path is "/path/:id/:name" and given path is "/path/to/1/alice". params order is [{"id": "1"}, {"name": "alice"}], not [{"name": "alice"}, {"id": "1"}].
+func (rt *Router) Lookup(path string) (data interface{}, params Params, found bool) {
+	if data, found := rt.static[path]; found {
+		return data, nil, true
+	}
+	if len(rt.param.node) == 1 {
+		return nil, nil, false
+	}
+	nd, params, found := rt.param.lookup(path, make([]Param, 0, rt.SizeHint), 1)
+	if !found {
+		return nil, nil, false
+	}
+	for i := 0; i < len(params); i++ {
+		params[i].Name = nd.paramNames[i]
+	}
+	return nd.data, params, true
+}
+
+// Build builds URL router from records.
+func (rt *Router) Build(records []Record) error {
+	statics, params := makeRecords(records)
+	if len(params) > MaxSize {
+		return fmt.Errorf("denco: too many records")
+	}
+	if rt.SizeHint < 0 {
+		rt.SizeHint = 0
+		for _, p := range params {
+			size := 0
+			for _, k := range p.Key {
+				if k == ParamCharacter || k == WildcardCharacter {
+					size++
+				}
+			}
+			if size > rt.SizeHint {
+				rt.SizeHint = size
+			}
+		}
+	}
+	for _, r := range statics {
+		rt.static[r.Key] = r.Value
+	}
+	if err := rt.param.build(params, 1, 0, make(map[int]struct{})); err != nil {
+		return err
+	}
+	return nil
+}
+
+// Param represents name and value of path parameter.
+type Param struct {
+	Name  string
+	Value string
+}
+
+// Params represents the name and value of path parameters.
+type Params []Param
+
+// Get gets the first value associated with the given name.
+// If there are no values associated with the key, Get returns "".
+func (ps Params) Get(name string) string {
+	for _, p := range ps {
+		if p.Name == name {
+			return p.Value
+		}
+	}
+	return ""
+}
+
+type doubleArray struct {
+	bc   []baseCheck
+	node []*node
+}
+
+func newDoubleArray() *doubleArray {
+	return &doubleArray{
+		bc:   []baseCheck{0},
+		node: []*node{nil}, // A start index is adjusting to 1 because 0 will be used as a mark of non-existent node.
+	}
+}
+
+// baseCheck contains BASE, CHECK and Extra flags.
+// From the top, 22bits of BASE, 2bits of Extra flags and 8bits of CHECK.
+//
+//  BASE (22bit) | Extra flags (2bit) | CHECK (8bit)
+// |----------------------|--|--------|
+// 32                    10  8         0
+type baseCheck uint32
+
+func (bc baseCheck) Base() int {
+	return int(bc >> 10)
+}
+
+func (bc *baseCheck) SetBase(base int) {
+	*bc |= baseCheck(base) << 10
+}
+
+func (bc baseCheck) Check() byte {
+	return byte(bc)
+}
+
+func (bc *baseCheck) SetCheck(check byte) {
+	*bc |= baseCheck(check)
+}
+
+func (bc baseCheck) IsEmpty() bool {
+	return bc&0xfffffcff == 0
+}
+
+func (bc baseCheck) IsSingleParam() bool {
+	return bc&paramTypeSingle == paramTypeSingle
+}
+
+func (bc baseCheck) IsWildcardParam() bool {
+	return bc&paramTypeWildcard == paramTypeWildcard
+}
+
+func (bc baseCheck) IsAnyParam() bool {
+	return bc&paramTypeAny != 0
+}
+
+func (bc *baseCheck) SetSingleParam() {
+	*bc |= (1 << 8)
+}
+
+func (bc *baseCheck) SetWildcardParam() {
+	*bc |= (1 << 9)
+}
+
+const (
+	paramTypeSingle   = 0x0100
+	paramTypeWildcard = 0x0200
+	paramTypeAny      = 0x0300
+)
+
+func (da *doubleArray) lookup(path string, params []Param, idx int) (*node, []Param, bool) {
+	indices := make([]uint64, 0, 1)
+	for i := 0; i < len(path); i++ {
+		if da.bc[idx].IsAnyParam() {
+			indices = append(indices, (uint64(i)<<32)|(uint64(idx)&0xffffffff))
+		}
+		c := path[i]
+		if idx = nextIndex(da.bc[idx].Base(), c); idx >= len(da.bc) || da.bc[idx].Check() != c {
+			goto BACKTRACKING
+		}
+	}
+	if next := nextIndex(da.bc[idx].Base(), TerminationCharacter); next < len(da.bc) && da.bc[next].Check() == TerminationCharacter {
+		return da.node[da.bc[next].Base()], params, true
+	}
+BACKTRACKING:
+	for j := len(indices) - 1; j >= 0; j-- {
+		i, idx := int(indices[j]>>32), int(indices[j]&0xffffffff)
+		if da.bc[idx].IsSingleParam() {
+			idx := nextIndex(da.bc[idx].Base(), ParamCharacter)
+			if idx >= len(da.bc) {
+				break
+			}
+			next := NextSeparator(path, i)
+			params := append(params, Param{Value: path[i:next]})
+			if nd, params, found := da.lookup(path[next:], params, idx); found {
+				return nd, params, true
+			}
+		}
+		if da.bc[idx].IsWildcardParam() {
+			idx := nextIndex(da.bc[idx].Base(), WildcardCharacter)
+			params := append(params, Param{Value: path[i:]})
+			return da.node[da.bc[idx].Base()], params, true
+		}
+	}
+	return nil, nil, false
+}
+
+// build builds double-array from records.
+func (da *doubleArray) build(srcs []*record, idx, depth int, usedBase map[int]struct{}) error {
+	sort.Stable(recordSlice(srcs))
+	base, siblings, leaf, err := da.arrange(srcs, idx, depth, usedBase)
+	if err != nil {
+		return err
+	}
+	if leaf != nil {
+		nd, err := makeNode(leaf)
+		if err != nil {
+			return err
+		}
+		da.bc[idx].SetBase(len(da.node))
+		da.node = append(da.node, nd)
+	}
+	for _, sib := range siblings {
+		da.setCheck(nextIndex(base, sib.c), sib.c)
+	}
+	for _, sib := range siblings {
+		records := srcs[sib.start:sib.end]
+		switch sib.c {
+		case ParamCharacter:
+			for _, r := range records {
+				next := NextSeparator(r.Key, depth+1)
+				name := r.Key[depth+1 : next]
+				r.paramNames = append(r.paramNames, name)
+				r.Key = r.Key[next:]
+			}
+			da.bc[idx].SetSingleParam()
+			if err := da.build(records, nextIndex(base, sib.c), 0, usedBase); err != nil {
+				return err
+			}
+		case WildcardCharacter:
+			r := records[0]
+			name := r.Key[depth+1 : len(r.Key)-1]
+			r.paramNames = append(r.paramNames, name)
+			r.Key = ""
+			da.bc[idx].SetWildcardParam()
+			if err := da.build(records, nextIndex(base, sib.c), 0, usedBase); err != nil {
+				return err
+			}
+		default:
+			if err := da.build(records, nextIndex(base, sib.c), depth+1, usedBase); err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+// setBase sets BASE.
+func (da *doubleArray) setBase(i, base int) {
+	da.bc[i].SetBase(base)
+}
+
+// setCheck sets CHECK.
+func (da *doubleArray) setCheck(i int, check byte) {
+	da.bc[i].SetCheck(check)
+}
+
+// findEmptyIndex returns an index of unused BASE/CHECK node.
+func (da *doubleArray) findEmptyIndex(start int) int {
+	i := start
+	for ; i < len(da.bc); i++ {
+		if da.bc[i].IsEmpty() {
+			break
+		}
+	}
+	return i
+}
+
+// findBase returns good BASE.
+func (da *doubleArray) findBase(siblings []sibling, start int, usedBase map[int]struct{}) (base int) {
+	for idx, firstChar := start+1, siblings[0].c; ; idx = da.findEmptyIndex(idx + 1) {
+		base = nextIndex(idx, firstChar)
+		if _, used := usedBase[base]; used {
+			continue
+		}
+		i := 0
+		for ; i < len(siblings); i++ {
+			next := nextIndex(base, siblings[i].c)
+			if len(da.bc) <= next {
+				da.bc = append(da.bc, make([]baseCheck, next-len(da.bc)+1)...)
+			}
+			if !da.bc[next].IsEmpty() {
+				break
+			}
+		}
+		if i == len(siblings) {
+			break
+		}
+	}
+	usedBase[base] = struct{}{}
+	return base
+}
+
+func (da *doubleArray) arrange(records []*record, idx, depth int, usedBase map[int]struct{}) (base int, siblings []sibling, leaf *record, err error) {
+	siblings, leaf, err = makeSiblings(records, depth)
+	if err != nil {
+		return -1, nil, nil, err
+	}
+	if len(siblings) < 1 {
+		return -1, nil, leaf, nil
+	}
+	base = da.findBase(siblings, idx, usedBase)
+	if base > MaxSize {
+		return -1, nil, nil, fmt.Errorf("denco: too many elements of internal slice")
+	}
+	da.setBase(idx, base)
+	return base, siblings, leaf, err
+}
+
+// node represents a node of Double-Array.
+type node struct {
+	data interface{}
+
+	// Names of path parameters.
+	paramNames []string
+}
+
+// makeNode returns a new node from record.
+func makeNode(r *record) (*node, error) {
+	dups := make(map[string]bool)
+	for _, name := range r.paramNames {
+		if dups[name] {
+			return nil, fmt.Errorf("denco: path parameter `%v' is duplicated in the key `%v'", name, r.Key)
+		}
+		dups[name] = true
+	}
+	return &node{data: r.Value, paramNames: r.paramNames}, nil
+}
+
+// sibling represents an intermediate data of build for Double-Array.
+type sibling struct {
+	// An index of start of duplicated characters.
+	start int
+
+	// An index of end of duplicated characters.
+	end int
+
+	// A character of sibling.
+	c byte
+}
+
+// nextIndex returns a next index of array of BASE/CHECK.
+func nextIndex(base int, c byte) int {
+	return base ^ int(c)
+}
+
+// makeSiblings returns slice of sibling.
+func makeSiblings(records []*record, depth int) (sib []sibling, leaf *record, err error) {
+	var (
+		pc byte
+		n  int
+	)
+	for i, r := range records {
+		if len(r.Key) <= depth {
+			leaf = r
+			continue
+		}
+		c := r.Key[depth]
+		switch {
+		case pc < c:
+			sib = append(sib, sibling{start: i, c: c})
+		case pc == c:
+			continue
+		default:
+			return nil, nil, fmt.Errorf("denco: BUG: routing table hasn't been sorted")
+		}
+		if n > 0 {
+			sib[n-1].end = i
+		}
+		pc = c
+		n++
+	}
+	if n == 0 {
+		return nil, leaf, nil
+	}
+	sib[n-1].end = len(records)
+	return sib, leaf, nil
+}
+
+// Record represents a record data for router construction.
+type Record struct {
+	// Key for router construction.
+	Key string
+
+	// Result value for Key.
+	Value interface{}
+}
+
+// NewRecord returns a new Record.
+func NewRecord(key string, value interface{}) Record {
+	return Record{
+		Key:   key,
+		Value: value,
+	}
+}
+
+// record represents a record that use to build the Double-Array.
+type record struct {
+	Record
+	paramNames []string
+}
+
+// makeRecords returns the records that use to build Double-Arrays.
+func makeRecords(srcs []Record) (statics, params []*record) {
+	spChars := string([]byte{ParamCharacter, WildcardCharacter})
+	termChar := string(TerminationCharacter)
+	for _, r := range srcs {
+		if strings.ContainsAny(r.Key, spChars) {
+			r.Key += termChar
+			params = append(params, &record{Record: r})
+		} else {
+			statics = append(statics, &record{Record: r})
+		}
+	}
+	return statics, params
+}
+
+// recordSlice represents a slice of Record for sort and implements the sort.Interface.
+type recordSlice []*record
+
+// Len implements the sort.Interface.Len.
+func (rs recordSlice) Len() int {
+	return len(rs)
+}
+
+// Less implements the sort.Interface.Less.
+func (rs recordSlice) Less(i, j int) bool {
+	return rs[i].Key < rs[j].Key
+}
+
+// Swap implements the sort.Interface.Swap.
+func (rs recordSlice) Swap(i, j int) {
+	rs[i], rs[j] = rs[j], rs[i]
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/denco/router_bench_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/denco/router_bench_test.go
@@ -0,0 +1,178 @@
+package denco_test
+
+import (
+	"bytes"
+	"crypto/rand"
+	"fmt"
+	"math/big"
+	"testing"
+
+	"github.com/go-openapi/runtime/middleware/denco"
+)
+
+func BenchmarkRouterLookupStatic100(b *testing.B) {
+	benchmarkRouterLookupStatic(b, 100)
+}
+
+func BenchmarkRouterLookupStatic300(b *testing.B) {
+	benchmarkRouterLookupStatic(b, 300)
+}
+
+func BenchmarkRouterLookupStatic700(b *testing.B) {
+	benchmarkRouterLookupStatic(b, 700)
+}
+
+func BenchmarkRouterLookupSingleParam100(b *testing.B) {
+	records := makeTestSingleParamRecords(100)
+	benchmarkRouterLookupSingleParam(b, records)
+}
+
+func BenchmarkRouterLookupSingleParam300(b *testing.B) {
+	records := makeTestSingleParamRecords(300)
+	benchmarkRouterLookupSingleParam(b, records)
+}
+
+func BenchmarkRouterLookupSingleParam700(b *testing.B) {
+	records := makeTestSingleParamRecords(700)
+	benchmarkRouterLookupSingleParam(b, records)
+}
+
+func BenchmarkRouterLookupSingle2Param100(b *testing.B) {
+	records := makeTestSingle2ParamRecords(100)
+	benchmarkRouterLookupSingleParam(b, records)
+}
+
+func BenchmarkRouterLookupSingle2Param300(b *testing.B) {
+	records := makeTestSingle2ParamRecords(300)
+	benchmarkRouterLookupSingleParam(b, records)
+}
+
+func BenchmarkRouterLookupSingle2Param700(b *testing.B) {
+	records := makeTestSingle2ParamRecords(700)
+	benchmarkRouterLookupSingleParam(b, records)
+}
+
+func BenchmarkRouterBuildStatic100(b *testing.B) {
+	records := makeTestStaticRecords(100)
+	benchmarkRouterBuild(b, records)
+}
+
+func BenchmarkRouterBuildStatic300(b *testing.B) {
+	records := makeTestStaticRecords(300)
+	benchmarkRouterBuild(b, records)
+}
+
+func BenchmarkRouterBuildStatic700(b *testing.B) {
+	records := makeTestStaticRecords(700)
+	benchmarkRouterBuild(b, records)
+}
+
+func BenchmarkRouterBuildSingleParam100(b *testing.B) {
+	records := makeTestSingleParamRecords(100)
+	benchmarkRouterBuild(b, records)
+}
+
+func BenchmarkRouterBuildSingleParam300(b *testing.B) {
+	records := makeTestSingleParamRecords(300)
+	benchmarkRouterBuild(b, records)
+}
+
+func BenchmarkRouterBuildSingleParam700(b *testing.B) {
+	records := makeTestSingleParamRecords(700)
+	benchmarkRouterBuild(b, records)
+}
+
+func BenchmarkRouterBuildSingle2Param100(b *testing.B) {
+	records := makeTestSingle2ParamRecords(100)
+	benchmarkRouterBuild(b, records)
+}
+
+func BenchmarkRouterBuildSingle2Param300(b *testing.B) {
+	records := makeTestSingle2ParamRecords(300)
+	benchmarkRouterBuild(b, records)
+}
+
+func BenchmarkRouterBuildSingle2Param700(b *testing.B) {
+	records := makeTestSingle2ParamRecords(700)
+	benchmarkRouterBuild(b, records)
+}
+
+func benchmarkRouterLookupStatic(b *testing.B, n int) {
+	b.StopTimer()
+	router := denco.New()
+	records := makeTestStaticRecords(n)
+	if err := router.Build(records); err != nil {
+		b.Fatal(err)
+	}
+	record := pickTestRecord(records)
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		if r, _, _ := router.Lookup(record.Key); r != record.Value {
+			b.Fail()
+		}
+	}
+}
+
+func benchmarkRouterLookupSingleParam(b *testing.B, records []denco.Record) {
+	router := denco.New()
+	if err := router.Build(records); err != nil {
+		b.Fatal(err)
+	}
+	record := pickTestRecord(records)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		if _, _, found := router.Lookup(record.Key); !found {
+			b.Fail()
+		}
+	}
+}
+
+func benchmarkRouterBuild(b *testing.B, records []denco.Record) {
+	for i := 0; i < b.N; i++ {
+		router := denco.New()
+		if err := router.Build(records); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+func makeTestStaticRecords(n int) []denco.Record {
+	records := make([]denco.Record, n)
+	for i := 0; i < n; i++ {
+		records[i] = denco.NewRecord("/"+randomString(50), fmt.Sprintf("testroute%d", i))
+	}
+	return records
+}
+
+func makeTestSingleParamRecords(n int) []denco.Record {
+	records := make([]denco.Record, n)
+	for i := 0; i < len(records); i++ {
+		records[i] = denco.NewRecord(fmt.Sprintf("/user%d/:name", i), fmt.Sprintf("testroute%d", i))
+	}
+	return records
+}
+
+func makeTestSingle2ParamRecords(n int) []denco.Record {
+	records := make([]denco.Record, n)
+	for i := 0; i < len(records); i++ {
+		records[i] = denco.NewRecord(fmt.Sprintf("/user%d/:name/comment/:id", i), fmt.Sprintf("testroute%d", i))
+	}
+	return records
+}
+
+func pickTestRecord(records []denco.Record) denco.Record {
+	return records[len(records)/2]
+}
+
+func randomString(n int) string {
+	const srcStrings = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/"
+	var buf bytes.Buffer
+	for i := 0; i < n; i++ {
+		num, err := rand.Int(rand.Reader, big.NewInt(int64(len(srcStrings)-1)))
+		if err != nil {
+			panic(err)
+		}
+		buf.WriteByte(srcStrings[num.Int64()])
+	}
+	return buf.String()
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/denco/router_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/denco/router_test.go
@@ -0,0 +1,524 @@
+package denco_test
+
+import (
+	"fmt"
+	"math/rand"
+	"reflect"
+	"testing"
+	"time"
+
+	"github.com/go-openapi/runtime/middleware/denco"
+)
+
+func routes() []denco.Record {
+	return []denco.Record{
+		{"/", "testroute0"},
+		{"/path/to/route", "testroute1"},
+		{"/path/to/other", "testroute2"},
+		{"/path/to/route/a", "testroute3"},
+		{"/path/to/:param", "testroute4"},
+		{"/gists/:param1/foo/:param2", "testroute12"},
+		{"/gists/:param1/foo/bar", "testroute11"},
+		{"/:param1/:param2/foo/:param3", "testroute13"},
+		{"/path/to/wildcard/*routepath", "testroute5"},
+		{"/path/to/:param1/:param2", "testroute6"},
+		{"/path/to/:param1/sep/:param2", "testroute7"},
+		{"/:year/:month/:day", "testroute8"},
+		{"/user/:id", "testroute9"},
+		{"/a/to/b/:param/*routepath", "testroute10"},
+	}
+}
+
+var realURIs = []denco.Record{
+	{"/authorizations", "/authorizations"},
+	{"/authorizations/:id", "/authorizations/:id"},
+	{"/applications/:client_id/tokens/:access_token", "/applications/:client_id/tokens/:access_token"},
+	{"/events", "/events"},
+	{"/repos/:owner/:repo/events", "/repos/:owner/:repo/events"},
+	{"/networks/:owner/:repo/events", "/networks/:owner/:repo/events"},
+	{"/orgs/:org/events", "/orgs/:org/events"},
+	{"/users/:user/received_events", "/users/:user/received_events"},
+	{"/users/:user/received_events/public", "/users/:user/received_events/public"},
+	{"/users/:user/events", "/users/:user/events"},
+	{"/users/:user/events/public", "/users/:user/events/public"},
+	{"/users/:user/events/orgs/:org", "/users/:user/events/orgs/:org"},
+	{"/feeds", "/feeds"},
+	{"/notifications", "/notifications"},
+	{"/repos/:owner/:repo/notifications", "/repos/:owner/:repo/notifications"},
+	{"/notifications/threads/:id", "/notifications/threads/:id"},
+	{"/notifications/threads/:id/subscription", "/notifications/threads/:id/subscription"},
+	{"/repos/:owner/:repo/stargazers", "/repos/:owner/:repo/stargazers"},
+	{"/users/:user/starred", "/users/:user/starred"},
+	{"/user/starred", "/user/starred"},
+	{"/user/starred/:owner/:repo", "/user/starred/:owner/:repo"},
+	{"/repos/:owner/:repo/subscribers", "/repos/:owner/:repo/subscribers"},
+	{"/users/:user/subscriptions", "/users/:user/subscriptions"},
+	{"/user/subscriptions", "/user/subscriptions"},
+	{"/repos/:owner/:repo/subscription", "/repos/:owner/:repo/subscription"},
+	{"/user/subscriptions/:owner/:repo", "/user/subscriptions/:owner/:repo"},
+	{"/users/:user/gists", "/users/:user/gists"},
+	{"/gists", "/gists"},
+	{"/gists/:id", "/gists/:id"},
+	{"/gists/:id/star", "/gists/:id/star"},
+	{"/repos/:owner/:repo/git/blobs/:sha", "/repos/:owner/:repo/git/blobs/:sha"},
+	{"/repos/:owner/:repo/git/commits/:sha", "/repos/:owner/:repo/git/commits/:sha"},
+	{"/repos/:owner/:repo/git/refs", "/repos/:owner/:repo/git/refs"},
+	{"/repos/:owner/:repo/git/tags/:sha", "/repos/:owner/:repo/git/tags/:sha"},
+	{"/repos/:owner/:repo/git/trees/:sha", "/repos/:owner/:repo/git/trees/:sha"},
+	{"/issues", "/issues"},
+	{"/user/issues", "/user/issues"},
+	{"/orgs/:org/issues", "/orgs/:org/issues"},
+	{"/repos/:owner/:repo/issues", "/repos/:owner/:repo/issues"},
+	{"/repos/:owner/:repo/issues/:number", "/repos/:owner/:repo/issues/:number"},
+	{"/repos/:owner/:repo/assignees", "/repos/:owner/:repo/assignees"},
+	{"/repos/:owner/:repo/assignees/:assignee", "/repos/:owner/:repo/assignees/:assignee"},
+	{"/repos/:owner/:repo/issues/:number/comments", "/repos/:owner/:repo/issues/:number/comments"},
+	{"/repos/:owner/:repo/issues/:number/events", "/repos/:owner/:repo/issues/:number/events"},
+	{"/repos/:owner/:repo/labels", "/repos/:owner/:repo/labels"},
+	{"/repos/:owner/:repo/labels/:name", "/repos/:owner/:repo/labels/:name"},
+	{"/repos/:owner/:repo/issues/:number/labels", "/repos/:owner/:repo/issues/:number/labels"},
+	{"/repos/:owner/:repo/milestones/:number/labels", "/repos/:owner/:repo/milestones/:number/labels"},
+	{"/repos/:owner/:repo/milestones", "/repos/:owner/:repo/milestones"},
+	{"/repos/:owner/:repo/milestones/:number", "/repos/:owner/:repo/milestones/:number"},
+	{"/emojis", "/emojis"},
+	{"/gitignore/templates", "/gitignore/templates"},
+	{"/gitignore/templates/:name", "/gitignore/templates/:name"},
+	{"/meta", "/meta"},
+	{"/rate_limit", "/rate_limit"},
+	{"/users/:user/orgs", "/users/:user/orgs"},
+	{"/user/orgs", "/user/orgs"},
+	{"/orgs/:org", "/orgs/:org"},
+	{"/orgs/:org/members", "/orgs/:org/members"},
+	{"/orgs/:org/members/:user", "/orgs/:org/members/:user"},
+	{"/orgs/:org/public_members", "/orgs/:org/public_members"},
+	{"/orgs/:org/public_members/:user", "/orgs/:org/public_members/:user"},
+	{"/orgs/:org/teams", "/orgs/:org/teams"},
+	{"/teams/:id", "/teams/:id"},
+	{"/teams/:id/members", "/teams/:id/members"},
+	{"/teams/:id/members/:user", "/teams/:id/members/:user"},
+	{"/teams/:id/repos", "/teams/:id/repos"},
+	{"/teams/:id/repos/:owner/:repo", "/teams/:id/repos/:owner/:repo"},
+	{"/user/teams", "/user/teams"},
+	{"/repos/:owner/:repo/pulls", "/repos/:owner/:repo/pulls"},
+	{"/repos/:owner/:repo/pulls/:number", "/repos/:owner/:repo/pulls/:number"},
+	{"/repos/:owner/:repo/pulls/:number/commits", "/repos/:owner/:repo/pulls/:number/commits"},
+	{"/repos/:owner/:repo/pulls/:number/files", "/repos/:owner/:repo/pulls/:number/files"},
+	{"/repos/:owner/:repo/pulls/:number/merge", "/repos/:owner/:repo/pulls/:number/merge"},
+	{"/repos/:owner/:repo/pulls/:number/comments", "/repos/:owner/:repo/pulls/:number/comments"},
+	{"/user/repos", "/user/repos"},
+	{"/users/:user/repos", "/users/:user/repos"},
+	{"/orgs/:org/repos", "/orgs/:org/repos"},
+	{"/repositories", "/repositories"},
+	{"/repos/:owner/:repo", "/repos/:owner/:repo"},
+	{"/repos/:owner/:repo/contributors", "/repos/:owner/:repo/contributors"},
+	{"/repos/:owner/:repo/languages", "/repos/:owner/:repo/languages"},
+	{"/repos/:owner/:repo/teams", "/repos/:owner/:repo/teams"},
+	{"/repos/:owner/:repo/tags", "/repos/:owner/:repo/tags"},
+	{"/repos/:owner/:repo/branches", "/repos/:owner/:repo/branches"},
+	{"/repos/:owner/:repo/branches/:branch", "/repos/:owner/:repo/branches/:branch"},
+	{"/repos/:owner/:repo/collaborators", "/repos/:owner/:repo/collaborators"},
+	{"/repos/:owner/:repo/collaborators/:user", "/repos/:owner/:repo/collaborators/:user"},
+	{"/repos/:owner/:repo/comments", "/repos/:owner/:repo/comments"},
+	{"/repos/:owner/:repo/commits/:sha/comments", "/repos/:owner/:repo/commits/:sha/comments"},
+	{"/repos/:owner/:repo/comments/:id", "/repos/:owner/:repo/comments/:id"},
+	{"/repos/:owner/:repo/commits", "/repos/:owner/:repo/commits"},
+	{"/repos/:owner/:repo/commits/:sha", "/repos/:owner/:repo/commits/:sha"},
+	{"/repos/:owner/:repo/readme", "/repos/:owner/:repo/readme"},
+	{"/repos/:owner/:repo/keys", "/repos/:owner/:repo/keys"},
+	{"/repos/:owner/:repo/keys/:id", "/repos/:owner/:repo/keys/:id"},
+	{"/repos/:owner/:repo/downloads", "/repos/:owner/:repo/downloads"},
+	{"/repos/:owner/:repo/downloads/:id", "/repos/:owner/:repo/downloads/:id"},
+	{"/repos/:owner/:repo/forks", "/repos/:owner/:repo/forks"},
+	{"/repos/:owner/:repo/hooks", "/repos/:owner/:repo/hooks"},
+	{"/repos/:owner/:repo/hooks/:id", "/repos/:owner/:repo/hooks/:id"},
+	{"/repos/:owner/:repo/releases", "/repos/:owner/:repo/releases"},
+	{"/repos/:owner/:repo/releases/:id", "/repos/:owner/:repo/releases/:id"},
+	{"/repos/:owner/:repo/releases/:id/assets", "/repos/:owner/:repo/releases/:id/assets"},
+	{"/repos/:owner/:repo/stats/contributors", "/repos/:owner/:repo/stats/contributors"},
+	{"/repos/:owner/:repo/stats/commit_activity", "/repos/:owner/:repo/stats/commit_activity"},
+	{"/repos/:owner/:repo/stats/code_frequency", "/repos/:owner/:repo/stats/code_frequency"},
+	{"/repos/:owner/:repo/stats/participation", "/repos/:owner/:repo/stats/participation"},
+	{"/repos/:owner/:repo/stats/punch_card", "/repos/:owner/:repo/stats/punch_card"},
+	{"/repos/:owner/:repo/statuses/:ref", "/repos/:owner/:repo/statuses/:ref"},
+	{"/search/repositories", "/search/repositories"},
+	{"/search/code", "/search/code"},
+	{"/search/issues", "/search/issues"},
+	{"/search/users", "/search/users"},
+	{"/legacy/issues/search/:owner/:repository/:state/:keyword", "/legacy/issues/search/:owner/:repository/:state/:keyword"},
+	{"/legacy/repos/search/:keyword", "/legacy/repos/search/:keyword"},
+	{"/legacy/user/search/:keyword", "/legacy/user/search/:keyword"},
+	{"/legacy/user/email/:email", "/legacy/user/email/:email"},
+	{"/users/:user", "/users/:user"},
+	{"/user", "/user"},
+	{"/users", "/users"},
+	{"/user/emails", "/user/emails"},
+	{"/users/:user/followers", "/users/:user/followers"},
+	{"/user/followers", "/user/followers"},
+	{"/users/:user/following", "/users/:user/following"},
+	{"/user/following", "/user/following"},
+	{"/user/following/:user", "/user/following/:user"},
+	{"/users/:user/following/:target_user", "/users/:user/following/:target_user"},
+	{"/users/:user/keys", "/users/:user/keys"},
+	{"/user/keys", "/user/keys"},
+	{"/user/keys/:id", "/user/keys/:id"},
+	{"/people/:userId", "/people/:userId"},
+	{"/people", "/people"},
+	{"/activities/:activityId/people/:collection", "/activities/:activityId/people/:collection"},
+	{"/people/:userId/people/:collection", "/people/:userId/people/:collection"},
+	{"/people/:userId/openIdConnect", "/people/:userId/openIdConnect"},
+	{"/people/:userId/activities/:collection", "/people/:userId/activities/:collection"},
+	{"/activities/:activityId", "/activities/:activityId"},
+	{"/activities", "/activities"},
+	{"/activities/:activityId/comments", "/activities/:activityId/comments"},
+	{"/comments/:commentId", "/comments/:commentId"},
+	{"/people/:userId/moments/:collection", "/people/:userId/moments/:collection"},
+}
+
+type testcase struct {
+	path   string
+	value  interface{}
+	params []denco.Param
+	found  bool
+}
+
+func runLookupTest(t *testing.T, records []denco.Record, testcases []testcase) {
+	r := denco.New()
+	if err := r.Build(records); err != nil {
+		t.Fatal(err)
+	}
+	for _, testcase := range testcases {
+		data, params, found := r.Lookup(testcase.path)
+		if !reflect.DeepEqual(data, testcase.value) || !reflect.DeepEqual(params, denco.Params(testcase.params)) || !reflect.DeepEqual(found, testcase.found) {
+			t.Errorf("Router.Lookup(%q) => (%#v, %#v, %#v), want (%#v, %#v, %#v)", testcase.path, data, params, found, testcase.value, denco.Params(testcase.params), testcase.found)
+		}
+	}
+}
+
+func TestRouter_Lookup(t *testing.T) {
+	testcases := []testcase{
+		{"/", "testroute0", nil, true},
+		{"/gists/1323/foo/bar", "testroute11", []denco.Param{{"param1", "1323"}}, true},
+		{"/gists/1323/foo/133", "testroute12", []denco.Param{{"param1", "1323"}, {"param2", "133"}}, true},
+		{"/234/1323/foo/133", "testroute13", []denco.Param{{"param1", "234"}, {"param2", "1323"}, {"param3", "133"}}, true},
+		{"/path/to/route", "testroute1", nil, true},
+		{"/path/to/other", "testroute2", nil, true},
+		{"/path/to/route/a", "testroute3", nil, true},
+		{"/path/to/hoge", "testroute4", []denco.Param{{"param", "hoge"}}, true},
+		{"/path/to/wildcard/some/params", "testroute5", []denco.Param{{"routepath", "some/params"}}, true},
+		{"/path/to/o1/o2", "testroute6", []denco.Param{{"param1", "o1"}, {"param2", "o2"}}, true},
+		{"/path/to/p1/sep/p2", "testroute7", []denco.Param{{"param1", "p1"}, {"param2", "p2"}}, true},
+		{"/2014/01/06", "testroute8", []denco.Param{{"year", "2014"}, {"month", "01"}, {"day", "06"}}, true},
+		{"/user/777", "testroute9", []denco.Param{{"id", "777"}}, true},
+		{"/a/to/b/p1/some/wildcard/params", "testroute10", []denco.Param{{"param", "p1"}, {"routepath", "some/wildcard/params"}}, true},
+		{"/missing", nil, nil, false},
+	}
+	runLookupTest(t, routes(), testcases)
+
+	records := []denco.Record{
+		{"/", "testroute0"},
+		{"/:b", "testroute1"},
+		{"/*wildcard", "testroute2"},
+	}
+	testcases = []testcase{
+		{"/", "testroute0", nil, true},
+		{"/true", "testroute1", []denco.Param{{"b", "true"}}, true},
+		{"/foo/bar", "testroute2", []denco.Param{{"wildcard", "foo/bar"}}, true},
+	}
+	runLookupTest(t, records, testcases)
+
+	records = []denco.Record{
+		{"/networks/:owner/:repo/events", "testroute0"},
+		{"/orgs/:org/events", "testroute1"},
+		{"/notifications/threads/:id", "testroute2"},
+	}
+	testcases = []testcase{
+		{"/networks/:owner/:repo/events", "testroute0", []denco.Param{{"owner", ":owner"}, {"repo", ":repo"}}, true},
+		{"/orgs/:org/events", "testroute1", []denco.Param{{"org", ":org"}}, true},
+		{"/notifications/threads/:id", "testroute2", []denco.Param{{"id", ":id"}}, true},
+	}
+	runLookupTest(t, records, testcases)
+
+	runLookupTest(t, []denco.Record{
+		{"/", "route2"},
+	}, []testcase{
+		{"/user/alice", nil, nil, false},
+	})
+
+	runLookupTest(t, []denco.Record{
+		{"/user/:name", "route1"},
+	}, []testcase{
+		{"/", nil, nil, false},
+	})
+
+	runLookupTest(t, []denco.Record{
+		{"/*wildcard", "testroute0"},
+		{"/a/:b", "testroute1"},
+	}, []testcase{
+		{"/a", "testroute0", []denco.Param{{"wildcard", "a"}}, true},
+	})
+}
+
+func TestRouter_Lookup_withManyRoutes(t *testing.T) {
+	n := 1000
+	rand.Seed(time.Now().UnixNano())
+	records := make([]denco.Record, n)
+	for i := 0; i < n; i++ {
+		records[i] = denco.Record{Key: "/" + randomString(rand.Intn(50)+10), Value: fmt.Sprintf("route%d", i)}
+	}
+	router := denco.New()
+	if err := router.Build(records); err != nil {
+		t.Fatal(err)
+	}
+	for _, r := range records {
+		data, params, found := router.Lookup(r.Key)
+		if !reflect.DeepEqual(data, r.Value) || len(params) != 0 || !reflect.DeepEqual(found, true) {
+			t.Errorf("Router.Lookup(%q) => (%#v, %#v, %#v), want (%#v, %#v, %#v)", r.Key, data, len(params), found, r.Value, 0, true)
+		}
+	}
+}
+
+func TestRouter_Lookup_realURIs(t *testing.T) {
+	testcases := []testcase{
+		{"/authorizations", "/authorizations", nil, true},
+		{"/authorizations/1", "/authorizations/:id", []denco.Param{{"id", "1"}}, true},
+		{"/applications/1/tokens/zohRoo7e", "/applications/:client_id/tokens/:access_token", []denco.Param{{"client_id", "1"}, {"access_token", "zohRoo7e"}}, true},
+		{"/events", "/events", nil, true},
+		{"/repos/naoina/denco/events", "/repos/:owner/:repo/events", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/networks/naoina/denco/events", "/networks/:owner/:repo/events", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/orgs/something/events", "/orgs/:org/events", []denco.Param{{"org", "something"}}, true},
+		{"/users/naoina/received_events", "/users/:user/received_events", []denco.Param{{"user", "naoina"}}, true},
+		{"/users/naoina/received_events/public", "/users/:user/received_events/public", []denco.Param{{"user", "naoina"}}, true},
+		{"/users/naoina/events", "/users/:user/events", []denco.Param{{"user", "naoina"}}, true},
+		{"/users/naoina/events/public", "/users/:user/events/public", []denco.Param{{"user", "naoina"}}, true},
+		{"/users/naoina/events/orgs/something", "/users/:user/events/orgs/:org", []denco.Param{{"user", "naoina"}, {"org", "something"}}, true},
+		{"/feeds", "/feeds", nil, true},
+		{"/notifications", "/notifications", nil, true},
+		{"/repos/naoina/denco/notifications", "/repos/:owner/:repo/notifications", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/notifications/threads/1", "/notifications/threads/:id", []denco.Param{{"id", "1"}}, true},
+		{"/notifications/threads/2/subscription", "/notifications/threads/:id/subscription", []denco.Param{{"id", "2"}}, true},
+		{"/repos/naoina/denco/stargazers", "/repos/:owner/:repo/stargazers", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/users/naoina/starred", "/users/:user/starred", []denco.Param{{"user", "naoina"}}, true},
+		{"/user/starred", "/user/starred", nil, true},
+		{"/user/starred/naoina/denco", "/user/starred/:owner/:repo", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/subscribers", "/repos/:owner/:repo/subscribers", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/users/naoina/subscriptions", "/users/:user/subscriptions", []denco.Param{{"user", "naoina"}}, true},
+		{"/user/subscriptions", "/user/subscriptions", nil, true},
+		{"/repos/naoina/denco/subscription", "/repos/:owner/:repo/subscription", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/user/subscriptions/naoina/denco", "/user/subscriptions/:owner/:repo", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/users/naoina/gists", "/users/:user/gists", []denco.Param{{"user", "naoina"}}, true},
+		{"/gists", "/gists", nil, true},
+		{"/gists/1", "/gists/:id", []denco.Param{{"id", "1"}}, true},
+		{"/gists/2/star", "/gists/:id/star", []denco.Param{{"id", "2"}}, true},
+		{"/repos/naoina/denco/git/blobs/03c3bbc7f0d12268b9ca53d4fbfd8dc5ae5697b9", "/repos/:owner/:repo/git/blobs/:sha", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"sha", "03c3bbc7f0d12268b9ca53d4fbfd8dc5ae5697b9"}}, true},
+		{"/repos/naoina/denco/git/commits/03c3bbc7f0d12268b9ca53d4fbfd8dc5ae5697b9", "/repos/:owner/:repo/git/commits/:sha", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"sha", "03c3bbc7f0d12268b9ca53d4fbfd8dc5ae5697b9"}}, true},
+		{"/repos/naoina/denco/git/refs", "/repos/:owner/:repo/git/refs", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/git/tags/03c3bbc7f0d12268b9ca53d4fbfd8dc5ae5697b9", "/repos/:owner/:repo/git/tags/:sha", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"sha", "03c3bbc7f0d12268b9ca53d4fbfd8dc5ae5697b9"}}, true},
+		{"/repos/naoina/denco/git/trees/03c3bbc7f0d12268b9ca53d4fbfd8dc5ae5697b9", "/repos/:owner/:repo/git/trees/:sha", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"sha", "03c3bbc7f0d12268b9ca53d4fbfd8dc5ae5697b9"}}, true},
+		{"/issues", "/issues", nil, true},
+		{"/user/issues", "/user/issues", nil, true},
+		{"/orgs/something/issues", "/orgs/:org/issues", []denco.Param{{"org", "something"}}, true},
+		{"/repos/naoina/denco/issues", "/repos/:owner/:repo/issues", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/issues/1", "/repos/:owner/:repo/issues/:number", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"number", "1"}}, true},
+		{"/repos/naoina/denco/assignees", "/repos/:owner/:repo/assignees", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/assignees/foo", "/repos/:owner/:repo/assignees/:assignee", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"assignee", "foo"}}, true},
+		{"/repos/naoina/denco/issues/1/comments", "/repos/:owner/:repo/issues/:number/comments", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"number", "1"}}, true},
+		{"/repos/naoina/denco/issues/1/events", "/repos/:owner/:repo/issues/:number/events", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"number", "1"}}, true},
+		{"/repos/naoina/denco/labels", "/repos/:owner/:repo/labels", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/labels/bug", "/repos/:owner/:repo/labels/:name", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"name", "bug"}}, true},
+		{"/repos/naoina/denco/issues/1/labels", "/repos/:owner/:repo/issues/:number/labels", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"number", "1"}}, true},
+		{"/repos/naoina/denco/milestones/1/labels", "/repos/:owner/:repo/milestones/:number/labels", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"number", "1"}}, true},
+		{"/repos/naoina/denco/milestones", "/repos/:owner/:repo/milestones", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/milestones/1", "/repos/:owner/:repo/milestones/:number", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"number", "1"}}, true},
+		{"/emojis", "/emojis", nil, true},
+		{"/gitignore/templates", "/gitignore/templates", nil, true},
+		{"/gitignore/templates/Go", "/gitignore/templates/:name", []denco.Param{{"name", "Go"}}, true},
+		{"/meta", "/meta", nil, true},
+		{"/rate_limit", "/rate_limit", nil, true},
+		{"/users/naoina/orgs", "/users/:user/orgs", []denco.Param{{"user", "naoina"}}, true},
+		{"/user/orgs", "/user/orgs", nil, true},
+		{"/orgs/something", "/orgs/:org", []denco.Param{{"org", "something"}}, true},
+		{"/orgs/something/members", "/orgs/:org/members", []denco.Param{{"org", "something"}}, true},
+		{"/orgs/something/members/naoina", "/orgs/:org/members/:user", []denco.Param{{"org", "something"}, {"user", "naoina"}}, true},
+		{"/orgs/something/public_members", "/orgs/:org/public_members", []denco.Param{{"org", "something"}}, true},
+		{"/orgs/something/public_members/naoina", "/orgs/:org/public_members/:user", []denco.Param{{"org", "something"}, {"user", "naoina"}}, true},
+		{"/orgs/something/teams", "/orgs/:org/teams", []denco.Param{{"org", "something"}}, true},
+		{"/teams/1", "/teams/:id", []denco.Param{{"id", "1"}}, true},
+		{"/teams/2/members", "/teams/:id/members", []denco.Param{{"id", "2"}}, true},
+		{"/teams/3/members/naoina", "/teams/:id/members/:user", []denco.Param{{"id", "3"}, {"user", "naoina"}}, true},
+		{"/teams/4/repos", "/teams/:id/repos", []denco.Param{{"id", "4"}}, true},
+		{"/teams/5/repos/naoina/denco", "/teams/:id/repos/:owner/:repo", []denco.Param{{"id", "5"}, {"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/user/teams", "/user/teams", nil, true},
+		{"/repos/naoina/denco/pulls", "/repos/:owner/:repo/pulls", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/pulls/1", "/repos/:owner/:repo/pulls/:number", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"number", "1"}}, true},
+		{"/repos/naoina/denco/pulls/1/commits", "/repos/:owner/:repo/pulls/:number/commits", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"number", "1"}}, true},
+		{"/repos/naoina/denco/pulls/1/files", "/repos/:owner/:repo/pulls/:number/files", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"number", "1"}}, true},
+		{"/repos/naoina/denco/pulls/1/merge", "/repos/:owner/:repo/pulls/:number/merge", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"number", "1"}}, true},
+		{"/repos/naoina/denco/pulls/1/comments", "/repos/:owner/:repo/pulls/:number/comments", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"number", "1"}}, true},
+		{"/user/repos", "/user/repos", nil, true},
+		{"/users/naoina/repos", "/users/:user/repos", []denco.Param{{"user", "naoina"}}, true},
+		{"/orgs/something/repos", "/orgs/:org/repos", []denco.Param{{"org", "something"}}, true},
+		{"/repositories", "/repositories", nil, true},
+		{"/repos/naoina/denco", "/repos/:owner/:repo", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/contributors", "/repos/:owner/:repo/contributors", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/languages", "/repos/:owner/:repo/languages", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/teams", "/repos/:owner/:repo/teams", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/tags", "/repos/:owner/:repo/tags", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/branches", "/repos/:owner/:repo/branches", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/branches/master", "/repos/:owner/:repo/branches/:branch", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"branch", "master"}}, true},
+		{"/repos/naoina/denco/collaborators", "/repos/:owner/:repo/collaborators", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/collaborators/something", "/repos/:owner/:repo/collaborators/:user", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"user", "something"}}, true},
+		{"/repos/naoina/denco/comments", "/repos/:owner/:repo/comments", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/commits/03c3bbc7f0d12268b9ca53d4fbfd8dc5ae5697b9/comments", "/repos/:owner/:repo/commits/:sha/comments", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"sha", "03c3bbc7f0d12268b9ca53d4fbfd8dc5ae5697b9"}}, true},
+		{"/repos/naoina/denco/comments/1", "/repos/:owner/:repo/comments/:id", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"id", "1"}}, true},
+		{"/repos/naoina/denco/commits", "/repos/:owner/:repo/commits", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/commits/03c3bbc7f0d12268b9ca53d4fbfd8dc5ae5697b9", "/repos/:owner/:repo/commits/:sha", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"sha", "03c3bbc7f0d12268b9ca53d4fbfd8dc5ae5697b9"}}, true},
+		{"/repos/naoina/denco/readme", "/repos/:owner/:repo/readme", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/keys", "/repos/:owner/:repo/keys", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/keys/1", "/repos/:owner/:repo/keys/:id", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"id", "1"}}, true},
+		{"/repos/naoina/denco/downloads", "/repos/:owner/:repo/downloads", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/downloads/2", "/repos/:owner/:repo/downloads/:id", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"id", "2"}}, true},
+		{"/repos/naoina/denco/forks", "/repos/:owner/:repo/forks", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/hooks", "/repos/:owner/:repo/hooks", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/hooks/2", "/repos/:owner/:repo/hooks/:id", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"id", "2"}}, true},
+		{"/repos/naoina/denco/releases", "/repos/:owner/:repo/releases", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/releases/1", "/repos/:owner/:repo/releases/:id", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"id", "1"}}, true},
+		{"/repos/naoina/denco/releases/1/assets", "/repos/:owner/:repo/releases/:id/assets", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"id", "1"}}, true},
+		{"/repos/naoina/denco/stats/contributors", "/repos/:owner/:repo/stats/contributors", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/stats/commit_activity", "/repos/:owner/:repo/stats/commit_activity", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/stats/code_frequency", "/repos/:owner/:repo/stats/code_frequency", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/stats/participation", "/repos/:owner/:repo/stats/participation", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/stats/punch_card", "/repos/:owner/:repo/stats/punch_card", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}}, true},
+		{"/repos/naoina/denco/statuses/master", "/repos/:owner/:repo/statuses/:ref", []denco.Param{{"owner", "naoina"}, {"repo", "denco"}, {"ref", "master"}}, true},
+		{"/search/repositories", "/search/repositories", nil, true},
+		{"/search/code", "/search/code", nil, true},
+		{"/search/issues", "/search/issues", nil, true},
+		{"/search/users", "/search/users", nil, true},
+		{"/legacy/issues/search/naoina/denco/closed/test", "/legacy/issues/search/:owner/:repository/:state/:keyword", []denco.Param{{"owner", "naoina"}, {"repository", "denco"}, {"state", "closed"}, {"keyword", "test"}}, true},
+		{"/legacy/repos/search/test", "/legacy/repos/search/:keyword", []denco.Param{{"keyword", "test"}}, true},
+		{"/legacy/user/search/test", "/legacy/user/search/:keyword", []denco.Param{{"keyword", "test"}}, true},
+		{"/legacy/user/email/naoina@kuune.org", "/legacy/user/email/:email", []denco.Param{{"email", "naoina@kuune.org"}}, true},
+		{"/users/naoina", "/users/:user", []denco.Param{{"user", "naoina"}}, true},
+		{"/user", "/user", nil, true},
+		{"/users", "/users", nil, true},
+		{"/user/emails", "/user/emails", nil, true},
+		{"/users/naoina/followers", "/users/:user/followers", []denco.Param{{"user", "naoina"}}, true},
+		{"/user/followers", "/user/followers", nil, true},
+		{"/users/naoina/following", "/users/:user/following", []denco.Param{{"user", "naoina"}}, true},
+		{"/user/following", "/user/following", nil, true},
+		{"/user/following/naoina", "/user/following/:user", []denco.Param{{"user", "naoina"}}, true},
+		{"/users/naoina/following/target", "/users/:user/following/:target_user", []denco.Param{{"user", "naoina"}, {"target_user", "target"}}, true},
+		{"/users/naoina/keys", "/users/:user/keys", []denco.Param{{"user", "naoina"}}, true},
+		{"/user/keys", "/user/keys", nil, true},
+		{"/user/keys/1", "/user/keys/:id", []denco.Param{{"id", "1"}}, true},
+		{"/people/me", "/people/:userId", []denco.Param{{"userId", "me"}}, true},
+		{"/people", "/people", nil, true},
+		{"/activities/foo/people/vault", "/activities/:activityId/people/:collection", []denco.Param{{"activityId", "foo"}, {"collection", "vault"}}, true},
+		{"/people/me/people/vault", "/people/:userId/people/:collection", []denco.Param{{"userId", "me"}, {"collection", "vault"}}, true},
+		{"/people/me/openIdConnect", "/people/:userId/openIdConnect", []denco.Param{{"userId", "me"}}, true},
+		{"/people/me/activities/vault", "/people/:userId/activities/:collection", []denco.Param{{"userId", "me"}, {"collection", "vault"}}, true},
+		{"/activities/foo", "/activities/:activityId", []denco.Param{{"activityId", "foo"}}, true},
+		{"/activities", "/activities", nil, true},
+		{"/activities/foo/comments", "/activities/:activityId/comments", []denco.Param{{"activityId", "foo"}}, true},
+		{"/comments/hoge", "/comments/:commentId", []denco.Param{{"commentId", "hoge"}}, true},
+		{"/people/me/moments/vault", "/people/:userId/moments/:collection", []denco.Param{{"userId", "me"}, {"collection", "vault"}}, true},
+	}
+	runLookupTest(t, realURIs, testcases)
+}
+
+func TestRouter_Build(t *testing.T) {
+	// test for duplicate name of path parameters.
+	func() {
+		r := denco.New()
+		if err := r.Build([]denco.Record{
+			{"/:user/:id/:id", "testroute0"},
+			{"/:user/:user/:id", "testroute0"},
+		}); err == nil {
+			t.Errorf("no error returned by duplicate name of path parameters")
+		}
+	}()
+}
+
+func TestRouter_Build_withoutSizeHint(t *testing.T) {
+	for _, v := range []struct {
+		keys     []string
+		sizeHint int
+	}{
+		{[]string{"/user"}, 0},
+		{[]string{"/user/:id"}, 1},
+		{[]string{"/user/:id/post"}, 1},
+		{[]string{"/user/:id/:group"}, 2},
+		{[]string{"/user/:id/post/:cid"}, 2},
+		{[]string{"/user/:id/post/:cid", "/admin/:id/post/:cid"}, 2},
+		{[]string{"/user/:id", "/admin/:id/post/:cid"}, 2},
+		{[]string{"/user/:id/post/:cid", "/admin/:id/post/:cid/:type"}, 3},
+	} {
+		r := denco.New()
+		actual := r.SizeHint
+		expect := -1
+		if !reflect.DeepEqual(actual, expect) {
+			t.Errorf(`before Build; Router.SizeHint => (%[1]T=%#[1]v); want (%[2]T=%#[2]v)`, actual, expect)
+		}
+		records := make([]denco.Record, len(v.keys))
+		for i, k := range v.keys {
+			records[i] = denco.Record{Key: k, Value: "value"}
+		}
+		if err := r.Build(records); err != nil {
+			t.Fatal(err)
+		}
+		actual = r.SizeHint
+		expect = v.sizeHint
+		if !reflect.DeepEqual(actual, expect) {
+			t.Errorf(`Router.Build(%#v); Router.SizeHint => (%[2]T=%#[2]v); want (%[3]T=%#[3]v)`, records, actual, expect)
+		}
+	}
+}
+
+func TestRouter_Build_withSizeHint(t *testing.T) {
+	for _, v := range []struct {
+		key      string
+		sizeHint int
+		expect   int
+	}{
+		{"/user", 0, 0},
+		{"/user", 1, 1},
+		{"/user", 2, 2},
+		{"/user/:id", 3, 3},
+		{"/user/:id/:group", 0, 0},
+		{"/user/:id/:group", 1, 1},
+	} {
+		r := denco.New()
+		r.SizeHint = v.sizeHint
+		records := []denco.Record{
+			{v.key, "value"},
+		}
+		if err := r.Build(records); err != nil {
+			t.Fatal(err)
+		}
+		actual := r.SizeHint
+		expect := v.expect
+		if !reflect.DeepEqual(actual, expect) {
+			t.Errorf(`Router.Build(%#v); Router.SizeHint => (%[2]T=%#[2]v); want (%[3]T=%#[3]v)`, records, actual, expect)
+		}
+	}
+}
+
+func TestParams_Get(t *testing.T) {
+	params := denco.Params([]denco.Param{
+		{"name1", "value1"},
+		{"name2", "value2"},
+		{"name3", "value3"},
+		{"name1", "value4"},
+	})
+	for _, v := range []struct{ value, expected string }{
+		{"name1", "value1"},
+		{"name2", "value2"},
+		{"name3", "value3"},
+		{"name4", ""},
+	} {
+		actual := params.Get(v.value)
+		expected := v.expected
+		if !reflect.DeepEqual(actual, expected) {
+			t.Errorf("Params.Get(%q) => %#v, want %#v", v.value, actual, expected)
+		}
+	}
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/denco/server.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/denco/server.go
@@ -0,0 +1,106 @@
+package denco
+
+import (
+	"net/http"
+)
+
+// Mux represents a multiplexer for HTTP request.
+type Mux struct{}
+
+// NewMux returns a new Mux.
+func NewMux() *Mux {
+	return &Mux{}
+}
+
+// GET is shorthand of Mux.Handler("GET", path, handler).
+func (m *Mux) GET(path string, handler HandlerFunc) Handler {
+	return m.Handler("GET", path, handler)
+}
+
+// POST is shorthand of Mux.Handler("POST", path, handler).
+func (m *Mux) POST(path string, handler HandlerFunc) Handler {
+	return m.Handler("POST", path, handler)
+}
+
+// PUT is shorthand of Mux.Handler("PUT", path, handler).
+func (m *Mux) PUT(path string, handler HandlerFunc) Handler {
+	return m.Handler("PUT", path, handler)
+}
+
+// HEAD is shorthand of Mux.Handler("HEAD", path, handler).
+func (m *Mux) HEAD(path string, handler HandlerFunc) Handler {
+	return m.Handler("HEAD", path, handler)
+}
+
+// Handler returns a handler for HTTP method.
+func (m *Mux) Handler(method, path string, handler HandlerFunc) Handler {
+	return Handler{
+		Method: method,
+		Path:   path,
+		Func:   handler,
+	}
+}
+
+// Build builds a http.Handler.
+func (m *Mux) Build(handlers []Handler) (http.Handler, error) {
+	recordMap := make(map[string][]Record)
+	for _, h := range handlers {
+		recordMap[h.Method] = append(recordMap[h.Method], NewRecord(h.Path, h.Func))
+	}
+	mux := newServeMux()
+	for m, records := range recordMap {
+		router := New()
+		if err := router.Build(records); err != nil {
+			return nil, err
+		}
+		mux.routers[m] = router
+	}
+	return mux, nil
+}
+
+// Handler represents a handler of HTTP request.
+type Handler struct {
+	// Method is an HTTP method.
+	Method string
+
+	// Path is a routing path for handler.
+	Path string
+
+	// Func is a function of handler of HTTP request.
+	Func HandlerFunc
+}
+
+// The HandlerFunc type is aliased to type of handler function.
+type HandlerFunc func(w http.ResponseWriter, r *http.Request, params Params)
+
+type serveMux struct {
+	routers map[string]*Router
+}
+
+func newServeMux() *serveMux {
+	return &serveMux{
+		routers: make(map[string]*Router),
+	}
+}
+
+// ServeHTTP implements http.Handler interface.
+func (mux *serveMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	handler, params := mux.handler(r.Method, r.URL.Path)
+	handler(w, r, params)
+}
+
+func (mux *serveMux) handler(method, path string) (HandlerFunc, []Param) {
+	if router, found := mux.routers[method]; found {
+		if handler, params, found := router.Lookup(path); found {
+			return handler.(HandlerFunc), params
+		}
+	}
+	return NotFound, nil
+}
+
+// NotFound replies to the request with an HTTP 404 not found error.
+// NotFound is called when unknown HTTP method or a handler not found.
+// If you want to use the your own NotFound handler, please overwrite this variable.
+var NotFound = func(w http.ResponseWriter, r *http.Request, _ Params) {
+	http.NotFound(w, r)
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/denco/server_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/denco/server_test.go
@@ -0,0 +1,106 @@
+package denco_test
+
+import (
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/go-openapi/runtime/middleware/denco"
+)
+
+func testHandlerFunc(w http.ResponseWriter, r *http.Request, params denco.Params) {
+	fmt.Fprintf(w, "method: %s, path: %s, params: %v", r.Method, r.URL.Path, params)
+}
+
+func TestMux(t *testing.T) {
+	mux := denco.NewMux()
+	handler, err := mux.Build([]denco.Handler{
+		mux.GET("/", testHandlerFunc),
+		mux.GET("/user/:name", testHandlerFunc),
+		mux.POST("/user/:name", testHandlerFunc),
+		mux.HEAD("/user/:name", testHandlerFunc),
+		mux.PUT("/user/:name", testHandlerFunc),
+		mux.Handler("GET", "/user/handler", testHandlerFunc),
+		mux.Handler("POST", "/user/handler", testHandlerFunc),
+		{"PUT", "/user/inference", testHandlerFunc},
+	})
+	if err != nil {
+		t.Fatal(err)
+	}
+	server := httptest.NewServer(handler)
+	defer server.Close()
+
+	for _, v := range []struct {
+		status                 int
+		method, path, expected string
+	}{
+		{200, "GET", "/", "method: GET, path: /, params: []"},
+		{200, "GET", "/user/alice", "method: GET, path: /user/alice, params: [{name alice}]"},
+		{200, "POST", "/user/bob", "method: POST, path: /user/bob, params: [{name bob}]"},
+		{200, "HEAD", "/user/alice", ""},
+		{200, "PUT", "/user/bob", "method: PUT, path: /user/bob, params: [{name bob}]"},
+		{404, "POST", "/", "404 page not found\n"},
+		{404, "GET", "/unknown", "404 page not found\n"},
+		{404, "POST", "/user/alice/1", "404 page not found\n"},
+		{200, "GET", "/user/handler", "method: GET, path: /user/handler, params: []"},
+		{200, "POST", "/user/handler", "method: POST, path: /user/handler, params: []"},
+		{200, "PUT", "/user/inference", "method: PUT, path: /user/inference, params: []"},
+	} {
+		req, err := http.NewRequest(v.method, server.URL+v.path, nil)
+		if err != nil {
+			t.Error(err)
+			continue
+		}
+		res, err := http.DefaultClient.Do(req)
+		if err != nil {
+			t.Error(err)
+			continue
+		}
+		defer res.Body.Close()
+		body, err := ioutil.ReadAll(res.Body)
+		if err != nil {
+			t.Error(err)
+			continue
+		}
+		actual := string(body)
+		expected := v.expected
+		if res.StatusCode != v.status || actual != expected {
+			t.Errorf(`%s "%s" => %#v %#v, want %#v %#v`, v.method, v.path, res.StatusCode, actual, v.status, expected)
+		}
+	}
+}
+
+func TestNotFound(t *testing.T) {
+	mux := denco.NewMux()
+	handler, err := mux.Build([]denco.Handler{})
+	if err != nil {
+		t.Fatal(err)
+	}
+	server := httptest.NewServer(handler)
+	defer server.Close()
+
+	origNotFound := denco.NotFound
+	defer func() {
+		denco.NotFound = origNotFound
+	}()
+	denco.NotFound = func(w http.ResponseWriter, r *http.Request, params denco.Params) {
+		w.WriteHeader(http.StatusServiceUnavailable)
+		fmt.Fprintf(w, "method: %s, path: %s, params: %v", r.Method, r.URL.Path, params)
+	}
+	res, err := http.Get(server.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer res.Body.Close()
+	body, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		t.Fatal(err)
+	}
+	actual := string(body)
+	expected := "method: GET, path: /, params: []"
+	if res.StatusCode != http.StatusServiceUnavailable || actual != expected {
+		t.Errorf(`GET "/" => %#v %#v, want %#v %#v`, res.StatusCode, actual, http.StatusServiceUnavailable, expected)
+	}
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/denco/util.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/denco/util.go
@@ -0,0 +1,12 @@
+package denco
+
+// NextSeparator returns an index of next separator in path.
+func NextSeparator(path string, start int) int {
+	for start < len(path) {
+		if c := path[start]; c == '/' || c == TerminationCharacter {
+			break
+		}
+		start++
+	}
+	return start
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/denco/util_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/denco/util_test.go
@@ -0,0 +1,31 @@
+package denco_test
+
+import (
+	"reflect"
+	"testing"
+
+	"github.com/go-openapi/runtime/middleware/denco"
+)
+
+func TestNextSeparator(t *testing.T) {
+	for _, testcase := range []struct {
+		path     string
+		start    int
+		expected interface{}
+	}{
+		{"/path/to/route", 0, 0},
+		{"/path/to/route", 1, 5},
+		{"/path/to/route", 9, 14},
+		{"/path.html", 1, 10},
+		{"/foo/bar.html", 1, 4},
+		{"/foo/bar.html/baz.png", 5, 13},
+		{"/foo/bar.html/baz.png", 14, 21},
+		{"path#", 0, 4},
+	} {
+		actual := denco.NextSeparator(testcase.path, testcase.start)
+		expected := testcase.expected
+		if !reflect.DeepEqual(actual, expected) {
+			t.Errorf("path = %q, start = %v expect %v, but %v", testcase.path, testcase.start, expected, actual)
+		}
+	}
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/doc.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/doc.go
@@ -0,0 +1,65 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 middleware provides the library with helper functions for serving swagger APIs.
+
+Pseudo middleware handler
+
+  import (
+  	"net/http"
+
+  	"github.com/go-openapi/errors"
+  	"github.com/gorilla/context"
+  )
+
+  func newCompleteMiddleware(ctx *Context) http.Handler {
+  	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+  		defer context.Clear(r)
+
+  		// use context to lookup routes
+  		if matched, ok := ctx.RouteInfo(r); ok {
+
+  			if len(matched.Authenticators) > 0 {
+  				if _, err := ctx.Authorize(r, matched); err != nil {
+  					ctx.Respond(rw, r, matched.Produces, matched, err)
+  					return
+  				}
+  			}
+
+  			bound, validation := ctx.BindAndValidate(r, matched)
+  			if validation != nil {
+  				ctx.Respond(rw, r, matched.Produces, matched, validation)
+  				return
+  			}
+
+  			result, err := matched.Handler.Handle(bound)
+  			if err != nil {
+  				ctx.Respond(rw, r, matched.Produces, matched, err)
+  				return
+  			}
+
+  			ctx.Respond(rw, r, matched.Produces, matched, result)
+  			return
+  		}
+
+  		// Not found, check if it exists in the other methods first
+  		if others := ctx.AllowedMethods(r); len(others) > 0 {
+  			ctx.Respond(rw, r, ctx.spec.RequiredProduces(), nil, errors.MethodNotAllowed(r.Method, others))
+  			return
+  		}
+  		ctx.Respond(rw, r, ctx.spec.RequiredProduces(), nil, errors.NotFound("path %s was not found", r.URL.Path))
+  	})
+  }
+*/
+package middleware
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/header/header.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/header/header.go
@@ -0,0 +1,299 @@
+// Copyright 2013 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 or at
+// https://developers.google.com/open-source/licenses/bsd.
+
+// this file was taken from the github.com/golang/gddo repository
+
+// Package header provides functions for parsing HTTP headers.
+package header
+
+import (
+	"net/http"
+	"strings"
+	"time"
+)
+
+// Octet types from RFC 2616.
+var octetTypes [256]octetType
+
+type octetType byte
+
+const (
+	isToken octetType = 1 << iota
+	isSpace
+)
+
+func init() {
+	// OCTET      = <any 8-bit sequence of data>
+	// CHAR       = <any US-ASCII character (octets 0 - 127)>
+	// CTL        = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
+	// CR         = <US-ASCII CR, carriage return (13)>
+	// LF         = <US-ASCII LF, linefeed (10)>
+	// SP         = <US-ASCII SP, space (32)>
+	// HT         = <US-ASCII HT, horizontal-tab (9)>
+	// <">        = <US-ASCII double-quote mark (34)>
+	// CRLF       = CR LF
+	// LWS        = [CRLF] 1*( SP | HT )
+	// TEXT       = <any OCTET except CTLs, but including LWS>
+	// separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <">
+	//              | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT
+	// token      = 1*<any CHAR except CTLs or separators>
+	// qdtext     = <any TEXT except <">>
+
+	for c := 0; c < 256; c++ {
+		var t octetType
+		isCtl := c <= 31 || c == 127
+		isChar := 0 <= c && c <= 127
+		isSeparator := strings.IndexRune(" \t\"(),/:;<=>?@[]\\{}", rune(c)) >= 0
+		if strings.IndexRune(" \t\r\n", rune(c)) >= 0 {
+			t |= isSpace
+		}
+		if isChar && !isCtl && !isSeparator {
+			t |= isToken
+		}
+		octetTypes[c] = t
+	}
+}
+
+// Copy returns a shallow copy of the header.
+func Copy(header http.Header) http.Header {
+	h := make(http.Header)
+	for k, vs := range header {
+		h[k] = vs
+	}
+	return h
+}
+
+var timeLayouts = []string{"Mon, 02 Jan 2006 15:04:05 GMT", time.RFC850, time.ANSIC}
+
+// ParseTime parses the header as time. The zero value is returned if the
+// header is not present or there is an error parsing the
+// header.
+func ParseTime(header http.Header, key string) time.Time {
+	if s := header.Get(key); s != "" {
+		for _, layout := range timeLayouts {
+			if t, err := time.Parse(layout, s); err == nil {
+				return t.UTC()
+			}
+		}
+	}
+	return time.Time{}
+}
+
+// ParseList parses a comma separated list of values. Commas are ignored in
+// quoted strings. Quoted values are not unescaped or unquoted. Whitespace is
+// trimmed.
+func ParseList(header http.Header, key string) []string {
+	var result []string
+	for _, s := range header[http.CanonicalHeaderKey(key)] {
+		begin := 0
+		end := 0
+		escape := false
+		quote := false
+		for i := 0; i < len(s); i++ {
+			b := s[i]
+			switch {
+			case escape:
+				escape = false
+				end = i + 1
+			case quote:
+				switch b {
+				case '\\':
+					escape = true
+				case '"':
+					quote = false
+				}
+				end = i + 1
+			case b == '"':
+				quote = true
+				end = i + 1
+			case octetTypes[b]&isSpace != 0:
+				if begin == end {
+					begin = i + 1
+					end = begin
+				}
+			case b == ',':
+				if begin < end {
+					result = append(result, s[begin:end])
+				}
+				begin = i + 1
+				end = begin
+			default:
+				end = i + 1
+			}
+		}
+		if begin < end {
+			result = append(result, s[begin:end])
+		}
+	}
+	return result
+}
+
+// ParseValueAndParams parses a comma separated list of values with optional
+// semicolon separated name-value pairs. Content-Type and Content-Disposition
+// headers are in this format.
+func ParseValueAndParams(header http.Header, key string) (value string, params map[string]string) {
+	params = make(map[string]string)
+	s := header.Get(key)
+	value, s = expectTokenSlash(s)
+	if value == "" {
+		return
+	}
+	value = strings.ToLower(value)
+	s = skipSpace(s)
+	for strings.HasPrefix(s, ";") {
+		var pkey string
+		pkey, s = expectToken(skipSpace(s[1:]))
+		if pkey == "" {
+			return
+		}
+		if !strings.HasPrefix(s, "=") {
+			return
+		}
+		var pvalue string
+		pvalue, s = expectTokenOrQuoted(s[1:])
+		if pvalue == "" {
+			return
+		}
+		pkey = strings.ToLower(pkey)
+		params[pkey] = pvalue
+		s = skipSpace(s)
+	}
+	return
+}
+
+type AcceptSpec struct {
+	Value string
+	Q     float64
+}
+
+// ParseAccept parses Accept* headers.
+func ParseAccept(header http.Header, key string) (specs []AcceptSpec) {
+loop:
+	for _, s := range header[key] {
+		for {
+			var spec AcceptSpec
+			spec.Value, s = expectTokenSlash(s)
+			if spec.Value == "" {
+				continue loop
+			}
+			spec.Q = 1.0
+			s = skipSpace(s)
+			if strings.HasPrefix(s, ";") {
+				s = skipSpace(s[1:])
+				if !strings.HasPrefix(s, "q=") {
+					continue loop
+				}
+				spec.Q, s = expectQuality(s[2:])
+				if spec.Q < 0.0 {
+					continue loop
+				}
+			}
+			specs = append(specs, spec)
+			s = skipSpace(s)
+			if !strings.HasPrefix(s, ",") {
+				continue loop
+			}
+			s = skipSpace(s[1:])
+		}
+	}
+	return
+}
+
+func skipSpace(s string) (rest string) {
+	i := 0
+	for ; i < len(s); i++ {
+		if octetTypes[s[i]]&isSpace == 0 {
+			break
+		}
+	}
+	return s[i:]
+}
+
+func expectToken(s string) (token, rest string) {
+	i := 0
+	for ; i < len(s); i++ {
+		if octetTypes[s[i]]&isToken == 0 {
+			break
+		}
+	}
+	return s[:i], s[i:]
+}
+
+func expectTokenSlash(s string) (token, rest string) {
+	i := 0
+	for ; i < len(s); i++ {
+		b := s[i]
+		if (octetTypes[b]&isToken == 0) && b != '/' {
+			break
+		}
+	}
+	return s[:i], s[i:]
+}
+
+func expectQuality(s string) (q float64, rest string) {
+	switch {
+	case len(s) == 0:
+		return -1, ""
+	case s[0] == '0':
+		q = 0
+	case s[0] == '1':
+		q = 1
+	default:
+		return -1, ""
+	}
+	s = s[1:]
+	if !strings.HasPrefix(s, ".") {
+		return q, s
+	}
+	s = s[1:]
+	i := 0
+	n := 0
+	d := 1
+	for ; i < len(s); i++ {
+		b := s[i]
+		if b < '0' || b > '9' {
+			break
+		}
+		n = n*10 + int(b) - '0'
+		d *= 10
+	}
+	return q + float64(n)/float64(d), s[i:]
+}
+
+func expectTokenOrQuoted(s string) (value string, rest string) {
+	if !strings.HasPrefix(s, "\"") {
+		return expectToken(s)
+	}
+	s = s[1:]
+	for i := 0; i < len(s); i++ {
+		switch s[i] {
+		case '"':
+			return s[:i], s[i+1:]
+		case '\\':
+			p := make([]byte, len(s)-1)
+			j := copy(p, s[:i])
+			escape := true
+			for i = i + 1; i < len(s); i++ {
+				b := s[i]
+				switch {
+				case escape:
+					escape = false
+					p[j] = b
+					j += 1
+				case b == '\\':
+					escape = true
+				case b == '"':
+					return string(p[:j]), s[i+1:]
+				default:
+					p[j] = b
+					j += 1
+				}
+			}
+			return "", ""
+		}
+	}
+	return "", ""
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/negotiate.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/negotiate.go
@@ -0,0 +1,82 @@
+// Copyright 2013 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 or at
+// https://developers.google.com/open-source/licenses/bsd.
+
+// this file was taken from the github.com/golang/gddo repository
+
+package middleware
+
+import (
+	"net/http"
+	"strings"
+
+	"github.com/go-openapi/runtime/middleware/header"
+)
+
+// NegotiateContentEncoding returns the best offered content encoding for the
+// request's Accept-Encoding header. If two offers match with equal weight and
+// then the offer earlier in the list is preferred. If no offers are
+// acceptable, then "" is returned.
+func NegotiateContentEncoding(r *http.Request, offers []string) string {
+	bestOffer := "identity"
+	bestQ := -1.0
+	specs := header.ParseAccept(r.Header, "Accept-Encoding")
+	for _, offer := range offers {
+		for _, spec := range specs {
+			if spec.Q > bestQ &&
+				(spec.Value == "*" || spec.Value == offer) {
+				bestQ = spec.Q
+				bestOffer = offer
+			}
+		}
+	}
+	if bestQ == 0 {
+		bestOffer = ""
+	}
+	return bestOffer
+}
+
+// NegotiateContentType returns the best offered content type for the request's
+// Accept header. If two offers match with equal weight, then the more specific
+// offer is preferred.  For example, text/* trumps */*. If two offers match
+// with equal weight and specificity, then the offer earlier in the list is
+// preferred. If no offers match, then defaultOffer is returned.
+func NegotiateContentType(r *http.Request, offers []string, defaultOffer string) string {
+	bestOffer := defaultOffer
+	bestQ := -1.0
+	bestWild := 3
+	specs := header.ParseAccept(r.Header, "Accept")
+	for _, offer := range offers {
+		for _, spec := range specs {
+			switch {
+			case spec.Q == 0.0:
+				// ignore
+			case spec.Q < bestQ:
+				// better match found
+			case spec.Value == "*/*":
+				if spec.Q > bestQ || bestWild > 2 {
+					bestQ = spec.Q
+					bestWild = 2
+					bestOffer = offer
+				}
+			case strings.HasSuffix(spec.Value, "/*"):
+				if strings.HasPrefix(offer, spec.Value[:len(spec.Value)-1]) &&
+					(spec.Q > bestQ || bestWild > 1) {
+					bestQ = spec.Q
+					bestWild = 1
+					bestOffer = offer
+				}
+			default:
+				if spec.Value == offer &&
+					(spec.Q > bestQ || bestWild > 0) {
+					bestQ = spec.Q
+					bestWild = 0
+					bestOffer = offer
+				}
+			}
+		}
+	}
+	return bestOffer
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/negotiate_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/negotiate_test.go
@@ -0,0 +1,70 @@
+// Copyright 2013 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 or at
+// https://developers.google.com/open-source/licenses/bsd.
+
+package middleware
+
+import (
+	"net/http"
+	"testing"
+)
+
+var negotiateContentEncodingTests = []struct {
+	s      string
+	offers []string
+	expect string
+}{
+	{"", []string{"identity", "gzip"}, "identity"},
+	{"*;q=0", []string{"identity", "gzip"}, ""},
+	{"gzip", []string{"identity", "gzip"}, "gzip"},
+}
+
+func TestNegotiateContentEnoding(t *testing.T) {
+	for _, tt := range negotiateContentEncodingTests {
+		r := &http.Request{Header: http.Header{"Accept-Encoding": {tt.s}}}
+		actual := NegotiateContentEncoding(r, tt.offers)
+		if actual != tt.expect {
+			t.Errorf("NegotiateContentEncoding(%q, %#v)=%q, want %q", tt.s, tt.offers, actual, tt.expect)
+		}
+	}
+}
+
+var negotiateContentTypeTests = []struct {
+	s            string
+	offers       []string
+	defaultOffer string
+	expect       string
+}{
+	{"text/html, */*;q=0", []string{"x/y"}, "", ""},
+	{"text/html, */*", []string{"x/y"}, "", "x/y"},
+	{"text/html, image/png", []string{"text/html", "image/png"}, "", "text/html"},
+	{"text/html, image/png", []string{"image/png", "text/html"}, "", "image/png"},
+	{"text/html, image/png; q=0.5", []string{"image/png"}, "", "image/png"},
+	{"text/html, image/png; q=0.5", []string{"text/html"}, "", "text/html"},
+	{"text/html, image/png; q=0.5", []string{"foo/bar"}, "", ""},
+	{"text/html, image/png; q=0.5", []string{"image/png", "text/html"}, "", "text/html"},
+	{"text/html, image/png; q=0.5", []string{"text/html", "image/png"}, "", "text/html"},
+	{"text/html;q=0.5, image/png", []string{"image/png"}, "", "image/png"},
+	{"text/html;q=0.5, image/png", []string{"text/html"}, "", "text/html"},
+	{"text/html;q=0.5, image/png", []string{"image/png", "text/html"}, "", "image/png"},
+	{"text/html;q=0.5, image/png", []string{"text/html", "image/png"}, "", "image/png"},
+	{"image/png, image/*;q=0.5", []string{"image/jpg", "image/png"}, "", "image/png"},
+	{"image/png, image/*;q=0.5", []string{"image/jpg"}, "", "image/jpg"},
+	{"image/png, image/*;q=0.5", []string{"image/jpg", "image/gif"}, "", "image/jpg"},
+	{"image/png, image/*", []string{"image/jpg", "image/gif"}, "", "image/jpg"},
+	{"image/png, image/*", []string{"image/gif", "image/jpg"}, "", "image/gif"},
+	{"image/png, image/*", []string{"image/gif", "image/png"}, "", "image/png"},
+	{"image/png, image/*", []string{"image/png", "image/gif"}, "", "image/png"},
+}
+
+func TestNegotiateContentType(t *testing.T) {
+	for _, tt := range negotiateContentTypeTests {
+		r := &http.Request{Header: http.Header{"Accept": {tt.s}}}
+		actual := NegotiateContentType(r, tt.offers, tt.defaultOffer)
+		if actual != tt.expect {
+			t.Errorf("NegotiateContentType(%q, %#v, %q)=%q, want %q", tt.s, tt.offers, tt.defaultOffer, actual, tt.expect)
+		}
+	}
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/not_implemented.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/not_implemented.go
@@ -0,0 +1,48 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 middleware
+
+import (
+	"net/http"
+
+	"github.com/go-openapi/runtime"
+)
+
+type errorResp struct {
+	code     int
+	response interface{}
+	headers  http.Header
+}
+
+func (e *errorResp) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
+	for k, v := range e.headers {
+		for _, val := range v {
+			rw.Header().Add(k, val)
+		}
+	}
+	if e.code > 0 {
+		rw.WriteHeader(e.code)
+	} else {
+		rw.WriteHeader(http.StatusInternalServerError)
+	}
+	if err := producer.Produce(rw, e.response); err != nil {
+		panic(err)
+	}
+}
+
+// NotImplemented the error response when the response is not implemented
+func NotImplemented(message string) Responder {
+	return &errorResp{http.StatusNotImplemented, message, make(http.Header)}
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/operation.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/operation.go
@@ -0,0 +1,25 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 middleware
+
+import "net/http"
+
+func newOperationExecutor(ctx *Context) http.Handler {
+	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+		// use context to lookup routes
+		route, _ := ctx.RouteInfo(r)
+		route.Handler.ServeHTTP(rw, r)
+	})
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/operation_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/operation_test.go
@@ -0,0 +1,64 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 middleware
+
+import (
+	"net/http"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/runtime/internal/testing/petstore"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestOperationExecutor(t *testing.T) {
+	spec, api := petstore.NewAPI(t)
+	api.RegisterOperation("get", "/pets", runtime.OperationHandlerFunc(func(params interface{}) (interface{}, error) {
+		return []interface{}{
+			map[string]interface{}{"id": 1, "name": "a dog"},
+		}, nil
+	}))
+
+	context := NewContext(spec, api, nil)
+	context.router = DefaultRouter(spec, context.api)
+	mw := newOperationExecutor(context)
+
+	recorder := httptest.NewRecorder()
+	request, _ := http.NewRequest("GET", "/pets", nil)
+	request.Header.Add("Accept", "application/json")
+	request.SetBasicAuth("admin", "admin")
+	mw.ServeHTTP(recorder, request)
+	assert.Equal(t, 200, recorder.Code)
+	assert.Equal(t, `[{"id":1,"name":"a dog"}]`+"\n", recorder.Body.String())
+
+	spec, api = petstore.NewAPI(t)
+	api.RegisterOperation("get", "/pets", runtime.OperationHandlerFunc(func(params interface{}) (interface{}, error) {
+		return nil, errors.New(422, "expected")
+	}))
+
+	context = NewContext(spec, api, nil)
+	context.router = DefaultRouter(spec, context.api)
+	mw = newOperationExecutor(context)
+
+	recorder = httptest.NewRecorder()
+	request, _ = http.NewRequest("GET", "/pets", nil)
+	request.Header.Add("Accept", "application/json")
+	request.SetBasicAuth("admin", "admin")
+	mw.ServeHTTP(recorder, request)
+	assert.Equal(t, 422, recorder.Code)
+	assert.Equal(t, `{"code":422,"message":"expected"}`, recorder.Body.String())
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/parameter.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/parameter.go
@@ -0,0 +1,477 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 middleware
+
+import (
+	"encoding"
+	"encoding/base64"
+	"fmt"
+	"io"
+	"net/http"
+	"reflect"
+	"strconv"
+
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/strfmt"
+	"github.com/go-openapi/swag"
+	"github.com/go-openapi/validate"
+)
+
+const defaultMaxMemory = 32 << 20
+
+var textUnmarshalType = reflect.TypeOf(new(encoding.TextUnmarshaler)).Elem()
+
+func newUntypedParamBinder(param spec.Parameter, spec *spec.Swagger, formats strfmt.Registry) *untypedParamBinder {
+	binder := new(untypedParamBinder)
+	binder.Name = param.Name
+	binder.parameter = &param
+	binder.formats = formats
+	if param.In != "body" {
+		binder.validator = validate.NewParamValidator(&param, formats)
+	} else {
+		binder.validator = validate.NewSchemaValidator(param.Schema, spec, param.Name, formats)
+	}
+
+	return binder
+}
+
+type untypedParamBinder struct {
+	parameter *spec.Parameter
+	formats   strfmt.Registry
+	Name      string
+	validator validate.EntityValidator
+}
+
+func (p *untypedParamBinder) Type() reflect.Type {
+	return p.typeForSchema(p.parameter.Type, p.parameter.Format, p.parameter.Items)
+}
+
+func (p *untypedParamBinder) typeForSchema(tpe, format string, items *spec.Items) reflect.Type {
+	switch tpe {
+	case "boolean":
+		return reflect.TypeOf(true)
+
+	case "string":
+		if tt, ok := p.formats.GetType(format); ok {
+			return tt
+		}
+		return reflect.TypeOf("")
+
+	case "integer":
+		switch format {
+		case "int8":
+			return reflect.TypeOf(int8(0))
+		case "int16":
+			return reflect.TypeOf(int16(0))
+		case "int32":
+			return reflect.TypeOf(int32(0))
+		case "int64":
+			return reflect.TypeOf(int64(0))
+		default:
+			return reflect.TypeOf(int64(0))
+		}
+
+	case "number":
+		switch format {
+		case "float":
+			return reflect.TypeOf(float32(0))
+		case "double":
+			return reflect.TypeOf(float64(0))
+		}
+
+	case "array":
+		if items == nil {
+			return nil
+		}
+		itemsType := p.typeForSchema(items.Type, items.Format, items.Items)
+		if itemsType == nil {
+			return nil
+		}
+		return reflect.MakeSlice(reflect.SliceOf(itemsType), 0, 0).Type()
+
+	case "file":
+		return reflect.TypeOf(&runtime.File{}).Elem()
+
+	case "object":
+		return reflect.TypeOf(map[string]interface{}{})
+	}
+	return nil
+}
+
+func (p *untypedParamBinder) allowsMulti() bool {
+	return p.parameter.In == "query" || p.parameter.In == "formData"
+}
+
+func (p *untypedParamBinder) readValue(values runtime.Gettable, target reflect.Value) ([]string, bool, bool, error) {
+	name, in, cf, tpe := p.parameter.Name, p.parameter.In, p.parameter.CollectionFormat, p.parameter.Type
+	if tpe == "array" {
+		if cf == "multi" {
+			if !p.allowsMulti() {
+				return nil, false, false, errors.InvalidCollectionFormat(name, in, cf)
+			}
+			vv, hasKey, _ := values.GetOK(name)
+			return vv, false, hasKey, nil
+		}
+
+		v, hk, hv := values.GetOK(name)
+		if !hv {
+			return nil, false, hk, nil
+		}
+		d, c, e := p.readFormattedSliceFieldValue(v[len(v)-1], target)
+		return d, c, hk, e
+	}
+
+	vv, hk, _ := values.GetOK(name)
+	return vv, false, hk, nil
+}
+
+func (p *untypedParamBinder) Bind(request *http.Request, routeParams RouteParams, consumer runtime.Consumer, target reflect.Value) error {
+	// fmt.Println("binding", p.name, "as", p.Type())
+	switch p.parameter.In {
+	case "query":
+		data, custom, hasKey, err := p.readValue(runtime.Values(request.URL.Query()), target)
+		if err != nil {
+			return err
+		}
+		if custom {
+			return nil
+		}
+
+		return p.bindValue(data, hasKey, target)
+
+	case "header":
+		data, custom, hasKey, err := p.readValue(runtime.Values(request.Header), target)
+		if err != nil {
+			return err
+		}
+		if custom {
+			return nil
+		}
+		return p.bindValue(data, hasKey, target)
+
+	case "path":
+		data, custom, hasKey, err := p.readValue(routeParams, target)
+		if err != nil {
+			return err
+		}
+		if custom {
+			return nil
+		}
+		return p.bindValue(data, hasKey, target)
+
+	case "formData":
+		var err error
+		var mt string
+
+		mt, _, e := runtime.ContentType(request.Header)
+		if e != nil {
+			// because of the interface conversion go thinks the error is not nil
+			// so we first check for nil and then set the err var if it's not nil
+			err = e
+		}
+
+		if err != nil {
+			return errors.InvalidContentType("", []string{"multipart/form-data", "application/x-www-form-urlencoded"})
+		}
+
+		if mt != "multipart/form-data" && mt != "application/x-www-form-urlencoded" {
+			return errors.InvalidContentType(mt, []string{"multipart/form-data", "application/x-www-form-urlencoded"})
+		}
+
+		if mt == "multipart/form-data" {
+			if err := request.ParseMultipartForm(defaultMaxMemory); err != nil {
+				return errors.NewParseError(p.Name, p.parameter.In, "", err)
+			}
+		}
+
+		if err := request.ParseForm(); err != nil {
+			return errors.NewParseError(p.Name, p.parameter.In, "", err)
+		}
+
+		if p.parameter.Type == "file" {
+			file, header, err := request.FormFile(p.parameter.Name)
+			if err != nil {
+				return errors.NewParseError(p.Name, p.parameter.In, "", err)
+			}
+			target.Set(reflect.ValueOf(runtime.File{Data: file, Header: header}))
+			return nil
+		}
+
+		if request.MultipartForm != nil {
+			data, custom, hasKey, err := p.readValue(runtime.Values(request.MultipartForm.Value), target)
+			if err != nil {
+				return err
+			}
+			if custom {
+				return nil
+			}
+			return p.bindValue(data, hasKey, target)
+		}
+		data, custom, hasKey, err := p.readValue(runtime.Values(request.PostForm), target)
+		if err != nil {
+			return err
+		}
+		if custom {
+			return nil
+		}
+		return p.bindValue(data, hasKey, target)
+
+	case "body":
+		newValue := reflect.New(target.Type())
+		if !runtime.HasBody(request) {
+			if p.parameter.Default != nil {
+				target.Set(reflect.ValueOf(p.parameter.Default))
+			}
+
+			return nil
+		}
+		if err := consumer.Consume(request.Body, newValue.Interface()); err != nil {
+			if err == io.EOF && p.parameter.Default != nil {
+				target.Set(reflect.ValueOf(p.parameter.Default))
+				return nil
+			}
+			tpe := p.parameter.Type
+			if p.parameter.Format != "" {
+				tpe = p.parameter.Format
+			}
+			return errors.InvalidType(p.Name, p.parameter.In, tpe, nil)
+		}
+		target.Set(reflect.Indirect(newValue))
+		return nil
+	default:
+		return errors.New(500, fmt.Sprintf("invalid parameter location %q", p.parameter.In))
+	}
+}
+
+func (p *untypedParamBinder) bindValue(data []string, hasKey bool, target reflect.Value) error {
+	if p.parameter.Type == "array" {
+		return p.setSliceFieldValue(target, p.parameter.Default, data, hasKey)
+	}
+	var d string
+	if len(data) > 0 {
+		d = data[len(data)-1]
+	}
+	return p.setFieldValue(target, p.parameter.Default, d, hasKey)
+}
+
+func (p *untypedParamBinder) setFieldValue(target reflect.Value, defaultValue interface{}, data string, hasKey bool) error {
+	tpe := p.parameter.Type
+	if p.parameter.Format != "" {
+		tpe = p.parameter.Format
+	}
+
+	if (!hasKey || (!p.parameter.AllowEmptyValue && data == "")) && p.parameter.Required && p.parameter.Default == nil {
+		return errors.Required(p.Name, p.parameter.In)
+	}
+
+	ok, err := p.tryUnmarshaler(target, defaultValue, data)
+	if err != nil {
+		return errors.InvalidType(p.Name, p.parameter.In, tpe, data)
+	}
+	if ok {
+		return nil
+	}
+
+	defVal := reflect.Zero(target.Type())
+	if defaultValue != nil {
+		defVal = reflect.ValueOf(defaultValue)
+	}
+
+	if tpe == "byte" {
+		if data == "" {
+			if target.CanSet() {
+				target.SetBytes(defVal.Bytes())
+			}
+			return nil
+		}
+
+		b, err := base64.StdEncoding.DecodeString(data)
+		if err != nil {
+			b, err = base64.URLEncoding.DecodeString(data)
+			if err != nil {
+				return errors.InvalidType(p.Name, p.parameter.In, tpe, data)
+			}
+		}
+		if target.CanSet() {
+			target.SetBytes(b)
+		}
+		return nil
+	}
+
+	switch target.Kind() {
+	case reflect.Bool:
+		if data == "" {
+			if target.CanSet() {
+				target.SetBool(defVal.Bool())
+			}
+			return nil
+		}
+		b, err := swag.ConvertBool(data)
+		if err != nil {
+			return err
+		}
+		if target.CanSet() {
+			target.SetBool(b)
+		}
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		if data == "" {
+			if target.CanSet() {
+				target.SetInt(defVal.Int())
+			}
+			return nil
+		}
+		i, err := strconv.ParseInt(data, 10, 64)
+		if err != nil {
+			return errors.InvalidType(p.Name, p.parameter.In, tpe, data)
+		}
+		if target.OverflowInt(i) {
+			return errors.InvalidType(p.Name, p.parameter.In, tpe, data)
+		}
+		if target.CanSet() {
+			target.SetInt(i)
+		}
+
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		if data == "" {
+			if target.CanSet() {
+				target.SetUint(defVal.Uint())
+			}
+			return nil
+		}
+		u, err := strconv.ParseUint(data, 10, 64)
+		if err != nil {
+			return errors.InvalidType(p.Name, p.parameter.In, tpe, data)
+		}
+		if target.OverflowUint(u) {
+			return errors.InvalidType(p.Name, p.parameter.In, tpe, data)
+		}
+		if target.CanSet() {
+			target.SetUint(u)
+		}
+
+	case reflect.Float32, reflect.Float64:
+		if data == "" {
+			if target.CanSet() {
+				target.SetFloat(defVal.Float())
+			}
+			return nil
+		}
+		f, err := strconv.ParseFloat(data, 64)
+		if err != nil {
+			return errors.InvalidType(p.Name, p.parameter.In, tpe, data)
+		}
+		if target.OverflowFloat(f) {
+			return errors.InvalidType(p.Name, p.parameter.In, tpe, data)
+		}
+		if target.CanSet() {
+			target.SetFloat(f)
+		}
+
+	case reflect.String:
+		value := data
+		if value == "" {
+			value = defVal.String()
+		}
+		// validate string
+		if target.CanSet() {
+			target.SetString(value)
+		}
+
+	case reflect.Ptr:
+		if data == "" && defVal.Kind() == reflect.Ptr {
+			if target.CanSet() {
+				target.Set(defVal)
+			}
+			return nil
+		}
+		newVal := reflect.New(target.Type().Elem())
+		if err := p.setFieldValue(reflect.Indirect(newVal), defVal, data, hasKey); err != nil {
+			return err
+		}
+		if target.CanSet() {
+			target.Set(newVal)
+		}
+
+	default:
+		return errors.InvalidType(p.Name, p.parameter.In, tpe, data)
+	}
+	return nil
+}
+
+func (p *untypedParamBinder) tryUnmarshaler(target reflect.Value, defaultValue interface{}, data string) (bool, error) {
+	if !target.CanSet() {
+		return false, nil
+	}
+	// When a type implements encoding.TextUnmarshaler we'll use that instead of reflecting some more
+	if reflect.PtrTo(target.Type()).Implements(textUnmarshalType) {
+		if defaultValue != nil && len(data) == 0 {
+			target.Set(reflect.ValueOf(defaultValue))
+			return true, nil
+		}
+		value := reflect.New(target.Type())
+		if err := value.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(data)); err != nil {
+			return true, err
+		}
+		target.Set(reflect.Indirect(value))
+		return true, nil
+	}
+	return false, nil
+}
+
+func (p *untypedParamBinder) readFormattedSliceFieldValue(data string, target reflect.Value) ([]string, bool, error) {
+	ok, err := p.tryUnmarshaler(target, p.parameter.Default, data)
+	if err != nil {
+		return nil, true, err
+	}
+	if ok {
+		return nil, true, nil
+	}
+
+	return swag.SplitByFormat(data, p.parameter.CollectionFormat), false, nil
+}
+
+func (p *untypedParamBinder) setSliceFieldValue(target reflect.Value, defaultValue interface{}, data []string, hasKey bool) error {
+	sz := len(data)
+	if (!hasKey || (!p.parameter.AllowEmptyValue && (sz == 0 || (sz == 1 && data[0] == "")))) && p.parameter.Required && defaultValue == nil {
+		return errors.Required(p.Name, p.parameter.In)
+	}
+
+	defVal := reflect.Zero(target.Type())
+	if defaultValue != nil {
+		defVal = reflect.ValueOf(defaultValue)
+	}
+
+	if !target.CanSet() {
+		return nil
+	}
+	if sz == 0 {
+		target.Set(defVal)
+		return nil
+	}
+
+	value := reflect.MakeSlice(reflect.SliceOf(target.Type().Elem()), sz, sz)
+
+	for i := 0; i < sz; i++ {
+		if err := p.setFieldValue(value.Index(i), nil, data[i], hasKey); err != nil {
+			return err
+		}
+	}
+
+	target.Set(value)
+
+	return nil
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/parameter_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/parameter_test.go
@@ -0,0 +1,340 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 middleware
+
+import (
+	"math"
+	"net/url"
+	"reflect"
+	"strconv"
+	"testing"
+
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/strfmt"
+	"github.com/stretchr/testify/assert"
+)
+
+type email struct {
+	Address string
+}
+
+type paramFactory func(string) *spec.Parameter
+
+var paramFactories = []paramFactory{
+	spec.QueryParam,
+	spec.HeaderParam,
+	spec.PathParam,
+	spec.FormDataParam,
+}
+
+func np(param *spec.Parameter) *untypedParamBinder {
+	return newUntypedParamBinder(*param, new(spec.Swagger), strfmt.Default)
+}
+
+var stringItems = new(spec.Items)
+
+func init() {
+	stringItems.Type = "string"
+}
+
+func testCollectionFormat(t *testing.T, param *spec.Parameter, valid bool) {
+	binder := &untypedParamBinder{
+		parameter: param,
+	}
+	_, _, _, err := binder.readValue(runtime.Values(nil), reflect.ValueOf(nil))
+	if valid {
+		assert.NoError(t, err)
+	} else {
+		assert.Error(t, err)
+		assert.Equal(t, errors.InvalidCollectionFormat(param.Name, param.In, param.CollectionFormat), err)
+	}
+}
+
+func requiredError(param *spec.Parameter) *errors.Validation {
+	return errors.Required(param.Name, param.In)
+}
+
+func validateRequiredTest(t *testing.T, param *spec.Parameter, value reflect.Value) {
+
+	binder := np(param)
+	err := binder.bindValue([]string{}, true, value)
+	assert.Error(t, err)
+	assert.NotNil(t, param)
+	assert.EqualError(t, requiredError(param), err.Error())
+	err = binder.bindValue([]string{""}, true, value)
+	if assert.Error(t, err) {
+		assert.EqualError(t, requiredError(param), err.Error())
+	}
+
+	// should be impossible data, but let's go with it
+	err = binder.bindValue([]string{"a"}, false, value)
+	assert.Error(t, err)
+	assert.EqualError(t, requiredError(param), err.Error())
+	err = binder.bindValue([]string{""}, false, value)
+	assert.Error(t, err)
+	assert.EqualError(t, requiredError(param), err.Error())
+}
+
+func validateRequiredAllowEmptyTest(t *testing.T, param *spec.Parameter, value reflect.Value) {
+	param.AllowEmptyValue = true
+	binder := np(param)
+	err := binder.bindValue([]string{}, true, value)
+	assert.NoError(t, err)
+	if assert.NotNil(t, param) {
+		err = binder.bindValue([]string{""}, true, value)
+		assert.NoError(t, err)
+		err = binder.bindValue([]string{"1"}, false, value)
+		assert.Error(t, err)
+		assert.EqualError(t, requiredError(param), err.Error())
+		err = binder.bindValue([]string{""}, false, value)
+		assert.Error(t, err)
+		assert.EqualError(t, requiredError(param), err.Error())
+	}
+}
+
+func TestRequiredValidation(t *testing.T) {
+	strParam := spec.QueryParam("name").Typed("string", "").AsRequired()
+	validateRequiredTest(t, strParam, reflect.ValueOf(""))
+	validateRequiredAllowEmptyTest(t, strParam, reflect.ValueOf(""))
+
+	intParam := spec.QueryParam("id").Typed("integer", "int32").AsRequired()
+	validateRequiredTest(t, intParam, reflect.ValueOf(int32(0)))
+	validateRequiredAllowEmptyTest(t, intParam, reflect.ValueOf(int32(0)))
+	longParam := spec.QueryParam("id").Typed("integer", "int64").AsRequired()
+	validateRequiredTest(t, longParam, reflect.ValueOf(int64(0)))
+	validateRequiredAllowEmptyTest(t, longParam, reflect.ValueOf(int64(0)))
+
+	floatParam := spec.QueryParam("score").Typed("number", "float").AsRequired()
+	validateRequiredTest(t, floatParam, reflect.ValueOf(float32(0)))
+	validateRequiredAllowEmptyTest(t, floatParam, reflect.ValueOf(float32(0)))
+	doubleParam := spec.QueryParam("score").Typed("number", "double").AsRequired()
+	validateRequiredTest(t, doubleParam, reflect.ValueOf(float64(0)))
+	validateRequiredAllowEmptyTest(t, doubleParam, reflect.ValueOf(float64(0)))
+
+	dateTimeParam := spec.QueryParam("registered").Typed("string", "date-time").AsRequired()
+	validateRequiredTest(t, dateTimeParam, reflect.ValueOf(strfmt.DateTime{}))
+	// validateRequiredAllowEmptyTest(t, dateTimeParam, reflect.ValueOf(strfmt.DateTime{}))
+
+	dateParam := spec.QueryParam("registered").Typed("string", "date").AsRequired()
+	validateRequiredTest(t, dateParam, reflect.ValueOf(strfmt.Date{}))
+	// validateRequiredAllowEmptyTest(t, dateParam, reflect.ValueOf(strfmt.DateTime{}))
+
+	sliceParam := spec.QueryParam("tags").CollectionOf(stringItems, "").AsRequired()
+	validateRequiredTest(t, sliceParam, reflect.MakeSlice(reflect.TypeOf([]string{}), 0, 0))
+	validateRequiredAllowEmptyTest(t, sliceParam, reflect.MakeSlice(reflect.TypeOf([]string{}), 0, 0))
+}
+
+func TestInvalidCollectionFormat(t *testing.T) {
+	validCf1 := spec.QueryParam("validFmt").CollectionOf(stringItems, "multi")
+	validCf2 := spec.FormDataParam("validFmt2").CollectionOf(stringItems, "multi")
+	invalidCf1 := spec.HeaderParam("invalidHdr").CollectionOf(stringItems, "multi")
+	invalidCf2 := spec.PathParam("invalidPath").CollectionOf(stringItems, "multi")
+
+	testCollectionFormat(t, validCf1, true)
+	testCollectionFormat(t, validCf2, true)
+	testCollectionFormat(t, invalidCf1, false)
+	testCollectionFormat(t, invalidCf2, false)
+}
+
+func invalidTypeError(param *spec.Parameter, data interface{}) *errors.Validation {
+	tpe := param.Type
+	if param.Format != "" {
+		tpe = param.Format
+	}
+	return errors.InvalidType(param.Name, param.In, tpe, data)
+}
+
+func TestTypeValidation(t *testing.T) {
+	for _, newParam := range paramFactories {
+		intParam := newParam("badInt").Typed("integer", "int32")
+		value := reflect.ValueOf(int32(0))
+		binder := np(intParam)
+		err := binder.bindValue([]string{"yada"}, true, value)
+		// fails for invalid string
+		assert.Error(t, err)
+		assert.Equal(t, invalidTypeError(intParam, "yada"), err)
+		// fails for overflow
+		val := int64(math.MaxInt32)
+		str := strconv.FormatInt(val, 10) + "0"
+		v := int32(0)
+		value = reflect.ValueOf(&v).Elem()
+		binder = np(intParam)
+		err = binder.bindValue([]string{str}, true, value)
+		assert.Error(t, err)
+		assert.Equal(t, invalidTypeError(intParam, str), err)
+
+		longParam := newParam("badLong").Typed("integer", "int64")
+		value = reflect.ValueOf(int64(0))
+		binder = np(longParam)
+		err = binder.bindValue([]string{"yada"}, true, value)
+		// fails for invalid string
+		assert.Error(t, err)
+		assert.Equal(t, invalidTypeError(longParam, "yada"), err)
+		// fails for overflow
+		str2 := strconv.FormatInt(math.MaxInt64, 10) + "0"
+		v2 := int64(0)
+		vv2 := reflect.ValueOf(&v2).Elem()
+		binder = np(longParam)
+		err = binder.bindValue([]string{str2}, true, vv2)
+		assert.Error(t, err)
+		assert.Equal(t, invalidTypeError(longParam, str2), err)
+
+		floatParam := newParam("badFloat").Typed("number", "float")
+		value = reflect.ValueOf(float64(0))
+		binder = np(floatParam)
+		err = binder.bindValue([]string{"yada"}, true, value)
+		// fails for invalid string
+		assert.Error(t, err)
+		assert.Equal(t, invalidTypeError(floatParam, "yada"), err)
+		// fails for overflow
+		str3 := strconv.FormatFloat(math.MaxFloat64, 'f', 5, 64)
+		v3 := reflect.TypeOf(float32(0))
+		value = reflect.New(v3).Elem()
+		binder = np(floatParam)
+		err = binder.bindValue([]string{str3}, true, value)
+		assert.Error(t, err)
+		assert.Equal(t, invalidTypeError(floatParam, str3), err)
+
+		doubleParam := newParam("badDouble").Typed("number", "double")
+		value = reflect.ValueOf(float64(0))
+		binder = np(doubleParam)
+		err = binder.bindValue([]string{"yada"}, true, value)
+		// fails for invalid string
+		assert.Error(t, err)
+		assert.Equal(t, invalidTypeError(doubleParam, "yada"), err)
+		// fails for overflow
+		str4 := "9" + strconv.FormatFloat(math.MaxFloat64, 'f', 5, 64)
+		v4 := reflect.TypeOf(float64(0))
+		value = reflect.New(v4).Elem()
+		binder = np(doubleParam)
+		err = binder.bindValue([]string{str4}, true, value)
+		assert.Error(t, err)
+		assert.Equal(t, invalidTypeError(doubleParam, str4), err)
+
+		dateParam := newParam("badDate").Typed("string", "date")
+		value = reflect.ValueOf(strfmt.Date{})
+		binder = np(dateParam)
+		err = binder.bindValue([]string{"yada"}, true, value)
+		// fails for invalid string
+		assert.Error(t, err)
+		assert.Equal(t, invalidTypeError(dateParam, "yada"), err)
+
+		dateTimeParam := newParam("badDateTime").Typed("string", "date-time")
+		value = reflect.ValueOf(strfmt.DateTime{})
+		binder = np(dateTimeParam)
+		err = binder.bindValue([]string{"yada"}, true, value)
+		// fails for invalid string
+		assert.Error(t, err)
+		assert.Equal(t, invalidTypeError(dateTimeParam, "yada"), err)
+
+		byteParam := newParam("badByte").Typed("string", "byte")
+		values := url.Values(map[string][]string{})
+		values.Add("badByte", "yaüda")
+		v5 := []byte{}
+		value = reflect.ValueOf(&v5).Elem()
+		binder = np(byteParam)
+		err = binder.bindValue([]string{"yaüda"}, true, value)
+		// fails for invalid string
+		assert.Error(t, err)
+		assert.Equal(t, invalidTypeError(byteParam, "yaüda"), err)
+	}
+}
+
+func TestTypeDetectionInvalidItems(t *testing.T) {
+	withoutItems := spec.QueryParam("without").CollectionOf(nil, "")
+	binder := &untypedParamBinder{
+		Name:      "without",
+		parameter: withoutItems,
+	}
+	assert.Nil(t, binder.Type())
+
+	items := new(spec.Items)
+	items.Type = "array"
+	withInvalidItems := spec.QueryParam("invalidItems").CollectionOf(items, "")
+	binder = &untypedParamBinder{
+		Name:      "invalidItems",
+		parameter: withInvalidItems,
+	}
+	assert.Nil(t, binder.Type())
+
+	noType := spec.QueryParam("invalidType")
+	noType.Type = "invalid"
+	binder = &untypedParamBinder{
+		Name:      "invalidType",
+		parameter: noType,
+	}
+	assert.Nil(t, binder.Type())
+}
+
+// type emailStrFmt struct {
+// 	name      string
+// 	tpe       reflect.Type
+// 	validator FormatValidator
+// }
+//
+// func (e *emailStrFmt) Name() string {
+// 	return e.name
+// }
+//
+// func (e *emailStrFmt) Type() reflect.Type {
+// 	return e.tpe
+// }
+//
+// func (e *emailStrFmt) Matches(str string) bool {
+// 	return e.validator(str)
+// }
+//
+// func TestTypeDetectionValid(t *testing.T) {
+// 	// emlFmt := &emailStrFmt{
+// 	// 	name: "email",
+// 	// 	tpe:  reflect.TypeOf(email{}),
+// 	// }
+// 	// formats := []StringFormat{emlFmt}
+//
+// 	expected := map[string]reflect.Type{
+// 		"name":         reflect.TypeOf(""),
+// 		"id":           reflect.TypeOf(int64(0)),
+// 		"age":          reflect.TypeOf(int32(0)),
+// 		"score":        reflect.TypeOf(float32(0)),
+// 		"factor":       reflect.TypeOf(float64(0)),
+// 		"friend":       reflect.TypeOf(map[string]interface{}{}),
+// 		"X-Request-Id": reflect.TypeOf(int64(0)),
+// 		"tags":         reflect.TypeOf([]string{}),
+// 		"confirmed":    reflect.TypeOf(true),
+// 		"planned":      reflect.TypeOf(swagger.Date{}),
+// 		"delivered":    reflect.TypeOf(swagger.DateTime{}),
+// 		"email":        reflect.TypeOf(email{}),
+// 		"picture":      reflect.TypeOf([]byte{}),
+// 		"file":         reflect.TypeOf(&swagger.File{}).Elem(),
+// 	}
+//
+// 	params := parametersForAllTypes("")
+// 	emailParam := spec.QueryParam("email").Typed("string", "email")
+// 	params["email"] = *emailParam
+//
+// 	fileParam := spec.FileParam("file")
+// 	params["file"] = *fileParam
+//
+// 	for _, v := range params {
+// 		binder := &paramBinder{
+// 			formats:   formats,
+// 			name:      v.Name,
+// 			parameter: &v,
+// 		}
+// 		assert.Equal(t, expected[v.Name], binder.Type(), "name: %s", v.Name)
+// 	}
+// }
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/request.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/request.go
@@ -0,0 +1,104 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 middleware
+
+import (
+	"net/http"
+	"reflect"
+
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/strfmt"
+)
+
+// RequestBinder binds and validates the data from a http request
+type untypedRequestBinder struct {
+	Spec         *spec.Swagger
+	Parameters   map[string]spec.Parameter
+	Formats      strfmt.Registry
+	paramBinders map[string]*untypedParamBinder
+}
+
+// NewRequestBinder creates a new binder for reading a request.
+func newUntypedRequestBinder(parameters map[string]spec.Parameter, spec *spec.Swagger, formats strfmt.Registry) *untypedRequestBinder {
+	binders := make(map[string]*untypedParamBinder)
+	for fieldName, param := range parameters {
+		binders[fieldName] = newUntypedParamBinder(param, spec, formats)
+	}
+	return &untypedRequestBinder{
+		Parameters:   parameters,
+		paramBinders: binders,
+		Spec:         spec,
+		Formats:      formats,
+	}
+}
+
+// Bind perform the databinding and validation
+func (o *untypedRequestBinder) Bind(request *http.Request, routeParams RouteParams, consumer runtime.Consumer, data interface{}) error {
+	val := reflect.Indirect(reflect.ValueOf(data))
+	isMap := val.Kind() == reflect.Map
+	var result []error
+
+	for fieldName, param := range o.Parameters {
+		binder := o.paramBinders[fieldName]
+
+		var target reflect.Value
+		if !isMap {
+			binder.Name = fieldName
+			target = val.FieldByName(fieldName)
+		}
+
+		if isMap {
+			tpe := binder.Type()
+			if tpe == nil {
+				if param.Schema.Type.Contains("array") {
+					tpe = reflect.TypeOf([]interface{}{})
+				} else {
+					tpe = reflect.TypeOf(map[string]interface{}{})
+				}
+			}
+			target = reflect.Indirect(reflect.New(tpe))
+
+		}
+
+		if !target.IsValid() {
+			result = append(result, errors.New(500, "parameter name %q is an unknown field", binder.Name))
+			continue
+		}
+
+		if err := binder.Bind(request, routeParams, consumer, target); err != nil {
+			result = append(result, err)
+			continue
+		}
+
+		if binder.validator != nil {
+			rr := binder.validator.Validate(target.Interface())
+			if rr != nil && rr.HasErrors() {
+				result = append(result, rr.AsError())
+			}
+		}
+
+		if isMap {
+			val.SetMapIndex(reflect.ValueOf(param.Name), target)
+		}
+	}
+
+	if len(result) > 0 {
+		return errors.CompositeValidationError(result...)
+	}
+
+	return nil
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/request_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/request_test.go
@@ -0,0 +1,481 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 middleware
+
+import (
+	"bytes"
+	"io"
+	"io/ioutil"
+	"mime/multipart"
+	"net/http"
+	"net/url"
+	"strings"
+	"testing"
+	"time"
+
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/strfmt"
+	"github.com/stretchr/testify/assert"
+)
+
+type stubConsumer struct {
+}
+
+func (s *stubConsumer) Consume(_ io.Reader, _ interface{}) error {
+	return nil
+}
+
+type friend struct {
+	Name string `json:"name"`
+	Age  int    `json:"age"`
+}
+
+type jsonRequestParams struct {
+	ID        int64    // path
+	Name      string   // query
+	Friend    friend   // body
+	RequestID int64    // header
+	Tags      []string // csv
+}
+
+type jsonRequestPtr struct {
+	ID        int64    // path
+	Name      string   // query
+	RequestID int64    // header
+	Tags      []string // csv
+	Friend    *friend
+}
+
+type jsonRequestSlice struct {
+	ID        int64    // path
+	Name      string   // query
+	RequestID int64    // header
+	Tags      []string // csv
+	Friend    []friend
+}
+
+type jsonRequestAllTypes struct {
+	Confirmed bool
+	Planned   strfmt.Date
+	Delivered strfmt.DateTime
+	Age       int32
+	ID        int64
+	Score     float32
+	Factor    float64
+	Friend    friend
+	Name      string
+	Tags      []string
+	Picture   []byte
+	RequestID int64
+}
+
+func parametersForAllTypes(fmt string) map[string]spec.Parameter {
+	if fmt == "" {
+		fmt = "csv"
+	}
+	nameParam := spec.QueryParam("name").Typed("string", "")
+	idParam := spec.PathParam("id").Typed("integer", "int64")
+	ageParam := spec.QueryParam("age").Typed("integer", "int32")
+	scoreParam := spec.QueryParam("score").Typed("number", "float")
+	factorParam := spec.QueryParam("factor").Typed("number", "double")
+
+	friendSchema := new(spec.Schema).Typed("object", "")
+	friendParam := spec.BodyParam("friend", friendSchema)
+
+	requestIDParam := spec.HeaderParam("X-Request-Id").Typed("integer", "int64")
+	requestIDParam.Extensions = spec.Extensions(map[string]interface{}{})
+	requestIDParam.Extensions.Add("go-name", "RequestID")
+
+	items := new(spec.Items)
+	items.Type = "string"
+	tagsParam := spec.QueryParam("tags").CollectionOf(items, fmt)
+
+	confirmedParam := spec.QueryParam("confirmed").Typed("boolean", "")
+	plannedParam := spec.QueryParam("planned").Typed("string", "date")
+	deliveredParam := spec.QueryParam("delivered").Typed("string", "date-time")
+	pictureParam := spec.QueryParam("picture").Typed("string", "byte") // base64 encoded during transport
+
+	return map[string]spec.Parameter{
+		"ID":        *idParam,
+		"Name":      *nameParam,
+		"RequestID": *requestIDParam,
+		"Friend":    *friendParam,
+		"Tags":      *tagsParam,
+		"Age":       *ageParam,
+		"Score":     *scoreParam,
+		"Factor":    *factorParam,
+		"Confirmed": *confirmedParam,
+		"Planned":   *plannedParam,
+		"Delivered": *deliveredParam,
+		"Picture":   *pictureParam,
+	}
+}
+
+func parametersForJSONRequestParams(fmt string) map[string]spec.Parameter {
+	if fmt == "" {
+		fmt = "csv"
+	}
+	nameParam := spec.QueryParam("name").Typed("string", "")
+	idParam := spec.PathParam("id").Typed("integer", "int64")
+
+	friendSchema := new(spec.Schema).Typed("object", "")
+	friendParam := spec.BodyParam("friend", friendSchema)
+
+	requestIDParam := spec.HeaderParam("X-Request-Id").Typed("integer", "int64")
+	requestIDParam.Extensions = spec.Extensions(map[string]interface{}{})
+	requestIDParam.Extensions.Add("go-name", "RequestID")
+
+	items := new(spec.Items)
+	items.Type = "string"
+	tagsParam := spec.QueryParam("tags").CollectionOf(items, fmt)
+
+	return map[string]spec.Parameter{
+		"ID":        *idParam,
+		"Name":      *nameParam,
+		"RequestID": *requestIDParam,
+		"Friend":    *friendParam,
+		"Tags":      *tagsParam,
+	}
+}
+func parametersForJSONRequestSliceParams(fmt string) map[string]spec.Parameter {
+	if fmt == "" {
+		fmt = "csv"
+	}
+	nameParam := spec.QueryParam("name").Typed("string", "")
+	idParam := spec.PathParam("id").Typed("integer", "int64")
+
+	friendSchema := new(spec.Schema).Typed("object", "")
+	friendParam := spec.BodyParam("friend", spec.ArrayProperty(friendSchema))
+
+	requestIDParam := spec.HeaderParam("X-Request-Id").Typed("integer", "int64")
+	requestIDParam.Extensions = spec.Extensions(map[string]interface{}{})
+	requestIDParam.Extensions.Add("go-name", "RequestID")
+
+	items := new(spec.Items)
+	items.Type = "string"
+	tagsParam := spec.QueryParam("tags").CollectionOf(items, fmt)
+
+	return map[string]spec.Parameter{
+		"ID":        *idParam,
+		"Name":      *nameParam,
+		"RequestID": *requestIDParam,
+		"Friend":    *friendParam,
+		"Tags":      *tagsParam,
+	}
+}
+
+func TestRequestBindingDefaultValue(t *testing.T) {
+	confirmed := true
+	name := "thomas"
+	friend := map[string]interface{}{"name": "toby", "age": float64(32)}
+	id, age, score, factor := int64(7575), int32(348), float32(5.309), float64(37.403)
+	requestID := 19394858
+	tags := []string{"one", "two", "three"}
+	dt1 := time.Date(2014, 8, 9, 0, 0, 0, 0, time.UTC)
+	planned := strfmt.Date(dt1)
+	dt2 := time.Date(2014, 10, 12, 8, 5, 5, 0, time.UTC)
+	delivered := strfmt.DateTime(dt2)
+	uri, _ := url.Parse("http://localhost:8002/hello")
+	defaults := map[string]interface{}{
+		"id":           id,
+		"age":          age,
+		"score":        score,
+		"factor":       factor,
+		"name":         name,
+		"friend":       friend,
+		"X-Request-Id": requestID,
+		"tags":         tags,
+		"confirmed":    confirmed,
+		"planned":      planned,
+		"delivered":    delivered,
+		"picture":      []byte("hello"),
+	}
+	op2 := parametersForAllTypes("")
+	op3 := make(map[string]spec.Parameter)
+	for k, p := range op2 {
+		p.Default = defaults[p.Name]
+		op3[k] = p
+	}
+
+	req, _ := http.NewRequest("POST", uri.String(), bytes.NewBuffer(nil))
+	req.Header.Set("Content-Type", "application/json")
+	binder := newUntypedRequestBinder(op3, new(spec.Swagger), strfmt.Default)
+
+	data := make(map[string]interface{})
+	err := binder.Bind(req, RouteParams(nil), runtime.JSONConsumer(), &data)
+	assert.NoError(t, err)
+	assert.Equal(t, defaults["id"], data["id"])
+	assert.Equal(t, name, data["name"])
+	assert.Equal(t, friend, data["friend"])
+	assert.EqualValues(t, requestID, data["X-Request-Id"])
+	assert.Equal(t, tags, data["tags"])
+	assert.Equal(t, planned, data["planned"])
+	assert.Equal(t, delivered, data["delivered"])
+	assert.Equal(t, confirmed, data["confirmed"])
+	assert.Equal(t, age, data["age"])
+	assert.Equal(t, factor, data["factor"])
+	assert.Equal(t, score, data["score"])
+	assert.Equal(t, "hello", string(data["picture"].(strfmt.Base64)))
+}
+
+func TestRequestBindingForInvalid(t *testing.T) {
+
+	invalidParam := spec.QueryParam("some")
+
+	op1 := map[string]spec.Parameter{"Some": *invalidParam}
+
+	binder := newUntypedRequestBinder(op1, new(spec.Swagger), strfmt.Default)
+	req, _ := http.NewRequest("GET", "http://localhost:8002/hello?name=the-name", nil)
+
+	err := binder.Bind(req, nil, new(stubConsumer), new(jsonRequestParams))
+	assert.Error(t, err)
+
+	op2 := parametersForJSONRequestParams("")
+	binder = newUntypedRequestBinder(op2, new(spec.Swagger), strfmt.Default)
+
+	req, _ = http.NewRequest("POST", "http://localhost:8002/hello/1?name=the-name", bytes.NewBuffer([]byte(`{"name":"toby","age":32}`)))
+	req.Header.Set("Content-Type", "application(")
+	data := jsonRequestParams{}
+	err = binder.Bind(req, RouteParams([]RouteParam{{"id", "1"}}), runtime.JSONConsumer(), &data)
+	assert.Error(t, err)
+
+	req, _ = http.NewRequest("POST", "http://localhost:8002/hello/1?name=the-name", bytes.NewBuffer([]byte(`{]`)))
+	req.Header.Set("Content-Type", "application/json")
+	data = jsonRequestParams{}
+	err = binder.Bind(req, RouteParams([]RouteParam{{"id", "1"}}), runtime.JSONConsumer(), &data)
+	assert.Error(t, err)
+
+	invalidMultiParam := spec.HeaderParam("tags").CollectionOf(new(spec.Items), "multi")
+	op3 := map[string]spec.Parameter{"Tags": *invalidMultiParam}
+	binder = newUntypedRequestBinder(op3, new(spec.Swagger), strfmt.Default)
+
+	req, _ = http.NewRequest("POST", "http://localhost:8002/hello/1?name=the-name", bytes.NewBuffer([]byte(`{}`)))
+	req.Header.Set("Content-Type", "application/json")
+	data = jsonRequestParams{}
+	err = binder.Bind(req, RouteParams([]RouteParam{{"id", "1"}}), runtime.JSONConsumer(), &data)
+	assert.Error(t, err)
+
+	invalidMultiParam = spec.PathParam("").CollectionOf(new(spec.Items), "multi")
+
+	op4 := map[string]spec.Parameter{"Tags": *invalidMultiParam}
+	binder = newUntypedRequestBinder(op4, new(spec.Swagger), strfmt.Default)
+
+	req, _ = http.NewRequest("POST", "http://localhost:8002/hello/1?name=the-name", bytes.NewBuffer([]byte(`{}`)))
+	req.Header.Set("Content-Type", "application/json")
+	data = jsonRequestParams{}
+	err = binder.Bind(req, RouteParams([]RouteParam{{"id", "1"}}), runtime.JSONConsumer(), &data)
+	assert.Error(t, err)
+
+	invalidInParam := spec.HeaderParam("tags").Typed("string", "")
+	invalidInParam.In = "invalid"
+	op5 := map[string]spec.Parameter{"Tags": *invalidInParam}
+	binder = newUntypedRequestBinder(op5, new(spec.Swagger), strfmt.Default)
+
+	req, _ = http.NewRequest("POST", "http://localhost:8002/hello/1?name=the-name", bytes.NewBuffer([]byte(`{}`)))
+	req.Header.Set("Content-Type", "application/json")
+	data = jsonRequestParams{}
+	err = binder.Bind(req, RouteParams([]RouteParam{{"id", "1"}}), runtime.JSONConsumer(), &data)
+	assert.Error(t, err)
+}
+
+func TestRequestBindingForValid(t *testing.T) {
+
+	for _, fmt := range []string{"csv", "pipes", "tsv", "ssv", "multi"} {
+		op1 := parametersForJSONRequestParams(fmt)
+
+		binder := newUntypedRequestBinder(op1, new(spec.Swagger), strfmt.Default)
+
+		lval := []string{"one", "two", "three"}
+		queryString := ""
+		switch fmt {
+		case "multi":
+			queryString = strings.Join(lval, "&tags=")
+		case "ssv":
+			queryString = strings.Join(lval, " ")
+		case "pipes":
+			queryString = strings.Join(lval, "|")
+		case "tsv":
+			queryString = strings.Join(lval, "\t")
+		default:
+			queryString = strings.Join(lval, ",")
+		}
+
+		urlStr := "http://localhost:8002/hello/1?name=the-name&tags=" + queryString
+
+		req, _ := http.NewRequest("POST", urlStr, bytes.NewBuffer([]byte(`{"name":"toby","age":32}`)))
+		req.Header.Set("Content-Type", "application/json;charset=utf-8")
+		req.Header.Set("X-Request-Id", "1325959595")
+
+		data := jsonRequestParams{}
+		err := binder.Bind(req, RouteParams([]RouteParam{{"id", "1"}}), runtime.JSONConsumer(), &data)
+
+		expected := jsonRequestParams{
+			ID:        1,
+			Name:      "the-name",
+			Friend:    friend{"toby", 32},
+			RequestID: 1325959595,
+			Tags:      []string{"one", "two", "three"},
+		}
+		assert.NoError(t, err)
+		assert.Equal(t, expected, data)
+	}
+
+	op1 := parametersForJSONRequestParams("")
+
+	binder := newUntypedRequestBinder(op1, new(spec.Swagger), strfmt.Default)
+	urlStr := "http://localhost:8002/hello/1?name=the-name&tags=one,two,three"
+	req, _ := http.NewRequest("POST", urlStr, bytes.NewBuffer([]byte(`{"name":"toby","age":32}`)))
+	req.Header.Set("Content-Type", "application/json;charset=utf-8")
+	req.Header.Set("X-Request-Id", "1325959595")
+
+	data2 := jsonRequestPtr{}
+	err := binder.Bind(req, []RouteParam{{"id", "1"}}, runtime.JSONConsumer(), &data2)
+
+	expected2 := jsonRequestPtr{
+		Friend: &friend{"toby", 32},
+		Tags:   []string{"one", "two", "three"},
+	}
+	assert.NoError(t, err)
+	if data2.Friend == nil {
+		t.Fatal("friend is nil")
+	}
+	assert.Equal(t, *expected2.Friend, *data2.Friend)
+	assert.Equal(t, expected2.Tags, data2.Tags)
+
+	req, _ = http.NewRequest("POST", urlStr, bytes.NewBuffer([]byte(`[{"name":"toby","age":32}]`)))
+	req.Header.Set("Content-Type", "application/json;charset=utf-8")
+	req.Header.Set("X-Request-Id", "1325959595")
+	op2 := parametersForJSONRequestSliceParams("")
+	binder = newUntypedRequestBinder(op2, new(spec.Swagger), strfmt.Default)
+	data3 := jsonRequestSlice{}
+	err = binder.Bind(req, []RouteParam{{"id", "1"}}, runtime.JSONConsumer(), &data3)
+
+	expected3 := jsonRequestSlice{
+		Friend: []friend{{"toby", 32}},
+		Tags:   []string{"one", "two", "three"},
+	}
+	assert.NoError(t, err)
+	assert.Equal(t, expected3.Friend, data3.Friend)
+	assert.Equal(t, expected3.Tags, data3.Tags)
+}
+
+type formRequest struct {
+	Name string
+	Age  int
+}
+
+func parametersForFormUpload() map[string]spec.Parameter {
+	nameParam := spec.FormDataParam("name").Typed("string", "")
+
+	ageParam := spec.FormDataParam("age").Typed("integer", "int32")
+
+	return map[string]spec.Parameter{"Name": *nameParam, "Age": *ageParam}
+}
+
+func TestFormUpload(t *testing.T) {
+	params := parametersForFormUpload()
+	binder := newUntypedRequestBinder(params, new(spec.Swagger), strfmt.Default)
+
+	urlStr := "http://localhost:8002/hello"
+	req, _ := http.NewRequest("POST", urlStr, bytes.NewBufferString(`name=the-name&age=32`))
+	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+
+	data := formRequest{}
+	res := binder.Bind(req, nil, runtime.JSONConsumer(), &data)
+	assert.NoError(t, res)
+	assert.Equal(t, "the-name", data.Name)
+	assert.Equal(t, 32, data.Age)
+
+	req, _ = http.NewRequest("POST", urlStr, bytes.NewBufferString(`name=%3&age=32`))
+	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+
+	data = formRequest{}
+	assert.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
+}
+
+type fileRequest struct {
+	Name string       // body
+	File runtime.File // upload
+}
+
+func paramsForFileUpload() *untypedRequestBinder {
+	nameParam := spec.FormDataParam("name").Typed("string", "")
+
+	fileParam := spec.FileParam("file")
+
+	params := map[string]spec.Parameter{"Name": *nameParam, "File": *fileParam}
+	return newUntypedRequestBinder(params, new(spec.Swagger), strfmt.Default)
+}
+
+func TestBindingFileUpload(t *testing.T) {
+	binder := paramsForFileUpload()
+
+	body := bytes.NewBuffer(nil)
+	writer := multipart.NewWriter(body)
+	part, err := writer.CreateFormFile("file", "plain-jane.txt")
+	assert.NoError(t, err)
+
+	part.Write([]byte("the file contents"))
+	writer.WriteField("name", "the-name")
+	assert.NoError(t, writer.Close())
+
+	urlStr := "http://localhost:8002/hello"
+	req, _ := http.NewRequest("POST", urlStr, body)
+	req.Header.Set("Content-Type", writer.FormDataContentType())
+
+	data := fileRequest{}
+	assert.NoError(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
+	assert.Equal(t, "the-name", data.Name)
+	assert.NotNil(t, data.File)
+	assert.NotNil(t, data.File.Header)
+	assert.Equal(t, "plain-jane.txt", data.File.Header.Filename)
+
+	bb, err := ioutil.ReadAll(data.File.Data)
+	assert.NoError(t, err)
+	assert.Equal(t, []byte("the file contents"), bb)
+
+	req, _ = http.NewRequest("POST", urlStr, body)
+	req.Header.Set("Content-Type", "application/json")
+	data = fileRequest{}
+	assert.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
+
+	req, _ = http.NewRequest("POST", urlStr, body)
+	req.Header.Set("Content-Type", "application(")
+	data = fileRequest{}
+	assert.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
+
+	body = bytes.NewBuffer(nil)
+	writer = multipart.NewWriter(body)
+	part, err = writer.CreateFormFile("bad-name", "plain-jane.txt")
+	assert.NoError(t, err)
+
+	part.Write([]byte("the file contents"))
+	writer.WriteField("name", "the-name")
+	assert.NoError(t, writer.Close())
+	req, _ = http.NewRequest("POST", urlStr, body)
+	req.Header.Set("Content-Type", writer.FormDataContentType())
+
+	data = fileRequest{}
+	assert.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
+
+	req, _ = http.NewRequest("POST", urlStr, body)
+	req.Header.Set("Content-Type", writer.FormDataContentType())
+	req.MultipartReader()
+
+	data = fileRequest{}
+	assert.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
+
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/route_param_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/route_param_test.go
@@ -0,0 +1,38 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 middleware
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestRouteParams(t *testing.T) {
+	coll1 := RouteParams([]RouteParam{
+		{"blah", "foo"},
+		{"abc", "bar"},
+		{"ccc", "efg"},
+	})
+
+	v := coll1.Get("blah")
+	assert.Equal(t, v, "foo")
+	v2 := coll1.Get("abc")
+	assert.Equal(t, v2, "bar")
+	v3 := coll1.Get("ccc")
+	assert.Equal(t, v3, "efg")
+	v4 := coll1.Get("ydkdk")
+	assert.Empty(t, v4)
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/router.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/router.go
@@ -0,0 +1,254 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 middleware
+
+import (
+	"net/http"
+	"regexp"
+	"strings"
+
+	"github.com/go-openapi/analysis"
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/loads"
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/runtime/middleware/denco"
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/strfmt"
+	"github.com/gorilla/context"
+)
+
+// RouteParam is a object to capture route params in a framework agnostic way.
+// implementations of the muxer should use these route params to communicate with the
+// swagger framework
+type RouteParam struct {
+	Name  string
+	Value string
+}
+
+// RouteParams the collection of route params
+type RouteParams []RouteParam
+
+// Get gets the value for the route param for the specified key
+func (r RouteParams) Get(name string) string {
+	vv, _, _ := r.GetOK(name)
+	if len(vv) > 0 {
+		return vv[len(vv)-1]
+	}
+	return ""
+}
+
+// GetOK gets the value but also returns booleans to indicate if a key or value
+// is present. This aids in validation and satisfies an interface in use there
+//
+// The returned values are: data, has key, has value
+func (r RouteParams) GetOK(name string) ([]string, bool, bool) {
+	for _, p := range r {
+		if p.Name == name {
+			return []string{p.Value}, true, p.Value != ""
+		}
+	}
+	return nil, false, false
+}
+
+func newRouter(ctx *Context, next http.Handler) http.Handler {
+	if ctx.router == nil {
+		ctx.router = DefaultRouter(ctx.spec, ctx.api)
+	}
+	basePath := ctx.spec.BasePath()
+	isRoot := basePath == "" || basePath == "/"
+	for strings.HasSuffix(basePath, "/") {
+		basePath = basePath[:len(basePath)-1]
+	}
+
+	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+		defer context.Clear(r)
+		// use context to lookup routes
+		if isRoot {
+			if _, ok := ctx.RouteInfo(r); ok {
+				next.ServeHTTP(rw, r)
+				return
+			}
+		} else {
+			ep := r.URL.EscapedPath()
+			if p := strings.TrimPrefix(ep, basePath); len(p) < len(ep) {
+				r.URL.Path = p
+				if _, ok := ctx.RouteInfo(r); ok {
+					next.ServeHTTP(rw, r)
+					return
+				}
+			}
+		}
+		// Not found, check if it exists in the other methods first
+		if others := ctx.AllowedMethods(r); len(others) > 0 {
+			ctx.Respond(rw, r, ctx.analyzer.RequiredProduces(), nil, errors.MethodNotAllowed(r.Method, others))
+			return
+		}
+
+		ctx.Respond(rw, r, ctx.analyzer.RequiredProduces(), nil, errors.NotFound("path %s was not found", r.URL.Path))
+	})
+}
+
+// RoutableAPI represents an interface for things that can serve
+// as a provider of implementations for the swagger router
+type RoutableAPI interface {
+	HandlerFor(string, string) (http.Handler, bool)
+	ServeErrorFor(string) func(http.ResponseWriter, *http.Request, error)
+	ConsumersFor([]string) map[string]runtime.Consumer
+	ProducersFor([]string) map[string]runtime.Producer
+	AuthenticatorsFor(map[string]spec.SecurityScheme) map[string]runtime.Authenticator
+	Formats() strfmt.Registry
+	DefaultProduces() string
+	DefaultConsumes() string
+}
+
+// Router represents a swagger aware router
+type Router interface {
+	Lookup(method, path string) (*MatchedRoute, bool)
+	OtherMethods(method, path string) []string
+}
+
+type defaultRouteBuilder struct {
+	spec     *loads.Document
+	analyzer *analysis.Spec
+	api      RoutableAPI
+	records  map[string][]denco.Record
+}
+
+type defaultRouter struct {
+	spec    *loads.Document
+	api     RoutableAPI
+	routers map[string]*denco.Router
+}
+
+func newDefaultRouteBuilder(spec *loads.Document, api RoutableAPI) *defaultRouteBuilder {
+	return &defaultRouteBuilder{
+		spec:     spec,
+		analyzer: analysis.New(spec.Spec()),
+		api:      api,
+		records:  make(map[string][]denco.Record),
+	}
+}
+
+// DefaultRouter creates a default implemenation of the router
+func DefaultRouter(spec *loads.Document, api RoutableAPI) Router {
+	builder := newDefaultRouteBuilder(spec, api)
+	if spec != nil {
+		for method, paths := range builder.analyzer.Operations() {
+			for path, operation := range paths {
+				builder.AddRoute(method, path, operation)
+			}
+		}
+	}
+	return builder.Build()
+}
+
+type routeEntry struct {
+	PathPattern    string
+	BasePath       string
+	Operation      *spec.Operation
+	Consumes       []string
+	Consumers      map[string]runtime.Consumer
+	Produces       []string
+	Producers      map[string]runtime.Producer
+	Parameters     map[string]spec.Parameter
+	Handler        http.Handler
+	Formats        strfmt.Registry
+	Binder         *untypedRequestBinder
+	Authenticators map[string]runtime.Authenticator
+	Scopes         map[string][]string
+}
+
+// MatchedRoute represents the route that was matched in this request
+type MatchedRoute struct {
+	routeEntry
+	Params   RouteParams
+	Consumer runtime.Consumer
+	Producer runtime.Producer
+}
+
+func (d *defaultRouter) Lookup(method, path string) (*MatchedRoute, bool) {
+	if router, ok := d.routers[strings.ToUpper(method)]; ok {
+		if m, rp, ok := router.Lookup(path); ok && m != nil {
+			if entry, ok := m.(*routeEntry); ok {
+				var params RouteParams
+				for _, p := range rp {
+					params = append(params, RouteParam{Name: p.Name, Value: p.Value})
+				}
+				return &MatchedRoute{routeEntry: *entry, Params: params}, true
+			}
+		}
+	}
+	return nil, false
+}
+
+func (d *defaultRouter) OtherMethods(method, path string) []string {
+	mn := strings.ToUpper(method)
+	var methods []string
+	for k, v := range d.routers {
+		if k != mn {
+			if _, _, ok := v.Lookup(path); ok {
+				methods = append(methods, k)
+				continue
+			}
+		}
+	}
+	return methods
+}
+
+var pathConverter = regexp.MustCompile(`{(\w+)}`)
+
+func (d *defaultRouteBuilder) AddRoute(method, path string, operation *spec.Operation) {
+	mn := strings.ToUpper(method)
+
+	if handler, ok := d.api.HandlerFor(method, path); ok {
+		consumes := d.analyzer.ConsumesFor(operation)
+		produces := d.analyzer.ProducesFor(operation)
+		parameters := d.analyzer.ParamsFor(method, path)
+		definitions := d.analyzer.SecurityDefinitionsFor(operation)
+		requirements := d.analyzer.SecurityRequirementsFor(operation)
+		scopes := make(map[string][]string, len(requirements))
+		for _, v := range requirements {
+			scopes[v.Name] = v.Scopes
+		}
+
+		record := denco.NewRecord(pathConverter.ReplaceAllString(path, ":$1"), &routeEntry{
+			Operation:      operation,
+			Handler:        handler,
+			Consumes:       consumes,
+			Produces:       produces,
+			Consumers:      d.api.ConsumersFor(consumes),
+			Producers:      d.api.ProducersFor(produces),
+			Parameters:     parameters,
+			Formats:        d.api.Formats(),
+			Binder:         newUntypedRequestBinder(parameters, d.spec.Spec(), d.api.Formats()),
+			Authenticators: d.api.AuthenticatorsFor(definitions),
+			Scopes:         scopes,
+		})
+		d.records[mn] = append(d.records[mn], record)
+	}
+}
+
+func (d *defaultRouteBuilder) Build() *defaultRouter {
+	routers := make(map[string]*denco.Router)
+	for method, records := range d.records {
+		router := denco.New()
+		router.Build(records)
+		routers[method] = router
+	}
+	return &defaultRouter{
+		spec:    d.spec,
+		routers: routers,
+	}
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/router_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/router_test.go
@@ -0,0 +1,196 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 middleware
+
+import (
+	"net/http"
+	"net/http/httptest"
+	"sort"
+	"strings"
+	"testing"
+
+	"github.com/go-openapi/analysis"
+	"github.com/go-openapi/loads"
+	"github.com/go-openapi/runtime/internal/testing/petstore"
+	"github.com/go-openapi/runtime/middleware/untyped"
+	"github.com/stretchr/testify/assert"
+)
+
+func terminator(rw http.ResponseWriter, r *http.Request) {
+	rw.WriteHeader(http.StatusOK)
+}
+
+func TestRouterMiddleware(t *testing.T) {
+	spec, api := petstore.NewAPI(t)
+	context := NewContext(spec, api, nil)
+	mw := newRouter(context, http.HandlerFunc(terminator))
+
+	recorder := httptest.NewRecorder()
+	request, _ := http.NewRequest("GET", "/api/pets", nil)
+
+	mw.ServeHTTP(recorder, request)
+	assert.Equal(t, 200, recorder.Code)
+
+	recorder = httptest.NewRecorder()
+	request, _ = http.NewRequest("DELETE", "/api/pets", nil)
+
+	mw.ServeHTTP(recorder, request)
+	assert.Equal(t, http.StatusMethodNotAllowed, recorder.Code)
+
+	methods := strings.Split(recorder.Header().Get("Allow"), ",")
+	sort.Sort(sort.StringSlice(methods))
+	assert.Equal(t, "GET,POST", strings.Join(methods, ","))
+
+	recorder = httptest.NewRecorder()
+	request, _ = http.NewRequest("GET", "/nopets", nil)
+
+	mw.ServeHTTP(recorder, request)
+	assert.Equal(t, http.StatusNotFound, recorder.Code)
+
+	spec, api = petstore.NewRootAPI(t)
+	context = NewContext(spec, api, nil)
+	mw = newRouter(context, http.HandlerFunc(terminator))
+
+	recorder = httptest.NewRecorder()
+	request, _ = http.NewRequest("GET", "/pets", nil)
+
+	mw.ServeHTTP(recorder, request)
+	assert.Equal(t, 200, recorder.Code)
+
+	recorder = httptest.NewRecorder()
+	request, _ = http.NewRequest("DELETE", "/pets", nil)
+
+	mw.ServeHTTP(recorder, request)
+	assert.Equal(t, http.StatusMethodNotAllowed, recorder.Code)
+
+	methods = strings.Split(recorder.Header().Get("Allow"), ",")
+	sort.Sort(sort.StringSlice(methods))
+	assert.Equal(t, "GET,POST", strings.Join(methods, ","))
+
+	recorder = httptest.NewRecorder()
+	request, _ = http.NewRequest("GET", "/nopets", nil)
+
+	mw.ServeHTTP(recorder, request)
+	assert.Equal(t, http.StatusNotFound, recorder.Code)
+
+}
+
+func TestRouterBuilder(t *testing.T) {
+	spec, api := petstore.NewAPI(t)
+	analyzed := analysis.New(spec.Spec())
+
+	assert.Len(t, analyzed.RequiredConsumes(), 3)
+	assert.Len(t, analyzed.RequiredProduces(), 5)
+	assert.Len(t, analyzed.OperationIDs(), 4)
+
+	// context := NewContext(spec, api)
+	builder := petAPIRouterBuilder(spec, api, analyzed)
+	getRecords := builder.records["GET"]
+	postRecords := builder.records["POST"]
+	deleteRecords := builder.records["DELETE"]
+
+	assert.Len(t, getRecords, 2)
+	assert.Len(t, postRecords, 1)
+	assert.Len(t, deleteRecords, 1)
+
+	assert.Empty(t, builder.records["PATCH"])
+	assert.Empty(t, builder.records["OPTIONS"])
+	assert.Empty(t, builder.records["HEAD"])
+	assert.Empty(t, builder.records["PUT"])
+
+	rec := postRecords[0]
+	assert.Equal(t, rec.Key, "/pets")
+	val := rec.Value.(*routeEntry)
+	assert.Len(t, val.Consumers, 1)
+	assert.Len(t, val.Producers, 1)
+	assert.Len(t, val.Consumes, 1)
+	assert.Len(t, val.Produces, 1)
+
+	assert.Len(t, val.Parameters, 1)
+
+	recG := getRecords[0]
+	assert.Equal(t, recG.Key, "/pets")
+	valG := recG.Value.(*routeEntry)
+	assert.Len(t, valG.Consumers, 2)
+	assert.Len(t, valG.Producers, 4)
+	assert.Len(t, valG.Consumes, 2)
+	assert.Len(t, valG.Produces, 4)
+
+	assert.Len(t, valG.Parameters, 2)
+}
+
+func TestRouterCanonicalBasePath(t *testing.T) {
+	spec, api := petstore.NewAPI(t)
+	spec.Spec().BasePath = "/api///"
+	context := NewContext(spec, api, nil)
+	mw := newRouter(context, http.HandlerFunc(terminator))
+
+	recorder := httptest.NewRecorder()
+	request, _ := http.NewRequest("GET", "/api/pets", nil)
+
+	mw.ServeHTTP(recorder, request)
+	assert.Equal(t, 200, recorder.Code)
+}
+
+func TestRouter_EscapedPath(t *testing.T) {
+	spec, api := petstore.NewAPI(t)
+	spec.Spec().BasePath = "/api/"
+	context := NewContext(spec, api, nil)
+	mw := newRouter(context, http.HandlerFunc(terminator))
+
+	recorder := httptest.NewRecorder()
+	request, _ := http.NewRequest("GET", "/api/pets/123", nil)
+
+	mw.ServeHTTP(recorder, request)
+	assert.Equal(t, 200, recorder.Code)
+
+	recorder = httptest.NewRecorder()
+	request, _ = http.NewRequest("GET", "/api/pets/abc%2Fdef", nil)
+
+	mw.ServeHTTP(recorder, request)
+	assert.Equal(t, 200, recorder.Code)
+	ri, _ := context.RouteInfo(request)
+	assert.Equal(t, "abc%2Fdef", ri.Params.Get("id"))
+}
+
+func TestRouterStruct(t *testing.T) {
+	spec, api := petstore.NewAPI(t)
+	router := DefaultRouter(spec, newRoutableUntypedAPI(spec, api, new(Context)))
+
+	methods := router.OtherMethods("post", "/pets/{id}")
+	assert.Len(t, methods, 2)
+
+	entry, ok := router.Lookup("delete", "/pets/{id}")
+	assert.True(t, ok)
+	assert.NotNil(t, entry)
+	assert.Len(t, entry.Params, 1)
+	assert.Equal(t, "id", entry.Params[0].Name)
+
+	_, ok = router.Lookup("delete", "/pets")
+	assert.False(t, ok)
+
+	_, ok = router.Lookup("post", "/no-pets")
+	assert.False(t, ok)
+}
+
+func petAPIRouterBuilder(spec *loads.Document, api *untyped.API, analyzed *analysis.Spec) *defaultRouteBuilder {
+	builder := newDefaultRouteBuilder(spec, newRoutableUntypedAPI(spec, api, new(Context)))
+	builder.AddRoute("GET", "/pets", analyzed.AllPaths()["/pets"].Get)
+	builder.AddRoute("POST", "/pets", analyzed.AllPaths()["/pets"].Post)
+	builder.AddRoute("DELETE", "/pets/{id}", analyzed.AllPaths()["/pets/{id}"].Delete)
+	builder.AddRoute("GET", "/pets/{id}", analyzed.AllPaths()["/pets/{id}"].Get)
+
+	return builder
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/security.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/security.go
@@ -0,0 +1,34 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 middleware
+
+import "net/http"
+
+func newSecureAPI(ctx *Context, next http.Handler) http.Handler {
+	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+		route, _ := ctx.RouteInfo(r)
+		if len(route.Authenticators) == 0 {
+			next.ServeHTTP(rw, r)
+			return
+		}
+
+		if _, err := ctx.Authorize(r, route); err != nil {
+			ctx.Respond(rw, r, route.Produces, route, err)
+			return
+		}
+
+		next.ServeHTTP(rw, r)
+	})
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/security_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/security_test.go
@@ -0,0 +1,58 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 middleware
+
+import (
+	"net/http"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/go-openapi/runtime/internal/testing/petstore"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestSecurityMiddleware(t *testing.T) {
+	spec, api := petstore.NewAPI(t)
+	context := NewContext(spec, api, nil)
+	context.router = DefaultRouter(spec, context.api)
+	mw := newSecureAPI(context, http.HandlerFunc(terminator))
+
+	recorder := httptest.NewRecorder()
+	request, _ := http.NewRequest("GET", "/pets", nil)
+
+	mw.ServeHTTP(recorder, request)
+	assert.Equal(t, 401, recorder.Code)
+
+	recorder = httptest.NewRecorder()
+	request, _ = http.NewRequest("GET", "/pets", nil)
+	request.SetBasicAuth("admin", "wrong")
+
+	mw.ServeHTTP(recorder, request)
+	assert.Equal(t, 401, recorder.Code)
+
+	recorder = httptest.NewRecorder()
+	request, _ = http.NewRequest("GET", "/pets", nil)
+	request.SetBasicAuth("admin", "admin")
+
+	mw.ServeHTTP(recorder, request)
+	assert.Equal(t, 200, recorder.Code)
+
+	recorder = httptest.NewRecorder()
+	request, _ = http.NewRequest("GET", "/pets/1", nil)
+
+	mw.ServeHTTP(recorder, request)
+	assert.Equal(t, 200, recorder.Code)
+
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/spec.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/spec.go
@@ -0,0 +1,63 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 middleware
+
+import (
+	"encoding/json"
+	"net/http"
+
+	"github.com/go-openapi/spec"
+)
+
+func specMiddleware(ctx *Context, next http.Handler) http.Handler {
+	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+		if r.URL.Path == "/swagger.json" {
+			rw.Header().Set("Content-Type", "application/json")
+			rw.WriteHeader(http.StatusOK)
+			rw.Write(ctx.spec.Raw())
+			return
+		}
+		if next == nil {
+			ctx.NotFound(rw, r)
+			return
+		}
+		next.ServeHTTP(rw, r)
+	})
+}
+
+// Spec creates a middleware to serve a swagger spec.
+// This allows for altering the spec before starting the http listener.
+// This can be useful
+//
+func Spec(basePath string, swsp *spec.Swagger, next http.Handler) http.Handler {
+	if basePath == "/" {
+		basePath = ""
+	}
+	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+		if r.URL.Path == basePath+"/swagger.json" {
+			rw.Header().Set("Content-Type", "application/json")
+			rw.WriteHeader(http.StatusOK)
+			dec := json.NewEncoder(rw)
+			dec.Encode(swsp)
+			return
+		}
+		if next == nil {
+			rw.Header().Set("Content-Type", "application/json")
+			rw.WriteHeader(http.StatusNotFound)
+			return
+		}
+		next.ServeHTTP(rw, r)
+	})
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/spec_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/spec_test.go
@@ -0,0 +1,56 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 middleware
+
+import (
+	"net/http"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/runtime/internal/testing/petstore"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestServeSpecMiddleware(t *testing.T) {
+	spec, api := petstore.NewAPI(t)
+	ctx := NewContext(spec, api, nil)
+
+	handler := specMiddleware(ctx, nil)
+	// serves spec
+	request, _ := http.NewRequest("GET", "/swagger.json", nil)
+	request.Header.Add(runtime.HeaderContentType, runtime.JSONMime)
+	recorder := httptest.NewRecorder()
+	handler.ServeHTTP(recorder, request)
+	assert.Equal(t, 200, recorder.Code)
+
+	// returns 404 when no next handler
+	request, _ = http.NewRequest("GET", "/api/pets", nil)
+	request.Header.Add(runtime.HeaderContentType, runtime.JSONMime)
+	recorder = httptest.NewRecorder()
+	handler.ServeHTTP(recorder, request)
+	assert.Equal(t, 404, recorder.Code)
+
+	// forwards to next handler for other url
+	handler = specMiddleware(ctx, http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+		rw.WriteHeader(http.StatusOK)
+	}))
+	request, _ = http.NewRequest("GET", "/api/pets", nil)
+	request.Header.Add(runtime.HeaderContentType, runtime.JSONMime)
+	recorder = httptest.NewRecorder()
+	handler.ServeHTTP(recorder, request)
+	assert.Equal(t, 200, recorder.Code)
+
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/string_conversion_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/string_conversion_test.go
@@ -0,0 +1,301 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 middleware
+
+import (
+	"errors"
+	"reflect"
+	"strings"
+	"testing"
+	"time"
+
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/strfmt"
+	"github.com/go-openapi/swag"
+	"github.com/stretchr/testify/assert"
+)
+
+var evaluatesAsTrue = []string{"true", "1", "yes", "ok", "y", "on", "selected", "checked", "t", "enabled"}
+
+type unmarshallerSlice []string
+
+func (u *unmarshallerSlice) UnmarshalText(data []byte) error {
+	if len(data) == 0 {
+		return errors.New("an error")
+	}
+	*u = strings.Split(string(data), ",")
+	return nil
+}
+
+type SomeOperationParams struct {
+	Name        string
+	ID          int64
+	Confirmed   bool
+	Age         int
+	Visits      int32
+	Count       int16
+	Seq         int8
+	UID         uint64
+	UAge        uint
+	UVisits     uint32
+	UCount      uint16
+	USeq        uint8
+	Score       float32
+	Rate        float64
+	Timestamp   strfmt.DateTime
+	Birthdate   strfmt.Date
+	LastFailure *strfmt.DateTime
+	Unsupported struct{}
+	Tags        []string
+	Prefs       []int32
+	Categories  unmarshallerSlice
+}
+
+func FloatParamTest(t *testing.T, fName, pName, format string, val reflect.Value, defVal, expectedDef interface{}, actual func() interface{}) {
+	fld := val.FieldByName(pName)
+	binder := &untypedParamBinder{
+		parameter: spec.QueryParam(pName).Typed("number", "double").WithDefault(defVal),
+		Name:      pName,
+	}
+
+	err := binder.setFieldValue(fld, defVal, "5", true)
+	assert.NoError(t, err)
+	assert.EqualValues(t, 5, actual())
+
+	err = binder.setFieldValue(fld, defVal, "", true)
+	assert.NoError(t, err)
+	assert.EqualValues(t, expectedDef, actual())
+
+	err = binder.setFieldValue(fld, defVal, "yada", true)
+	assert.Error(t, err)
+}
+
+func IntParamTest(t *testing.T, pName string, val reflect.Value, defVal, expectedDef interface{}, actual func() interface{}) {
+	fld := val.FieldByName(pName)
+
+	binder := &untypedParamBinder{
+		parameter: spec.QueryParam(pName).Typed("integer", "int64").WithDefault(defVal),
+		Name:      pName,
+	}
+	err := binder.setFieldValue(fld, defVal, "5", true)
+	assert.NoError(t, err)
+	assert.EqualValues(t, 5, actual())
+
+	err = binder.setFieldValue(fld, defVal, "", true)
+	assert.NoError(t, err)
+	assert.EqualValues(t, expectedDef, actual())
+
+	err = binder.setFieldValue(fld, defVal, "yada", true)
+	assert.Error(t, err)
+}
+
+func TestParamBinding(t *testing.T) {
+
+	actual := new(SomeOperationParams)
+	val := reflect.ValueOf(actual).Elem()
+	pName := "Name"
+	fld := val.FieldByName(pName)
+
+	binder := &untypedParamBinder{
+		parameter: spec.QueryParam(pName).Typed("string", "").WithDefault("some-name"),
+		Name:      pName,
+	}
+
+	err := binder.setFieldValue(fld, "some-name", "the name value", true)
+	assert.NoError(t, err)
+	assert.Equal(t, "the name value", actual.Name)
+
+	err = binder.setFieldValue(fld, "some-name", "", true)
+	assert.NoError(t, err)
+	assert.Equal(t, "some-name", actual.Name)
+
+	IntParamTest(t, "ID", val, 1, 1, func() interface{} { return actual.ID })
+	IntParamTest(t, "ID", val, nil, 0, func() interface{} { return actual.ID })
+	IntParamTest(t, "Age", val, 1, 1, func() interface{} { return actual.Age })
+	IntParamTest(t, "Age", val, nil, 0, func() interface{} { return actual.Age })
+	IntParamTest(t, "Visits", val, 1, 1, func() interface{} { return actual.Visits })
+	IntParamTest(t, "Visits", val, nil, 0, func() interface{} { return actual.Visits })
+	IntParamTest(t, "Count", val, 1, 1, func() interface{} { return actual.Count })
+	IntParamTest(t, "Count", val, nil, 0, func() interface{} { return actual.Count })
+	IntParamTest(t, "Seq", val, 1, 1, func() interface{} { return actual.Seq })
+	IntParamTest(t, "Seq", val, nil, 0, func() interface{} { return actual.Seq })
+	IntParamTest(t, "UID", val, uint64(1), 1, func() interface{} { return actual.UID })
+	IntParamTest(t, "UID", val, uint64(0), 0, func() interface{} { return actual.UID })
+	IntParamTest(t, "UAge", val, uint(1), 1, func() interface{} { return actual.UAge })
+	IntParamTest(t, "UAge", val, nil, 0, func() interface{} { return actual.UAge })
+	IntParamTest(t, "UVisits", val, uint32(1), 1, func() interface{} { return actual.UVisits })
+	IntParamTest(t, "UVisits", val, nil, 0, func() interface{} { return actual.UVisits })
+	IntParamTest(t, "UCount", val, uint16(1), 1, func() interface{} { return actual.UCount })
+	IntParamTest(t, "UCount", val, nil, 0, func() interface{} { return actual.UCount })
+	IntParamTest(t, "USeq", val, uint8(1), 1, func() interface{} { return actual.USeq })
+	IntParamTest(t, "USeq", val, nil, 0, func() interface{} { return actual.USeq })
+
+	FloatParamTest(t, "score", "Score", "float", val, 1.0, 1, func() interface{} { return actual.Score })
+	FloatParamTest(t, "score", "Score", "float", val, nil, 0, func() interface{} { return actual.Score })
+	FloatParamTest(t, "rate", "Rate", "double", val, 1.0, 1, func() interface{} { return actual.Rate })
+	FloatParamTest(t, "rate", "Rate", "double", val, nil, 0, func() interface{} { return actual.Rate })
+
+	pName = "Confirmed"
+	confirmedField := val.FieldByName(pName)
+	binder = &untypedParamBinder{
+		parameter: spec.QueryParam(pName).Typed("boolean", "").WithDefault(true),
+		Name:      pName,
+	}
+
+	for _, tv := range evaluatesAsTrue {
+		err = binder.setFieldValue(confirmedField, true, tv, true)
+		assert.NoError(t, err)
+		assert.True(t, actual.Confirmed)
+	}
+
+	err = binder.setFieldValue(confirmedField, true, "", true)
+	assert.NoError(t, err)
+	assert.True(t, actual.Confirmed)
+
+	err = binder.setFieldValue(confirmedField, true, "0", true)
+	assert.NoError(t, err)
+	assert.False(t, actual.Confirmed)
+
+	pName = "Timestamp"
+	timeField := val.FieldByName(pName)
+	dt := strfmt.DateTime(time.Date(2014, 3, 19, 2, 9, 0, 0, time.UTC))
+	binder = &untypedParamBinder{
+		parameter: spec.QueryParam(pName).Typed("string", "date-time").WithDefault(dt),
+		Name:      pName,
+	}
+	exp := strfmt.DateTime(time.Date(2014, 5, 14, 2, 9, 0, 0, time.UTC))
+
+	err = binder.setFieldValue(timeField, dt, exp.String(), true)
+	assert.NoError(t, err)
+	assert.Equal(t, exp, actual.Timestamp)
+
+	err = binder.setFieldValue(timeField, dt, "", true)
+	assert.NoError(t, err)
+	assert.Equal(t, dt, actual.Timestamp)
+
+	err = binder.setFieldValue(timeField, dt, "yada", true)
+	assert.Error(t, err)
+
+	ddt := strfmt.Date(time.Date(2014, 3, 19, 0, 0, 0, 0, time.UTC))
+	pName = "Birthdate"
+	dateField := val.FieldByName(pName)
+	binder = &untypedParamBinder{
+		parameter: spec.QueryParam(pName).Typed("string", "date").WithDefault(ddt),
+		Name:      pName,
+	}
+	expd := strfmt.Date(time.Date(2014, 5, 14, 0, 0, 0, 0, time.UTC))
+
+	err = binder.setFieldValue(dateField, ddt, expd.String(), true)
+	assert.NoError(t, err)
+	assert.Equal(t, expd, actual.Birthdate)
+
+	err = binder.setFieldValue(dateField, ddt, "", true)
+	assert.NoError(t, err)
+	assert.Equal(t, ddt, actual.Birthdate)
+
+	err = binder.setFieldValue(dateField, ddt, "yada", true)
+	assert.Error(t, err)
+
+	dt = strfmt.DateTime(time.Date(2014, 3, 19, 2, 9, 0, 0, time.UTC))
+	fdt := &dt
+	pName = "LastFailure"
+	ftimeField := val.FieldByName(pName)
+	binder = &untypedParamBinder{
+		parameter: spec.QueryParam(pName).Typed("string", "date").WithDefault(fdt),
+		Name:      pName,
+	}
+	exp = strfmt.DateTime(time.Date(2014, 5, 14, 2, 9, 0, 0, time.UTC))
+	fexp := &exp
+
+	err = binder.setFieldValue(ftimeField, fdt, fexp.String(), true)
+	assert.NoError(t, err)
+	assert.Equal(t, fexp, actual.LastFailure)
+
+	err = binder.setFieldValue(ftimeField, fdt, "", true)
+	assert.NoError(t, err)
+	assert.Equal(t, fdt, actual.LastFailure)
+
+	err = binder.setFieldValue(ftimeField, fdt, "", true)
+	assert.NoError(t, err)
+	assert.Equal(t, fdt, actual.LastFailure)
+
+	actual.LastFailure = nil
+	err = binder.setFieldValue(ftimeField, fdt, "yada", true)
+	assert.Error(t, err)
+	assert.Nil(t, actual.LastFailure)
+
+	pName = "Unsupported"
+	unsupportedField := val.FieldByName(pName)
+	binder = &untypedParamBinder{
+		parameter: spec.QueryParam(pName).Typed("string", ""),
+		Name:      pName,
+	}
+	err = binder.setFieldValue(unsupportedField, nil, "", true)
+	assert.Error(t, err)
+}
+
+func TestSliceConversion(t *testing.T) {
+
+	actual := new(SomeOperationParams)
+	val := reflect.ValueOf(actual).Elem()
+
+	// prefsField := val.FieldByName("Prefs")
+	// cData := "yada,2,3"
+	// _, _, err := readFormattedSliceFieldValue("Prefs", prefsField, cData, "csv", nil)
+	// assert.Error(t, err)
+
+	sliced := []string{"some", "string", "values"}
+	seps := map[string]string{"ssv": " ", "tsv": "\t", "pipes": "|", "csv": ",", "": ","}
+
+	tagsField := val.FieldByName("Tags")
+	for k, sep := range seps {
+		binder := &untypedParamBinder{
+			Name:      "Tags",
+			parameter: spec.QueryParam("tags").CollectionOf(stringItems, k),
+		}
+
+		actual.Tags = nil
+		cData := strings.Join(sliced, sep)
+		tags, _, err := binder.readFormattedSliceFieldValue(cData, tagsField)
+		assert.NoError(t, err)
+		assert.Equal(t, sliced, tags)
+		cData = strings.Join(sliced, " "+sep+" ")
+		tags, _, err = binder.readFormattedSliceFieldValue(cData, tagsField)
+		assert.NoError(t, err)
+		assert.Equal(t, sliced, tags)
+		tags, _, err = binder.readFormattedSliceFieldValue("", tagsField)
+		assert.NoError(t, err)
+		assert.Empty(t, tags)
+	}
+
+	assert.Nil(t, swag.SplitByFormat("yada", "multi"))
+	assert.Nil(t, swag.SplitByFormat("", ""))
+
+	categoriesField := val.FieldByName("Categories")
+	binder := &untypedParamBinder{
+		Name:      "Categories",
+		parameter: spec.QueryParam("categories").CollectionOf(stringItems, "csv"),
+	}
+	cData := strings.Join(sliced, ",")
+	categories, custom, err := binder.readFormattedSliceFieldValue(cData, categoriesField)
+	assert.NoError(t, err)
+	assert.EqualValues(t, sliced, actual.Categories)
+	assert.True(t, custom)
+	assert.Empty(t, categories)
+	categories, custom, err = binder.readFormattedSliceFieldValue("", categoriesField)
+	assert.Error(t, err)
+	assert.True(t, custom)
+	assert.Empty(t, categories)
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/untyped/api.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/untyped/api.go
@@ -0,0 +1,263 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 untyped
+
+import (
+	"fmt"
+	"net/http"
+	"sort"
+	"strings"
+
+	"github.com/go-openapi/analysis"
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/loads"
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/strfmt"
+)
+
+// NewAPI creates the default untyped API
+func NewAPI(spec *loads.Document) *API {
+	var an *analysis.Spec
+	if spec != nil && spec.Spec() != nil {
+		an = analysis.New(spec.Spec())
+	}
+	return &API{
+		spec:            spec,
+		analyzer:        an,
+		DefaultProduces: runtime.JSONMime,
+		DefaultConsumes: runtime.JSONMime,
+		consumers: map[string]runtime.Consumer{
+			runtime.JSONMime: runtime.JSONConsumer(),
+		},
+		producers: map[string]runtime.Producer{
+			runtime.JSONMime: runtime.JSONProducer(),
+		},
+		authenticators: make(map[string]runtime.Authenticator),
+		operations:     make(map[string]map[string]runtime.OperationHandler),
+		ServeError:     errors.ServeError,
+		Models:         make(map[string]func() interface{}),
+		formats:        strfmt.NewFormats(),
+	}
+}
+
+// API represents an untyped mux for a swagger spec
+type API struct {
+	spec            *loads.Document
+	analyzer        *analysis.Spec
+	DefaultProduces string
+	DefaultConsumes string
+	consumers       map[string]runtime.Consumer
+	producers       map[string]runtime.Producer
+	authenticators  map[string]runtime.Authenticator
+	operations      map[string]map[string]runtime.OperationHandler
+	ServeError      func(http.ResponseWriter, *http.Request, error)
+	Models          map[string]func() interface{}
+	formats         strfmt.Registry
+}
+
+// Formats returns the registered string formats
+func (d *API) Formats() strfmt.Registry {
+	if d.formats == nil {
+		d.formats = strfmt.NewFormats()
+	}
+	return d.formats
+}
+
+// RegisterFormat registers a custom format validator
+func (d *API) RegisterFormat(name string, format strfmt.Format, validator strfmt.Validator) {
+	if d.formats == nil {
+		d.formats = strfmt.NewFormats()
+	}
+	d.formats.Add(name, format, validator)
+}
+
+// RegisterAuth registers an auth handler in this api
+func (d *API) RegisterAuth(scheme string, handler runtime.Authenticator) {
+	if d.authenticators == nil {
+		d.authenticators = make(map[string]runtime.Authenticator)
+	}
+	d.authenticators[scheme] = handler
+}
+
+// RegisterConsumer registers a consumer for a media type.
+func (d *API) RegisterConsumer(mediaType string, handler runtime.Consumer) {
+	if d.consumers == nil {
+		d.consumers = map[string]runtime.Consumer{runtime.JSONMime: runtime.JSONConsumer()}
+	}
+	d.consumers[strings.ToLower(mediaType)] = handler
+}
+
+// RegisterProducer registers a producer for a media type
+func (d *API) RegisterProducer(mediaType string, handler runtime.Producer) {
+	if d.producers == nil {
+		d.producers = map[string]runtime.Producer{runtime.JSONMime: runtime.JSONProducer()}
+	}
+	d.producers[strings.ToLower(mediaType)] = handler
+}
+
+// RegisterOperation registers an operation handler for an operation name
+func (d *API) RegisterOperation(method, path string, handler runtime.OperationHandler) {
+	if d.operations == nil {
+		d.operations = make(map[string]map[string]runtime.OperationHandler)
+	}
+	um := strings.ToUpper(method)
+	if b, ok := d.operations[um]; !ok || b == nil {
+		d.operations[um] = make(map[string]runtime.OperationHandler)
+	}
+	d.operations[um][path] = handler
+}
+
+// OperationHandlerFor returns the operation handler for the specified id if it can be found
+func (d *API) OperationHandlerFor(method, path string) (runtime.OperationHandler, bool) {
+	if d.operations == nil {
+		return nil, false
+	}
+	if pi, ok := d.operations[strings.ToUpper(method)]; ok {
+		h, ok := pi[path]
+		return h, ok
+	}
+	return nil, false
+}
+
+// ConsumersFor gets the consumers for the specified media types
+func (d *API) ConsumersFor(mediaTypes []string) map[string]runtime.Consumer {
+	result := make(map[string]runtime.Consumer)
+	for _, mt := range mediaTypes {
+		if consumer, ok := d.consumers[mt]; ok {
+			result[mt] = consumer
+		}
+	}
+	return result
+}
+
+// ProducersFor gets the producers for the specified media types
+func (d *API) ProducersFor(mediaTypes []string) map[string]runtime.Producer {
+	result := make(map[string]runtime.Producer)
+	for _, mt := range mediaTypes {
+		if producer, ok := d.producers[mt]; ok {
+			result[mt] = producer
+		}
+	}
+	return result
+}
+
+// AuthenticatorsFor gets the authenticators for the specified security schemes
+func (d *API) AuthenticatorsFor(schemes map[string]spec.SecurityScheme) map[string]runtime.Authenticator {
+	result := make(map[string]runtime.Authenticator)
+	for k := range schemes {
+		if a, ok := d.authenticators[k]; ok {
+			result[k] = a
+		}
+	}
+	return result
+}
+
+// Validate validates this API for any missing items
+func (d *API) Validate() error {
+	return d.validate()
+}
+
+// validateWith validates the registrations in this API against the provided spec analyzer
+func (d *API) validate() error {
+	var consumes []string
+	for k := range d.consumers {
+		consumes = append(consumes, k)
+	}
+
+	var produces []string
+	for k := range d.producers {
+		produces = append(produces, k)
+	}
+
+	var authenticators []string
+	for k := range d.authenticators {
+		authenticators = append(authenticators, k)
+	}
+
+	var operations []string
+	for m, v := range d.operations {
+		for p := range v {
+			operations = append(operations, fmt.Sprintf("%s %s", strings.ToUpper(m), p))
+		}
+	}
+
+	var definedAuths []string
+	for k := range d.spec.Spec().SecurityDefinitions {
+		definedAuths = append(definedAuths, k)
+	}
+
+	if err := d.verify("consumes", consumes, d.analyzer.RequiredConsumes()); err != nil {
+		return err
+	}
+	if err := d.verify("produces", produces, d.analyzer.RequiredProduces()); err != nil {
+		return err
+	}
+	if err := d.verify("operation", operations, d.analyzer.OperationIDs()); err != nil {
+		return err
+	}
+
+	requiredAuths := d.analyzer.RequiredSecuritySchemes()
+	if err := d.verify("auth scheme", authenticators, requiredAuths); err != nil {
+		return err
+	}
+	fmt.Printf("comparing %s with %s\n", strings.Join(definedAuths, ","), strings.Join(requiredAuths, ","))
+	if err := d.verify("security definitions", definedAuths, requiredAuths); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d *API) verify(name string, registrations []string, expectations []string) error {
+
+	sort.Sort(sort.StringSlice(registrations))
+	sort.Sort(sort.StringSlice(expectations))
+
+	expected := map[string]struct{}{}
+	seen := map[string]struct{}{}
+
+	for _, v := range expectations {
+		expected[v] = struct{}{}
+	}
+
+	var unspecified []string
+	for _, v := range registrations {
+		seen[v] = struct{}{}
+		if _, ok := expected[v]; !ok {
+			unspecified = append(unspecified, v)
+		}
+	}
+
+	for k := range seen {
+		delete(expected, k)
+	}
+
+	var unregistered []string
+	for k := range expected {
+		unregistered = append(unregistered, k)
+	}
+	sort.Sort(sort.StringSlice(unspecified))
+	sort.Sort(sort.StringSlice(unregistered))
+
+	if len(unregistered) > 0 || len(unspecified) > 0 {
+		return &errors.APIVerificationFailed{
+			Section:              name,
+			MissingSpecification: unspecified,
+			MissingRegistration:  unregistered,
+		}
+	}
+
+	return nil
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/untyped/api_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/untyped/api_test.go
@@ -0,0 +1,278 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 untyped
+
+import (
+	"io"
+	"sort"
+	"testing"
+
+	"github.com/go-openapi/analysis"
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/loads"
+	"github.com/go-openapi/runtime"
+	swaggerspec "github.com/go-openapi/spec"
+	"github.com/stretchr/testify/assert"
+)
+
+func stubAutenticator() runtime.Authenticator {
+	return runtime.AuthenticatorFunc(func(_ interface{}) (bool, interface{}, error) { return false, nil, nil })
+}
+
+type stubConsumer struct {
+}
+
+func (s *stubConsumer) Consume(_ io.Reader, _ interface{}) error {
+	return nil
+}
+
+type stubProducer struct {
+}
+
+func (s *stubProducer) Produce(_ io.Writer, _ interface{}) error {
+	return nil
+}
+
+type stubOperationHandler struct {
+}
+
+func (s *stubOperationHandler) ParameterModel() interface{} {
+	return nil
+}
+
+func (s *stubOperationHandler) Handle(params interface{}) (interface{}, error) {
+	return nil, nil
+}
+
+func TestUntypedAPIRegistrations(t *testing.T) {
+	api := NewAPI(new(loads.Document))
+
+	api.RegisterConsumer("application/yada", new(stubConsumer))
+	api.RegisterProducer("application/yada-2", new(stubProducer))
+	api.RegisterOperation("get", "/{someId}", new(stubOperationHandler))
+	api.RegisterAuth("basic", stubAutenticator())
+
+	assert.NotEmpty(t, api.authenticators)
+
+	_, ok := api.authenticators["basic"]
+	assert.True(t, ok)
+	_, ok = api.consumers["application/yada"]
+	assert.True(t, ok)
+	_, ok = api.producers["application/yada-2"]
+	assert.True(t, ok)
+	_, ok = api.consumers["application/json"]
+	assert.True(t, ok)
+	_, ok = api.producers["application/json"]
+	assert.True(t, ok)
+	_, ok = api.operations["GET"]["/{someId}"]
+	assert.True(t, ok)
+
+	h, ok := api.OperationHandlerFor("get", "/{someId}")
+	assert.True(t, ok)
+	assert.NotNil(t, h)
+
+	_, ok = api.OperationHandlerFor("doesntExist", "/{someId}")
+	assert.False(t, ok)
+}
+
+func TestUntypedAppValidation(t *testing.T) {
+	invalidSpecStr := `{
+  "consumes": ["application/json"],
+  "produces": ["application/json"],
+  "security": [
+    {"apiKey":[]}
+  ],
+  "parameters": {
+    "format": {
+      "in": "query",
+      "name": "format",
+      "type": "string"
+    }
+  },
+  "paths": {
+    "/": {
+      "parameters": [
+        {
+          "name": "limit",
+          "type": "integer",
+          "format": "int32",
+          "x-go-name": "Limit"
+        }
+      ],
+      "get": {
+        "consumes": ["application/x-yaml"],
+        "produces": ["application/x-yaml"],
+        "security": [
+          {"basic":[]}
+        ],
+        "operationId": "someOperation",
+        "parameters": [
+          {
+            "name": "skip",
+            "type": "integer",
+            "format": "int32"
+          }
+        ]
+      }
+    }
+  }
+}`
+	specStr := `{
+	  "consumes": ["application/json"],
+	  "produces": ["application/json"],
+	  "security": [
+	    {"apiKey":[]}
+	  ],
+	  "securityDefinitions": {
+	    "basic": { "type": "basic" },
+	    "apiKey": { "type": "apiKey", "in":"header", "name":"X-API-KEY" }
+	  },
+	  "parameters": {
+	  	"format": {
+	  		"in": "query",
+	  		"name": "format",
+	  		"type": "string"
+	  	}
+	  },
+	  "paths": {
+	  	"/": {
+	  		"parameters": [
+	  			{
+	  				"name": "limit",
+			  		"type": "integer",
+			  		"format": "int32",
+			  		"x-go-name": "Limit"
+			  	}
+	  		],
+	  		"get": {
+	  			"consumes": ["application/x-yaml"],
+	  			"produces": ["application/x-yaml"],
+	        "security": [
+	          {"basic":[]}
+	        ],
+	  			"operationId": "someOperation",
+	  			"parameters": [
+	  				{
+				  		"name": "skip",
+				  		"type": "integer",
+				  		"format": "int32"
+				  	}
+	  			]
+	  		}
+	  	}
+	  }
+	}`
+	validSpec, err := loads.Analyzed([]byte(specStr), "")
+	assert.NoError(t, err)
+	assert.NotNil(t, validSpec)
+
+	spec, err := loads.Analyzed([]byte(invalidSpecStr), "")
+	assert.NoError(t, err)
+	assert.NotNil(t, spec)
+
+	analyzed := analysis.New(spec.Spec())
+	analyzedValid := analysis.New(validSpec.Spec())
+	cons := analyzed.ConsumesFor(analyzed.AllPaths()["/"].Get)
+	assert.Len(t, cons, 1)
+	prods := analyzed.RequiredProduces()
+	assert.Len(t, prods, 2)
+
+	api1 := NewAPI(spec)
+	err = api1.Validate()
+	assert.Error(t, err)
+	assert.Equal(t, "missing [application/x-yaml] consumes registrations", err.Error())
+	api1.RegisterConsumer("application/x-yaml", new(stubConsumer))
+	err = api1.validate()
+	assert.Error(t, err)
+	assert.Equal(t, "missing [application/x-yaml] produces registrations", err.Error())
+	api1.RegisterProducer("application/x-yaml", new(stubProducer))
+	err = api1.validate()
+	assert.Error(t, err)
+	assert.Equal(t, "missing [GET /] operation registrations", err.Error())
+	api1.RegisterOperation("get", "/", new(stubOperationHandler))
+	err = api1.validate()
+	assert.Error(t, err)
+	assert.Equal(t, "missing [apiKey, basic] auth scheme registrations", err.Error())
+	api1.RegisterAuth("basic", stubAutenticator())
+	api1.RegisterAuth("apiKey", stubAutenticator())
+	err = api1.validate()
+	assert.Error(t, err)
+	assert.Equal(t, "missing [apiKey, basic] security definitions registrations", err.Error())
+
+	api3 := NewAPI(validSpec)
+	api3.RegisterConsumer("application/x-yaml", new(stubConsumer))
+	api3.RegisterProducer("application/x-yaml", new(stubProducer))
+	api3.RegisterOperation("get", "/", new(stubOperationHandler))
+	api3.RegisterAuth("basic", stubAutenticator())
+	api3.RegisterAuth("apiKey", stubAutenticator())
+	err = api3.validate()
+	assert.NoError(t, err)
+	api3.RegisterConsumer("application/something", new(stubConsumer))
+	err = api3.validate()
+	assert.Error(t, err)
+	assert.Equal(t, "missing from spec file [application/something] consumes", err.Error())
+
+	api2 := NewAPI(spec)
+	api2.RegisterConsumer("application/something", new(stubConsumer))
+	err = api2.validate()
+	assert.Error(t, err)
+	assert.Equal(t, "missing [application/x-yaml] consumes registrations\nmissing from spec file [application/something] consumes", err.Error())
+	api2.RegisterConsumer("application/x-yaml", new(stubConsumer))
+	delete(api2.consumers, "application/something")
+	api2.RegisterProducer("application/something", new(stubProducer))
+	err = api2.validate()
+	assert.Error(t, err)
+	assert.Equal(t, "missing [application/x-yaml] produces registrations\nmissing from spec file [application/something] produces", err.Error())
+	delete(api2.producers, "application/something")
+	api2.RegisterProducer("application/x-yaml", new(stubProducer))
+
+	expected := []string{"application/x-yaml"}
+	sort.Sort(sort.StringSlice(expected))
+	consumes := analyzed.ConsumesFor(analyzed.AllPaths()["/"].Get)
+	sort.Sort(sort.StringSlice(consumes))
+	assert.Equal(t, expected, consumes)
+	consumers := api1.ConsumersFor(consumes)
+	assert.Len(t, consumers, 1)
+
+	produces := analyzed.ProducesFor(analyzed.AllPaths()["/"].Get)
+	sort.Sort(sort.StringSlice(produces))
+	assert.Equal(t, expected, produces)
+	producers := api1.ProducersFor(produces)
+	assert.Len(t, producers, 1)
+
+	definitions := analyzedValid.SecurityDefinitionsFor(analyzedValid.AllPaths()["/"].Get)
+	expectedSchemes := map[string]swaggerspec.SecurityScheme{"basic": *swaggerspec.BasicAuth()}
+	assert.Equal(t, expectedSchemes, definitions)
+	authenticators := api3.AuthenticatorsFor(definitions)
+	assert.Len(t, authenticators, 1)
+
+	opHandler := runtime.OperationHandlerFunc(func(data interface{}) (interface{}, error) {
+		return data, nil
+	})
+	d, err := opHandler.Handle(1)
+	assert.NoError(t, err)
+	assert.Equal(t, 1, d)
+
+	authenticator := runtime.AuthenticatorFunc(func(params interface{}) (bool, interface{}, error) {
+		if str, ok := params.(string); ok {
+			return ok, str, nil
+		}
+		return true, nil, errors.Unauthenticated("authenticator")
+	})
+	ok, p, err := authenticator.Authenticate("hello")
+	assert.True(t, ok)
+	assert.NoError(t, err)
+	assert.Equal(t, "hello", p)
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/untyped_request_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/untyped_request_test.go
@@ -0,0 +1,164 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 middleware
+
+import (
+	"bytes"
+	"encoding/base64"
+	"encoding/json"
+	"io/ioutil"
+	"mime/multipart"
+	"net/http"
+	"net/url"
+	"strings"
+	"testing"
+	"time"
+
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/strfmt"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestUntypedFormPost(t *testing.T) {
+	params := parametersForFormUpload()
+	binder := newUntypedRequestBinder(params, nil, strfmt.Default)
+
+	urlStr := "http://localhost:8002/hello"
+	req, _ := http.NewRequest("POST", urlStr, bytes.NewBufferString(`name=the-name&age=32`))
+	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+
+	data := make(map[string]interface{})
+	assert.NoError(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
+	assert.Equal(t, "the-name", data["name"])
+	assert.EqualValues(t, 32, data["age"])
+
+	req, _ = http.NewRequest("POST", urlStr, bytes.NewBufferString(`name=%3&age=32`))
+	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+
+	data = make(map[string]interface{})
+	assert.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
+}
+
+func TestUntypedFileUpload(t *testing.T) {
+	binder := paramsForFileUpload()
+
+	body := bytes.NewBuffer(nil)
+	writer := multipart.NewWriter(body)
+	part, err := writer.CreateFormFile("file", "plain-jane.txt")
+	assert.NoError(t, err)
+
+	part.Write([]byte("the file contents"))
+	writer.WriteField("name", "the-name")
+	assert.NoError(t, writer.Close())
+
+	urlStr := "http://localhost:8002/hello"
+	req, _ := http.NewRequest("POST", urlStr, body)
+	req.Header.Set("Content-Type", writer.FormDataContentType())
+
+	data := make(map[string]interface{})
+	assert.NoError(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
+	assert.Equal(t, "the-name", data["name"])
+	assert.NotNil(t, data["file"])
+	assert.IsType(t, runtime.File{}, data["file"])
+	file := data["file"].(runtime.File)
+	assert.NotNil(t, file.Header)
+	assert.Equal(t, "plain-jane.txt", file.Header.Filename)
+
+	bb, err := ioutil.ReadAll(file.Data)
+	assert.NoError(t, err)
+	assert.Equal(t, []byte("the file contents"), bb)
+
+	req, _ = http.NewRequest("POST", urlStr, body)
+	req.Header.Set("Content-Type", "application/json")
+	data = make(map[string]interface{})
+	assert.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
+
+	req, _ = http.NewRequest("POST", urlStr, body)
+	req.Header.Set("Content-Type", "application(")
+	data = make(map[string]interface{})
+	assert.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
+
+	body = bytes.NewBuffer(nil)
+	writer = multipart.NewWriter(body)
+	part, err = writer.CreateFormFile("bad-name", "plain-jane.txt")
+	assert.NoError(t, err)
+
+	part.Write([]byte("the file contents"))
+	writer.WriteField("name", "the-name")
+	assert.NoError(t, writer.Close())
+	req, _ = http.NewRequest("POST", urlStr, body)
+	req.Header.Set("Content-Type", writer.FormDataContentType())
+
+	data = make(map[string]interface{})
+	assert.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
+
+	req, _ = http.NewRequest("POST", urlStr, body)
+	req.Header.Set("Content-Type", writer.FormDataContentType())
+	req.MultipartReader()
+
+	data = make(map[string]interface{})
+	assert.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
+}
+
+func TestUntypedBindingTypesForValid(t *testing.T) {
+
+	op2 := parametersForAllTypes("")
+	binder := newUntypedRequestBinder(op2, nil, strfmt.Default)
+
+	confirmed := true
+	name := "thomas"
+	friend := map[string]interface{}{"name": "toby", "age": json.Number("32")}
+	id, age, score, factor := int64(7575), int32(348), float32(5.309), float64(37.403)
+	requestID := 19394858
+	tags := []string{"one", "two", "three"}
+	dt1 := time.Date(2014, 8, 9, 0, 0, 0, 0, time.UTC)
+	planned := strfmt.Date(dt1)
+	dt2 := time.Date(2014, 10, 12, 8, 5, 5, 0, time.UTC)
+	delivered := strfmt.DateTime(dt2)
+	picture := base64.URLEncoding.EncodeToString([]byte("hello"))
+	uri, _ := url.Parse("http://localhost:8002/hello/7575")
+	qs := uri.Query()
+	qs.Add("name", name)
+	qs.Add("confirmed", "true")
+	qs.Add("age", "348")
+	qs.Add("score", "5.309")
+	qs.Add("factor", "37.403")
+	qs.Add("tags", strings.Join(tags, ","))
+	qs.Add("planned", planned.String())
+	qs.Add("delivered", delivered.String())
+	qs.Add("picture", picture)
+
+	req, _ := http.NewRequest("POST", uri.String()+"?"+qs.Encode(), bytes.NewBuffer([]byte(`{"name":"toby","age":32}`)))
+	req.Header.Set("Content-Type", "application/json")
+	req.Header.Set("X-Request-Id", "19394858")
+
+	data := make(map[string]interface{})
+	err := binder.Bind(req, RouteParams([]RouteParam{{"id", "7575"}}), runtime.JSONConsumer(), &data)
+	assert.NoError(t, err)
+	assert.Equal(t, id, data["id"])
+	assert.Equal(t, name, data["name"])
+	assert.Equal(t, friend, data["friend"])
+	assert.EqualValues(t, requestID, data["X-Request-Id"])
+	assert.Equal(t, tags, data["tags"])
+	assert.Equal(t, planned, data["planned"])
+	assert.Equal(t, delivered, data["delivered"])
+	assert.Equal(t, confirmed, data["confirmed"])
+	assert.Equal(t, age, data["age"])
+	assert.Equal(t, factor, data["factor"])
+	assert.Equal(t, score, data["score"])
+	pb, _ := base64.URLEncoding.DecodeString(picture)
+	assert.EqualValues(t, pb, data["picture"].(strfmt.Base64))
+
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/validation.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/validation.go
@@ -0,0 +1,131 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 middleware
+
+import (
+	"mime"
+	"net/http"
+
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/swag"
+)
+
+// NewValidation starts a new validation middleware
+func newValidation(ctx *Context, next http.Handler) http.Handler {
+
+	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+		matched, _ := ctx.RouteInfo(r)
+		_, result := ctx.BindAndValidate(r, matched)
+
+		if result != nil {
+			ctx.Respond(rw, r, matched.Produces, matched, result)
+			return
+		}
+
+		next.ServeHTTP(rw, r)
+	})
+}
+
+type validation struct {
+	context *Context
+	result  []error
+	request *http.Request
+	route   *MatchedRoute
+	bound   map[string]interface{}
+}
+
+type untypedBinder map[string]interface{}
+
+func (ub untypedBinder) BindRequest(r *http.Request, route *MatchedRoute, consumer runtime.Consumer) error {
+	if err := route.Binder.Bind(r, route.Params, consumer, ub); err != nil {
+		return err
+	}
+	return nil
+}
+
+// ContentType validates the content type of a request
+func validateContentType(allowed []string, actual string) error {
+	if len(allowed) == 0 {
+		return nil
+	}
+	mt, _, err := mime.ParseMediaType(actual)
+	if err != nil {
+		return errors.InvalidContentType(actual, allowed)
+	}
+	if swag.ContainsStringsCI(allowed, mt) {
+		return nil
+	}
+	return errors.InvalidContentType(actual, allowed)
+}
+
+func validateRequest(ctx *Context, request *http.Request, route *MatchedRoute) *validation {
+	validate := &validation{
+		context: ctx,
+		request: request,
+		route:   route,
+		bound:   make(map[string]interface{}),
+	}
+
+	validate.contentType()
+	if len(validate.result) == 0 {
+		validate.responseFormat()
+	}
+	if len(validate.result) == 0 {
+		validate.parameters()
+	}
+
+	return validate
+}
+
+func (v *validation) parameters() {
+	if result := v.route.Binder.Bind(v.request, v.route.Params, v.route.Consumer, v.bound); result != nil {
+		if result.Error() == "validation failure list" {
+			for _, e := range result.(*errors.Validation).Value.([]interface{}) {
+				v.result = append(v.result, e.(error))
+			}
+			return
+		}
+		v.result = append(v.result, result)
+	}
+}
+
+func (v *validation) contentType() {
+	if len(v.result) == 0 && runtime.HasBody(v.request) {
+		ct, _, err := v.context.ContentType(v.request)
+		if err != nil {
+			v.result = append(v.result, err)
+		}
+		if len(v.result) == 0 {
+			if err := validateContentType(v.route.Consumes, ct); err != nil {
+				v.result = append(v.result, err)
+			}
+		}
+		if ct != "" && v.route.Consumer == nil {
+			cons, ok := v.route.Consumers[ct]
+			if !ok {
+				v.result = append(v.result, errors.New(500, "no consumer registered for %s", ct))
+			} else {
+				v.route.Consumer = cons
+			}
+		}
+	}
+}
+
+func (v *validation) responseFormat() {
+	if str := v.context.ResponseFormat(v.request, v.route.Produces); str == "" && runtime.HasBody(v.request) {
+		v.result = append(v.result, errors.InvalidResponseFormat(v.request.Header.Get(runtime.HeaderAccept), v.route.Produces))
+	}
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/validation_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/middleware/validation_test.go
@@ -0,0 +1,130 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 middleware
+
+import (
+	"bytes"
+	"net/http"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/runtime/internal/testing/petstore"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestContentTypeValidation(t *testing.T) {
+	spec, api := petstore.NewAPI(t)
+	context := NewContext(spec, api, nil)
+	context.router = DefaultRouter(spec, context.api)
+	mw := newValidation(context, http.HandlerFunc(terminator))
+
+	recorder := httptest.NewRecorder()
+	request, _ := http.NewRequest("GET", "/pets", nil)
+	request.Header.Add("Accept", "*/*")
+	mw.ServeHTTP(recorder, request)
+	assert.Equal(t, 200, recorder.Code)
+
+	recorder = httptest.NewRecorder()
+	request, _ = http.NewRequest("POST", "/pets", nil)
+	request.Header.Add("content-type", "application(")
+	request.ContentLength = 1
+
+	mw.ServeHTTP(recorder, request)
+	assert.Equal(t, 400, recorder.Code)
+	assert.Equal(t, "application/json", recorder.Header().Get("content-type"))
+
+	recorder = httptest.NewRecorder()
+	request, _ = http.NewRequest("POST", "/pets", nil)
+	request.Header.Add("Accept", "application/json")
+	request.Header.Add("content-type", "text/html")
+	request.ContentLength = 1
+
+	mw.ServeHTTP(recorder, request)
+	assert.Equal(t, 415, recorder.Code)
+	assert.Equal(t, "application/json", recorder.Header().Get("content-type"))
+
+	recorder = httptest.NewRecorder()
+	request, _ = http.NewRequest("POST", "/pets", nil)
+	request.Header.Add("Accept", "application/json")
+	request.Header.Add("content-type", "text/html")
+	request.TransferEncoding = []string{"chunked"}
+
+	mw.ServeHTTP(recorder, request)
+	assert.Equal(t, 415, recorder.Code)
+	assert.Equal(t, "application/json", recorder.Header().Get("content-type"))
+
+	recorder = httptest.NewRecorder()
+	request, _ = http.NewRequest("POST", "/pets", nil)
+	request.Header.Add("Accept", "application/json")
+	request.Header.Add("content-type", "text/html")
+
+	mw.ServeHTTP(recorder, request)
+	assert.Equal(t, 422, recorder.Code)
+	assert.Equal(t, "application/json", recorder.Header().Get("content-type"))
+}
+
+func TestResponseFormatValidation(t *testing.T) {
+	spec, api := petstore.NewAPI(t)
+	context := NewContext(spec, api, nil)
+	context.router = DefaultRouter(spec, context.api)
+	mw := newValidation(context, http.HandlerFunc(terminator))
+
+	recorder := httptest.NewRecorder()
+	request, _ := http.NewRequest("POST", "/pets", bytes.NewBuffer([]byte(`name: Dog`)))
+	request.Header.Set(runtime.HeaderContentType, "application/x-yaml")
+	request.Header.Set(runtime.HeaderAccept, "application/x-yaml")
+
+	mw.ServeHTTP(recorder, request)
+	assert.Equal(t, 200, recorder.Code, recorder.Body.String())
+
+	recorder = httptest.NewRecorder()
+	request, _ = http.NewRequest("POST", "/pets", bytes.NewBuffer([]byte(`name: Dog`)))
+	request.Header.Set(runtime.HeaderContentType, "application/x-yaml")
+	request.Header.Set(runtime.HeaderAccept, "application/sml")
+
+	mw.ServeHTTP(recorder, request)
+	assert.Equal(t, http.StatusNotAcceptable, recorder.Code)
+}
+
+func TestValidateContentType(t *testing.T) {
+	data := []struct {
+		hdr     string
+		allowed []string
+		err     *errors.Validation
+	}{
+		{"application/json", []string{"application/json"}, nil},
+		{"application/json", []string{"application/x-yaml", "text/html"}, errors.InvalidContentType("application/json", []string{"application/x-yaml", "text/html"})},
+		{"text/html; charset=utf-8", []string{"text/html"}, nil},
+		{"text/html;charset=utf-8", []string{"text/html"}, nil},
+		{"", []string{"application/json"}, errors.InvalidContentType("", []string{"application/json"})},
+		{"text/html;           charset=utf-8", []string{"application/json"}, errors.InvalidContentType("text/html;           charset=utf-8", []string{"application/json"})},
+		{"application(", []string{"application/json"}, errors.InvalidContentType("application(", []string{"application/json"})},
+		{"application/json;char*", []string{"application/json"}, errors.InvalidContentType("application/json;char*", []string{"application/json"})},
+	}
+
+	for _, v := range data {
+		err := validateContentType(v.allowed, v.hdr)
+		if v.err == nil {
+			assert.NoError(t, err, "input: %q", v.hdr)
+		} else {
+			assert.Error(t, err, "input: %q", v.hdr)
+			assert.IsType(t, &errors.Validation{}, err, "input: %q", v.hdr)
+			assert.Equal(t, v.err.Error(), err.Error(), "input: %q", v.hdr)
+			assert.EqualValues(t, http.StatusUnsupportedMediaType, err.(*errors.Validation).Code())
+		}
+	}
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/request.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/request.go
@@ -0,0 +1,77 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 runtime
+
+import (
+	"io"
+	"net/http"
+	"strings"
+
+	"github.com/go-openapi/swag"
+)
+
+// CanHaveBody returns true if this method can have a body
+func CanHaveBody(method string) bool {
+	mn := strings.ToUpper(method)
+	return mn == "POST" || mn == "PUT" || mn == "PATCH" || mn == "DELETE"
+}
+
+// IsSafe returns true if this is a request with a safe method
+func IsSafe(r *http.Request) bool {
+	mn := strings.ToUpper(r.Method)
+	return mn == "GET" || mn == "HEAD"
+}
+
+// AllowsBody returns true if the request allows for a body
+func AllowsBody(r *http.Request) bool {
+	mn := strings.ToUpper(r.Method)
+	return mn != "HEAD"
+}
+
+// HasBody returns true if this method needs a content-type
+func HasBody(r *http.Request) bool {
+	return len(r.TransferEncoding) > 0 || r.ContentLength > 0
+}
+
+// JSONRequest creates a new http request with json headers set
+func JSONRequest(method, urlStr string, body io.Reader) (*http.Request, error) {
+	req, err := http.NewRequest(method, urlStr, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header.Add(HeaderContentType, JSONMime)
+	req.Header.Add(HeaderAccept, JSONMime)
+	return req, nil
+}
+
+// Gettable for things with a method GetOK(string) (data string, hasKey bool, hasValue bool)
+type Gettable interface {
+	GetOK(string) ([]string, bool, bool)
+}
+
+// ReadSingleValue reads a single value from the source
+func ReadSingleValue(values Gettable, name string) string {
+	vv, _, hv := values.GetOK(name)
+	if hv {
+		return vv[len(vv)-1]
+	}
+	return ""
+}
+
+// ReadCollectionValue reads a collection value from a string data source
+func ReadCollectionValue(values Gettable, name, collectionFormat string) []string {
+	v := ReadSingleValue(values, name)
+	return swag.SplitByFormat(v, collectionFormat)
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/request_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/request_test.go
@@ -0,0 +1,122 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 runtime
+
+import (
+	"net/url"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+/*
+type tstreadcloser struct {
+	closed bool
+}
+
+func (t *tstreadcloser) Read(p []byte) (int, error) { return 0, nil }
+func (t *tstreadcloser) Close() error {
+	t.closed = true
+	return nil
+}
+
+func TestPeekingReader(t *testing.T) {
+	// just passes to original reader when nothing called
+	exp1 := []byte("original")
+	pr1 := &peekingReader{rdr: ioutil.NopCloser(bytes.NewReader(exp1))}
+	b1, err := ioutil.ReadAll(pr1)
+	if assert.NoError(t, err) {
+		assert.Equal(t, exp1, b1)
+	}
+
+	// uses actual when there was some buffering
+	exp2 := []byte("actual")
+	pt1, pt2 := []byte("a"), []byte("ctual")
+	pr2 := &peekingReader{
+		rdr:    ioutil.NopCloser(bytes.NewReader(exp1)),
+		actual: io.MultiReader(bytes.NewReader(pt1), bytes.NewReader(pt2)),
+		peeked: pt1,
+	}
+	b2, err := ioutil.ReadAll(pr2)
+	if assert.NoError(t, err) {
+		assert.Equal(t, exp2, b2)
+	}
+
+	// closes original reader
+	tr := new(tstreadcloser)
+	pr3 := &peekingReader{
+		rdr:    tr,
+		actual: ioutil.NopCloser(bytes.NewBuffer(nil)),
+		peeked: pt1,
+	}
+
+
+	// returns true when peeked previously with data
+	// returns true when peeked with data
+}
+*/
+
+func TestJSONRequest(t *testing.T) {
+	req, err := JSONRequest("GET", "/swagger.json", nil)
+	assert.NoError(t, err)
+	assert.Equal(t, "GET", req.Method)
+	assert.Equal(t, JSONMime, req.Header.Get(HeaderContentType))
+	assert.Equal(t, JSONMime, req.Header.Get(HeaderAccept))
+
+	req, err = JSONRequest("GET", "%2", nil)
+	assert.Error(t, err)
+	assert.Nil(t, req)
+}
+
+//func TestCanHaveBody(t *testing.T) {
+//assert.True(t, CanHaveBody("put"))
+//assert.True(t, CanHaveBody("post"))
+//assert.True(t, CanHaveBody("patch"))
+//assert.True(t, CanHaveBody("delete"))
+//assert.False(t, CanHaveBody(""))
+//assert.False(t, CanHaveBody("get"))
+//assert.False(t, CanHaveBody("options"))
+//assert.False(t, CanHaveBody("head"))
+//assert.False(t, CanHaveBody("invalid"))
+//}
+
+func TestReadSingle(t *testing.T) {
+	values := url.Values(make(map[string][]string))
+	values.Add("something", "the thing")
+	assert.Equal(t, "the thing", ReadSingleValue(tv(values), "something"))
+	assert.Empty(t, ReadSingleValue(tv(values), "notthere"))
+}
+
+func TestReadCollection(t *testing.T) {
+	values := url.Values(make(map[string][]string))
+	values.Add("something", "value1,value2")
+	assert.Equal(t, []string{"value1", "value2"}, ReadCollectionValue(tv(values), "something", "csv"))
+	assert.Empty(t, ReadCollectionValue(tv(values), "notthere", ""))
+}
+
+type tv map[string][]string
+
+func (v tv) GetOK(key string) (value []string, hasKey bool, hasValue bool) {
+	value, hasKey = v[key]
+	if !hasKey {
+		return
+	}
+	if len(value) == 0 {
+		return
+	}
+	hasValue = true
+	return
+
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/security/apikey_auth_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/security/apikey_auth_test.go
@@ -0,0 +1,94 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 security
+
+import (
+	"net/http"
+	"testing"
+
+	"github.com/go-openapi/errors"
+	"github.com/stretchr/testify/assert"
+)
+
+var tokenAuth = TokenAuthentication(func(token string) (interface{}, error) {
+	if token == "token123" {
+		return "admin", nil
+	}
+	return nil, errors.Unauthenticated("token")
+})
+
+func TestInvalidApiKeyAuthInitialization(t *testing.T) {
+	assert.Panics(t, func() { APIKeyAuth("api_key", "qery", tokenAuth) })
+}
+
+func TestValidApiKeyAuth(t *testing.T) {
+	ta := APIKeyAuth("api_key", "query", tokenAuth)
+	ta2 := APIKeyAuth("X-API-KEY", "header", tokenAuth)
+
+	req1, _ := http.NewRequest("GET", "/blah?api_key=token123", nil)
+
+	ok, usr, err := ta.Authenticate(req1)
+	assert.True(t, ok)
+	assert.Equal(t, "admin", usr)
+	assert.NoError(t, err)
+
+	req2, _ := http.NewRequest("GET", "/blah", nil)
+	req2.Header.Set("X-API-KEY", "token123")
+
+	ok, usr, err = ta2.Authenticate(req2)
+	assert.True(t, ok)
+	assert.Equal(t, "admin", usr)
+	assert.NoError(t, err)
+}
+
+func TestInvalidApiKeyAuth(t *testing.T) {
+	ta := APIKeyAuth("api_key", "query", tokenAuth)
+	ta2 := APIKeyAuth("X-API-KEY", "header", tokenAuth)
+
+	req1, _ := http.NewRequest("GET", "/blah?api_key=token124", nil)
+
+	ok, usr, err := ta.Authenticate(req1)
+	assert.True(t, ok)
+	assert.Equal(t, nil, usr)
+	assert.Error(t, err)
+
+	req2, _ := http.NewRequest("GET", "/blah", nil)
+	req2.Header.Set("X-API-KEY", "token124")
+
+	ok, usr, err = ta2.Authenticate(req2)
+	assert.True(t, ok)
+	assert.Equal(t, nil, usr)
+	assert.Error(t, err)
+}
+
+func TestMissingApiKeyAuth(t *testing.T) {
+	ta := APIKeyAuth("api_key", "query", tokenAuth)
+	ta2 := APIKeyAuth("X-API-KEY", "header", tokenAuth)
+
+	req1, _ := http.NewRequest("GET", "/blah", nil)
+	req1.Header.Set("X-API-KEY", "token123")
+
+	ok, usr, err := ta.Authenticate(req1)
+	assert.False(t, ok)
+	assert.Equal(t, nil, usr)
+	assert.NoError(t, err)
+
+	req2, _ := http.NewRequest("GET", "/blah?api_key=token123", nil)
+
+	ok, usr, err = ta2.Authenticate(req2)
+	assert.False(t, ok)
+	assert.Equal(t, nil, usr)
+	assert.NoError(t, err)
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/security/authenticator.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/security/authenticator.go
@@ -0,0 +1,127 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 security
+
+import (
+	"net/http"
+	"strings"
+
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/runtime"
+)
+
+// httpAuthenticator is a function that authenticates a HTTP request
+func httpAuthenticator(handler func(*http.Request) (bool, interface{}, error)) runtime.Authenticator {
+	return runtime.AuthenticatorFunc(func(params interface{}) (bool, interface{}, error) {
+		if request, ok := params.(*http.Request); ok {
+			return handler(request)
+		}
+		if scoped, ok := params.(*ScopedAuthRequest); ok {
+			return handler(scoped.Request)
+		}
+		return false, nil, nil
+	})
+}
+
+func scopedAuthenticator(handler func(*ScopedAuthRequest) (bool, interface{}, error)) runtime.Authenticator {
+	return runtime.AuthenticatorFunc(func(params interface{}) (bool, interface{}, error) {
+		if request, ok := params.(*ScopedAuthRequest); ok {
+			return handler(request)
+		}
+		return false, nil, nil
+	})
+}
+
+// UserPassAuthentication authentication function
+type UserPassAuthentication func(string, string) (interface{}, error)
+
+// TokenAuthentication authentication function
+type TokenAuthentication func(string) (interface{}, error)
+
+// ScopedTokenAuthentication authentication function
+type ScopedTokenAuthentication func(string, []string) (interface{}, error)
+
+// BasicAuth creates a basic auth authenticator with the provided authentication function
+func BasicAuth(authenticate UserPassAuthentication) runtime.Authenticator {
+	return httpAuthenticator(func(r *http.Request) (bool, interface{}, error) {
+		if usr, pass, ok := r.BasicAuth(); ok {
+			p, err := authenticate(usr, pass)
+			return true, p, err
+		}
+
+		return false, nil, nil
+	})
+}
+
+// APIKeyAuth creates an authenticator that uses a token for authorization.
+// This token can be obtained from either a header or a query string
+func APIKeyAuth(name, in string, authenticate TokenAuthentication) runtime.Authenticator {
+	inl := strings.ToLower(in)
+	if inl != "query" && inl != "header" {
+		// panic because this is most likely a typo
+		panic(errors.New(500, "api key auth: in value needs to be either \"query\" or \"header\"."))
+	}
+
+	var getToken func(*http.Request) string
+	switch inl {
+	case "header":
+		getToken = func(r *http.Request) string { return r.Header.Get(name) }
+	case "query":
+		getToken = func(r *http.Request) string { return r.URL.Query().Get(name) }
+	}
+
+	return httpAuthenticator(func(r *http.Request) (bool, interface{}, error) {
+		token := getToken(r)
+		if token == "" {
+			return false, nil, nil
+		}
+
+		p, err := authenticate(token)
+		return true, p, err
+	})
+}
+
+// ScopedAuthRequest contains both a http request and the required scopes for a particular operation
+type ScopedAuthRequest struct {
+	Request        *http.Request
+	RequiredScopes []string
+}
+
+// BearerAuth for use with oauth2 flows
+func BearerAuth(name string, authenticate ScopedTokenAuthentication) runtime.Authenticator {
+	const prefix = "Bearer "
+	return scopedAuthenticator(func(r *ScopedAuthRequest) (bool, interface{}, error) {
+		var token string
+		hdr := r.Request.Header.Get("Authorization")
+		if strings.HasPrefix(hdr, prefix) {
+			token = strings.TrimPrefix(hdr, prefix)
+		}
+		if token == "" {
+			qs := r.Request.URL.Query()
+			token = qs.Get("access_token")
+		}
+		ct, _, _ := runtime.ContentType(r.Request.Header)
+		if token == "" && (ct == "application/x-www-form-urlencoded" || ct == "multipart/form-data") {
+			token = r.Request.FormValue("access_token")
+		}
+
+		if token == "" {
+			return false, nil, nil
+		}
+
+		p, err := authenticate(token, r.RequiredScopes)
+		return true, p, err
+	})
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/security/basic_auth_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/security/basic_auth_test.go
@@ -0,0 +1,75 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 security
+
+import (
+	"net/http"
+	"testing"
+
+	"github.com/go-openapi/errors"
+	"github.com/stretchr/testify/assert"
+)
+
+var basicAuthHandler = UserPassAuthentication(func(user, pass string) (interface{}, error) {
+	if user == "admin" && pass == "123456" {
+		return "admin", nil
+	}
+	return "", errors.Unauthenticated("basic")
+})
+
+func TestValidBasicAuth(t *testing.T) {
+	ba := BasicAuth(basicAuthHandler)
+
+	req, _ := http.NewRequest("GET", "/blah", nil)
+	req.SetBasicAuth("admin", "123456")
+	ok, usr, err := ba.Authenticate(req)
+
+	assert.NoError(t, err)
+	assert.True(t, ok)
+	assert.Equal(t, "admin", usr)
+}
+
+func TestInvalidBasicAuth(t *testing.T) {
+	ba := BasicAuth(basicAuthHandler)
+
+	req, _ := http.NewRequest("GET", "/blah", nil)
+	req.SetBasicAuth("admin", "admin")
+	ok, usr, err := ba.Authenticate(req)
+
+	assert.Error(t, err)
+	assert.True(t, ok)
+	assert.Equal(t, "", usr)
+}
+
+func TestMissingbasicAuth(t *testing.T) {
+	ba := BasicAuth(basicAuthHandler)
+
+	req, _ := http.NewRequest("GET", "/blah", nil)
+
+	ok, usr, err := ba.Authenticate(req)
+	assert.NoError(t, err)
+	assert.False(t, ok)
+	assert.Equal(t, nil, usr)
+}
+
+func TestNoRequestBasicAuth(t *testing.T) {
+	ba := BasicAuth(basicAuthHandler)
+
+	ok, usr, err := ba.Authenticate("token")
+
+	assert.NoError(t, err)
+	assert.False(t, ok)
+	assert.Nil(t, usr)
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/security/bearer_auth_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/security/bearer_auth_test.go
@@ -0,0 +1,143 @@
+package security
+
+import (
+	"bytes"
+	"mime/multipart"
+	"net/http"
+	"net/url"
+	"strings"
+	"testing"
+
+	"github.com/go-openapi/errors"
+	"github.com/stretchr/testify/assert"
+)
+
+var bearerAuth = ScopedTokenAuthentication(func(token string, requiredScopes []string) (interface{}, error) {
+	if token == "token123" {
+		return "admin", nil
+	}
+	return nil, errors.Unauthenticated("bearer")
+})
+
+func TestValidBearerAuth(t *testing.T) {
+	ba := BearerAuth("owners_auth", bearerAuth)
+
+	req1, _ := http.NewRequest("GET", "/blah?access_token=token123", nil)
+
+	ok, usr, err := ba.Authenticate(&ScopedAuthRequest{Request: req1})
+	assert.True(t, ok)
+	assert.Equal(t, "admin", usr)
+	assert.NoError(t, err)
+
+	req2, _ := http.NewRequest("GET", "/blah", nil)
+	req2.Header.Set("Authorization", "Bearer token123")
+
+	ok, usr, err = ba.Authenticate(&ScopedAuthRequest{Request: req2})
+	assert.True(t, ok)
+	assert.Equal(t, "admin", usr)
+	assert.NoError(t, err)
+
+	body := url.Values(map[string][]string{})
+	body.Set("access_token", "token123")
+	req3, _ := http.NewRequest("POST", "/blah", strings.NewReader(body.Encode()))
+	req3.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+
+	ok, usr, err = ba.Authenticate(&ScopedAuthRequest{Request: req3})
+	assert.True(t, ok)
+	assert.Equal(t, "admin", usr)
+	assert.NoError(t, err)
+
+	mpbody := bytes.NewBuffer(nil)
+	writer := multipart.NewWriter(mpbody)
+	writer.WriteField("access_token", "token123")
+	writer.Close()
+	req4, _ := http.NewRequest("POST", "/blah", mpbody)
+	req4.Header.Set("Content-Type", writer.FormDataContentType())
+
+	ok, usr, err = ba.Authenticate(&ScopedAuthRequest{Request: req4})
+	assert.True(t, ok)
+	assert.Equal(t, "admin", usr)
+	assert.NoError(t, err)
+}
+
+func TestInvalidBearerAuth(t *testing.T) {
+	ba := BearerAuth("owners_auth", bearerAuth)
+
+	req1, _ := http.NewRequest("GET", "/blah?access_token=token124", nil)
+
+	ok, usr, err := ba.Authenticate(&ScopedAuthRequest{Request: req1})
+	assert.True(t, ok)
+	assert.Equal(t, nil, usr)
+	assert.Error(t, err)
+
+	req2, _ := http.NewRequest("GET", "/blah", nil)
+	req2.Header.Set("Authorization", "Bearer token124")
+
+	ok, usr, err = ba.Authenticate(&ScopedAuthRequest{Request: req2})
+	assert.True(t, ok)
+	assert.Equal(t, nil, usr)
+	assert.Error(t, err)
+
+	body := url.Values(map[string][]string{})
+	body.Set("access_token", "token124")
+	req3, _ := http.NewRequest("POST", "/blah", strings.NewReader(body.Encode()))
+	req3.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+
+	ok, usr, err = ba.Authenticate(&ScopedAuthRequest{Request: req3})
+	assert.True(t, ok)
+	assert.Equal(t, nil, usr)
+	assert.Error(t, err)
+
+	mpbody := bytes.NewBuffer(nil)
+	writer := multipart.NewWriter(mpbody)
+	writer.WriteField("access_token", "token124")
+	writer.Close()
+	req4, _ := http.NewRequest("POST", "/blah", mpbody)
+	req4.Header.Set("Content-Type", writer.FormDataContentType())
+
+	ok, usr, err = ba.Authenticate(&ScopedAuthRequest{Request: req4})
+	assert.True(t, ok)
+	assert.Equal(t, nil, usr)
+	assert.Error(t, err)
+}
+
+func TestMissingBearerAuth(t *testing.T) {
+	ba := BearerAuth("owners_auth", bearerAuth)
+
+	req1, _ := http.NewRequest("GET", "/blah?access_toke=token123", nil)
+
+	ok, usr, err := ba.Authenticate(&ScopedAuthRequest{Request: req1})
+	assert.False(t, ok)
+	assert.Equal(t, nil, usr)
+	assert.NoError(t, err)
+
+	req2, _ := http.NewRequest("GET", "/blah", nil)
+	req2.Header.Set("Authorization", "Beare token123")
+
+	ok, usr, err = ba.Authenticate(&ScopedAuthRequest{Request: req2})
+	assert.False(t, ok)
+	assert.Equal(t, nil, usr)
+	assert.NoError(t, err)
+
+	body := url.Values(map[string][]string{})
+	body.Set("access_toke", "token123")
+	req3, _ := http.NewRequest("POST", "/blah", strings.NewReader(body.Encode()))
+	req3.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+
+	ok, usr, err = ba.Authenticate(&ScopedAuthRequest{Request: req3})
+	assert.False(t, ok)
+	assert.Equal(t, nil, usr)
+	assert.NoError(t, err)
+
+	mpbody := bytes.NewBuffer(nil)
+	writer := multipart.NewWriter(mpbody)
+	writer.WriteField("access_toke", "token123")
+	writer.Close()
+	req4, _ := http.NewRequest("POST", "/blah", mpbody)
+	req4.Header.Set("Content-Type", writer.FormDataContentType())
+
+	ok, usr, err = ba.Authenticate(&ScopedAuthRequest{Request: req4})
+	assert.False(t, ok)
+	assert.Equal(t, nil, usr)
+	assert.NoError(t, err)
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/statuses.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/statuses.go
@@ -0,0 +1,90 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 runtime
+
+// Statuses lists the most common HTTP status codes to default message
+// taken from http://status.es
+var Statuses = map[int]string{
+	100: "Continue",
+	101: "Switching Protocols",
+	102: "Processing",
+	103: "Checkpoint",
+	122: "URI too long",
+	200: "OK",
+	201: "Created",
+	202: "Accepted",
+	203: "Request Processed",
+	204: "No Content",
+	205: "Reset Content",
+	206: "Partial Content",
+	207: "Mutli-Status",
+	208: "Already Reported",
+	226: "IM Used",
+	300: "Multiple Choices",
+	301: "Moved Permanently",
+	302: "Found",
+	303: "See Other",
+	304: "Not Modified",
+	305: "Use Proxy",
+	306: "Switch Proxy",
+	307: "Temporary Redirect",
+	308: "Permanent Redirect",
+	400: "Bad Request",
+	401: "Unauthorized",
+	402: "Payment Required",
+	403: "Forbidden",
+	404: "Not Found",
+	405: "Method Not Allowed",
+	406: "Not Acceptable",
+	407: "Proxy Authentication Required",
+	408: "Request Timeout",
+	409: "Conflict",
+	410: "Gone",
+	411: "Length Required",
+	412: "Precondition Failed",
+	413: "Request Entity Too Large",
+	414: "Request-URI Too Long",
+	415: "Unsupported Media Type",
+	416: "Request Range Not Satisfiable",
+	417: "Expectation Failed",
+	418: "I'm a teapot",
+	420: "Enhance Your Calm",
+	422: "Unprocessable Entity",
+	423: "Locked",
+	424: "Failed Dependency",
+	426: "Upgrade Required",
+	428: "Precondition Required",
+	429: "Too Many Requests",
+	431: "Request Header Fields Too Large",
+	444: "No Response",
+	449: "Retry With",
+	450: "Blocked by Windows Parental Controls",
+	451: "Wrong Exchange Server",
+	499: "Client Closed Request",
+	500: "Internal Server Error",
+	501: "Not Implemented",
+	502: "Bad Gateway",
+	503: "Service Unavailable",
+	504: "Gateway Timeout",
+	505: "HTTP Version Not Supported",
+	506: "Variant Also Negotiates",
+	507: "Insufficient Storage",
+	508: "Loop Detected",
+	509: "Bandwidth Limit Exceeded",
+	510: "Not Extended",
+	511: "Network Authentication Required",
+	598: "Network read timeout error",
+	599: "Network connect timeout error",
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/text.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/text.go
@@ -0,0 +1,52 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 runtime
+
+import (
+	"bytes"
+	"io"
+	"unsafe"
+
+	"github.com/go-openapi/swag"
+)
+
+// TextConsumer creates a new text consumer
+func TextConsumer() Consumer {
+	return ConsumerFunc(func(reader io.Reader, data interface{}) error {
+		buf := new(bytes.Buffer)
+		_, err := buf.ReadFrom(reader)
+		if err != nil {
+			return err
+		}
+		b := buf.Bytes()
+		*(data.(*string)) = *(*string)(unsafe.Pointer(&b))
+		return nil
+	})
+}
+
+// TextProducer creates a new text producer
+func TextProducer() Producer {
+	return ProducerFunc(func(writer io.Writer, data interface{}) error {
+		var buf *bytes.Buffer
+		switch tped := data.(type) {
+		case *string:
+			buf = bytes.NewBufferString(swag.StringValue(tped))
+		case string:
+			buf = bytes.NewBufferString(tped)
+		}
+		_, err := buf.WriteTo(writer)
+		return err
+	})
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/text_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/text_test.go
@@ -0,0 +1,45 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 runtime
+
+import (
+	"bytes"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+var consProdText = `The quick brown fox jumped over the lazy dog.`
+
+func TestTextConsumer(t *testing.T) {
+	cons := TextConsumer()
+	var data string
+	err := cons.Consume(bytes.NewBuffer([]byte(consProdText)), &data)
+	assert.NoError(t, err)
+	assert.Equal(t, consProdText, data)
+}
+
+func TestTextProducer(t *testing.T) {
+	prod := TextProducer()
+	rw := httptest.NewRecorder()
+	err := prod.Produce(rw, consProdText)
+	assert.NoError(t, err)
+	assert.Equal(t, consProdText, rw.Body.String())
+	rw2 := httptest.NewRecorder()
+	err2 := prod.Produce(rw2, &consProdText)
+	assert.NoError(t, err2)
+	assert.Equal(t, consProdText, rw2.Body.String())
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/values.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/values.go
@@ -0,0 +1,19 @@
+package runtime
+
+// Values typically represent parameters on a http request.
+type Values map[string][]string
+
+// GetOK returns the values collection for the given key.
+// When the key is present in the map it will return true for hasKey.
+// When the value is not empty it will return true for hasValue.
+func (v Values) GetOK(key string) (value []string, hasKey bool, hasValue bool) {
+	value, hasKey = v[key]
+	if !hasKey {
+		return
+	}
+	if len(value) == 0 {
+		return
+	}
+	hasValue = true
+	return
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/xml.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/xml.go
@@ -0,0 +1,36 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 runtime
+
+import (
+	"encoding/xml"
+	"io"
+)
+
+// XMLConsumer creates a new XML consumer
+func XMLConsumer() Consumer {
+	return ConsumerFunc(func(reader io.Reader, data interface{}) error {
+		dec := xml.NewDecoder(reader)
+		return dec.Decode(data)
+	})
+}
+
+// XMLProducer creates a new XML producer
+func XMLProducer() Producer {
+	return ProducerFunc(func(writer io.Writer, data interface{}) error {
+		enc := xml.NewEncoder(writer)
+		return enc.Encode(data)
+	})
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/xml_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/xml_test.go
@@ -0,0 +1,53 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 runtime
+
+import (
+	"bytes"
+	"encoding/xml"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+var consProdXML = `<person><name>Somebody</name><id>1</id></person>`
+
+func TestXMLConsumer(t *testing.T) {
+	cons := XMLConsumer()
+	var data struct {
+		XMLName xml.Name `xml:"person"`
+		Name    string   `xml:"name"`
+		ID      int      `xml:"id"`
+	}
+	err := cons.Consume(bytes.NewBuffer([]byte(consProdXML)), &data)
+	assert.NoError(t, err)
+	assert.Equal(t, "Somebody", data.Name)
+	assert.Equal(t, 1, data.ID)
+}
+
+func TestXMLProducer(t *testing.T) {
+	prod := XMLProducer()
+	data := struct {
+		XMLName xml.Name `xml:"person"`
+		Name    string   `xml:"name"`
+		ID      int      `xml:"id"`
+	}{Name: "Somebody", ID: 1}
+
+	rw := httptest.NewRecorder()
+	err := prod.Produce(rw, data)
+	assert.NoError(t, err)
+	assert.Equal(t, consProdXML, rw.Body.String())
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/yamlpc/yaml.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/yamlpc/yaml.go
@@ -0,0 +1,44 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 yamlpc
+
+import (
+	"io"
+	"io/ioutil"
+
+	"github.com/go-openapi/runtime"
+
+	"gopkg.in/yaml.v2"
+)
+
+// YAMLConsumer creates a consumer for yaml data
+func YAMLConsumer() runtime.Consumer {
+	return runtime.ConsumerFunc(func(r io.Reader, v interface{}) error {
+		buf, err := ioutil.ReadAll(r)
+		if err != nil {
+			return err
+		}
+		return yaml.Unmarshal(buf, v)
+	})
+}
+
+// YAMLProducer creates a producer for yaml data
+func YAMLProducer() runtime.Producer {
+	return runtime.ProducerFunc(func(w io.Writer, v interface{}) error {
+		b, _ := yaml.Marshal(v) // can't make this error come up
+		_, err := w.Write(b)
+		return err
+	})
+}
Index: golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/yamlpc/yaml_test.go
===================================================================
--- /dev/null
+++ golang-github-go-openapi-validate/vendor/github.com/go-openapi/runtime/yamlpc/yaml_test.go
@@ -0,0 +1,62 @@
+// Copyright 2015 go-swagger maintainers
+//
+// 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 yamlpc
+
+import (
+	"bytes"
+	"errors"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+var consProdYAML = "name: Somebody\nid: 1\n"
+
+func TestYAMLConsumer(t *testing.T) {
+	cons := YAMLConsumer()
+	var data struct {
+		Name string
+		ID   int
+	}
+	err := cons.Consume(bytes.NewBuffer([]byte(consProdYAML)), &data)
+	assert.NoError(t, err)
+	assert.Equal(t, "Somebody", data.Name)
+	assert.Equal(t, 1, data.ID)
+}
+
+func TestYAMLProducer(t *testing.T) {
+	prod := YAMLProducer()
+	data := struct {
+		Name string `yaml:"name"`
+		ID   int    `yaml:"id"`
+	}{Name: "Somebody", ID: 1}
+
+	rw := httptest.NewRecorder()
+	err := prod.Produce(rw, data)
+	assert.NoError(t, err)
+	assert.Equal(t, consProdYAML, rw.Body.String())
+}
+
+type failReader struct {
+}
+
+func (f *failReader) Read(p []byte) (n int, err error) {
+	return 0, errors.New("expected")
+}
+func TestFailYAMLReader(t *testing.T) {
+	cons := YAMLConsumer()
+	assert.Error(t, cons.Consume(&failReader{}, nil))
+}
