diff --git a/go/vendor/github.com/go-openapi/validate/.editorconfig b/go/vendor/github.com/go-openapi/validate/.editorconfig
new file mode 100644
index 0000000..3152da6
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/.editorconfig
@@ -0,0 +1,26 @@
+# top-most EditorConfig file
+root = true
+
+# Unix-style newlines with a newline ending every file
+[*]
+end_of_line = lf
+insert_final_newline = true
+indent_style = space
+indent_size = 2
+trim_trailing_whitespace = true
+
+# Set default charset
+[*.{js,py,go,scala,rb,java,html,css,less,sass,md}]
+charset = utf-8
+
+# Tab indentation (no size specified)
+[*.go]
+indent_style = tab
+
+[*.md]
+trim_trailing_whitespace = false
+
+# Matches the exact files either package.json or .travis.yml
+[{package.json,.travis.yml}]
+indent_style = space
+indent_size = 2
diff --git a/go/vendor/github.com/go-openapi/validate/.gitignore b/go/vendor/github.com/go-openapi/validate/.gitignore
new file mode 100644
index 0000000..fea8b84
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/.gitignore
@@ -0,0 +1,5 @@
+secrets.yml
+coverage.out
+*.cov
+*.out
+playground
diff --git a/go/vendor/github.com/go-openapi/validate/.golangci.yml b/go/vendor/github.com/go-openapi/validate/.golangci.yml
new file mode 100644
index 0000000..c2c5071
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/.golangci.yml
@@ -0,0 +1,20 @@
+linters-settings:
+  govet:
+    check-shadowing: true
+  golint:
+    min-confidence: 0
+  gocyclo:
+    min-complexity: 25
+  maligned:
+    suggest-new: true
+  dupl:
+    threshold: 100
+  goconst:
+    min-len: 2
+    min-occurrences: 2
+
+linters:
+  enable-all: true
+  disable:
+    - maligned
+    - lll
diff --git a/go/vendor/github.com/go-openapi/validate/.travis.yml b/go/vendor/github.com/go-openapi/validate/.travis.yml
new file mode 100644
index 0000000..c0d6fca
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/.travis.yml
@@ -0,0 +1,35 @@
+after_success:
+- bash <(curl -s https://codecov.io/bash)
+env:
+- TEST_COMMAND="go test -v -race -covermode=atomic"
+- TEST_COMMAND="go test -v -timeout=20m -cover -coverprofile=coverage.txt -args -enable-long"
+- TEST_COMMAND="go test -v -timeout=30m -args -enable-go-swagger"
+- TEST_COMMAND="go test -v -timeout=30m github.com/go-openapi/runtime/..."
+go:
+- '1.9'
+- 1.10.x
+- 1.11.x
+install:
+- 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 github.com/kr/pretty
+- go get -u gopkg.in/yaml.v2
+- go get -u github.com/go-openapi/spec
+- 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
+- go get -u github.com/go-openapi/runtime
+- go get -u github.com/docker/go-units
+language: go
+matrix:
+  exclude:
+  - env: TEST_COMMAND="go test -v -timeout=30m -args -enable-go-swagger"
+    go: 1.8
+notifications:
+  slack:
+    secure: EmObnQuM9Mw8J9vpFaKKHqSMN4Wsr/A9+v7ewAD5cEhA0T1P4m7MbJMiJOhxUhj/X+BFh2DamW+P2lT8mybj5wg8wnkQ2BteKA8Tawi6f9PRw2NRheO8tAi8o/npLnlmet0kc93mn+oLuqHw36w4+j5mkOl2FghkfGiUVhwrhkCP7KXQN+3TU87e+/HzQumlJ3nsE+6terVxkH3PmaUTsS5ONaODZfuxFpfb7RsoEl3skHf6d+tr+1nViLxxly7558Nc33C+W1mr0qiEvMLZ+kJ/CpGWBJ6CUJM3jm6hNe2eMuIPwEK2hxZob8c7n22VPap4K6a0bBRoydoDXaba+2sD7Ym6ivDO/DVyL44VeBBLyIiIBylDGQdZH+6SoWm90Qe/i7tnY/T5Ao5igT8f3cfQY1c3EsTfqmlDfrhmACBmwSlgkdVBLTprHL63JMY24LWmh4jhxsmMRZhCL4dze8su1w6pLN/pD1pGHtKYCEVbdTmaM3PblNRFf12XB7qosmQsgUndH4Vq3bTbU0s1pKjeDhRyLvFzvR0TBbo0pDLEoF1A/i5GVFWa7yLZNUDudQERRh7qv/xBl2excIaQ1sV4DSVm7bAE9l6Kp+yeHQJW2uN6Y3X8wu9gB9nv9l5HBze7wh8KE6PyWAOLYYqZg9/sAtsv/2GcQqXcKFF1zcA=
+script:
+- (eval "$TEST_COMMAND")
diff --git a/go/vendor/github.com/go-openapi/validate/CODE_OF_CONDUCT.md b/go/vendor/github.com/go-openapi/validate/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..9322b06
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/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/
diff --git a/go/vendor/github.com/go-openapi/validate/LICENSE b/go/vendor/github.com/go-openapi/validate/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/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.
diff --git a/go/vendor/github.com/go-openapi/validate/README.md b/go/vendor/github.com/go-openapi/validate/README.md
new file mode 100644
index 0000000..08fb352
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/README.md
@@ -0,0 +1,6 @@
+# Validation helpers [![Build Status](https://travis-ci.org/go-openapi/validate.svg?branch=master)](https://travis-ci.org/go-openapi/validate) [![codecov](https://codecov.io/gh/go-openapi/validate/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/validate) [![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/validate/master/LICENSE)
+[![GoDoc](https://godoc.org/github.com/go-openapi/validate?status.svg)](http://godoc.org/github.com/go-openapi/validate)
+[![GolangCI](https://golangci.com/badges/github.com/go-openapi/validate.svg)](https://golangci.com)
+[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/validate)](https://goreportcard.com/report/github.com/go-openapi/validate)
diff --git a/go/vendor/github.com/go-openapi/validate/debug.go b/go/vendor/github.com/go-openapi/validate/debug.go
new file mode 100644
index 0000000..8815fd9
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/debug.go
@@ -0,0 +1,47 @@
+// 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 validate
+
+import (
+	"fmt"
+	"log"
+	"os"
+	"path/filepath"
+	"runtime"
+)
+
+var (
+	// Debug is true when the SWAGGER_DEBUG env var is not empty.
+	// It enables a more verbose logging of validators.
+	Debug = os.Getenv("SWAGGER_DEBUG") != ""
+	// validateLogger is a debug logger for this package
+	validateLogger *log.Logger
+)
+
+func init() {
+	debugOptions()
+}
+
+func debugOptions() {
+	validateLogger = log.New(os.Stdout, "validate:", log.LstdFlags)
+}
+
+func debugLog(msg string, args ...interface{}) {
+	// A private, trivial trace logger, based on go-openapi/spec/expander.go:debugLog()
+	if Debug {
+		_, file1, pos1, _ := runtime.Caller(1)
+		validateLogger.Printf("%s:%d: %s", filepath.Base(file1), pos1, fmt.Sprintf(msg, args...))
+	}
+}
diff --git a/go/vendor/github.com/go-openapi/validate/default_validator.go b/go/vendor/github.com/go-openapi/validate/default_validator.go
new file mode 100644
index 0000000..35c631b
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/default_validator.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 validate
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/go-openapi/spec"
+)
+
+// defaultValidator validates default values in a spec.
+// According to Swagger spec, default values MUST validate their schema.
+type defaultValidator struct {
+	SpecValidator  *SpecValidator
+	visitedSchemas map[string]bool
+}
+
+// resetVisited resets the internal state of visited schemas
+func (d *defaultValidator) resetVisited() {
+	d.visitedSchemas = map[string]bool{}
+}
+
+// beingVisited asserts a schema is being visited
+func (d *defaultValidator) beingVisited(path string) {
+	d.visitedSchemas[path] = true
+}
+
+// isVisited tells if a path has already been visited
+func (d *defaultValidator) isVisited(path string) bool {
+	found := d.visitedSchemas[path]
+	if !found {
+		// search for overlapping paths
+		frags := strings.Split(path, ".")
+		if len(frags) < 2 {
+			// shortcut exit on smaller paths
+			return found
+		}
+		last := len(frags) - 1
+		var currentFragStr, parent string
+		for i := range frags {
+			if i == 0 {
+				currentFragStr = frags[last]
+			} else {
+				currentFragStr = strings.Join([]string{frags[last-i], currentFragStr}, ".")
+			}
+			if i < last {
+				parent = strings.Join(frags[0:last-i], ".")
+			} else {
+				parent = ""
+			}
+			if strings.HasSuffix(parent, currentFragStr) {
+				found = true
+				break
+			}
+		}
+	}
+	return found
+}
+
+// Validate validates the default values declared in the swagger spec
+func (d *defaultValidator) Validate() (errs *Result) {
+	errs = new(Result)
+	if d == nil || d.SpecValidator == nil {
+		return errs
+	}
+	d.resetVisited()
+	errs.Merge(d.validateDefaultValueValidAgainstSchema()) // error -
+	return errs
+}
+
+func (d *defaultValidator) validateDefaultValueValidAgainstSchema() *Result {
+	// every default value that is specified must validate against the schema for that property
+	// headers, items, parameters, schema
+
+	res := new(Result)
+	s := d.SpecValidator
+
+	for method, pathItem := range s.analyzer.Operations() {
+		if pathItem != nil { // Safeguard
+			for path, op := range pathItem {
+				// parameters
+				for _, param := range paramHelp.safeExpandedParamsFor(path, method, op.ID, res, s) {
+					if param.Default != nil && param.Required {
+						res.AddWarnings(requiredHasDefaultMsg(param.Name, param.In))
+					}
+
+					// reset explored schemas to get depth-first recursive-proof exploration
+					d.resetVisited()
+
+					// Check simple parameters first
+					// default values provided must validate against their inline definition (no explicit schema)
+					if param.Default != nil && param.Schema == nil {
+						// check param default value is valid
+						red := NewParamValidator(&param, s.KnownFormats).Validate(param.Default)
+						if red.HasErrorsOrWarnings() {
+							res.AddErrors(defaultValueDoesNotValidateMsg(param.Name, param.In))
+							res.Merge(red)
+						}
+					}
+
+					// Recursively follows Items and Schemas
+					if param.Items != nil {
+						red := d.validateDefaultValueItemsAgainstSchema(param.Name, param.In, &param, param.Items)
+						if red.HasErrorsOrWarnings() {
+							res.AddErrors(defaultValueItemsDoesNotValidateMsg(param.Name, param.In))
+							res.Merge(red)
+						}
+					}
+
+					if param.Schema != nil {
+						// Validate default value against schema
+						red := d.validateDefaultValueSchemaAgainstSchema(param.Name, param.In, param.Schema)
+						if red.HasErrorsOrWarnings() {
+							res.AddErrors(defaultValueDoesNotValidateMsg(param.Name, param.In))
+							res.Merge(red)
+						}
+					}
+				}
+
+				if op.Responses != nil {
+					if op.Responses.Default != nil {
+						// Same constraint on default Response
+						res.Merge(d.validateDefaultInResponse(op.Responses.Default, "default", path, 0, op.ID))
+					}
+					// Same constraint on regular Responses
+					if op.Responses.StatusCodeResponses != nil { // Safeguard
+						for code, r := range op.Responses.StatusCodeResponses {
+							res.Merge(d.validateDefaultInResponse(&r, "response", path, code, op.ID))
+						}
+					}
+				} else {
+					// Empty op.ID means there is no meaningful operation: no need to report a specific message
+					if op.ID != "" {
+						res.AddErrors(noValidResponseMsg(op.ID))
+					}
+				}
+			}
+		}
+	}
+	if s.spec.Spec().Definitions != nil { // Safeguard
+		// reset explored schemas to get depth-first recursive-proof exploration
+		d.resetVisited()
+		for nm, sch := range s.spec.Spec().Definitions {
+			res.Merge(d.validateDefaultValueSchemaAgainstSchema(fmt.Sprintf("definitions.%s", nm), "body", &sch))
+		}
+	}
+	return res
+}
+
+func (d *defaultValidator) validateDefaultInResponse(resp *spec.Response, responseType, path string, responseCode int, operationID string) *Result {
+	s := d.SpecValidator
+
+	response, res := responseHelp.expandResponseRef(resp, path, s)
+	if !res.IsValid() {
+		return res
+	}
+
+	responseName, responseCodeAsStr := responseHelp.responseMsgVariants(responseType, responseCode)
+
+	if response.Headers != nil { // Safeguard
+		for nm, h := range response.Headers {
+			// reset explored schemas to get depth-first recursive-proof exploration
+			d.resetVisited()
+
+			if h.Default != nil {
+				red := NewHeaderValidator(nm, &h, s.KnownFormats).Validate(h.Default)
+				if red.HasErrorsOrWarnings() {
+					res.AddErrors(defaultValueHeaderDoesNotValidateMsg(operationID, nm, responseName))
+					res.Merge(red)
+				}
+			}
+
+			// Headers have inline definition, like params
+			if h.Items != nil {
+				red := d.validateDefaultValueItemsAgainstSchema(nm, "header", &h, h.Items)
+				if red.HasErrorsOrWarnings() {
+					res.AddErrors(defaultValueHeaderItemsDoesNotValidateMsg(operationID, nm, responseName))
+					res.Merge(red)
+				}
+			}
+
+			if _, err := compileRegexp(h.Pattern); err != nil {
+				res.AddErrors(invalidPatternInHeaderMsg(operationID, nm, responseName, h.Pattern, err))
+			}
+
+			// Headers don't have schema
+		}
+	}
+	if response.Schema != nil {
+		// reset explored schemas to get depth-first recursive-proof exploration
+		d.resetVisited()
+
+		red := d.validateDefaultValueSchemaAgainstSchema(responseCodeAsStr, "response", response.Schema)
+		if red.HasErrorsOrWarnings() {
+			// Additional message to make sure the context of the error is not lost
+			res.AddErrors(defaultValueInDoesNotValidateMsg(operationID, responseName))
+			res.Merge(red)
+		}
+	}
+	return res
+}
+
+func (d *defaultValidator) validateDefaultValueSchemaAgainstSchema(path, in string, schema *spec.Schema) *Result {
+	if schema == nil || d.isVisited(path) {
+		// Avoids recursing if we are already done with that check
+		return nil
+	}
+	d.beingVisited(path)
+	res := new(Result)
+	s := d.SpecValidator
+
+	if schema.Default != nil {
+		res.Merge(NewSchemaValidator(schema, s.spec.Spec(), path+".default", s.KnownFormats).Validate(schema.Default))
+	}
+	if schema.Items != nil {
+		if schema.Items.Schema != nil {
+			res.Merge(d.validateDefaultValueSchemaAgainstSchema(path+".items.default", in, schema.Items.Schema))
+		}
+		// Multiple schemas in items
+		if schema.Items.Schemas != nil { // Safeguard
+			for i, sch := range schema.Items.Schemas {
+				res.Merge(d.validateDefaultValueSchemaAgainstSchema(fmt.Sprintf("%s.items[%d].default", path, i), in, &sch))
+			}
+		}
+	}
+	if _, err := compileRegexp(schema.Pattern); err != nil {
+		res.AddErrors(invalidPatternInMsg(path, in, schema.Pattern))
+	}
+	if schema.AdditionalItems != nil && schema.AdditionalItems.Schema != nil {
+		// NOTE: we keep validating values, even though additionalItems is not supported by Swagger 2.0 (and 3.0 as well)
+		res.Merge(d.validateDefaultValueSchemaAgainstSchema(fmt.Sprintf("%s.additionalItems", path), in, schema.AdditionalItems.Schema))
+	}
+	for propName, prop := range schema.Properties {
+		res.Merge(d.validateDefaultValueSchemaAgainstSchema(path+"."+propName, in, &prop))
+	}
+	for propName, prop := range schema.PatternProperties {
+		res.Merge(d.validateDefaultValueSchemaAgainstSchema(path+"."+propName, in, &prop))
+	}
+	if schema.AdditionalProperties != nil && schema.AdditionalProperties.Schema != nil {
+		res.Merge(d.validateDefaultValueSchemaAgainstSchema(fmt.Sprintf("%s.additionalProperties", path), in, schema.AdditionalProperties.Schema))
+	}
+	if schema.AllOf != nil {
+		for i, aoSch := range schema.AllOf {
+			res.Merge(d.validateDefaultValueSchemaAgainstSchema(fmt.Sprintf("%s.allOf[%d]", path, i), in, &aoSch))
+		}
+	}
+	return res
+}
+
+func (d *defaultValidator) validateDefaultValueItemsAgainstSchema(path, in string, root interface{}, items *spec.Items) *Result {
+	res := new(Result)
+	s := d.SpecValidator
+	if items != nil {
+		if items.Default != nil {
+			res.Merge(newItemsValidator(path, in, items, root, s.KnownFormats).Validate(0, items.Default))
+		}
+		if items.Items != nil {
+			res.Merge(d.validateDefaultValueItemsAgainstSchema(path+"[0].default", in, root, items.Items))
+		}
+		if _, err := compileRegexp(items.Pattern); err != nil {
+			res.AddErrors(invalidPatternInMsg(path, in, items.Pattern))
+		}
+	}
+	return res
+}
diff --git a/go/vendor/github.com/go-openapi/validate/doc.go b/go/vendor/github.com/go-openapi/validate/doc.go
new file mode 100644
index 0000000..f5ca9a5
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/doc.go
@@ -0,0 +1,85 @@
+// 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 validate provides methods to validate a swagger specification,
+as well as tools to validate data against their schema.
+
+This package follows Swagger 2.0. specification (aka OpenAPI 2.0). Reference
+can be found here: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md.
+
+Validating a specification
+
+Validates a spec document (from JSON or YAML) against the JSON schema for swagger,
+then checks a number of extra rules that can't be expressed in JSON schema.
+
+Entry points:
+  - Spec()
+  - NewSpecValidator()
+  - SpecValidator.Validate()
+
+Reported as errors:
+  [x] definition can't declare a property that's already defined by one of its ancestors
+  [x] definition's ancestor can't be a descendant of the same model
+  [x] path uniqueness: each api path should be non-verbatim (account for path param names) unique per method
+  [x] each security reference should contain only unique scopes
+  [x] each security scope in a security definition should be unique
+  [x] parameters in path must be unique
+  [x] each path parameter must correspond to a parameter placeholder and vice versa
+  [x] each referenceable definition must have references
+  [x] each definition property listed in the required array must be defined in the properties of the model
+  [x] each parameter should have a unique `name` and `type` combination
+  [x] each operation should have only 1 parameter of type body
+  [x] each reference must point to a valid object
+  [x] every default value that is specified must validate against the schema for that property
+  [x] items property is required for all schemas/definitions of type `array`
+  [x] path parameters must be declared a required
+  [x] headers must not contain $ref
+  [x] schema and property examples provided must validate against their respective object's schema
+  [x] examples provided must validate their schema
+
+Reported as warnings:
+  [x] path parameters should not contain any of [{,},\w]
+  [x] empty path
+  [x] unused definitions
+  [x] unsupported validation of examples on non-JSON media types
+  [x] examples in response without schema
+  [x] readOnly properties should not be required
+
+Validating a schema
+
+The schema validation toolkit validates data against JSON-schema-draft 04 schema.
+
+It is tested against the full json-schema-testing-suite (https://github.com/json-schema-org/JSON-Schema-Test-Suite),
+except for the optional part (bignum, ECMA regexp, ...).
+
+It supports the complete JSON-schema vocabulary, including keywords not supported by Swagger (e.g. additionalItems, ...)
+
+Entry points:
+  - AgainstSchema()
+  - ...
+
+Known limitations
+
+With the current version of this package, the following aspects of swagger are not yet supported:
+  [ ] errors and warnings are not reported with key/line number in spec
+  [ ] default values and examples on responses only support application/json producer type
+  [ ] invalid numeric constraints (such as Minimum, etc..) are not checked except for default and example values
+  [ ] rules for collectionFormat are not implemented
+  [ ] no validation rule for polymorphism support (discriminator) [not done here]
+  [ ] valid js ECMA regexp not supported by Go regexp engine are considered invalid
+  [ ] arbitrary large numbers are not supported: max is math.MaxFloat64
+
+*/
+package validate
diff --git a/go/vendor/github.com/go-openapi/validate/example_validator.go b/go/vendor/github.com/go-openapi/validate/example_validator.go
new file mode 100644
index 0000000..b2acf10
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/example_validator.go
@@ -0,0 +1,299 @@
+// 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 validate
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/go-openapi/spec"
+)
+
+// ExampleValidator validates example values defined in a spec
+type exampleValidator struct {
+	SpecValidator  *SpecValidator
+	visitedSchemas map[string]bool
+}
+
+// resetVisited resets the internal state of visited schemas
+func (ex *exampleValidator) resetVisited() {
+	ex.visitedSchemas = map[string]bool{}
+}
+
+// beingVisited asserts a schema is being visited
+func (ex *exampleValidator) beingVisited(path string) {
+	ex.visitedSchemas[path] = true
+}
+
+// isVisited tells if a path has already been visited
+func (ex *exampleValidator) isVisited(path string) bool {
+	found := ex.visitedSchemas[path]
+	if !found {
+		// search for overlapping paths
+		frags := strings.Split(path, ".")
+		if len(frags) < 2 {
+			// shortcut exit on smaller paths
+			return found
+		}
+		last := len(frags) - 1
+		var currentFragStr, parent string
+		for i := range frags {
+			if i == 0 {
+				currentFragStr = frags[last]
+			} else {
+				currentFragStr = strings.Join([]string{frags[last-i], currentFragStr}, ".")
+			}
+			if i < last {
+				parent = strings.Join(frags[0:last-i], ".")
+			} else {
+				parent = ""
+			}
+			if strings.HasSuffix(parent, currentFragStr) {
+				found = true
+				break
+			}
+		}
+	}
+	return found
+}
+
+// Validate validates the example values declared in the swagger spec
+// Example values MUST conform to their schema.
+//
+// With Swagger 2.0, examples are supported in:
+//   - schemas
+//   - individual property
+//   - responses
+//
+func (ex *exampleValidator) Validate() (errs *Result) {
+	errs = new(Result)
+	if ex == nil || ex.SpecValidator == nil {
+		return errs
+	}
+	ex.resetVisited()
+	errs.Merge(ex.validateExampleValueValidAgainstSchema()) // error -
+
+	return errs
+}
+
+func (ex *exampleValidator) validateExampleValueValidAgainstSchema() *Result {
+	// every example value that is specified must validate against the schema for that property
+	// in: schemas, properties, object, items
+	// not in: headers, parameters without schema
+
+	res := new(Result)
+	s := ex.SpecValidator
+
+	for method, pathItem := range s.analyzer.Operations() {
+		if pathItem != nil { // Safeguard
+			for path, op := range pathItem {
+				// parameters
+				for _, param := range paramHelp.safeExpandedParamsFor(path, method, op.ID, res, s) {
+
+					// As of swagger 2.0, Examples are not supported in simple parameters
+					// However, it looks like it is supported by go-openapi
+
+					// reset explored schemas to get depth-first recursive-proof exploration
+					ex.resetVisited()
+
+					// Check simple parameters first
+					// default values provided must validate against their inline definition (no explicit schema)
+					if param.Example != nil && param.Schema == nil {
+						// check param default value is valid
+						red := NewParamValidator(&param, s.KnownFormats).Validate(param.Example)
+						if red.HasErrorsOrWarnings() {
+							res.AddWarnings(exampleValueDoesNotValidateMsg(param.Name, param.In))
+							res.MergeAsWarnings(red)
+						}
+					}
+
+					// Recursively follows Items and Schemas
+					if param.Items != nil {
+						red := ex.validateExampleValueItemsAgainstSchema(param.Name, param.In, &param, param.Items)
+						if red.HasErrorsOrWarnings() {
+							res.AddWarnings(exampleValueItemsDoesNotValidateMsg(param.Name, param.In))
+							res.Merge(red)
+						}
+					}
+
+					if param.Schema != nil {
+						// Validate example value against schema
+						red := ex.validateExampleValueSchemaAgainstSchema(param.Name, param.In, param.Schema)
+						if red.HasErrorsOrWarnings() {
+							res.AddWarnings(exampleValueDoesNotValidateMsg(param.Name, param.In))
+							res.Merge(red)
+						}
+					}
+				}
+
+				if op.Responses != nil {
+					if op.Responses.Default != nil {
+						// Same constraint on default Response
+						res.Merge(ex.validateExampleInResponse(op.Responses.Default, "default", path, 0, op.ID))
+					}
+					// Same constraint on regular Responses
+					if op.Responses.StatusCodeResponses != nil { // Safeguard
+						for code, r := range op.Responses.StatusCodeResponses {
+							res.Merge(ex.validateExampleInResponse(&r, "response", path, code, op.ID))
+						}
+					}
+				} else {
+					// Empty op.ID means there is no meaningful operation: no need to report a specific message
+					if op.ID != "" {
+						res.AddErrors(noValidResponseMsg(op.ID))
+					}
+				}
+			}
+		}
+	}
+	if s.spec.Spec().Definitions != nil { // Safeguard
+		// reset explored schemas to get depth-first recursive-proof exploration
+		ex.resetVisited()
+		for nm, sch := range s.spec.Spec().Definitions {
+			res.Merge(ex.validateExampleValueSchemaAgainstSchema(fmt.Sprintf("definitions.%s", nm), "body", &sch))
+		}
+	}
+	return res
+}
+
+func (ex *exampleValidator) validateExampleInResponse(resp *spec.Response, responseType, path string, responseCode int, operationID string) *Result {
+	s := ex.SpecValidator
+
+	response, res := responseHelp.expandResponseRef(resp, path, s)
+	if !res.IsValid() { // Safeguard
+		return res
+	}
+
+	responseName, responseCodeAsStr := responseHelp.responseMsgVariants(responseType, responseCode)
+
+	if response.Headers != nil { // Safeguard
+		for nm, h := range response.Headers {
+			// reset explored schemas to get depth-first recursive-proof exploration
+			ex.resetVisited()
+
+			if h.Example != nil {
+				red := NewHeaderValidator(nm, &h, s.KnownFormats).Validate(h.Example)
+				if red.HasErrorsOrWarnings() {
+					res.AddWarnings(exampleValueHeaderDoesNotValidateMsg(operationID, nm, responseName))
+					res.MergeAsWarnings(red)
+				}
+			}
+
+			// Headers have inline definition, like params
+			if h.Items != nil {
+				red := ex.validateExampleValueItemsAgainstSchema(nm, "header", &h, h.Items)
+				if red.HasErrorsOrWarnings() {
+					res.AddWarnings(exampleValueHeaderItemsDoesNotValidateMsg(operationID, nm, responseName))
+					res.MergeAsWarnings(red)
+				}
+			}
+
+			if _, err := compileRegexp(h.Pattern); err != nil {
+				res.AddErrors(invalidPatternInHeaderMsg(operationID, nm, responseName, h.Pattern, err))
+			}
+
+			// Headers don't have schema
+		}
+	}
+	if response.Schema != nil {
+		// reset explored schemas to get depth-first recursive-proof exploration
+		ex.resetVisited()
+
+		red := ex.validateExampleValueSchemaAgainstSchema(responseCodeAsStr, "response", response.Schema)
+		if red.HasErrorsOrWarnings() {
+			// Additional message to make sure the context of the error is not lost
+			res.AddWarnings(exampleValueInDoesNotValidateMsg(operationID, responseName))
+			res.Merge(red)
+		}
+	}
+
+	if response.Examples != nil {
+		if response.Schema != nil {
+			if example, ok := response.Examples["application/json"]; ok {
+				res.MergeAsWarnings(NewSchemaValidator(response.Schema, s.spec.Spec(), path, s.KnownFormats).Validate(example))
+			} else {
+				// TODO: validate other media types too
+				res.AddWarnings(examplesMimeNotSupportedMsg(operationID, responseName))
+			}
+		} else {
+			res.AddWarnings(examplesWithoutSchemaMsg(operationID, responseName))
+		}
+	}
+	return res
+}
+
+func (ex *exampleValidator) validateExampleValueSchemaAgainstSchema(path, in string, schema *spec.Schema) *Result {
+	if schema == nil || ex.isVisited(path) {
+		// Avoids recursing if we are already done with that check
+		return nil
+	}
+	ex.beingVisited(path)
+	s := ex.SpecValidator
+	res := new(Result)
+
+	if schema.Example != nil {
+		res.MergeAsWarnings(NewSchemaValidator(schema, s.spec.Spec(), path+".example", s.KnownFormats).Validate(schema.Example))
+	}
+	if schema.Items != nil {
+		if schema.Items.Schema != nil {
+			res.Merge(ex.validateExampleValueSchemaAgainstSchema(path+".items.example", in, schema.Items.Schema))
+		}
+		// Multiple schemas in items
+		if schema.Items.Schemas != nil { // Safeguard
+			for i, sch := range schema.Items.Schemas {
+				res.Merge(ex.validateExampleValueSchemaAgainstSchema(fmt.Sprintf("%s.items[%d].example", path, i), in, &sch))
+			}
+		}
+	}
+	if _, err := compileRegexp(schema.Pattern); err != nil {
+		res.AddErrors(invalidPatternInMsg(path, in, schema.Pattern))
+	}
+	if schema.AdditionalItems != nil && schema.AdditionalItems.Schema != nil {
+		// NOTE: we keep validating values, even though additionalItems is unsupported in Swagger 2.0 (and 3.0 as well)
+		res.Merge(ex.validateExampleValueSchemaAgainstSchema(fmt.Sprintf("%s.additionalItems", path), in, schema.AdditionalItems.Schema))
+	}
+	for propName, prop := range schema.Properties {
+		res.Merge(ex.validateExampleValueSchemaAgainstSchema(path+"."+propName, in, &prop))
+	}
+	for propName, prop := range schema.PatternProperties {
+		res.Merge(ex.validateExampleValueSchemaAgainstSchema(path+"."+propName, in, &prop))
+	}
+	if schema.AdditionalProperties != nil && schema.AdditionalProperties.Schema != nil {
+		res.Merge(ex.validateExampleValueSchemaAgainstSchema(fmt.Sprintf("%s.additionalProperties", path), in, schema.AdditionalProperties.Schema))
+	}
+	if schema.AllOf != nil {
+		for i, aoSch := range schema.AllOf {
+			res.Merge(ex.validateExampleValueSchemaAgainstSchema(fmt.Sprintf("%s.allOf[%d]", path, i), in, &aoSch))
+		}
+	}
+	return res
+}
+
+func (ex *exampleValidator) validateExampleValueItemsAgainstSchema(path, in string, root interface{}, items *spec.Items) *Result {
+	res := new(Result)
+	s := ex.SpecValidator
+	if items != nil {
+		if items.Example != nil {
+			res.MergeAsWarnings(newItemsValidator(path, in, items, root, s.KnownFormats).Validate(0, items.Example))
+		}
+		if items.Items != nil {
+			res.Merge(ex.validateExampleValueItemsAgainstSchema(path+"[0].example", in, root, items.Items))
+		}
+		if _, err := compileRegexp(items.Pattern); err != nil {
+			res.AddErrors(invalidPatternInMsg(path, in, items.Pattern))
+		}
+	}
+	return res
+}
diff --git a/go/vendor/github.com/go-openapi/validate/formats.go b/go/vendor/github.com/go-openapi/validate/formats.go
new file mode 100644
index 0000000..b7afe98
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/formats.go
@@ -0,0 +1,73 @@
+// 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 validate
+
+import (
+	"reflect"
+
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/strfmt"
+)
+
+type formatValidator struct {
+	Format       string
+	Path         string
+	In           string
+	KnownFormats strfmt.Registry
+}
+
+func (f *formatValidator) SetPath(path string) {
+	f.Path = path
+}
+
+func (f *formatValidator) Applies(source interface{}, kind reflect.Kind) bool {
+	doit := func() bool {
+		if source == nil {
+			return false
+		}
+		switch source.(type) {
+		case *spec.Items:
+			it := source.(*spec.Items)
+			return kind == reflect.String && f.KnownFormats.ContainsName(it.Format)
+		case *spec.Parameter:
+			par := source.(*spec.Parameter)
+			return kind == reflect.String && f.KnownFormats.ContainsName(par.Format)
+		case *spec.Schema:
+			sch := source.(*spec.Schema)
+			return kind == reflect.String && f.KnownFormats.ContainsName(sch.Format)
+		case *spec.Header:
+			hdr := source.(*spec.Header)
+			return kind == reflect.String && f.KnownFormats.ContainsName(hdr.Format)
+		}
+		return false
+	}
+	r := doit()
+	debugLog("format validator for %q applies %t for %T (kind: %v)\n", f.Path, r, source, kind)
+	return r
+}
+
+func (f *formatValidator) Validate(val interface{}) *Result {
+	result := new(Result)
+	debugLog("validating \"%v\" against format: %s", val, f.Format)
+
+	if err := FormatOf(f.Path, f.In, f.Format, val.(string), f.KnownFormats); err != nil {
+		result.AddErrors(err)
+	}
+
+	if result.HasErrors() {
+		return result
+	}
+	return nil
+}
diff --git a/go/vendor/github.com/go-openapi/validate/go.mod b/go/vendor/github.com/go-openapi/validate/go.mod
new file mode 100644
index 0000000..cb6199a
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/go.mod
@@ -0,0 +1,14 @@
+module github.com/go-openapi/validate
+
+require (
+	github.com/go-openapi/analysis v0.17.0
+	github.com/go-openapi/errors v0.17.0
+	github.com/go-openapi/jsonpointer v0.17.0
+	github.com/go-openapi/loads v0.17.0
+	github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9
+	github.com/go-openapi/spec v0.17.0
+	github.com/go-openapi/strfmt v0.17.0
+	github.com/go-openapi/swag v0.17.0
+	github.com/stretchr/testify v1.2.2
+	gopkg.in/yaml.v2 v2.2.1
+)
diff --git a/go/vendor/github.com/go-openapi/validate/go.sum b/go/vendor/github.com/go-openapi/validate/go.sum
new file mode 100644
index 0000000..34286d4
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/go.sum
@@ -0,0 +1,41 @@
+github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4=
+github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
+github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
+github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
+github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf h1:eg0MeVzsP1G42dRafH3vf+al2vQIJU0YHX+1Tw87oco=
+github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb h1:D4uzjWwKYQ5XnAvUbuvHW93esHg7F8N/OYeBBcJoTr0=
+github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
+github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
+github.com/go-openapi/analysis v0.17.0 h1:8JV+dzJJiK46XqGLqqLav8ZfEiJECp8jlOFhpiCdZ+0=
+github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
+github.com/go-openapi/errors v0.17.0 h1:47T+LqPrQUxFXQnB22aLBfsTRFSqWp5y4OiFgQm+/Lw=
+github.com/go-openapi/errors v0.17.0/go.mod h1:La0D2x9HoXenv7MDEiAv6vWoe84CXFo0PQRk/jdQlww=
+github.com/go-openapi/jsonpointer v0.17.0 h1:Bpl2DtZ6k7wKqfFs7e+4P08+M9I3FQgn09a1UsRUQbk=
+github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
+github.com/go-openapi/jsonreference v0.17.0 h1:d/o7/fsLWWQZACbihvZxcyLQ59jfUVs7WOJv/ak7T7A=
+github.com/go-openapi/jsonreference v0.17.0/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
+github.com/go-openapi/loads v0.17.0 h1:H22nMs3GDQk4SwAaFQ+jLNw+0xoFeCueawhZlv8MBYs=
+github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
+github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9 h1:zXd+rkzHwMIYVTJ/j/v8zUQ9j3Ir32gC5Dn9DzZVvCk=
+github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
+github.com/go-openapi/spec v0.17.0 h1:MM5YaXBdBOEcjGHW5WayrAY5Ze2ydNyy71JHeTi7xUc=
+github.com/go-openapi/spec v0.17.0/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
+github.com/go-openapi/strfmt v0.17.0 h1:79+bCyGHowS3rkr6z8RcG5jVzdKpeKXlDuW6yqE50TM=
+github.com/go-openapi/strfmt v0.17.0/go.mod h1:/bCWipNKhC9QMhD8HRe2EGbU8G0D4Yvh0G6X4k1Xwvg=
+github.com/go-openapi/swag v0.17.0 h1:7wu+dZ5k83kvUWeAb+WUkFiUhDzwGqzTR/NhWzeo1JU=
+github.com/go-openapi/swag v0.17.0/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
+github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
+github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
+github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+golang.org/x/net v0.0.0-20181005035420-146acd28ed58 h1:otZG8yDCO4LVps5+9bxOeNiCvgmOyt96J3roHTYs7oE=
+golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/go/vendor/github.com/go-openapi/validate/helpers.go b/go/vendor/github.com/go-openapi/validate/helpers.go
new file mode 100644
index 0000000..7ac8771
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/helpers.go
@@ -0,0 +1,265 @@
+// 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 validate
+
+// TODO: define this as package validate/internal
+// This must be done while keeping CI intact with all tests and test coverage
+
+import (
+	"reflect"
+	"strconv"
+	"strings"
+
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/spec"
+)
+
+const swaggerBody = "body"
+const objectType = "object"
+
+// Helpers available at the package level
+var (
+	pathHelp     *pathHelper
+	valueHelp    *valueHelper
+	errorHelp    *errorHelper
+	paramHelp    *paramHelper
+	responseHelp *responseHelper
+)
+
+type errorHelper struct {
+	// A collection of unexported helpers for error construction
+}
+
+func (h *errorHelper) sErr(err errors.Error) *Result {
+	// Builds a Result from standard errors.Error
+	return &Result{Errors: []error{err}}
+}
+
+func (h *errorHelper) addPointerError(res *Result, err error, ref string, fromPath string) *Result {
+	// Provides more context on error messages
+	// reported by the jsoinpointer package by altering the passed Result
+	if err != nil {
+		res.AddErrors(cannotResolveRefMsg(fromPath, ref, err))
+	}
+	return res
+}
+
+type pathHelper struct {
+	// A collection of unexported helpers for path validation
+}
+
+func (h *pathHelper) stripParametersInPath(path string) string {
+	// Returns a path stripped from all path parameters, with multiple or trailing slashes removed.
+	//
+	// Stripping is performed on a slash-separated basis, e.g '/a{/b}' remains a{/b} and not /a.
+	//  - Trailing "/" make a difference, e.g. /a/ !~ /a (ex: canary/bitbucket.org/swagger.json)
+	//  - presence or absence of a parameter makes a difference, e.g. /a/{log} !~ /a/ (ex: canary/kubernetes/swagger.json)
+
+	// Regexp to extract parameters from path, with surrounding {}.
+	// NOTE: important non-greedy modifier
+	rexParsePathParam := mustCompileRegexp(`{[^{}]+?}`)
+	strippedSegments := []string{}
+
+	for _, segment := range strings.Split(path, "/") {
+		strippedSegments = append(strippedSegments, rexParsePathParam.ReplaceAllString(segment, "X"))
+	}
+	return strings.Join(strippedSegments, "/")
+}
+
+func (h *pathHelper) extractPathParams(path string) (params []string) {
+	// Extracts all params from a path, with surrounding "{}"
+	rexParsePathParam := mustCompileRegexp(`{[^{}]+?}`)
+
+	for _, segment := range strings.Split(path, "/") {
+		for _, v := range rexParsePathParam.FindAllStringSubmatch(segment, -1) {
+			params = append(params, v...)
+		}
+	}
+	return
+}
+
+type valueHelper struct {
+	// A collection of unexported helpers for value validation
+}
+
+func (h *valueHelper) asInt64(val interface{}) int64 {
+	// Number conversion function for int64, without error checking
+	// (implements an implicit type upgrade).
+	v := reflect.ValueOf(val)
+	switch v.Kind() {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return v.Int()
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		return int64(v.Uint())
+	case reflect.Float32, reflect.Float64:
+		return int64(v.Float())
+	default:
+		//panic("Non numeric value in asInt64()")
+		return 0
+	}
+}
+
+func (h *valueHelper) asUint64(val interface{}) uint64 {
+	// Number conversion function for uint64, without error checking
+	// (implements an implicit type upgrade).
+	v := reflect.ValueOf(val)
+	switch v.Kind() {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return uint64(v.Int())
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		return v.Uint()
+	case reflect.Float32, reflect.Float64:
+		return uint64(v.Float())
+	default:
+		//panic("Non numeric value in asUint64()")
+		return 0
+	}
+}
+
+// Same for unsigned floats
+func (h *valueHelper) asFloat64(val interface{}) float64 {
+	// Number conversion function for float64, without error checking
+	// (implements an implicit type upgrade).
+	v := reflect.ValueOf(val)
+	switch v.Kind() {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return float64(v.Int())
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		return float64(v.Uint())
+	case reflect.Float32, reflect.Float64:
+		return v.Float()
+	default:
+		//panic("Non numeric value in asFloat64()")
+		return 0
+	}
+}
+
+type paramHelper struct {
+	// A collection of unexported helpers for parameters resolution
+}
+
+func (h *paramHelper) safeExpandedParamsFor(path, method, operationID string, res *Result, s *SpecValidator) (params []spec.Parameter) {
+	operation, ok := s.analyzer.OperationFor(method, path)
+	if ok {
+		// expand parameters first if necessary
+		resolvedParams := []spec.Parameter{}
+		for _, ppr := range operation.Parameters {
+			resolvedParam, red := h.resolveParam(path, method, operationID, &ppr, s)
+			res.Merge(red)
+			if resolvedParam != nil {
+				resolvedParams = append(resolvedParams, *resolvedParam)
+			}
+		}
+		// remove params with invalid expansion from Slice
+		operation.Parameters = resolvedParams
+
+		for _, ppr := range s.analyzer.SafeParamsFor(method, path,
+			func(p spec.Parameter, err error) bool {
+				// since params have already been expanded, there are few causes for error
+				res.AddErrors(someParametersBrokenMsg(path, method, operationID))
+				// original error from analyzer
+				res.AddErrors(err)
+				return true
+			}) {
+			params = append(params, ppr)
+		}
+	}
+	return
+}
+
+func (h *paramHelper) resolveParam(path, method, operationID string, param *spec.Parameter, s *SpecValidator) (*spec.Parameter, *Result) {
+	// Ensure parameter is expanded
+	var err error
+	res := new(Result)
+	isRef := param.Ref.String() != ""
+	if s.spec.SpecFilePath() == "" {
+		err = spec.ExpandParameterWithRoot(param, s.spec.Spec(), nil)
+	} else {
+		err = spec.ExpandParameter(param, s.spec.SpecFilePath())
+
+	}
+	if err != nil { // Safeguard
+		// NOTE: we may enter enter here when the whole parameter is an unresolved $ref
+		refPath := strings.Join([]string{"\"" + path + "\"", method}, ".")
+		errorHelp.addPointerError(res, err, param.Ref.String(), refPath)
+		return nil, res
+	}
+	res.Merge(h.checkExpandedParam(param, param.Name, param.In, operationID, isRef))
+	return param, res
+}
+
+func (h *paramHelper) checkExpandedParam(pr *spec.Parameter, path, in, operation string, isRef bool) *Result {
+	// Secure parameter structure after $ref resolution
+	res := new(Result)
+	simpleZero := spec.SimpleSchema{}
+	// Try to explain why... best guess
+	if pr.In == swaggerBody && (pr.SimpleSchema != simpleZero && pr.SimpleSchema.Type != objectType) {
+		if isRef {
+			// Most likely, a $ref with a sibling is an unwanted situation: in itself this is a warning...
+			// but we detect it because of the following error:
+			// schema took over Parameter for an unexplained reason
+			res.AddWarnings(refShouldNotHaveSiblingsMsg(path, operation))
+		}
+		res.AddErrors(invalidParameterDefinitionMsg(path, in, operation))
+	} else if pr.In != swaggerBody && pr.Schema != nil {
+		if isRef {
+			res.AddWarnings(refShouldNotHaveSiblingsMsg(path, operation))
+		}
+		res.AddErrors(invalidParameterDefinitionAsSchemaMsg(path, in, operation))
+	} else if (pr.In == swaggerBody && pr.Schema == nil) ||
+		(pr.In != swaggerBody && pr.SimpleSchema == simpleZero) { // Safeguard
+		// Other unexpected mishaps
+		res.AddErrors(invalidParameterDefinitionMsg(path, in, operation))
+	}
+	return res
+}
+
+type responseHelper struct {
+	// A collection of unexported helpers for response resolution
+}
+
+func (r *responseHelper) expandResponseRef(
+	response *spec.Response,
+	path string, s *SpecValidator) (*spec.Response, *Result) {
+	// Ensure response is expanded
+	var err error
+	res := new(Result)
+	if s.spec.SpecFilePath() == "" {
+		// there is no physical document to resolve $ref in response
+		err = spec.ExpandResponseWithRoot(response, s.spec.Spec(), nil)
+	} else {
+		err = spec.ExpandResponse(response, s.spec.SpecFilePath())
+	}
+	if err != nil { // Safeguard
+		// NOTE: we may enter here when the whole response is an unresolved $ref.
+		errorHelp.addPointerError(res, err, response.Ref.String(), path)
+		return nil, res
+	}
+	return response, res
+}
+
+func (r *responseHelper) responseMsgVariants(
+	responseType string,
+	responseCode int) (responseName, responseCodeAsStr string) {
+	// Path variants for messages
+	if responseType == "default" {
+		responseCodeAsStr = "default"
+		responseName = "default response"
+	} else {
+		responseCodeAsStr = strconv.Itoa(responseCode)
+		responseName = "response " + responseCodeAsStr
+	}
+	return
+}
diff --git a/go/vendor/github.com/go-openapi/validate/object_validator.go b/go/vendor/github.com/go-openapi/validate/object_validator.go
new file mode 100644
index 0000000..14e1982
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/object_validator.go
@@ -0,0 +1,264 @@
+// 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 validate
+
+import (
+	"reflect"
+	"regexp"
+	"strings"
+
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/strfmt"
+)
+
+type objectValidator struct {
+	Path                 string
+	In                   string
+	MaxProperties        *int64
+	MinProperties        *int64
+	Required             []string
+	Properties           map[string]spec.Schema
+	AdditionalProperties *spec.SchemaOrBool
+	PatternProperties    map[string]spec.Schema
+	Root                 interface{}
+	KnownFormats         strfmt.Registry
+}
+
+func (o *objectValidator) SetPath(path string) {
+	o.Path = path
+}
+
+func (o *objectValidator) Applies(source interface{}, kind reflect.Kind) bool {
+	// TODO: this should also work for structs
+	// there is a problem in the type validator where it will be unhappy about null values
+	// so that requires more testing
+	r := reflect.TypeOf(source) == specSchemaType && (kind == reflect.Map || kind == reflect.Struct)
+	debugLog("object validator for %q applies %t for %T (kind: %v)\n", o.Path, r, source, kind)
+	return r
+}
+
+func (o *objectValidator) isPropertyName() bool {
+	p := strings.Split(o.Path, ".")
+	return p[len(p)-1] == "properties" && p[len(p)-2] != "properties"
+}
+
+func (o *objectValidator) checkArrayMustHaveItems(res *Result, val map[string]interface{}) {
+	if t, typeFound := val["type"]; typeFound {
+		if tpe, ok := t.(string); ok && tpe == "array" {
+			if _, itemsKeyFound := val["items"]; !itemsKeyFound {
+				res.AddErrors(errors.Required("items", o.Path))
+			}
+		}
+	}
+}
+
+func (o *objectValidator) checkItemsMustBeTypeArray(res *Result, val map[string]interface{}) {
+	if !o.isPropertyName() {
+		if _, itemsKeyFound := val["items"]; itemsKeyFound {
+			t, typeFound := val["type"]
+			if typeFound {
+				if tpe, ok := t.(string); !ok || tpe != "array" {
+					res.AddErrors(errors.InvalidType(o.Path, o.In, "array", nil))
+				}
+			} else {
+				// there is no type
+				res.AddErrors(errors.Required("type", o.Path))
+			}
+		}
+	}
+}
+
+func (o *objectValidator) precheck(res *Result, val map[string]interface{}) {
+	o.checkArrayMustHaveItems(res, val)
+	o.checkItemsMustBeTypeArray(res, val)
+}
+
+func (o *objectValidator) Validate(data interface{}) *Result {
+	val := data.(map[string]interface{})
+	// TODO: guard against nil data
+	numKeys := int64(len(val))
+
+	if o.MinProperties != nil && numKeys < *o.MinProperties {
+		return errorHelp.sErr(errors.TooFewProperties(o.Path, o.In, *o.MinProperties))
+	}
+	if o.MaxProperties != nil && numKeys > *o.MaxProperties {
+		return errorHelp.sErr(errors.TooManyProperties(o.Path, o.In, *o.MaxProperties))
+	}
+
+	res := new(Result)
+
+	o.precheck(res, val)
+
+	// check validity of field names
+	if o.AdditionalProperties != nil && !o.AdditionalProperties.Allows {
+		// Case: additionalProperties: false
+		for k := range val {
+			_, regularProperty := o.Properties[k]
+			matched := false
+
+			for pk := range o.PatternProperties {
+				if matches, _ := regexp.MatchString(pk, k); matches {
+					matched = true
+					break
+				}
+			}
+
+			if !regularProperty && k != "$schema" && k != "id" && !matched {
+				// Special properties "$schema" and "id" are ignored
+				res.AddErrors(errors.PropertyNotAllowed(o.Path, o.In, k))
+
+				// BUG(fredbi): This section should move to a part dedicated to spec validation as
+				// it will conflict with regular schemas where a property "headers" is defined.
+
+				//
+				// Croaks a more explicit message on top of the standard one
+				// on some recognized cases.
+				//
+				// NOTE: edge cases with invalid type assertion are simply ignored here.
+				// NOTE: prefix your messages here by "IMPORTANT!" so there are not filtered
+				// by higher level callers (the IMPORTANT! tag will be eventually
+				// removed).
+				switch k {
+				// $ref is forbidden in header
+				case "headers":
+					if val[k] != nil {
+						if headers, mapOk := val[k].(map[string]interface{}); mapOk {
+							for headerKey, headerBody := range headers {
+								if headerBody != nil {
+									if headerSchema, mapOfMapOk := headerBody.(map[string]interface{}); mapOfMapOk {
+										if _, found := headerSchema["$ref"]; found {
+											var msg string
+											if refString, stringOk := headerSchema["$ref"].(string); stringOk {
+												msg = strings.Join([]string{", one may not use $ref=\":", refString, "\""}, "")
+											}
+											res.AddErrors(refNotAllowedInHeaderMsg(o.Path, headerKey, msg))
+										}
+									}
+								}
+							}
+						}
+					}
+					/*
+						case "$ref":
+							if val[k] != nil {
+								// TODO: check context of that ref: warn about siblings, check against invalid context
+							}
+					*/
+				}
+			}
+		}
+	} else {
+		// Cases: no additionalProperties (implying: true), or additionalProperties: true, or additionalProperties: { <<schema>> }
+		for key, value := range val {
+			_, regularProperty := o.Properties[key]
+
+			// Validates property against "patternProperties" if applicable
+			// BUG(fredbi): succeededOnce is always false
+
+			// NOTE: how about regular properties which do not match patternProperties?
+			matched, succeededOnce, _ := o.validatePatternProperty(key, value, res)
+
+			if !(regularProperty || matched || succeededOnce) {
+
+				// Cases: properties which are not regular properties and have not been matched by the PatternProperties validator
+				if o.AdditionalProperties != nil && o.AdditionalProperties.Schema != nil {
+					// AdditionalProperties as Schema
+					r := NewSchemaValidator(o.AdditionalProperties.Schema, o.Root, o.Path+"."+key, o.KnownFormats).Validate(value)
+					res.mergeForField(data.(map[string]interface{}), key, r)
+				} else if regularProperty && !(matched || succeededOnce) {
+					// TODO: this is dead code since regularProperty=false here
+					res.AddErrors(errors.FailedAllPatternProperties(o.Path, o.In, key))
+				}
+			}
+		}
+		// Valid cases: additionalProperties: true or undefined
+	}
+
+	createdFromDefaults := map[string]bool{}
+
+	// Property types:
+	// - regular Property
+	for pName := range o.Properties {
+		pSchema := o.Properties[pName] // one instance per iteration
+		rName := pName
+		if o.Path != "" {
+			rName = o.Path + "." + pName
+		}
+
+		// Recursively validates each property against its schema
+		if v, ok := val[pName]; ok {
+			r := NewSchemaValidator(&pSchema, o.Root, rName, o.KnownFormats).Validate(v)
+			res.mergeForField(data.(map[string]interface{}), pName, r)
+		} else if pSchema.Default != nil {
+			// If a default value is defined, creates the property from defaults
+			// NOTE: JSON schema does not enforce default values to be valid against schema. Swagger does.
+			createdFromDefaults[pName] = true
+			res.addPropertySchemata(data.(map[string]interface{}), pName, &pSchema)
+		}
+	}
+
+	// Check required properties
+	if len(o.Required) > 0 {
+		for _, k := range o.Required {
+			if _, ok := val[k]; !ok && !createdFromDefaults[k] {
+				res.AddErrors(errors.Required(o.Path+"."+k, o.In))
+				continue
+			}
+		}
+	}
+
+	// Check patternProperties
+	// TODO: it looks like we have done that twice in many cases
+	for key, value := range val {
+		_, regularProperty := o.Properties[key]
+		matched, _ /*succeededOnce*/, patterns := o.validatePatternProperty(key, value, res)
+		if !regularProperty && (matched /*|| succeededOnce*/) {
+			for _, pName := range patterns {
+				if v, ok := o.PatternProperties[pName]; ok {
+					r := NewSchemaValidator(&v, o.Root, o.Path+"."+key, o.KnownFormats).Validate(value)
+					res.mergeForField(data.(map[string]interface{}), key, r)
+				}
+			}
+		}
+	}
+	return res
+}
+
+// TODO: succeededOnce is not used anywhere
+func (o *objectValidator) validatePatternProperty(key string, value interface{}, result *Result) (bool, bool, []string) {
+	matched := false
+	succeededOnce := false
+	var patterns []string
+
+	for k, schema := range o.PatternProperties {
+		if match, _ := regexp.MatchString(k, key); match {
+			patterns = append(patterns, k)
+			matched = true
+			validator := NewSchemaValidator(&schema, o.Root, o.Path+"."+key, o.KnownFormats)
+
+			res := validator.Validate(value)
+			result.Merge(res)
+		}
+	}
+
+	// BUG(fredbi): can't get to here. Should remove dead code (commented out).
+
+	//if succeededOnce {
+	//	result.Inc()
+	//}
+
+	return matched, succeededOnce, patterns
+}
diff --git a/go/vendor/github.com/go-openapi/validate/options.go b/go/vendor/github.com/go-openapi/validate/options.go
new file mode 100644
index 0000000..deeec2f
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/options.go
@@ -0,0 +1,43 @@
+// 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 validate
+
+import "sync"
+
+// Opts specifies validation options for a SpecValidator.
+//
+// NOTE: other options might be needed, for example a go-swagger specific mode.
+type Opts struct {
+	ContinueOnErrors bool // true: continue reporting errors, even if spec is invalid
+}
+
+var (
+	defaultOpts      = Opts{ContinueOnErrors: false} // default is to stop validation on errors
+	defaultOptsMutex = &sync.Mutex{}
+)
+
+// SetContinueOnErrors sets global default behavior regarding spec validation errors reporting.
+//
+// For extended error reporting, you most likely want to set it to true.
+// For faster validation, it's better to give up early when a spec is detected as invalid: set it to false (this is the default).
+//
+// Setting this mode does NOT affect the validation status.
+//
+// NOTE: this method affects global defaults. It is not suitable for a concurrent usage.
+func SetContinueOnErrors(c bool) {
+	defer defaultOptsMutex.Unlock()
+	defaultOptsMutex.Lock()
+	defaultOpts.ContinueOnErrors = c
+}
diff --git a/go/vendor/github.com/go-openapi/validate/result.go b/go/vendor/github.com/go-openapi/validate/result.go
new file mode 100644
index 0000000..ae9b8db
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/result.go
@@ -0,0 +1,484 @@
+// 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 validate
+
+import (
+	"fmt"
+	"reflect"
+	"strings"
+
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/spec"
+)
+
+// Result represents a validation result set, composed of
+// errors and warnings.
+//
+// It is used to keep track of all detected errors and warnings during
+// the validation of a specification.
+//
+// Matchcount is used to determine
+// which errors are relevant in the case of AnyOf, OneOf
+// schema validation. Results from the validation branch
+// with most matches get eventually selected.
+//
+// TODO: keep path of key originating the error
+type Result struct {
+	Errors     []error
+	Warnings   []error
+	MatchCount int
+
+	// the object data
+	data interface{}
+
+	// Schemata for the root object
+	rootObjectSchemata schemata
+	// Schemata for object fields
+	fieldSchemata []fieldSchemata
+	// Schemata for slice items
+	itemSchemata []itemSchemata
+
+	cachedFieldSchemta map[FieldKey][]*spec.Schema
+	cachedItemSchemata map[ItemKey][]*spec.Schema
+}
+
+// FieldKey is a pair of an object and a field, usable as a key for a map.
+type FieldKey struct {
+	object reflect.Value // actually a map[string]interface{}, but the latter cannot be a key
+	field  string
+}
+
+// ItemKey is a pair of a slice and an index, usable as a key for a map.
+type ItemKey struct {
+	slice reflect.Value // actually a []interface{}, but the latter cannot be a key
+	index int
+}
+
+// NewFieldKey returns a pair of an object and field usable as a key of a map.
+func NewFieldKey(obj map[string]interface{}, field string) FieldKey {
+	return FieldKey{object: reflect.ValueOf(obj), field: field}
+}
+
+// Object returns the underlying object of this key.
+func (fk *FieldKey) Object() map[string]interface{} {
+	return fk.object.Interface().(map[string]interface{})
+}
+
+// Field returns the underlying field of this key.
+func (fk *FieldKey) Field() string {
+	return fk.field
+}
+
+// NewItemKey returns a pair of a slice and index usable as a key of a map.
+func NewItemKey(slice interface{}, i int) ItemKey {
+	return ItemKey{slice: reflect.ValueOf(slice), index: i}
+}
+
+// Slice returns the underlying slice of this key.
+func (ik *ItemKey) Slice() []interface{} {
+	return ik.slice.Interface().([]interface{})
+}
+
+// Index returns the underlying index of this key.
+func (ik *ItemKey) Index() int {
+	return ik.index
+}
+
+type fieldSchemata struct {
+	obj      map[string]interface{}
+	field    string
+	schemata schemata
+}
+
+type itemSchemata struct {
+	slice    reflect.Value
+	index    int
+	schemata schemata
+}
+
+// Merge merges this result with the other one(s), preserving match counts etc.
+func (r *Result) Merge(others ...*Result) *Result {
+	for _, other := range others {
+		if other == nil {
+			continue
+		}
+		r.mergeWithoutRootSchemata(other)
+		r.rootObjectSchemata.Append(other.rootObjectSchemata)
+	}
+	return r
+}
+
+// Data returns the original data object used for validation. Mutating this renders
+// the result invalid.
+func (r *Result) Data() interface{} {
+	return r.data
+}
+
+// RootObjectSchemata returns the schemata which apply to the root object.
+func (r *Result) RootObjectSchemata() []*spec.Schema {
+	return r.rootObjectSchemata.Slice()
+}
+
+// FieldSchemata returns the schemata which apply to fields in objects.
+func (r *Result) FieldSchemata() map[FieldKey][]*spec.Schema {
+	if r.cachedFieldSchemta != nil {
+		return r.cachedFieldSchemta
+	}
+
+	ret := make(map[FieldKey][]*spec.Schema, len(r.fieldSchemata))
+	for _, fs := range r.fieldSchemata {
+		key := NewFieldKey(fs.obj, fs.field)
+		if fs.schemata.one != nil {
+			ret[key] = append(ret[key], fs.schemata.one)
+		} else if len(fs.schemata.multiple) > 0 {
+			ret[key] = append(ret[key], fs.schemata.multiple...)
+		}
+	}
+	r.cachedFieldSchemta = ret
+	return ret
+}
+
+// ItemSchemata returns the schemata which apply to items in slices.
+func (r *Result) ItemSchemata() map[ItemKey][]*spec.Schema {
+	if r.cachedItemSchemata != nil {
+		return r.cachedItemSchemata
+	}
+
+	ret := make(map[ItemKey][]*spec.Schema, len(r.itemSchemata))
+	for _, ss := range r.itemSchemata {
+		key := NewItemKey(ss.slice, ss.index)
+		if ss.schemata.one != nil {
+			ret[key] = append(ret[key], ss.schemata.one)
+		} else if len(ss.schemata.multiple) > 0 {
+			ret[key] = append(ret[key], ss.schemata.multiple...)
+		}
+	}
+	r.cachedItemSchemata = ret
+	return ret
+}
+
+func (r *Result) resetCaches() {
+	r.cachedFieldSchemta = nil
+	r.cachedItemSchemata = nil
+}
+
+// mergeForField merges other into r, assigning other's root schemata to the given Object and field name.
+func (r *Result) mergeForField(obj map[string]interface{}, field string, other *Result) *Result {
+	if other == nil {
+		return r
+	}
+	r.mergeWithoutRootSchemata(other)
+
+	if other.rootObjectSchemata.Len() > 0 {
+		if r.fieldSchemata == nil {
+			r.fieldSchemata = make([]fieldSchemata, len(obj))
+		}
+		r.fieldSchemata = append(r.fieldSchemata, fieldSchemata{
+			obj:      obj,
+			field:    field,
+			schemata: other.rootObjectSchemata,
+		})
+	}
+
+	return r
+}
+
+// mergeForSlice merges other into r, assigning other's root schemata to the given slice and index.
+func (r *Result) mergeForSlice(slice reflect.Value, i int, other *Result) *Result {
+	if other == nil {
+		return r
+	}
+	r.mergeWithoutRootSchemata(other)
+
+	if other.rootObjectSchemata.Len() > 0 {
+		if r.itemSchemata == nil {
+			r.itemSchemata = make([]itemSchemata, slice.Len())
+		}
+		r.itemSchemata = append(r.itemSchemata, itemSchemata{
+			slice:    slice,
+			index:    i,
+			schemata: other.rootObjectSchemata,
+		})
+	}
+
+	return r
+}
+
+// addRootObjectSchemata adds the given schemata for the root object of the result.
+// The slice schemata might be reused. I.e. do not modify it after being added to a result.
+func (r *Result) addRootObjectSchemata(s *spec.Schema) {
+	r.rootObjectSchemata.Append(schemata{one: s})
+}
+
+// addPropertySchemata adds the given schemata for the object and field.
+// The slice schemata might be reused. I.e. do not modify it after being added to a result.
+func (r *Result) addPropertySchemata(obj map[string]interface{}, fld string, schema *spec.Schema) {
+	if r.fieldSchemata == nil {
+		r.fieldSchemata = make([]fieldSchemata, 0, len(obj))
+	}
+	r.fieldSchemata = append(r.fieldSchemata, fieldSchemata{obj: obj, field: fld, schemata: schemata{one: schema}})
+}
+
+// addSliceSchemata adds the given schemata for the slice and index.
+// The slice schemata might be reused. I.e. do not modify it after being added to a result.
+func (r *Result) addSliceSchemata(slice reflect.Value, i int, schema *spec.Schema) {
+	if r.itemSchemata == nil {
+		r.itemSchemata = make([]itemSchemata, 0, slice.Len())
+	}
+	r.itemSchemata = append(r.itemSchemata, itemSchemata{slice: slice, index: i, schemata: schemata{one: schema}})
+}
+
+// mergeWithoutRootSchemata merges other into r, ignoring the rootObject schemata.
+func (r *Result) mergeWithoutRootSchemata(other *Result) {
+	r.resetCaches()
+	r.AddErrors(other.Errors...)
+	r.AddWarnings(other.Warnings...)
+	r.MatchCount += other.MatchCount
+
+	if other.fieldSchemata != nil {
+		if r.fieldSchemata == nil {
+			r.fieldSchemata = other.fieldSchemata
+		} else {
+			for _, x := range other.fieldSchemata {
+				r.fieldSchemata = append(r.fieldSchemata, x)
+			}
+		}
+	}
+
+	if other.itemSchemata != nil {
+		if r.itemSchemata == nil {
+			r.itemSchemata = other.itemSchemata
+		} else {
+			for _, x := range other.itemSchemata {
+				r.itemSchemata = append(r.itemSchemata, x)
+			}
+		}
+	}
+}
+
+// MergeAsErrors merges this result with the other one(s), preserving match counts etc.
+//
+// Warnings from input are merged as Errors in the returned merged Result.
+func (r *Result) MergeAsErrors(others ...*Result) *Result {
+	for _, other := range others {
+		if other != nil {
+			r.resetCaches()
+			r.AddErrors(other.Errors...)
+			r.AddErrors(other.Warnings...)
+			r.MatchCount += other.MatchCount
+		}
+	}
+	return r
+}
+
+// MergeAsWarnings merges this result with the other one(s), preserving match counts etc.
+//
+// Errors from input are merged as Warnings in the returned merged Result.
+func (r *Result) MergeAsWarnings(others ...*Result) *Result {
+	for _, other := range others {
+		if other != nil {
+			r.resetCaches()
+			r.AddWarnings(other.Errors...)
+			r.AddWarnings(other.Warnings...)
+			r.MatchCount += other.MatchCount
+		}
+	}
+	return r
+}
+
+// AddErrors adds errors to this validation result (if not already reported).
+//
+// Since the same check may be passed several times while exploring the
+// spec structure (via $ref, ...) reported messages are kept
+// unique.
+func (r *Result) AddErrors(errors ...error) {
+	for _, e := range errors {
+		found := false
+		if e != nil {
+			for _, isReported := range r.Errors {
+				if e.Error() == isReported.Error() {
+					found = true
+					break
+				}
+			}
+			if !found {
+				r.Errors = append(r.Errors, e)
+			}
+		}
+	}
+}
+
+// AddWarnings adds warnings to this validation result (if not already reported).
+func (r *Result) AddWarnings(warnings ...error) {
+	for _, e := range warnings {
+		found := false
+		if e != nil {
+			for _, isReported := range r.Warnings {
+				if e.Error() == isReported.Error() {
+					found = true
+					break
+				}
+			}
+			if !found {
+				r.Warnings = append(r.Warnings, e)
+			}
+		}
+	}
+}
+
+func (r *Result) keepRelevantErrors() *Result {
+	// TODO: this one is going to disapear...
+	// keepRelevantErrors strips a result from standard errors and keeps
+	// the ones which are supposedly more accurate.
+	//
+	// The original result remains unaffected (creates a new instance of Result).
+	// This method is used to work around the "matchCount" filter which would otherwise
+	// strip our result from some accurate error reporting from lower level validators.
+	//
+	// NOTE: this implementation with a placeholder (IMPORTANT!) is neither clean nor
+	// very efficient. On the other hand, relying on go-openapi/errors to manipulate
+	// codes would require to change a lot here. So, for the moment, let's go with
+	// placeholders.
+	strippedErrors := []error{}
+	for _, e := range r.Errors {
+		if strings.HasPrefix(e.Error(), "IMPORTANT!") {
+			strippedErrors = append(strippedErrors, fmt.Errorf(strings.TrimPrefix(e.Error(), "IMPORTANT!")))
+		}
+	}
+	strippedWarnings := []error{}
+	for _, e := range r.Warnings {
+		if strings.HasPrefix(e.Error(), "IMPORTANT!") {
+			strippedWarnings = append(strippedWarnings, fmt.Errorf(strings.TrimPrefix(e.Error(), "IMPORTANT!")))
+		}
+	}
+	strippedResult := new(Result)
+	strippedResult.Errors = strippedErrors
+	strippedResult.Warnings = strippedWarnings
+	return strippedResult
+}
+
+// IsValid returns true when this result is valid.
+//
+// Returns true on a nil *Result.
+func (r *Result) IsValid() bool {
+	if r == nil {
+		return true
+	}
+	return len(r.Errors) == 0
+}
+
+// HasErrors returns true when this result is invalid.
+//
+// Returns false on a nil *Result.
+func (r *Result) HasErrors() bool {
+	if r == nil {
+		return false
+	}
+	return !r.IsValid()
+}
+
+// HasWarnings returns true when this result contains warnings.
+//
+// Returns false on a nil *Result.
+func (r *Result) HasWarnings() bool {
+	if r == nil {
+		return false
+	}
+	return len(r.Warnings) > 0
+}
+
+// HasErrorsOrWarnings returns true when this result contains
+// either errors or warnings.
+//
+// Returns false on a nil *Result.
+func (r *Result) HasErrorsOrWarnings() bool {
+	if r == nil {
+		return false
+	}
+	return len(r.Errors) > 0 || len(r.Warnings) > 0
+}
+
+// Inc increments the match count
+func (r *Result) Inc() {
+	r.MatchCount++
+}
+
+// AsError renders this result as an error interface
+//
+// TODO: reporting / pretty print with path ordered and indented
+func (r *Result) AsError() error {
+	if r.IsValid() {
+		return nil
+	}
+	return errors.CompositeValidationError(r.Errors...)
+}
+
+// schemata is an arbitrary number of schemata. It does a distinction between zero,
+// one and many schemata to avoid slice allocations.
+type schemata struct {
+	// one is set if there is exactly one schema. In that case multiple must be nil.
+	one *spec.Schema
+	// multiple is an arbitrary number of schemas. If it is set, one must be nil.
+	multiple []*spec.Schema
+}
+
+func (s *schemata) Len() int {
+	if s.one != nil {
+		return 1
+	}
+	return len(s.multiple)
+}
+
+func (s *schemata) Slice() []*spec.Schema {
+	if s == nil {
+		return nil
+	}
+	if s.one != nil {
+		return []*spec.Schema{s.one}
+	}
+	return s.multiple
+}
+
+// appendSchemata appends the schemata in other to s. It mutated s in-place.
+func (s *schemata) Append(other schemata) {
+	if other.one == nil && len(other.multiple) == 0 {
+		return
+	}
+	if s.one == nil && len(s.multiple) == 0 {
+		*s = other
+		return
+	}
+
+	if s.one != nil {
+		if other.one != nil {
+			s.multiple = []*spec.Schema{s.one, other.one}
+		} else {
+			t := make([]*spec.Schema, 0, 1+len(other.multiple))
+			s.multiple = append(append(t, s.one), other.multiple...)
+		}
+		s.one = nil
+	} else {
+		if other.one != nil {
+			s.multiple = append(s.multiple, other.one)
+		} else {
+			if cap(s.multiple) >= len(s.multiple)+len(other.multiple) {
+				s.multiple = append(s.multiple, other.multiple...)
+			} else {
+				t := make([]*spec.Schema, 0, len(s.multiple)+len(other.multiple))
+				s.multiple = append(append(t, s.multiple...), other.multiple...)
+			}
+		}
+	}
+}
diff --git a/go/vendor/github.com/go-openapi/validate/rexp.go b/go/vendor/github.com/go-openapi/validate/rexp.go
new file mode 100644
index 0000000..5a08243
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/rexp.go
@@ -0,0 +1,71 @@
+// 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 validate
+
+import (
+	re "regexp"
+	"sync"
+	"sync/atomic"
+)
+
+// Cache for compiled regular expressions
+var (
+	cacheMutex = &sync.Mutex{}
+	reDict     = atomic.Value{} //map[string]*re.Regexp
+)
+
+func compileRegexp(pattern string) (*re.Regexp, error) {
+	if cache, ok := reDict.Load().(map[string]*re.Regexp); ok {
+		if r := cache[pattern]; r != nil {
+			return r, nil
+		}
+	}
+
+	r, err := re.Compile(pattern)
+	if err != nil {
+		return nil, err
+	}
+	cacheRegexp(r)
+	return r, nil
+}
+
+func mustCompileRegexp(pattern string) *re.Regexp {
+	if cache, ok := reDict.Load().(map[string]*re.Regexp); ok {
+		if r := cache[pattern]; r != nil {
+			return r
+		}
+	}
+
+	r := re.MustCompile(pattern)
+	cacheRegexp(r)
+	return r
+}
+
+func cacheRegexp(r *re.Regexp) {
+	cacheMutex.Lock()
+	defer cacheMutex.Unlock()
+
+	if cache, ok := reDict.Load().(map[string]*re.Regexp); !ok || cache[r.String()] == nil {
+		newCache := map[string]*re.Regexp{
+			r.String(): r,
+		}
+
+		for k, v := range cache {
+			newCache[k] = v
+		}
+
+		reDict.Store(newCache)
+	}
+}
diff --git a/go/vendor/github.com/go-openapi/validate/schema.go b/go/vendor/github.com/go-openapi/validate/schema.go
new file mode 100644
index 0000000..860b30e
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/schema.go
@@ -0,0 +1,248 @@
+// 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 validate
+
+import (
+	"encoding/json"
+	"reflect"
+
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/strfmt"
+	"github.com/go-openapi/swag"
+)
+
+var (
+	specSchemaType    = reflect.TypeOf(&spec.Schema{})
+	specParameterType = reflect.TypeOf(&spec.Parameter{})
+	specItemsType     = reflect.TypeOf(&spec.Items{})
+	specHeaderType    = reflect.TypeOf(&spec.Header{})
+)
+
+// SchemaValidator validates data against a JSON schema
+type SchemaValidator struct {
+	Path         string
+	in           string
+	Schema       *spec.Schema
+	validators   []valueValidator
+	Root         interface{}
+	KnownFormats strfmt.Registry
+}
+
+// AgainstSchema validates the specified data against the provided schema, using a registry of supported formats.
+//
+// When no pre-parsed *spec.Schema structure is provided, it uses a JSON schema as default. See example.
+func AgainstSchema(schema *spec.Schema, data interface{}, formats strfmt.Registry) error {
+	res := NewSchemaValidator(schema, nil, "", formats).Validate(data)
+	if res.HasErrors() {
+		return errors.CompositeValidationError(res.Errors...)
+	}
+	return nil
+}
+
+// NewSchemaValidator creates a new schema validator.
+//
+// Panics if the provided schema is invalid.
+func NewSchemaValidator(schema *spec.Schema, rootSchema interface{}, root string, formats strfmt.Registry) *SchemaValidator {
+	if schema == nil {
+		return nil
+	}
+
+	if rootSchema == nil {
+		rootSchema = schema
+	}
+
+	if schema.ID != "" || schema.Ref.String() != "" || schema.Ref.IsRoot() {
+		err := spec.ExpandSchema(schema, rootSchema, nil)
+		if err != nil {
+			msg := invalidSchemaProvidedMsg(err).Error()
+			panic(msg)
+		}
+	}
+	s := SchemaValidator{Path: root, in: "body", Schema: schema, Root: rootSchema, KnownFormats: formats}
+	s.validators = []valueValidator{
+		s.typeValidator(),
+		s.schemaPropsValidator(),
+		s.stringValidator(),
+		s.formatValidator(),
+		s.numberValidator(),
+		s.sliceValidator(),
+		s.commonValidator(),
+		s.objectValidator(),
+	}
+	return &s
+}
+
+// SetPath sets the path for this schema valdiator
+func (s *SchemaValidator) SetPath(path string) {
+	s.Path = path
+}
+
+// Applies returns true when this schema validator applies
+func (s *SchemaValidator) Applies(source interface{}, kind reflect.Kind) bool {
+	_, ok := source.(*spec.Schema)
+	return ok
+}
+
+// Validate validates the data against the schema
+func (s *SchemaValidator) Validate(data interface{}) *Result {
+	result := &Result{data: data}
+	if s == nil {
+		return result
+	}
+	if s.Schema != nil {
+		result.addRootObjectSchemata(s.Schema)
+	}
+
+	if data == nil {
+		result.Merge(s.validators[0].Validate(data)) // type validator
+		result.Merge(s.validators[6].Validate(data)) // common validator
+		return result
+	}
+
+	tpe := reflect.TypeOf(data)
+	kind := tpe.Kind()
+	for kind == reflect.Ptr {
+		tpe = tpe.Elem()
+		kind = tpe.Kind()
+	}
+	d := data
+
+	if kind == reflect.Struct {
+		// NOTE: since reflect retrieves the true nature of types
+		// this means that all strfmt types passed here (e.g. strfmt.Datetime, etc..)
+		// are converted here to strings, and structs are systematically converted
+		// to map[string]interface{}.
+		d = swag.ToDynamicJSON(data)
+	}
+
+	// TODO: this part should be handed over to type validator
+	// Handle special case of json.Number data (number marshalled as string)
+	isnumber := s.Schema.Type.Contains("number") || s.Schema.Type.Contains("integer")
+	if num, ok := data.(json.Number); ok && isnumber {
+		if s.Schema.Type.Contains("integer") { // avoid lossy conversion
+			in, erri := num.Int64()
+			if erri != nil {
+				result.AddErrors(invalidTypeConversionMsg(s.Path, erri))
+				result.Inc()
+				return result
+			}
+			d = in
+		} else {
+			nf, errf := num.Float64()
+			if errf != nil {
+				result.AddErrors(invalidTypeConversionMsg(s.Path, errf))
+				result.Inc()
+				return result
+			}
+			d = nf
+		}
+
+		tpe = reflect.TypeOf(d)
+		kind = tpe.Kind()
+	}
+
+	for _, v := range s.validators {
+		if !v.Applies(s.Schema, kind) {
+			debugLog("%T does not apply for %v", v, kind)
+			continue
+		}
+
+		err := v.Validate(d)
+		result.Merge(err)
+		result.Inc()
+	}
+	result.Inc()
+
+	return result
+}
+
+func (s *SchemaValidator) typeValidator() valueValidator {
+	return &typeValidator{Type: s.Schema.Type, Format: s.Schema.Format, In: s.in, Path: s.Path}
+}
+
+func (s *SchemaValidator) commonValidator() valueValidator {
+	return &basicCommonValidator{
+		Path: s.Path,
+		In:   s.in,
+		Enum: s.Schema.Enum,
+	}
+}
+
+func (s *SchemaValidator) sliceValidator() valueValidator {
+	return &schemaSliceValidator{
+		Path:            s.Path,
+		In:              s.in,
+		MaxItems:        s.Schema.MaxItems,
+		MinItems:        s.Schema.MinItems,
+		UniqueItems:     s.Schema.UniqueItems,
+		AdditionalItems: s.Schema.AdditionalItems,
+		Items:           s.Schema.Items,
+		Root:            s.Root,
+		KnownFormats:    s.KnownFormats,
+	}
+}
+
+func (s *SchemaValidator) numberValidator() valueValidator {
+	return &numberValidator{
+		Path:             s.Path,
+		In:               s.in,
+		Default:          s.Schema.Default,
+		MultipleOf:       s.Schema.MultipleOf,
+		Maximum:          s.Schema.Maximum,
+		ExclusiveMaximum: s.Schema.ExclusiveMaximum,
+		Minimum:          s.Schema.Minimum,
+		ExclusiveMinimum: s.Schema.ExclusiveMinimum,
+	}
+}
+
+func (s *SchemaValidator) stringValidator() valueValidator {
+	return &stringValidator{
+		Path:      s.Path,
+		In:        s.in,
+		MaxLength: s.Schema.MaxLength,
+		MinLength: s.Schema.MinLength,
+		Pattern:   s.Schema.Pattern,
+	}
+}
+
+func (s *SchemaValidator) formatValidator() valueValidator {
+	return &formatValidator{
+		Path:         s.Path,
+		In:           s.in,
+		Format:       s.Schema.Format,
+		KnownFormats: s.KnownFormats,
+	}
+}
+
+func (s *SchemaValidator) schemaPropsValidator() valueValidator {
+	sch := s.Schema
+	return newSchemaPropsValidator(s.Path, s.in, sch.AllOf, sch.OneOf, sch.AnyOf, sch.Not, sch.Dependencies, s.Root, s.KnownFormats)
+}
+
+func (s *SchemaValidator) objectValidator() valueValidator {
+	return &objectValidator{
+		Path:                 s.Path,
+		In:                   s.in,
+		MaxProperties:        s.Schema.MaxProperties,
+		MinProperties:        s.Schema.MinProperties,
+		Required:             s.Schema.Required,
+		Properties:           s.Schema.Properties,
+		AdditionalProperties: s.Schema.AdditionalProperties,
+		PatternProperties:    s.Schema.PatternProperties,
+		Root:                 s.Root,
+		KnownFormats:         s.KnownFormats,
+	}
+}
diff --git a/go/vendor/github.com/go-openapi/validate/schema_messages.go b/go/vendor/github.com/go-openapi/validate/schema_messages.go
new file mode 100644
index 0000000..786e2e3
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/schema_messages.go
@@ -0,0 +1,78 @@
+// 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 validate
+
+import (
+	"github.com/go-openapi/errors"
+)
+
+// Error messages related to schema validation and returned as results.
+const (
+	// ArrayDoesNotAllowAdditionalItemsError when an additionalItems construct is not verified by the array values provided.
+	//
+	// TODO: should move to package go-openapi/errors
+	ArrayDoesNotAllowAdditionalItemsError = "array doesn't allow for additional items"
+
+	// HasDependencyError indicates that a dependencies construct was not verified
+	HasDependencyError = "%q has a dependency on %s"
+
+	// InvalidSchemaProvidedError indicates that the schema provided to validate a value cannot be properly compiled
+	InvalidSchemaProvidedError = "Invalid schema provided to SchemaValidator: %v"
+
+	// InvalidTypeConversionError indicates that a numerical conversion for the given type could not be carried on
+	InvalidTypeConversionError = "invalid type conversion in %s: %v "
+
+	// MustValidateAtLeastOneSchemaError indicates that in a AnyOf construct, none of the schema constraints specified were verified
+	MustValidateAtLeastOneSchemaError = "%q must validate at least one schema (anyOf)"
+
+	// MustValidateOnlyOneSchemaError indicates that in a OneOf construct, either none of the schema constraints specified were verified, or several were
+	MustValidateOnlyOneSchemaError = "%q must validate one and only one schema (oneOf). %s"
+
+	// MustValidateAllSchemasError indicates that in a AllOf construct, at least one of the schema constraints specified were not verified
+	//
+	// TODO: punctuation in message
+	MustValidateAllSchemasError = "%q must validate all the schemas (allOf)%s"
+
+	// MustNotValidateSchemaError indicates that in a Not construct, the schema constraint specified was verified
+	MustNotValidateSchemaError = "%q must not validate the schema (not)"
+)
+
+// Warning messages related to schema validation and returned as results
+const ()
+
+func invalidSchemaProvidedMsg(err error) errors.Error {
+	return errors.New(InternalErrorCode, InvalidSchemaProvidedError, err)
+}
+func invalidTypeConversionMsg(path string, err error) errors.Error {
+	return errors.New(errors.CompositeErrorCode, InvalidTypeConversionError, path, err)
+}
+func mustValidateOnlyOneSchemaMsg(path, additionalMsg string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, MustValidateOnlyOneSchemaError, path, additionalMsg)
+}
+func mustValidateAtLeastOneSchemaMsg(path string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, MustValidateAtLeastOneSchemaError, path)
+}
+func mustValidateAllSchemasMsg(path, additionalMsg string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, MustValidateAllSchemasError, path, additionalMsg)
+}
+func mustNotValidatechemaMsg(path string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, MustNotValidateSchemaError, path)
+}
+func hasADependencyMsg(path, depkey string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, HasDependencyError, path, depkey)
+}
+func arrayDoesNotAllowAdditionalItemsMsg() errors.Error {
+	return errors.New(errors.CompositeErrorCode, ArrayDoesNotAllowAdditionalItemsError)
+}
diff --git a/go/vendor/github.com/go-openapi/validate/schema_props.go b/go/vendor/github.com/go-openapi/validate/schema_props.go
new file mode 100644
index 0000000..c3dfa79
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/schema_props.go
@@ -0,0 +1,231 @@
+// 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 validate
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/strfmt"
+)
+
+type schemaPropsValidator struct {
+	Path            string
+	In              string
+	AllOf           []spec.Schema
+	OneOf           []spec.Schema
+	AnyOf           []spec.Schema
+	Not             *spec.Schema
+	Dependencies    spec.Dependencies
+	anyOfValidators []SchemaValidator
+	allOfValidators []SchemaValidator
+	oneOfValidators []SchemaValidator
+	notValidator    *SchemaValidator
+	Root            interface{}
+	KnownFormats    strfmt.Registry
+}
+
+func (s *schemaPropsValidator) SetPath(path string) {
+	s.Path = path
+}
+
+func newSchemaPropsValidator(path string, in string, allOf, oneOf, anyOf []spec.Schema, not *spec.Schema, deps spec.Dependencies, root interface{}, formats strfmt.Registry) *schemaPropsValidator {
+	anyValidators := make([]SchemaValidator, 0, len(anyOf))
+	for _, v := range anyOf {
+		anyValidators = append(anyValidators, *NewSchemaValidator(&v, root, path, formats))
+	}
+	allValidators := make([]SchemaValidator, 0, len(allOf))
+	for _, v := range allOf {
+		allValidators = append(allValidators, *NewSchemaValidator(&v, root, path, formats))
+	}
+	oneValidators := make([]SchemaValidator, 0, len(oneOf))
+	for _, v := range oneOf {
+		oneValidators = append(oneValidators, *NewSchemaValidator(&v, root, path, formats))
+	}
+
+	var notValidator *SchemaValidator
+	if not != nil {
+		notValidator = NewSchemaValidator(not, root, path, formats)
+	}
+
+	return &schemaPropsValidator{
+		Path:            path,
+		In:              in,
+		AllOf:           allOf,
+		OneOf:           oneOf,
+		AnyOf:           anyOf,
+		Not:             not,
+		Dependencies:    deps,
+		anyOfValidators: anyValidators,
+		allOfValidators: allValidators,
+		oneOfValidators: oneValidators,
+		notValidator:    notValidator,
+		Root:            root,
+		KnownFormats:    formats,
+	}
+}
+
+func (s *schemaPropsValidator) Applies(source interface{}, kind reflect.Kind) bool {
+	r := reflect.TypeOf(source) == specSchemaType
+	debugLog("schema props validator for %q applies %t for %T (kind: %v)\n", s.Path, r, source, kind)
+	return r
+}
+
+func (s *schemaPropsValidator) Validate(data interface{}) *Result {
+	mainResult := new(Result)
+
+	// Intermediary error results
+
+	// IMPORTANT! messages from underlying validators
+	keepResultAnyOf := new(Result)
+	keepResultOneOf := new(Result)
+	keepResultAllOf := new(Result)
+
+	// Validates at least one in anyOf schemas
+	var firstSuccess *Result
+	if len(s.anyOfValidators) > 0 {
+		var bestFailures *Result
+		succeededOnce := false
+		for _, anyOfSchema := range s.anyOfValidators {
+			result := anyOfSchema.Validate(data)
+			// We keep inner IMPORTANT! errors no matter what MatchCount tells us
+			keepResultAnyOf.Merge(result.keepRelevantErrors())
+			if result.IsValid() {
+				bestFailures = nil
+				succeededOnce = true
+				if firstSuccess == nil {
+					firstSuccess = result
+				}
+				keepResultAnyOf = new(Result)
+				break
+			}
+			// MatchCount is used to select errors from the schema with most positive checks
+			if bestFailures == nil || result.MatchCount > bestFailures.MatchCount {
+				bestFailures = result
+			}
+		}
+
+		if !succeededOnce {
+			mainResult.AddErrors(mustValidateAtLeastOneSchemaMsg(s.Path))
+		}
+		if bestFailures != nil {
+			mainResult.Merge(bestFailures)
+		} else if firstSuccess != nil {
+			mainResult.Merge(firstSuccess)
+		}
+	}
+
+	// Validates exactly one in oneOf schemas
+	if len(s.oneOfValidators) > 0 {
+		var bestFailures *Result
+		var firstSuccess *Result
+		validated := 0
+
+		for _, oneOfSchema := range s.oneOfValidators {
+			result := oneOfSchema.Validate(data)
+			// We keep inner IMPORTANT! errors no matter what MatchCount tells us
+			keepResultOneOf.Merge(result.keepRelevantErrors())
+			if result.IsValid() {
+				validated++
+				bestFailures = nil
+				if firstSuccess == nil {
+					firstSuccess = result
+				}
+				keepResultOneOf = new(Result)
+				continue
+			}
+			// MatchCount is used to select errors from the schema with most positive checks
+			if validated == 0 && (bestFailures == nil || result.MatchCount > bestFailures.MatchCount) {
+				bestFailures = result
+			}
+		}
+
+		if validated != 1 {
+			additionalMsg := ""
+			if validated == 0 {
+				additionalMsg = "Found none valid"
+			} else {
+				additionalMsg = fmt.Sprintf("Found %d valid alternatives", validated)
+			}
+
+			mainResult.AddErrors(mustValidateOnlyOneSchemaMsg(s.Path, additionalMsg))
+			if bestFailures != nil {
+				mainResult.Merge(bestFailures)
+			}
+		} else if firstSuccess != nil {
+			mainResult.Merge(firstSuccess)
+		}
+	}
+
+	// Validates all of allOf schemas
+	if len(s.allOfValidators) > 0 {
+		validated := 0
+
+		for _, allOfSchema := range s.allOfValidators {
+			result := allOfSchema.Validate(data)
+			// We keep inner IMPORTANT! errors no matter what MatchCount tells us
+			keepResultAllOf.Merge(result.keepRelevantErrors())
+			//keepResultAllOf.Merge(result)
+			if result.IsValid() {
+				validated++
+			}
+			mainResult.Merge(result)
+		}
+
+		if validated != len(s.allOfValidators) {
+			additionalMsg := ""
+			if validated == 0 {
+				additionalMsg = ". None validated"
+			}
+
+			mainResult.AddErrors(mustValidateAllSchemasMsg(s.Path, additionalMsg))
+		}
+	}
+
+	if s.notValidator != nil {
+		result := s.notValidator.Validate(data)
+		// We keep inner IMPORTANT! errors no matter what MatchCount tells us
+		if result.IsValid() {
+			mainResult.AddErrors(mustNotValidatechemaMsg(s.Path))
+		}
+	}
+
+	if s.Dependencies != nil && len(s.Dependencies) > 0 && reflect.TypeOf(data).Kind() == reflect.Map {
+		val := data.(map[string]interface{})
+		for key := range val {
+			if dep, ok := s.Dependencies[key]; ok {
+
+				if dep.Schema != nil {
+					mainResult.Merge(NewSchemaValidator(dep.Schema, s.Root, s.Path+"."+key, s.KnownFormats).Validate(data))
+					continue
+				}
+
+				if len(dep.Property) > 0 {
+					for _, depKey := range dep.Property {
+						if _, ok := val[depKey]; !ok {
+							mainResult.AddErrors(hasADependencyMsg(s.Path, depKey))
+						}
+					}
+				}
+			}
+		}
+	}
+
+	mainResult.Inc()
+	// In the end we retain best failures for schema validation
+	// plus, if any, composite errors which may explain special cases (tagged as IMPORTANT!).
+	return mainResult.Merge(keepResultAllOf, keepResultOneOf, keepResultAnyOf)
+}
diff --git a/go/vendor/github.com/go-openapi/validate/slice_validator.go b/go/vendor/github.com/go-openapi/validate/slice_validator.go
new file mode 100644
index 0000000..6e61594
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/slice_validator.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 validate
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/strfmt"
+)
+
+type schemaSliceValidator struct {
+	Path            string
+	In              string
+	MaxItems        *int64
+	MinItems        *int64
+	UniqueItems     bool
+	AdditionalItems *spec.SchemaOrBool
+	Items           *spec.SchemaOrArray
+	Root            interface{}
+	KnownFormats    strfmt.Registry
+}
+
+func (s *schemaSliceValidator) SetPath(path string) {
+	s.Path = path
+}
+
+func (s *schemaSliceValidator) Applies(source interface{}, kind reflect.Kind) bool {
+	_, ok := source.(*spec.Schema)
+	r := ok && kind == reflect.Slice
+	return r
+}
+
+func (s *schemaSliceValidator) Validate(data interface{}) *Result {
+	result := new(Result)
+	if data == nil {
+		return result
+	}
+	val := reflect.ValueOf(data)
+	size := val.Len()
+
+	if s.Items != nil && s.Items.Schema != nil {
+		validator := NewSchemaValidator(s.Items.Schema, s.Root, s.Path, s.KnownFormats)
+		for i := 0; i < size; i++ {
+			validator.SetPath(fmt.Sprintf("%s.%d", s.Path, i))
+			value := val.Index(i)
+			result.mergeForSlice(val, i, validator.Validate(value.Interface()))
+		}
+	}
+
+	itemsSize := 0
+	if s.Items != nil && len(s.Items.Schemas) > 0 {
+		itemsSize = len(s.Items.Schemas)
+		for i := 0; i < itemsSize; i++ {
+			validator := NewSchemaValidator(&s.Items.Schemas[i], s.Root, fmt.Sprintf("%s.%d", s.Path, i), s.KnownFormats)
+			if val.Len() <= i {
+				break
+			}
+			result.mergeForSlice(val, int(i), validator.Validate(val.Index(i).Interface()))
+		}
+	}
+	if s.AdditionalItems != nil && itemsSize < size {
+		if s.Items != nil && len(s.Items.Schemas) > 0 && !s.AdditionalItems.Allows {
+			result.AddErrors(arrayDoesNotAllowAdditionalItemsMsg())
+		}
+		if s.AdditionalItems.Schema != nil {
+			for i := itemsSize; i < size-itemsSize+1; i++ {
+				validator := NewSchemaValidator(s.AdditionalItems.Schema, s.Root, fmt.Sprintf("%s.%d", s.Path, i), s.KnownFormats)
+				result.mergeForSlice(val, int(i), validator.Validate(val.Index(int(i)).Interface()))
+			}
+		}
+	}
+
+	if s.MinItems != nil {
+		if err := MinItems(s.Path, s.In, int64(size), *s.MinItems); err != nil {
+			result.AddErrors(err)
+		}
+	}
+	if s.MaxItems != nil {
+		if err := MaxItems(s.Path, s.In, int64(size), *s.MaxItems); err != nil {
+			result.AddErrors(err)
+		}
+	}
+	if s.UniqueItems {
+		if err := UniqueItems(s.Path, s.In, val.Interface()); err != nil {
+			result.AddErrors(err)
+		}
+	}
+	result.Inc()
+	return result
+}
diff --git a/go/vendor/github.com/go-openapi/validate/spec.go b/go/vendor/github.com/go-openapi/validate/spec.go
new file mode 100644
index 0000000..08ccd22
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/spec.go
@@ -0,0 +1,777 @@
+// 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 validate
+
+import (
+	"encoding/json"
+	"fmt"
+	"sort"
+	"strings"
+
+	"github.com/go-openapi/analysis"
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/jsonpointer"
+	"github.com/go-openapi/loads"
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/strfmt"
+)
+
+// Spec validates an OpenAPI 2.0 specification document.
+//
+// Returns an error flattening in a single standard error, all validation messages.
+//
+//  - TODO: $ref should not have siblings
+//  - TODO: make sure documentation reflects all checks and warnings
+//  - TODO: check on discriminators
+//  - TODO: explicit message on unsupported keywords (better than "forbidden property"...)
+//  - TODO: full list of unresolved refs
+//  - TODO: validate numeric constraints (issue#581): this should be handled like defaults and examples
+//  - TODO: option to determine if we validate for go-swagger or in a more general context
+//  - TODO: check on required properties to support anyOf, allOf, oneOf
+//
+// NOTE: SecurityScopes are maps: no need to check uniqueness
+//
+func Spec(doc *loads.Document, formats strfmt.Registry) error {
+	errs, _ /*warns*/ := NewSpecValidator(doc.Schema(), formats).Validate(doc)
+	if errs.HasErrors() {
+		return errors.CompositeValidationError(errs.Errors...)
+	}
+	return nil
+}
+
+// SpecValidator validates a swagger 2.0 spec
+type SpecValidator struct {
+	schema       *spec.Schema // swagger 2.0 schema
+	spec         *loads.Document
+	analyzer     *analysis.Spec
+	expanded     *loads.Document
+	KnownFormats strfmt.Registry
+	Options      Opts // validation options
+}
+
+// NewSpecValidator creates a new swagger spec validator instance
+func NewSpecValidator(schema *spec.Schema, formats strfmt.Registry) *SpecValidator {
+	return &SpecValidator{
+		schema:       schema,
+		KnownFormats: formats,
+		Options:      defaultOpts,
+	}
+}
+
+// Validate validates the swagger spec
+func (s *SpecValidator) Validate(data interface{}) (errs *Result, warnings *Result) {
+	var sd *loads.Document
+	errs = new(Result)
+
+	switch v := data.(type) {
+	case *loads.Document:
+		sd = v
+	}
+	if sd == nil {
+		errs.AddErrors(invalidDocumentMsg())
+		return
+	}
+	s.spec = sd
+	s.analyzer = analysis.New(sd.Spec())
+
+	warnings = new(Result)
+
+	// Swagger schema validator
+	schv := NewSchemaValidator(s.schema, nil, "", s.KnownFormats)
+	var obj interface{}
+
+	// Raw spec unmarshalling errors
+	if err := json.Unmarshal(sd.Raw(), &obj); err != nil {
+		// NOTE: under normal conditions, the *load.Document has been already unmarshalled
+		// So this one is just a paranoid check on the behavior of the spec package
+		panic(InvalidDocumentError)
+	}
+
+	defer func() {
+		// errs holds all errors and warnings,
+		// warnings only warnings
+		errs.MergeAsWarnings(warnings)
+		warnings.AddErrors(errs.Warnings...)
+	}()
+
+	errs.Merge(schv.Validate(obj)) // error -
+	// There may be a point in continuing to try and determine more accurate errors
+	if !s.Options.ContinueOnErrors && errs.HasErrors() {
+		return // no point in continuing
+	}
+
+	errs.Merge(s.validateReferencesValid()) // error -
+	// There may be a point in continuing to try and determine more accurate errors
+	if !s.Options.ContinueOnErrors && errs.HasErrors() {
+		return // no point in continuing
+	}
+
+	errs.Merge(s.validateDuplicateOperationIDs())
+	errs.Merge(s.validateDuplicatePropertyNames()) // error -
+	errs.Merge(s.validateParameters())             // error -
+	errs.Merge(s.validateItems())                  // error -
+
+	// Properties in required definition MUST validate their schema
+	// Properties SHOULD NOT be declared as both required and readOnly (warning)
+	errs.Merge(s.validateRequiredDefinitions()) // error and warning
+
+	// There may be a point in continuing to try and determine more accurate errors
+	if !s.Options.ContinueOnErrors && errs.HasErrors() {
+		return // no point in continuing
+	}
+
+	// Values provided as default MUST validate their schema
+	df := &defaultValidator{SpecValidator: s}
+	errs.Merge(df.Validate())
+
+	// Values provided as examples MUST validate their schema
+	// Value provided as examples in a response without schema generate a warning
+	// Known limitations: examples in responses for mime type not application/json are ignored (warning)
+	ex := &exampleValidator{SpecValidator: s}
+	errs.Merge(ex.Validate())
+
+	errs.Merge(s.validateNonEmptyPathParamNames())
+
+	//errs.Merge(s.validateRefNoSibling()) // warning only
+	errs.Merge(s.validateReferenced()) // warning only
+
+	return
+}
+
+func (s *SpecValidator) validateNonEmptyPathParamNames() *Result {
+	res := new(Result)
+	if s.spec.Spec().Paths == nil {
+		// There is no Paths object: error
+		res.AddErrors(noValidPathMsg())
+	} else {
+		if s.spec.Spec().Paths.Paths == nil {
+			// Paths may be empty: warning
+			res.AddWarnings(noValidPathMsg())
+		} else {
+			for k := range s.spec.Spec().Paths.Paths {
+				if strings.Contains(k, "{}") {
+					res.AddErrors(emptyPathParameterMsg(k))
+				}
+			}
+		}
+	}
+	return res
+}
+
+func (s *SpecValidator) validateDuplicateOperationIDs() *Result {
+	// OperationID, if specified, must be unique across the board
+	res := new(Result)
+	known := make(map[string]int)
+	for _, v := range s.analyzer.OperationIDs() {
+		if v != "" {
+			known[v]++
+		}
+	}
+	for k, v := range known {
+		if v > 1 {
+			res.AddErrors(nonUniqueOperationIDMsg(k, v))
+		}
+	}
+	return res
+}
+
+type dupProp struct {
+	Name       string
+	Definition string
+}
+
+func (s *SpecValidator) validateDuplicatePropertyNames() *Result {
+	// definition can't declare a property that's already defined by one of its ancestors
+	res := new(Result)
+	for k, sch := range s.spec.Spec().Definitions {
+		if len(sch.AllOf) == 0 {
+			continue
+		}
+
+		knownanc := map[string]struct{}{
+			"#/definitions/" + k: {},
+		}
+
+		ancs, rec := s.validateCircularAncestry(k, sch, knownanc)
+		if rec != nil && (rec.HasErrors() || !rec.HasWarnings()) {
+			res.Merge(rec)
+		}
+		if len(ancs) > 0 {
+			res.AddErrors(circularAncestryDefinitionMsg(k, ancs))
+			return res
+		}
+
+		knowns := make(map[string]struct{})
+		dups, rep := s.validateSchemaPropertyNames(k, sch, knowns)
+		if rep != nil && (rep.HasErrors() || rep.HasWarnings()) {
+			res.Merge(rep)
+		}
+		if len(dups) > 0 {
+			var pns []string
+			for _, v := range dups {
+				pns = append(pns, v.Definition+"."+v.Name)
+			}
+			res.AddErrors(duplicatePropertiesMsg(k, pns))
+		}
+
+	}
+	return res
+}
+
+func (s *SpecValidator) resolveRef(ref *spec.Ref) (*spec.Schema, error) {
+	if s.spec.SpecFilePath() != "" {
+		return spec.ResolveRefWithBase(s.spec.Spec(), ref, &spec.ExpandOptions{RelativeBase: s.spec.SpecFilePath()})
+	}
+	// NOTE: it looks like with the new spec resolver, this code is now unrecheable
+	return spec.ResolveRef(s.spec.Spec(), ref)
+}
+
+func (s *SpecValidator) validateSchemaPropertyNames(nm string, sch spec.Schema, knowns map[string]struct{}) ([]dupProp, *Result) {
+	var dups []dupProp
+
+	schn := nm
+	schc := &sch
+	res := new(Result)
+
+	for schc.Ref.String() != "" {
+		// gather property names
+		reso, err := s.resolveRef(&schc.Ref)
+		if err != nil {
+			errorHelp.addPointerError(res, err, schc.Ref.String(), nm)
+			return dups, res
+		}
+		schc = reso
+		schn = sch.Ref.String()
+	}
+
+	if len(schc.AllOf) > 0 {
+		for _, chld := range schc.AllOf {
+			dup, rep := s.validateSchemaPropertyNames(schn, chld, knowns)
+			if rep != nil && (rep.HasErrors() || rep.HasWarnings()) {
+				res.Merge(rep)
+			}
+			dups = append(dups, dup...)
+		}
+		return dups, res
+	}
+
+	for k := range schc.Properties {
+		_, ok := knowns[k]
+		if ok {
+			dups = append(dups, dupProp{Name: k, Definition: schn})
+		} else {
+			knowns[k] = struct{}{}
+		}
+	}
+
+	return dups, res
+}
+
+func (s *SpecValidator) validateCircularAncestry(nm string, sch spec.Schema, knowns map[string]struct{}) ([]string, *Result) {
+	res := new(Result)
+
+	if sch.Ref.String() == "" && len(sch.AllOf) == 0 { // Safeguard. We should not be able to actually get there
+		return nil, res
+	}
+	var ancs []string
+
+	schn := nm
+	schc := &sch
+
+	for schc.Ref.String() != "" {
+		reso, err := s.resolveRef(&schc.Ref)
+		if err != nil {
+			errorHelp.addPointerError(res, err, schc.Ref.String(), nm)
+			return ancs, res
+		}
+		schc = reso
+		schn = sch.Ref.String()
+	}
+
+	if schn != nm && schn != "" {
+		if _, ok := knowns[schn]; ok {
+			ancs = append(ancs, schn)
+		}
+		knowns[schn] = struct{}{}
+
+		if len(ancs) > 0 {
+			return ancs, res
+		}
+	}
+
+	if len(schc.AllOf) > 0 {
+		for _, chld := range schc.AllOf {
+			if chld.Ref.String() != "" || len(chld.AllOf) > 0 {
+				anc, rec := s.validateCircularAncestry(schn, chld, knowns)
+				if rec != nil && (rec.HasErrors() || !rec.HasWarnings()) {
+					res.Merge(rec)
+				}
+				ancs = append(ancs, anc...)
+				if len(ancs) > 0 {
+					return ancs, res
+				}
+			}
+		}
+	}
+	return ancs, res
+}
+
+func (s *SpecValidator) validateItems() *Result {
+	// validate parameter, items, schema and response objects for presence of item if type is array
+	res := new(Result)
+
+	for method, pi := range s.analyzer.Operations() {
+		for path, op := range pi {
+			for _, param := range paramHelp.safeExpandedParamsFor(path, method, op.ID, res, s) {
+
+				if param.TypeName() == "array" && param.ItemsTypeName() == "" {
+					res.AddErrors(arrayInParamRequiresItemsMsg(param.Name, op.ID))
+					continue
+				}
+				if param.In != "body" {
+					if param.Items != nil {
+						items := param.Items
+						for items.TypeName() == "array" {
+							if items.ItemsTypeName() == "" {
+								res.AddErrors(arrayInParamRequiresItemsMsg(param.Name, op.ID))
+								break
+							}
+							items = items.Items
+						}
+					}
+				} else {
+					// In: body
+					if param.Schema != nil {
+						res.Merge(s.validateSchemaItems(*param.Schema, fmt.Sprintf("body param %q", param.Name), op.ID))
+					}
+				}
+			}
+
+			var responses []spec.Response
+			if op.Responses != nil {
+				if op.Responses.Default != nil {
+					responses = append(responses, *op.Responses.Default)
+				}
+				if op.Responses.StatusCodeResponses != nil {
+					for _, v := range op.Responses.StatusCodeResponses {
+						responses = append(responses, v)
+					}
+				}
+			}
+
+			for _, resp := range responses {
+				// Response headers with array
+				for hn, hv := range resp.Headers {
+					if hv.TypeName() == "array" && hv.ItemsTypeName() == "" {
+						res.AddErrors(arrayInHeaderRequiresItemsMsg(hn, op.ID))
+					}
+				}
+				if resp.Schema != nil {
+					res.Merge(s.validateSchemaItems(*resp.Schema, "response body", op.ID))
+				}
+			}
+		}
+	}
+	return res
+}
+
+// Verifies constraints on array type
+func (s *SpecValidator) validateSchemaItems(schema spec.Schema, prefix, opID string) *Result {
+	res := new(Result)
+	if !schema.Type.Contains("array") {
+		return res
+	}
+
+	if schema.Items == nil || schema.Items.Len() == 0 {
+		res.AddErrors(arrayRequiresItemsMsg(prefix, opID))
+		return res
+	}
+
+	if schema.Items.Schema != nil {
+		schema = *schema.Items.Schema
+		if _, err := compileRegexp(schema.Pattern); err != nil {
+			res.AddErrors(invalidItemsPatternMsg(prefix, opID, schema.Pattern))
+		}
+
+		res.Merge(s.validateSchemaItems(schema, prefix, opID))
+	}
+	return res
+}
+
+func (s *SpecValidator) validatePathParamPresence(path string, fromPath, fromOperation []string) *Result {
+	// Each defined operation path parameters must correspond to a named element in the API's path pattern.
+	// (For example, you cannot have a path parameter named id for the following path /pets/{petId} but you must have a path parameter named petId.)
+	res := new(Result)
+	for _, l := range fromPath {
+		var matched bool
+		for _, r := range fromOperation {
+			if l == "{"+r+"}" {
+				matched = true
+				break
+			}
+		}
+		if !matched {
+			res.AddErrors(noParameterInPathMsg(l))
+		}
+	}
+
+	for _, p := range fromOperation {
+		var matched bool
+		for _, r := range fromPath {
+			if "{"+p+"}" == r {
+				matched = true
+				break
+			}
+		}
+		if !matched {
+			res.AddErrors(pathParamNotInPathMsg(path, p))
+		}
+	}
+
+	return res
+}
+
+func (s *SpecValidator) validateReferenced() *Result {
+	var res Result
+	res.MergeAsWarnings(s.validateReferencedParameters())
+	res.MergeAsWarnings(s.validateReferencedResponses())
+	res.MergeAsWarnings(s.validateReferencedDefinitions())
+	return &res
+}
+
+func (s *SpecValidator) validateReferencedParameters() *Result {
+	// Each referenceable definition should have references.
+	params := s.spec.Spec().Parameters
+	if len(params) == 0 {
+		return nil
+	}
+
+	expected := make(map[string]struct{})
+	for k := range params {
+		expected["#/parameters/"+jsonpointer.Escape(k)] = struct{}{}
+	}
+	for _, k := range s.analyzer.AllParameterReferences() {
+		if _, ok := expected[k]; ok {
+			delete(expected, k)
+		}
+	}
+
+	if len(expected) == 0 {
+		return nil
+	}
+	result := new(Result)
+	for k := range expected {
+		result.AddWarnings(unusedParamMsg(k))
+	}
+	return result
+}
+
+func (s *SpecValidator) validateReferencedResponses() *Result {
+	// Each referenceable definition should have references.
+	responses := s.spec.Spec().Responses
+	if len(responses) == 0 {
+		return nil
+	}
+
+	expected := make(map[string]struct{})
+	for k := range responses {
+		expected["#/responses/"+jsonpointer.Escape(k)] = struct{}{}
+	}
+	for _, k := range s.analyzer.AllResponseReferences() {
+		if _, ok := expected[k]; ok {
+			delete(expected, k)
+		}
+	}
+
+	if len(expected) == 0 {
+		return nil
+	}
+	result := new(Result)
+	for k := range expected {
+		result.AddWarnings(unusedResponseMsg(k))
+	}
+	return result
+}
+
+func (s *SpecValidator) validateReferencedDefinitions() *Result {
+	// Each referenceable definition must have references.
+	defs := s.spec.Spec().Definitions
+	if len(defs) == 0 {
+		return nil
+	}
+
+	expected := make(map[string]struct{})
+	for k := range defs {
+		expected["#/definitions/"+jsonpointer.Escape(k)] = struct{}{}
+	}
+	for _, k := range s.analyzer.AllDefinitionReferences() {
+		if _, ok := expected[k]; ok {
+			delete(expected, k)
+		}
+	}
+
+	if len(expected) == 0 {
+		return nil
+	}
+
+	result := new(Result)
+	for k := range expected {
+		result.AddWarnings(unusedDefinitionMsg(k))
+	}
+	return result
+}
+
+func (s *SpecValidator) validateRequiredDefinitions() *Result {
+	// Each property listed in the required array must be defined in the properties of the model
+	res := new(Result)
+
+DEFINITIONS:
+	for d, schema := range s.spec.Spec().Definitions {
+		if schema.Required != nil { // Safeguard
+			for _, pn := range schema.Required {
+				red := s.validateRequiredProperties(pn, d, &schema)
+				res.Merge(red)
+				if !red.IsValid() && !s.Options.ContinueOnErrors {
+					break DEFINITIONS // there is an error, let's stop that bleeding
+				}
+			}
+		}
+	}
+	return res
+}
+
+func (s *SpecValidator) validateRequiredProperties(path, in string, v *spec.Schema) *Result {
+	// Takes care of recursive property definitions, which may be nested in additionalProperties schemas
+	res := new(Result)
+	propertyMatch := false
+	patternMatch := false
+	additionalPropertiesMatch := false
+	isReadOnly := false
+
+	// Regular properties
+	if _, ok := v.Properties[path]; ok {
+		propertyMatch = true
+		isReadOnly = v.Properties[path].ReadOnly
+	}
+
+	// NOTE: patternProperties are not supported in swagger. Even though, we continue validation here
+	// We check all defined patterns: if one regexp is invalid, croaks an error
+	for pp, pv := range v.PatternProperties {
+		re, err := compileRegexp(pp)
+		if err != nil {
+			res.AddErrors(invalidPatternMsg(pp, in))
+		} else if re.MatchString(path) {
+			patternMatch = true
+			if !propertyMatch {
+				isReadOnly = pv.ReadOnly
+			}
+		}
+	}
+
+	if !(propertyMatch || patternMatch) {
+		if v.AdditionalProperties != nil {
+			if v.AdditionalProperties.Allows && v.AdditionalProperties.Schema == nil {
+				additionalPropertiesMatch = true
+			} else if v.AdditionalProperties.Schema != nil {
+				// additionalProperties as schema are upported in swagger
+				// recursively validates additionalProperties schema
+				// TODO : anyOf, allOf, oneOf like in schemaPropsValidator
+				red := s.validateRequiredProperties(path, in, v.AdditionalProperties.Schema)
+				if red.IsValid() {
+					additionalPropertiesMatch = true
+					if !propertyMatch && !patternMatch {
+						isReadOnly = v.AdditionalProperties.Schema.ReadOnly
+					}
+				}
+				res.Merge(red)
+			}
+		}
+	}
+
+	if !(propertyMatch || patternMatch || additionalPropertiesMatch) {
+		res.AddErrors(requiredButNotDefinedMsg(path, in))
+	}
+
+	if isReadOnly {
+		res.AddWarnings(readOnlyAndRequiredMsg(in, path))
+	}
+	return res
+}
+
+func (s *SpecValidator) validateParameters() *Result {
+	// - for each method, path is unique, regardless of path parameters
+	//   e.g. GET:/petstore/{id}, GET:/petstore/{pet}, GET:/petstore are
+	//   considered duplicate paths
+	// - each parameter should have a unique `name` and `type` combination
+	// - each operation should have only 1 parameter of type body
+	// - there must be at most 1 parameter in body
+	// - parameters with pattern property must specify valid patterns
+	// - $ref in parameters must resolve
+	// - path param must be required
+	res := new(Result)
+	rexGarbledPathSegment := mustCompileRegexp(`.*[{}\s]+.*`)
+	for method, pi := range s.analyzer.Operations() {
+		methodPaths := make(map[string]map[string]string)
+		if pi != nil { // Safeguard
+			for path, op := range pi {
+				pathToAdd := pathHelp.stripParametersInPath(path)
+
+				// Warn on garbled path afer param stripping
+				if rexGarbledPathSegment.MatchString(pathToAdd) {
+					res.AddWarnings(pathStrippedParamGarbledMsg(pathToAdd))
+				}
+
+				// Check uniqueness of stripped paths
+				if _, found := methodPaths[method][pathToAdd]; found {
+
+					// Sort names for stable, testable output
+					if strings.Compare(path, methodPaths[method][pathToAdd]) < 0 {
+						res.AddErrors(pathOverlapMsg(path, methodPaths[method][pathToAdd]))
+					} else {
+						res.AddErrors(pathOverlapMsg(methodPaths[method][pathToAdd], path))
+					}
+				} else {
+					if _, found := methodPaths[method]; !found {
+						methodPaths[method] = map[string]string{}
+					}
+					methodPaths[method][pathToAdd] = path //Original non stripped path
+
+				}
+
+				var bodyParams []string
+				var paramNames []string
+				var hasForm, hasBody bool
+
+				// Check parameters names uniqueness for operation
+				// TODO: should be done after param expansion
+				res.Merge(s.checkUniqueParams(path, method, op))
+
+				for _, pr := range paramHelp.safeExpandedParamsFor(path, method, op.ID, res, s) {
+					// Validate pattern regexp for parameters with a Pattern property
+					if _, err := compileRegexp(pr.Pattern); err != nil {
+						res.AddErrors(invalidPatternInParamMsg(op.ID, pr.Name, pr.Pattern))
+					}
+
+					// There must be at most one parameter in body: list them all
+					if pr.In == "body" {
+						bodyParams = append(bodyParams, fmt.Sprintf("%q", pr.Name))
+						hasBody = true
+					}
+
+					if pr.In == "path" {
+						paramNames = append(paramNames, pr.Name)
+						// Path declared in path must have the required: true property
+						if !pr.Required {
+							res.AddErrors(pathParamRequiredMsg(op.ID, pr.Name))
+						}
+					}
+
+					if pr.In == "formData" {
+						hasForm = true
+					}
+				}
+
+				// In:formData and In:body are mutually exclusive
+				if hasBody && hasForm {
+					res.AddErrors(bothFormDataAndBodyMsg(op.ID))
+				}
+				// There must be at most one body param
+				// Accurately report situations when more than 1 body param is declared (possibly unnamed)
+				if len(bodyParams) > 1 {
+					sort.Strings(bodyParams)
+					res.AddErrors(multipleBodyParamMsg(op.ID, bodyParams))
+				}
+
+				// Check uniqueness of parameters in path
+				paramsInPath := pathHelp.extractPathParams(path)
+				for i, p := range paramsInPath {
+					for j, q := range paramsInPath {
+						if p == q && i > j {
+							res.AddErrors(pathParamNotUniqueMsg(path, p, q))
+							break
+						}
+					}
+				}
+
+				// Warns about possible malformed params in path
+				rexGarbledParam := mustCompileRegexp(`{.*[{}\s]+.*}`)
+				for _, p := range paramsInPath {
+					if rexGarbledParam.MatchString(p) {
+						res.AddWarnings(pathParamGarbledMsg(path, p))
+					}
+				}
+
+				// Match params from path vs params from params section
+				res.Merge(s.validatePathParamPresence(path, paramsInPath, paramNames))
+			}
+		}
+	}
+	return res
+}
+
+func (s *SpecValidator) validateReferencesValid() *Result {
+	// each reference must point to a valid object
+	res := new(Result)
+	for _, r := range s.analyzer.AllRefs() {
+		if !r.IsValidURI(s.spec.SpecFilePath()) { // Safeguard - spec should always yield a valid URI
+			res.AddErrors(invalidRefMsg(r.String()))
+		}
+	}
+	if !res.HasErrors() {
+		// NOTE: with default settings, loads.Document.Expanded()
+		// stops on first error. Anyhow, the expand option to continue
+		// on errors fails to report errors at all.
+		exp, err := s.spec.Expanded()
+		if err != nil {
+			res.AddErrors(unresolvedReferencesMsg(err))
+		}
+		s.expanded = exp
+	}
+	return res
+}
+
+func (s *SpecValidator) checkUniqueParams(path, method string, op *spec.Operation) *Result {
+	// Check for duplicate parameters declaration in param section.
+	// Each parameter should have a unique `name` and `type` combination
+	// NOTE: this could be factorized in analysis (when constructing the params map)
+	// However, there are some issues with such a factorization:
+	// - analysis does not seem to fully expand params
+	// - param keys may be altered by x-go-name
+	res := new(Result)
+	pnames := make(map[string]struct{})
+
+	if op.Parameters != nil { // Safeguard
+		for _, ppr := range op.Parameters {
+			var ok bool
+			pr, red := paramHelp.resolveParam(path, method, op.ID, &ppr, s)
+			res.Merge(red)
+
+			if pr != nil && pr.Name != "" { // params with empty name does no participate the check
+				key := fmt.Sprintf("%s#%s", pr.In, pr.Name)
+
+				if _, ok = pnames[key]; ok {
+					res.AddErrors(duplicateParamNameMsg(pr.In, pr.Name, op.ID))
+				}
+				pnames[key] = struct{}{}
+			}
+		}
+	}
+	return res
+}
+
+// SetContinueOnErrors sets the ContinueOnErrors option for this validator.
+func (s *SpecValidator) SetContinueOnErrors(c bool) {
+	s.Options.ContinueOnErrors = c
+}
diff --git a/go/vendor/github.com/go-openapi/validate/spec_messages.go b/go/vendor/github.com/go-openapi/validate/spec_messages.go
new file mode 100644
index 0000000..441bb51
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/spec_messages.go
@@ -0,0 +1,354 @@
+// 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 validate
+
+import (
+	"net/http"
+
+	"github.com/go-openapi/errors"
+)
+
+// Error messages related to spec validation and returned as results.
+const (
+	// ArrayRequiresItemsError ...
+	ArrayRequiresItemsError = "%s for %q is a collection without an element type (array requires items definition)"
+
+	// ArrayInParamRequiresItemsError ...
+	ArrayInParamRequiresItemsError = "param %q for %q is a collection without an element type (array requires item definition)"
+
+	// ArrayInHeaderRequiresItemsError ...
+	ArrayInHeaderRequiresItemsError = "header %q for %q is a collection without an element type (array requires items definition)"
+
+	// BothFormDataAndBodyError indicates that an operation specifies both a body and a formData parameter, which is forbidden
+	BothFormDataAndBodyError = "operation %q has both formData and body parameters. Only one such In: type may be used for a given operation"
+
+	// CannotResolveRefError when a $ref could not be resolved
+	CannotResolveReferenceError = "could not resolve reference in %s to $ref %s: %v"
+
+	// CircularAncestryDefinitionError ...
+	CircularAncestryDefinitionError = "definition %q has circular ancestry: %v"
+
+	// DefaultValueDoesNotValidateError results from an invalid default value provided
+	DefaultValueDoesNotValidateError = "default value for %s in %s does not validate its schema"
+
+	// DefaultValueItemsDoesNotValidateError results from an invalid default value provided for Items
+	DefaultValueItemsDoesNotValidateError = "default value for %s.items in %s does not validate its schema"
+
+	// DefaultValueHeaderDoesNotValidateError results from an invalid default value provided in header
+	DefaultValueHeaderDoesNotValidateError = "in operation %q, default value in header %s for %s does not validate its schema"
+
+	// DefaultValueHeaderItemsDoesNotValidateError results from an invalid default value provided in header.items
+	DefaultValueHeaderItemsDoesNotValidateError = "in operation %q, default value in header.items %s for %s does not validate its schema"
+
+	// DefaultValueInDoesNotValidateError ...
+	DefaultValueInDoesNotValidateError = "in operation %q, default value in %s does not validate its schema"
+
+	// DuplicateParamNameError ...
+	DuplicateParamNameError = "duplicate parameter name %q for %q in operation %q"
+
+	// DuplicatePropertiesError ...
+	DuplicatePropertiesError = "definition %q contains duplicate properties: %v"
+
+	// ExampleValueDoesNotValidateError results from an invalid example value provided
+	ExampleValueDoesNotValidateError = "example value for %s in %s does not validate its schema"
+
+	// ExampleValueItemsDoesNotValidateError results from an invalid example value provided for Items
+	ExampleValueItemsDoesNotValidateError = "example value for %s.items in %s does not validate its schema"
+
+	// ExampleValueHeaderDoesNotValidateError results from an invalid example value provided in header
+	ExampleValueHeaderDoesNotValidateError = "in operation %q, example value in header %s for %s does not validate its schema"
+
+	// ExampleValueHeaderItemsDoesNotValidateError results from an invalid example value provided in header.items
+	ExampleValueHeaderItemsDoesNotValidateError = "in operation %q, example value in header.items %s for %s does not validate its schema"
+
+	// ExampleValueInDoesNotValidateError ...
+	ExampleValueInDoesNotValidateError = "in operation %q, example value in %s does not validate its schema"
+
+	// EmptyPathParameterError means that a path parameter was found empty (e.g. "{}")
+	EmptyPathParameterError = "%q contains an empty path parameter"
+
+	// InvalidDocumentError states that spec validation only processes spec.Document objects
+	InvalidDocumentError = "spec validator can only validate spec.Document objects"
+
+	// InvalidItemsPatternError indicates an Items definition with invalid pattern
+	InvalidItemsPatternError = "%s for %q has invalid items pattern: %q"
+
+	// InvalidParameterDefinitionError indicates an error detected on a parameter definition
+	InvalidParameterDefinitionError = "invalid definition for parameter %s in %s in operation %q"
+
+	// InvalidParameterDefinitionAsSchemaError indicates an error detected on a parameter definition, which was mistaken with a schema definition.
+	// Most likely, this situation is encountered whenever a $ref has been added as a sibling of the parameter definition.
+	InvalidParameterDefinitionAsSchemaError = "invalid definition as Schema for parameter %s in %s in operation %q"
+
+	// InvalidPatternError ...
+	InvalidPatternError = "pattern %q is invalid in %s"
+
+	// InvalidPatternInError indicates an invalid pattern in a schema or items definition
+	InvalidPatternInError = "%s in %s has invalid pattern: %q"
+
+	// InvalidPatternInHeaderError indicates a header definition with an invalid pattern
+	InvalidPatternInHeaderError = "in operation %q, header %s for %s has invalid pattern %q: %v"
+
+	// InvalidPatternInParamError ...
+	InvalidPatternInParamError = "operation %q has invalid pattern in param %q: %q"
+
+	// InvalidReferenceError indicates that a $ref property could not be resolved
+	InvalidReferenceError = "invalid ref %q"
+
+	// InvalidResponseDefinitionAsSchemaError indicates an error detected on a response definition, which was mistaken with a schema definition.
+	// Most likely, this situation is encountered whenever a $ref has been added as a sibling of the response definition.
+	InvalidResponseDefinitionAsSchemaError = "invalid definition as Schema for response %s in %s"
+
+	// MultipleBodyParamError indicates that an operation specifies multiple parameter with in: body
+	MultipleBodyParamError = "operation %q has more than 1 body param: %v"
+
+	// NonUniqueOperationIDError indicates that the same operationId has been specified several times
+	NonUniqueOperationIDError = "%q is defined %d times"
+
+	// NoParameterInPathError indicates that a path was found without any parameter
+	NoParameterInPathError = "path param %q has no parameter definition"
+
+	// NoValidPathErrorOrWarning indicates that no single path could be validated. If Paths is empty, this message is only a warning.
+	NoValidPathErrorOrWarning = "spec has no valid path defined"
+
+	// NoValidResponseError indicates that no valid response description could be found for an operation
+	NoValidResponseError = "operation %q has no valid response"
+
+	// PathOverlapError ...
+	PathOverlapError = "path %s overlaps with %s"
+
+	// PathParamNotInPathError indicates that a parameter specified with in: path was not found in the path specification
+	PathParamNotInPathError = "path param %q is not present in path %q"
+
+	// PathParamNotUniqueError ...
+	PathParamNotUniqueError = "params in path %q must be unique: %q conflicts with %q"
+
+	// PathParamNotRequiredError ...
+	PathParamRequiredError = "in operation %q,path param %q must be declared as required"
+
+	// RefNotAllowedInHeaderError indicates a $ref was found in a header definition, which is not allowed by Swagger
+	RefNotAllowedInHeaderError = "IMPORTANT!in %q: $ref are not allowed in headers. In context for header %q%s"
+
+	// RequiredButNotDefinedError ...
+	RequiredButNotDefinedError = "%q is present in required but not defined as property in definition %q"
+
+	// SomeParametersBrokenError indicates that some parameters could not be resolved, which might result in partial checks to be carried on
+	SomeParametersBrokenError = "some parameters definitions are broken in %q.%s. Cannot carry on full checks on parameters for operation %s"
+
+	// UnresolvedReferencesError indicates that at least one $ref could not be resolved
+	UnresolvedReferencesError = "some references could not be resolved in spec. First found: %v"
+)
+
+// Warning messages related to spec validation and returned as results
+const (
+	// ExamplesWithoutSchemaWarning indicates that examples are provided for a response,but not schema to validate the example against
+	ExamplesWithoutSchemaWarning = "Examples provided without schema in operation %q, %s"
+
+	// ExamplesMimeNotSupportedWarning indicates that examples are provided with a mime type different than application/json, which
+	// the validator dos not support yetl
+	ExamplesMimeNotSupportedWarning = "No validation attempt for examples for media types other than application/json, in operation %q, %s"
+
+	// PathParamGarbledWarning ...
+	PathParamGarbledWarning = "in path %q, param %q contains {,} or white space. Albeit not stricly illegal, this is probably no what you want"
+
+	// PathStrippedParamGarbledWarning ...
+	PathStrippedParamGarbledWarning = "path stripped from path parameters %s contains {,} or white space. This is probably no what you want."
+
+	// ReadOnlyAndRequiredWarning ...
+	ReadOnlyAndRequiredWarning = "Required property %s in %q should not be marked as both required and readOnly"
+
+	// RefShouldNotHaveSiblingsWarning indicates that a $ref was found with a sibling definition. This results in the $ref taking over its siblings,
+	// which is most likely not wanted.
+	RefShouldNotHaveSiblingsWarning = "$ref property should have no sibling in %q.%s"
+
+	// RequiredHasDefaultWarning indicates that a required parameter property should not have a default
+	RequiredHasDefaultWarning = "%s in %s has a default value and is required as parameter"
+
+	// UnusedDefinitionWarning ...
+	UnusedDefinitionWarning = "definition %q is not used anywhere"
+
+	// UnusedParamWarning ...
+	UnusedParamWarning = "parameter %q is not used anywhere"
+
+	// UnusedResponseWarning ...
+	UnusedResponseWarning = "response %q is not used anywhere"
+)
+
+// Additional error codes
+const (
+	// InternalErrorCode reports an internal technical error
+	InternalErrorCode = http.StatusInternalServerError
+	// NotFoundErrorCode indicates that a resource (e.g. a $ref) could not be found
+	NotFoundErrorCode = http.StatusNotFound
+)
+
+func invalidDocumentMsg() errors.Error {
+	return errors.New(InternalErrorCode, InvalidDocumentError)
+}
+func invalidRefMsg(path string) errors.Error {
+	return errors.New(NotFoundErrorCode, InvalidReferenceError, path)
+}
+func unresolvedReferencesMsg(err error) errors.Error {
+	return errors.New(errors.CompositeErrorCode, UnresolvedReferencesError, err)
+}
+func noValidPathMsg() errors.Error {
+	return errors.New(errors.CompositeErrorCode, NoValidPathErrorOrWarning)
+}
+func emptyPathParameterMsg(path string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, EmptyPathParameterError, path)
+}
+func nonUniqueOperationIDMsg(path string, i int) errors.Error {
+	return errors.New(errors.CompositeErrorCode, NonUniqueOperationIDError, path, i)
+}
+func circularAncestryDefinitionMsg(path string, args interface{}) errors.Error {
+	return errors.New(errors.CompositeErrorCode, CircularAncestryDefinitionError, path, args)
+}
+func duplicatePropertiesMsg(path string, args interface{}) errors.Error {
+	return errors.New(errors.CompositeErrorCode, DuplicatePropertiesError, path, args)
+}
+func pathParamNotInPathMsg(path, param string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, PathParamNotInPathError, param, path)
+}
+func arrayRequiresItemsMsg(path, operation string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, ArrayRequiresItemsError, path, operation)
+}
+func arrayInParamRequiresItemsMsg(path, operation string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, ArrayInParamRequiresItemsError, path, operation)
+}
+func arrayInHeaderRequiresItemsMsg(path, operation string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, ArrayInHeaderRequiresItemsError, path, operation)
+}
+func invalidItemsPatternMsg(path, operation, pattern string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, InvalidItemsPatternError, path, operation, pattern)
+}
+func invalidPatternMsg(pattern, path string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, InvalidPatternError, pattern, path)
+}
+func requiredButNotDefinedMsg(path, definition string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, RequiredButNotDefinedError, path, definition)
+}
+func pathParamGarbledMsg(path, param string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, PathParamGarbledWarning, path, param)
+}
+func pathStrippedParamGarbledMsg(path string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, PathStrippedParamGarbledWarning, path)
+}
+func pathOverlapMsg(path, arg string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, PathOverlapError, path, arg)
+}
+func invalidPatternInParamMsg(operation, param, pattern string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, InvalidPatternInParamError, operation, param, pattern)
+}
+func pathParamRequiredMsg(operation, param string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, PathParamRequiredError, operation, param)
+}
+func bothFormDataAndBodyMsg(operation string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, BothFormDataAndBodyError, operation)
+}
+func multipleBodyParamMsg(operation string, args interface{}) errors.Error {
+	return errors.New(errors.CompositeErrorCode, MultipleBodyParamError, operation, args)
+}
+func pathParamNotUniqueMsg(path, param, arg string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, PathParamNotUniqueError, path, param, arg)
+}
+func duplicateParamNameMsg(path, param, operation string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, DuplicateParamNameError, param, path, operation)
+}
+func unusedParamMsg(arg string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, UnusedParamWarning, arg)
+}
+func unusedDefinitionMsg(arg string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, UnusedDefinitionWarning, arg)
+}
+func unusedResponseMsg(arg string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, UnusedResponseWarning, arg)
+}
+func readOnlyAndRequiredMsg(path, param string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, ReadOnlyAndRequiredWarning, param, path)
+}
+func noParameterInPathMsg(param string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, NoParameterInPathError, param)
+}
+func requiredHasDefaultMsg(param, path string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, RequiredHasDefaultWarning, param, path)
+}
+func defaultValueDoesNotValidateMsg(param, path string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, DefaultValueDoesNotValidateError, param, path)
+}
+func defaultValueItemsDoesNotValidateMsg(param, path string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, DefaultValueItemsDoesNotValidateError, param, path)
+}
+func noValidResponseMsg(operation string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, NoValidResponseError, operation)
+}
+func defaultValueHeaderDoesNotValidateMsg(operation, header, path string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, DefaultValueHeaderDoesNotValidateError, operation, header, path)
+}
+func defaultValueHeaderItemsDoesNotValidateMsg(operation, header, path string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, DefaultValueHeaderItemsDoesNotValidateError, operation, header, path)
+}
+func invalidPatternInHeaderMsg(operation, header, path, pattern string, args interface{}) errors.Error {
+	return errors.New(errors.CompositeErrorCode, InvalidPatternInHeaderError, operation, header, path, pattern, args)
+}
+func invalidPatternInMsg(path, in, pattern string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, InvalidPatternInError, path, in, pattern)
+}
+func defaultValueInDoesNotValidateMsg(operation, path string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, DefaultValueInDoesNotValidateError, operation, path)
+}
+func exampleValueDoesNotValidateMsg(param, path string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, ExampleValueDoesNotValidateError, param, path)
+}
+func exampleValueItemsDoesNotValidateMsg(param, path string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, ExampleValueItemsDoesNotValidateError, param, path)
+}
+func exampleValueHeaderDoesNotValidateMsg(operation, header, path string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, ExampleValueHeaderDoesNotValidateError, operation, header, path)
+}
+func exampleValueHeaderItemsDoesNotValidateMsg(operation, header, path string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, ExampleValueHeaderItemsDoesNotValidateError, operation, header, path)
+}
+func exampleValueInDoesNotValidateMsg(operation, path string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, ExampleValueInDoesNotValidateError, operation, path)
+}
+func examplesWithoutSchemaMsg(operation, response string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, ExamplesWithoutSchemaWarning, operation, response)
+}
+func examplesMimeNotSupportedMsg(operation, response string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, ExamplesMimeNotSupportedWarning, operation, response)
+}
+func refNotAllowedInHeaderMsg(path, header, ref string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, RefNotAllowedInHeaderError, path, header, ref)
+}
+func cannotResolveRefMsg(path, ref string, err error) errors.Error {
+	return errors.New(errors.CompositeErrorCode, CannotResolveReferenceError, path, ref, err)
+}
+func invalidParameterDefinitionMsg(path, method, operationID string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, InvalidParameterDefinitionError, path, method, operationID)
+}
+func invalidParameterDefinitionAsSchemaMsg(path, method, operationID string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, InvalidParameterDefinitionAsSchemaError, path, method, operationID)
+}
+
+// disabled
+//func invalidResponseDefinitionAsSchemaMsg(path, method string) errors.Error {
+//	return errors.New(errors.CompositeErrorCode, InvalidResponseDefinitionAsSchemaError, path, method)
+//}
+func someParametersBrokenMsg(path, method, operationID string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, SomeParametersBrokenError, path, method, operationID)
+}
+func refShouldNotHaveSiblingsMsg(path, operationID string) errors.Error {
+	return errors.New(errors.CompositeErrorCode, RefShouldNotHaveSiblingsWarning, operationID, path)
+}
diff --git a/go/vendor/github.com/go-openapi/validate/type.go b/go/vendor/github.com/go-openapi/validate/type.go
new file mode 100644
index 0000000..72c81a9
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/type.go
@@ -0,0 +1,177 @@
+// 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 validate
+
+import (
+	"reflect"
+	"strings"
+
+	"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"
+)
+
+type typeValidator struct {
+	Type   spec.StringOrArray
+	Format string
+	In     string
+	Path   string
+}
+
+func (t *typeValidator) schemaInfoForType(data interface{}) (string, string) {
+	// internal type to JSON type with swagger 2.0 format (with go-openapi/strfmt extensions),
+	// see https://github.com/go-openapi/strfmt/blob/master/README.md
+	// TODO: this switch really is some sort of reverse lookup for formats. It should be provided by strfmt.
+	switch data.(type) {
+	case []byte, strfmt.Base64, *strfmt.Base64:
+		return "string", "byte"
+	case strfmt.CreditCard, *strfmt.CreditCard:
+		return "string", "creditcard"
+	case strfmt.Date, *strfmt.Date:
+		return "string", "date"
+	case strfmt.DateTime, *strfmt.DateTime:
+		return "string", "date-time"
+	case strfmt.Duration, *strfmt.Duration:
+		return "string", "duration"
+	case runtime.File, *runtime.File:
+		return "file", ""
+	case strfmt.Email, *strfmt.Email:
+		return "string", "email"
+	case strfmt.HexColor, *strfmt.HexColor:
+		return "string", "hexcolor"
+	case strfmt.Hostname, *strfmt.Hostname:
+		return "string", "hostname"
+	case strfmt.IPv4, *strfmt.IPv4:
+		return "string", "ipv4"
+	case strfmt.IPv6, *strfmt.IPv6:
+		return "string", "ipv6"
+	case strfmt.ISBN, *strfmt.ISBN:
+		return "string", "isbn"
+	case strfmt.ISBN10, *strfmt.ISBN10:
+		return "string", "isbn10"
+	case strfmt.ISBN13, *strfmt.ISBN13:
+		return "string", "isbn13"
+	case strfmt.MAC, *strfmt.MAC:
+		return "string", "mac"
+	case strfmt.ObjectId, *strfmt.ObjectId:
+		return "string", "bsonobjectid"
+	case strfmt.Password, *strfmt.Password:
+		return "string", "password"
+	case strfmt.RGBColor, *strfmt.RGBColor:
+		return "string", "rgbcolor"
+	case strfmt.SSN, *strfmt.SSN:
+		return "string", "ssn"
+	case strfmt.URI, *strfmt.URI:
+		return "string", "uri"
+	case strfmt.UUID, *strfmt.UUID:
+		return "string", "uuid"
+	case strfmt.UUID3, *strfmt.UUID3:
+		return "string", "uuid3"
+	case strfmt.UUID4, *strfmt.UUID4:
+		return "string", "uuid4"
+	case strfmt.UUID5, *strfmt.UUID5:
+		return "string", "uuid5"
+	// TODO: missing binary (io.ReadCloser)
+	// TODO: missing json.Number
+	default:
+		val := reflect.ValueOf(data)
+		tpe := val.Type()
+		switch tpe.Kind() {
+		case reflect.Bool:
+			return "boolean", ""
+		case reflect.String:
+			return "string", ""
+		case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint8, reflect.Uint16, reflect.Uint32:
+			// NOTE: that is the spec. With go-openapi, is that not uint32 for unsigned integers?
+			return "integer", "int32"
+		case reflect.Int, reflect.Int64, reflect.Uint, reflect.Uint64:
+			return "integer", "int64"
+		case reflect.Float32:
+			// NOTE: is that not "float"?
+			return "number", "float32"
+		case reflect.Float64:
+			// NOTE: is that not "double"?
+			return "number", "float64"
+		// NOTE: go arrays (reflect.Array) are not supported (fixed length)
+		case reflect.Slice:
+			return "array", ""
+		case reflect.Map, reflect.Struct:
+			return "object", ""
+		case reflect.Interface:
+			// What to do here?
+			panic("dunno what to do here")
+		case reflect.Ptr:
+			return t.schemaInfoForType(reflect.Indirect(val).Interface())
+		}
+	}
+	return "", ""
+}
+
+func (t *typeValidator) SetPath(path string) {
+	t.Path = path
+}
+
+func (t *typeValidator) Applies(source interface{}, kind reflect.Kind) bool {
+	// typeValidator applies to Schema, Parameter and Header objects
+	stpe := reflect.TypeOf(source)
+	r := (len(t.Type) > 0 || t.Format != "") && (stpe == specSchemaType || stpe == specParameterType || stpe == specHeaderType)
+	debugLog("type validator for %q applies %t for %T (kind: %v)\n", t.Path, r, source, kind)
+	return r
+}
+
+func (t *typeValidator) Validate(data interface{}) *Result {
+	result := new(Result)
+	result.Inc()
+	if data == nil || reflect.DeepEqual(reflect.Zero(reflect.TypeOf(data)), reflect.ValueOf(data)) {
+		// nil or zero value for the passed structure require Type: null
+		if len(t.Type) > 0 && !t.Type.Contains("null") { // TODO: if a property is not required it also passes this
+			return errorHelp.sErr(errors.InvalidType(t.Path, t.In, strings.Join(t.Type, ","), "null"))
+		}
+		return result
+	}
+
+	// check if the type matches, should be used in every validator chain as first item
+	val := reflect.Indirect(reflect.ValueOf(data))
+	kind := val.Kind()
+
+	// infer schema type (JSON) and format from passed data type
+	schType, format := t.schemaInfoForType(data)
+
+	debugLog("path: %s, schType: %s,  format: %s, expType: %s, expFmt: %s, kind: %s", t.Path, schType, format, t.Type, t.Format, val.Kind().String())
+
+	// check numerical types
+	// TODO: check unsigned ints
+	// TODO: check json.Number (see schema.go)
+	isLowerInt := t.Format == "int64" && format == "int32"
+	isLowerFloat := t.Format == "float64" && format == "float32"
+	isFloatInt := schType == "number" && swag.IsFloat64AJSONInteger(val.Float()) && t.Type.Contains("integer")
+	isIntFloat := schType == "integer" && t.Type.Contains("number")
+
+	if kind != reflect.String && kind != reflect.Slice && t.Format != "" && !(t.Type.Contains(schType) || format == t.Format || isFloatInt || isIntFloat || isLowerInt || isLowerFloat) {
+		// TODO: test case
+		return errorHelp.sErr(errors.InvalidType(t.Path, t.In, t.Format, format))
+	}
+
+	if !(t.Type.Contains("number") || t.Type.Contains("integer")) && t.Format != "" && (kind == reflect.String || kind == reflect.Slice) {
+		return result
+	}
+
+	if !(t.Type.Contains(schType) || isFloatInt || isIntFloat) {
+		return errorHelp.sErr(errors.InvalidType(t.Path, t.In, strings.Join(t.Type, ","), schType))
+	}
+	return result
+}
diff --git a/go/vendor/github.com/go-openapi/validate/update-fixtures.sh b/go/vendor/github.com/go-openapi/validate/update-fixtures.sh
new file mode 100755
index 0000000..21b06e2
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/update-fixtures.sh
@@ -0,0 +1,15 @@
+#!/bin/bash 
+
+set -eu -o pipefail
+dir=$(git rev-parse --show-toplevel)
+scratch=$(mktemp -d -t tmp.XXXXXXXXXX)
+
+function finish {
+  rm -rf "$scratch"
+}
+trap finish EXIT SIGHUP SIGINT SIGTERM
+
+cd "$scratch"
+git clone https://github.com/json-schema-org/JSON-Schema-Test-Suite Suite
+cp -r Suite/tests/draft4/* "$dir/fixtures/jsonschema_suite"
+cp -a Suite/remotes "$dir/fixtures/jsonschema_suite"
diff --git a/go/vendor/github.com/go-openapi/validate/validator.go b/go/vendor/github.com/go-openapi/validate/validator.go
new file mode 100644
index 0000000..98c9f54
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/validator.go
@@ -0,0 +1,638 @@
+// 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 validate
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/strfmt"
+)
+
+// An EntityValidator is an interface for things that can validate entities
+type EntityValidator interface {
+	Validate(interface{}) *Result
+}
+
+type valueValidator interface {
+	SetPath(path string)
+	Applies(interface{}, reflect.Kind) bool
+	Validate(interface{}) *Result
+}
+
+type itemsValidator struct {
+	items        *spec.Items
+	root         interface{}
+	path         string
+	in           string
+	validators   []valueValidator
+	KnownFormats strfmt.Registry
+}
+
+func newItemsValidator(path, in string, items *spec.Items, root interface{}, formats strfmt.Registry) *itemsValidator {
+	iv := &itemsValidator{path: path, in: in, items: items, root: root, KnownFormats: formats}
+	iv.validators = []valueValidator{
+		&typeValidator{
+			Type:   spec.StringOrArray([]string{items.Type}),
+			Format: items.Format,
+			In:     in,
+			Path:   path,
+		},
+		iv.stringValidator(),
+		iv.formatValidator(),
+		iv.numberValidator(),
+		iv.sliceValidator(),
+		iv.commonValidator(),
+	}
+	return iv
+}
+
+func (i *itemsValidator) Validate(index int, data interface{}) *Result {
+	tpe := reflect.TypeOf(data)
+	kind := tpe.Kind()
+	mainResult := new(Result)
+	path := fmt.Sprintf("%s.%d", i.path, index)
+
+	for _, validator := range i.validators {
+		validator.SetPath(path)
+		if validator.Applies(i.root, kind) {
+			result := validator.Validate(data)
+			mainResult.Merge(result)
+			mainResult.Inc()
+			if result != nil && result.HasErrors() {
+				return mainResult
+			}
+		}
+	}
+	return mainResult
+}
+
+func (i *itemsValidator) commonValidator() valueValidator {
+	return &basicCommonValidator{
+		In:      i.in,
+		Default: i.items.Default,
+		Enum:    i.items.Enum,
+	}
+}
+
+func (i *itemsValidator) sliceValidator() valueValidator {
+	return &basicSliceValidator{
+		In:           i.in,
+		Default:      i.items.Default,
+		MaxItems:     i.items.MaxItems,
+		MinItems:     i.items.MinItems,
+		UniqueItems:  i.items.UniqueItems,
+		Source:       i.root,
+		Items:        i.items.Items,
+		KnownFormats: i.KnownFormats,
+	}
+}
+
+func (i *itemsValidator) numberValidator() valueValidator {
+	return &numberValidator{
+		In:               i.in,
+		Default:          i.items.Default,
+		MultipleOf:       i.items.MultipleOf,
+		Maximum:          i.items.Maximum,
+		ExclusiveMaximum: i.items.ExclusiveMaximum,
+		Minimum:          i.items.Minimum,
+		ExclusiveMinimum: i.items.ExclusiveMinimum,
+		Type:             i.items.Type,
+		Format:           i.items.Format,
+	}
+}
+
+func (i *itemsValidator) stringValidator() valueValidator {
+	return &stringValidator{
+		In:              i.in,
+		Default:         i.items.Default,
+		MaxLength:       i.items.MaxLength,
+		MinLength:       i.items.MinLength,
+		Pattern:         i.items.Pattern,
+		AllowEmptyValue: false,
+	}
+}
+
+func (i *itemsValidator) formatValidator() valueValidator {
+	return &formatValidator{
+		In: i.in,
+		//Default:      i.items.Default,
+		Format:       i.items.Format,
+		KnownFormats: i.KnownFormats,
+	}
+}
+
+type basicCommonValidator struct {
+	Path    string
+	In      string
+	Default interface{}
+	Enum    []interface{}
+}
+
+func (b *basicCommonValidator) SetPath(path string) {
+	b.Path = path
+}
+
+func (b *basicCommonValidator) Applies(source interface{}, kind reflect.Kind) bool {
+	switch source.(type) {
+	case *spec.Parameter, *spec.Schema, *spec.Header:
+		return true
+	}
+	return false
+}
+
+func (b *basicCommonValidator) Validate(data interface{}) (res *Result) {
+	if len(b.Enum) > 0 {
+		for _, enumValue := range b.Enum {
+			actualType := reflect.TypeOf(enumValue)
+			if actualType != nil { // Safeguard
+				expectedValue := reflect.ValueOf(data)
+				if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) {
+					if reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), enumValue) {
+						return nil
+					}
+				}
+			}
+		}
+		return errorHelp.sErr(errors.EnumFail(b.Path, b.In, data, b.Enum))
+	}
+	return nil
+}
+
+// A HeaderValidator has very limited subset of validations to apply
+type HeaderValidator struct {
+	name         string
+	header       *spec.Header
+	validators   []valueValidator
+	KnownFormats strfmt.Registry
+}
+
+// NewHeaderValidator creates a new header validator object
+func NewHeaderValidator(name string, header *spec.Header, formats strfmt.Registry) *HeaderValidator {
+	p := &HeaderValidator{name: name, header: header, KnownFormats: formats}
+	p.validators = []valueValidator{
+		&typeValidator{
+			Type:   spec.StringOrArray([]string{header.Type}),
+			Format: header.Format,
+			In:     "header",
+			Path:   name,
+		},
+		p.stringValidator(),
+		p.formatValidator(),
+		p.numberValidator(),
+		p.sliceValidator(),
+		p.commonValidator(),
+	}
+	return p
+}
+
+// Validate the value of the header against its schema
+func (p *HeaderValidator) Validate(data interface{}) *Result {
+	result := new(Result)
+	tpe := reflect.TypeOf(data)
+	kind := tpe.Kind()
+
+	for _, validator := range p.validators {
+		if validator.Applies(p.header, kind) {
+			if err := validator.Validate(data); err != nil {
+				result.Merge(err)
+				if err.HasErrors() {
+					return result
+				}
+			}
+		}
+	}
+	return nil
+}
+
+func (p *HeaderValidator) commonValidator() valueValidator {
+	return &basicCommonValidator{
+		Path:    p.name,
+		In:      "response",
+		Default: p.header.Default,
+		Enum:    p.header.Enum,
+	}
+}
+
+func (p *HeaderValidator) sliceValidator() valueValidator {
+	return &basicSliceValidator{
+		Path:         p.name,
+		In:           "response",
+		Default:      p.header.Default,
+		MaxItems:     p.header.MaxItems,
+		MinItems:     p.header.MinItems,
+		UniqueItems:  p.header.UniqueItems,
+		Items:        p.header.Items,
+		Source:       p.header,
+		KnownFormats: p.KnownFormats,
+	}
+}
+
+func (p *HeaderValidator) numberValidator() valueValidator {
+	return &numberValidator{
+		Path:             p.name,
+		In:               "response",
+		Default:          p.header.Default,
+		MultipleOf:       p.header.MultipleOf,
+		Maximum:          p.header.Maximum,
+		ExclusiveMaximum: p.header.ExclusiveMaximum,
+		Minimum:          p.header.Minimum,
+		ExclusiveMinimum: p.header.ExclusiveMinimum,
+		Type:             p.header.Type,
+		Format:           p.header.Format,
+	}
+}
+
+func (p *HeaderValidator) stringValidator() valueValidator {
+	return &stringValidator{
+		Path:            p.name,
+		In:              "response",
+		Default:         p.header.Default,
+		Required:        true,
+		MaxLength:       p.header.MaxLength,
+		MinLength:       p.header.MinLength,
+		Pattern:         p.header.Pattern,
+		AllowEmptyValue: false,
+	}
+}
+
+func (p *HeaderValidator) formatValidator() valueValidator {
+	return &formatValidator{
+		Path: p.name,
+		In:   "response",
+		//Default:      p.header.Default,
+		Format:       p.header.Format,
+		KnownFormats: p.KnownFormats,
+	}
+}
+
+// A ParamValidator has very limited subset of validations to apply
+type ParamValidator struct {
+	param        *spec.Parameter
+	validators   []valueValidator
+	KnownFormats strfmt.Registry
+}
+
+// NewParamValidator creates a new param validator object
+func NewParamValidator(param *spec.Parameter, formats strfmt.Registry) *ParamValidator {
+	p := &ParamValidator{param: param, KnownFormats: formats}
+	p.validators = []valueValidator{
+		&typeValidator{
+			Type:   spec.StringOrArray([]string{param.Type}),
+			Format: param.Format,
+			In:     param.In,
+			Path:   param.Name,
+		},
+		p.stringValidator(),
+		p.formatValidator(),
+		p.numberValidator(),
+		p.sliceValidator(),
+		p.commonValidator(),
+	}
+	return p
+}
+
+// Validate the data against the description of the parameter
+func (p *ParamValidator) Validate(data interface{}) *Result {
+	result := new(Result)
+	tpe := reflect.TypeOf(data)
+	kind := tpe.Kind()
+
+	// TODO: validate type
+	for _, validator := range p.validators {
+		if validator.Applies(p.param, kind) {
+			if err := validator.Validate(data); err != nil {
+				result.Merge(err)
+				if err.HasErrors() {
+					return result
+				}
+			}
+		}
+	}
+	return nil
+}
+
+func (p *ParamValidator) commonValidator() valueValidator {
+	return &basicCommonValidator{
+		Path:    p.param.Name,
+		In:      p.param.In,
+		Default: p.param.Default,
+		Enum:    p.param.Enum,
+	}
+}
+
+func (p *ParamValidator) sliceValidator() valueValidator {
+	return &basicSliceValidator{
+		Path:         p.param.Name,
+		In:           p.param.In,
+		Default:      p.param.Default,
+		MaxItems:     p.param.MaxItems,
+		MinItems:     p.param.MinItems,
+		UniqueItems:  p.param.UniqueItems,
+		Items:        p.param.Items,
+		Source:       p.param,
+		KnownFormats: p.KnownFormats,
+	}
+}
+
+func (p *ParamValidator) numberValidator() valueValidator {
+	return &numberValidator{
+		Path:             p.param.Name,
+		In:               p.param.In,
+		Default:          p.param.Default,
+		MultipleOf:       p.param.MultipleOf,
+		Maximum:          p.param.Maximum,
+		ExclusiveMaximum: p.param.ExclusiveMaximum,
+		Minimum:          p.param.Minimum,
+		ExclusiveMinimum: p.param.ExclusiveMinimum,
+		Type:             p.param.Type,
+		Format:           p.param.Format,
+	}
+}
+
+func (p *ParamValidator) stringValidator() valueValidator {
+	return &stringValidator{
+		Path:            p.param.Name,
+		In:              p.param.In,
+		Default:         p.param.Default,
+		AllowEmptyValue: p.param.AllowEmptyValue,
+		Required:        p.param.Required,
+		MaxLength:       p.param.MaxLength,
+		MinLength:       p.param.MinLength,
+		Pattern:         p.param.Pattern,
+	}
+}
+
+func (p *ParamValidator) formatValidator() valueValidator {
+	return &formatValidator{
+		Path: p.param.Name,
+		In:   p.param.In,
+		//Default:      p.param.Default,
+		Format:       p.param.Format,
+		KnownFormats: p.KnownFormats,
+	}
+}
+
+type basicSliceValidator struct {
+	Path           string
+	In             string
+	Default        interface{}
+	MaxItems       *int64
+	MinItems       *int64
+	UniqueItems    bool
+	Items          *spec.Items
+	Source         interface{}
+	itemsValidator *itemsValidator
+	KnownFormats   strfmt.Registry
+}
+
+func (s *basicSliceValidator) SetPath(path string) {
+	s.Path = path
+}
+
+func (s *basicSliceValidator) Applies(source interface{}, kind reflect.Kind) bool {
+	switch source.(type) {
+	case *spec.Parameter, *spec.Items, *spec.Header:
+		return kind == reflect.Slice
+	}
+	return false
+}
+
+func (s *basicSliceValidator) Validate(data interface{}) *Result {
+	val := reflect.ValueOf(data)
+
+	size := int64(val.Len())
+	if s.MinItems != nil {
+		if err := MinItems(s.Path, s.In, size, *s.MinItems); err != nil {
+			return errorHelp.sErr(err)
+		}
+	}
+
+	if s.MaxItems != nil {
+		if err := MaxItems(s.Path, s.In, size, *s.MaxItems); err != nil {
+			return errorHelp.sErr(err)
+		}
+	}
+
+	if s.UniqueItems {
+		if err := UniqueItems(s.Path, s.In, data); err != nil {
+			return errorHelp.sErr(err)
+		}
+	}
+
+	if s.itemsValidator == nil && s.Items != nil {
+		s.itemsValidator = newItemsValidator(s.Path, s.In, s.Items, s.Source, s.KnownFormats)
+	}
+
+	if s.itemsValidator != nil {
+		for i := 0; i < int(size); i++ {
+			ele := val.Index(i)
+			if err := s.itemsValidator.Validate(i, ele.Interface()); err != nil && err.HasErrors() {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+func (s *basicSliceValidator) hasDuplicates(value reflect.Value, size int) bool {
+	dict := make(map[interface{}]struct{})
+	for i := 0; i < size; i++ {
+		ele := value.Index(i)
+		if _, ok := dict[ele.Interface()]; ok {
+			return true
+		}
+		dict[ele.Interface()] = struct{}{}
+	}
+	return false
+}
+
+type numberValidator struct {
+	Path             string
+	In               string
+	Default          interface{}
+	MultipleOf       *float64
+	Maximum          *float64
+	ExclusiveMaximum bool
+	Minimum          *float64
+	ExclusiveMinimum bool
+	// Allows for more accurate behavior regarding integers
+	Type   string
+	Format string
+}
+
+func (n *numberValidator) SetPath(path string) {
+	n.Path = path
+}
+
+func (n *numberValidator) Applies(source interface{}, kind reflect.Kind) bool {
+	switch source.(type) {
+	case *spec.Parameter, *spec.Schema, *spec.Items, *spec.Header:
+		isInt := kind >= reflect.Int && kind <= reflect.Uint64
+		isFloat := kind == reflect.Float32 || kind == reflect.Float64
+		r := isInt || isFloat
+		debugLog("schema props validator for %q applies %t for %T (kind: %v) isInt=%t, isFloat=%t\n", n.Path, r, source, kind, isInt, isFloat)
+		return r
+	}
+	debugLog("schema props validator for %q applies %t for %T (kind: %v)\n", n.Path, false, source, kind)
+	return false
+}
+
+// Validate provides a validator for generic JSON numbers,
+//
+// By default, numbers are internally represented as float64.
+// Formats float, or float32 may alter this behavior by mapping to float32.
+// A special validation process is followed for integers, with optional "format":
+// this is an attempt to provide a validation with native types.
+//
+// NOTE: since the constraint specified (boundary, multipleOf) is unmarshalled
+// as float64, loss of information remains possible (e.g. on very large integers).
+//
+// Since this value directly comes from the unmarshalling, it is not possible
+// at this stage of processing to check further and guarantee the correctness of such values.
+//
+// Normally, the JSON Number.MAX_SAFE_INTEGER (resp. Number.MIN_SAFE_INTEGER)
+// would check we do not get such a loss.
+//
+// If this is the case, replace AddErrors() by AddWarnings() and IsValid() by !HasWarnings().
+//
+// TODO: consider replacing boundary check errors by simple warnings.
+//
+// TODO: default boundaries with MAX_SAFE_INTEGER are not checked (specific to json.Number?)
+func (n *numberValidator) Validate(val interface{}) *Result {
+	res := new(Result)
+
+	resMultiple := new(Result)
+	resMinimum := new(Result)
+	resMaximum := new(Result)
+
+	// Used only to attempt to validate constraint on value,
+	// even though value or constraint specified do not match type and format
+	data := valueHelp.asFloat64(val)
+
+	// Is the provided value within the range of the specified numeric type and format?
+	res.AddErrors(IsValueValidAgainstRange(val, n.Type, n.Format, "Checked", n.Path))
+
+	if n.MultipleOf != nil {
+		// Is the constraint specifier within the range of the specific numeric type and format?
+		resMultiple.AddErrors(IsValueValidAgainstRange(*n.MultipleOf, n.Type, n.Format, "MultipleOf", n.Path))
+		if resMultiple.IsValid() {
+			// Constraint validated with compatible types
+			if err := MultipleOfNativeType(n.Path, n.In, val, *n.MultipleOf); err != nil {
+				resMultiple.Merge(errorHelp.sErr(err))
+			}
+		} else {
+			// Constraint nevertheless validated, converted as general number
+			if err := MultipleOf(n.Path, n.In, data, *n.MultipleOf); err != nil {
+				resMultiple.Merge(errorHelp.sErr(err))
+			}
+		}
+	}
+
+	if n.Maximum != nil {
+		// Is the constraint specifier within the range of the specific numeric type and format?
+		resMaximum.AddErrors(IsValueValidAgainstRange(*n.Maximum, n.Type, n.Format, "Maximum boundary", n.Path))
+		if resMaximum.IsValid() {
+			// Constraint validated with compatible types
+			if err := MaximumNativeType(n.Path, n.In, val, *n.Maximum, n.ExclusiveMaximum); err != nil {
+				resMaximum.Merge(errorHelp.sErr(err))
+			}
+		} else {
+			// Constraint nevertheless validated, converted as general number
+			if err := Maximum(n.Path, n.In, data, *n.Maximum, n.ExclusiveMaximum); err != nil {
+				resMaximum.Merge(errorHelp.sErr(err))
+			}
+		}
+	}
+
+	if n.Minimum != nil {
+		// Is the constraint specifier within the range of the specific numeric type and format?
+		resMinimum.AddErrors(IsValueValidAgainstRange(*n.Minimum, n.Type, n.Format, "Minimum boundary", n.Path))
+		if resMinimum.IsValid() {
+			// Constraint validated with compatible types
+			if err := MinimumNativeType(n.Path, n.In, val, *n.Minimum, n.ExclusiveMinimum); err != nil {
+				resMinimum.Merge(errorHelp.sErr(err))
+			}
+		} else {
+			// Constraint nevertheless validated, converted as general number
+			if err := Minimum(n.Path, n.In, data, *n.Minimum, n.ExclusiveMinimum); err != nil {
+				resMinimum.Merge(errorHelp.sErr(err))
+			}
+		}
+	}
+	res.Merge(resMultiple, resMinimum, resMaximum)
+	res.Inc()
+	return res
+}
+
+type stringValidator struct {
+	Default         interface{}
+	Required        bool
+	AllowEmptyValue bool
+	MaxLength       *int64
+	MinLength       *int64
+	Pattern         string
+	Path            string
+	In              string
+}
+
+func (s *stringValidator) SetPath(path string) {
+	s.Path = path
+}
+
+func (s *stringValidator) Applies(source interface{}, kind reflect.Kind) bool {
+	switch source.(type) {
+	case *spec.Parameter, *spec.Schema, *spec.Items, *spec.Header:
+		r := kind == reflect.String
+		debugLog("string validator for %q applies %t for %T (kind: %v)\n", s.Path, r, source, kind)
+		return r
+	}
+	debugLog("string validator for %q applies %t for %T (kind: %v)\n", s.Path, false, source, kind)
+	return false
+}
+
+func (s *stringValidator) Validate(val interface{}) *Result {
+	data, ok := val.(string)
+	if !ok {
+		return errorHelp.sErr(errors.InvalidType(s.Path, s.In, "string", val))
+	}
+
+	if s.Required && !s.AllowEmptyValue && (s.Default == nil || s.Default == "") {
+		if err := RequiredString(s.Path, s.In, data); err != nil {
+			return errorHelp.sErr(err)
+		}
+	}
+
+	if s.MaxLength != nil {
+		if err := MaxLength(s.Path, s.In, data, *s.MaxLength); err != nil {
+			return errorHelp.sErr(err)
+		}
+	}
+
+	if s.MinLength != nil {
+		if err := MinLength(s.Path, s.In, data, *s.MinLength); err != nil {
+			return errorHelp.sErr(err)
+		}
+	}
+
+	if s.Pattern != "" {
+		if err := Pattern(s.Path, s.In, data, s.Pattern); err != nil {
+			return errorHelp.sErr(err)
+		}
+	}
+	return nil
+}
diff --git a/go/vendor/github.com/go-openapi/validate/values.go b/go/vendor/github.com/go-openapi/validate/values.go
new file mode 100644
index 0000000..24606da
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/validate/values.go
@@ -0,0 +1,398 @@
+// 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 validate
+
+import (
+	"fmt"
+	"reflect"
+	"unicode/utf8"
+
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/strfmt"
+	"github.com/go-openapi/swag"
+)
+
+// Enum validates if the data is a member of the enum
+func Enum(path, in string, data interface{}, enum interface{}) *errors.Validation {
+	val := reflect.ValueOf(enum)
+	if val.Kind() != reflect.Slice {
+		return nil
+	}
+
+	var values []interface{}
+	for i := 0; i < val.Len(); i++ {
+		ele := val.Index(i)
+		enumValue := ele.Interface()
+		if data != nil {
+			if reflect.DeepEqual(data, enumValue) {
+				return nil
+			}
+			actualType := reflect.TypeOf(enumValue)
+			if actualType == nil { // Safeguard. Frankly, I don't know how we may get a nil
+				continue
+			}
+			expectedValue := reflect.ValueOf(data)
+			if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) {
+				// Attempt comparison after type conversion
+				if reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), enumValue) {
+					return nil
+				}
+			}
+		}
+		values = append(values, enumValue)
+	}
+	return errors.EnumFail(path, in, data, values)
+}
+
+// MinItems validates that there are at least n items in a slice
+func MinItems(path, in string, size, min int64) *errors.Validation {
+	if size < min {
+		return errors.TooFewItems(path, in, min)
+	}
+	return nil
+}
+
+// MaxItems validates that there are at most n items in a slice
+func MaxItems(path, in string, size, max int64) *errors.Validation {
+	if size > max {
+		return errors.TooManyItems(path, in, max)
+	}
+	return nil
+}
+
+// UniqueItems validates that the provided slice has unique elements
+func UniqueItems(path, in string, data interface{}) *errors.Validation {
+	val := reflect.ValueOf(data)
+	if val.Kind() != reflect.Slice {
+		return nil
+	}
+	var unique []interface{}
+	for i := 0; i < val.Len(); i++ {
+		v := val.Index(i).Interface()
+		for _, u := range unique {
+			if reflect.DeepEqual(v, u) {
+				return errors.DuplicateItems(path, in)
+			}
+		}
+		unique = append(unique, v)
+	}
+	return nil
+}
+
+// MinLength validates a string for minimum length
+func MinLength(path, in, data string, minLength int64) *errors.Validation {
+	strLen := int64(utf8.RuneCount([]byte(data)))
+	if strLen < minLength {
+		return errors.TooShort(path, in, minLength)
+	}
+	return nil
+}
+
+// MaxLength validates a string for maximum length
+func MaxLength(path, in, data string, maxLength int64) *errors.Validation {
+	strLen := int64(utf8.RuneCount([]byte(data)))
+	if strLen > maxLength {
+		return errors.TooLong(path, in, maxLength)
+	}
+	return nil
+}
+
+// Required validates an interface for requiredness
+func Required(path, in string, data interface{}) *errors.Validation {
+	val := reflect.ValueOf(data)
+	if val.IsValid() {
+		if reflect.DeepEqual(reflect.Zero(val.Type()).Interface(), val.Interface()) {
+			return errors.Required(path, in)
+		}
+		return nil
+	}
+	return errors.Required(path, in)
+}
+
+// RequiredString validates a string for requiredness
+func RequiredString(path, in, data string) *errors.Validation {
+	if data == "" {
+		return errors.Required(path, in)
+	}
+	return nil
+}
+
+// RequiredNumber validates a number for requiredness
+func RequiredNumber(path, in string, data float64) *errors.Validation {
+	if data == 0 {
+		return errors.Required(path, in)
+	}
+	return nil
+}
+
+// Pattern validates a string against a regular expression
+func Pattern(path, in, data, pattern string) *errors.Validation {
+	re, err := compileRegexp(pattern)
+	if err != nil {
+		return errors.FailedPattern(path, in, fmt.Sprintf("%s, but pattern is invalid: %s", pattern, err.Error()))
+	}
+	if !re.MatchString(data) {
+		return errors.FailedPattern(path, in, pattern)
+	}
+	return nil
+}
+
+// MaximumInt validates if a number is smaller than a given maximum
+func MaximumInt(path, in string, data, max int64, exclusive bool) *errors.Validation {
+	if (!exclusive && data > max) || (exclusive && data >= max) {
+		return errors.ExceedsMaximumInt(path, in, max, exclusive)
+	}
+	return nil
+}
+
+// MaximumUint validates if a number is smaller than a given maximum
+func MaximumUint(path, in string, data, max uint64, exclusive bool) *errors.Validation {
+	if (!exclusive && data > max) || (exclusive && data >= max) {
+		return errors.ExceedsMaximumUint(path, in, max, exclusive)
+	}
+	return nil
+}
+
+// Maximum validates if a number is smaller than a given maximum
+func Maximum(path, in string, data, max float64, exclusive bool) *errors.Validation {
+	if (!exclusive && data > max) || (exclusive && data >= max) {
+		return errors.ExceedsMaximum(path, in, max, exclusive)
+	}
+	return nil
+}
+
+// Minimum validates if a number is smaller than a given minimum
+func Minimum(path, in string, data, min float64, exclusive bool) *errors.Validation {
+	if (!exclusive && data < min) || (exclusive && data <= min) {
+		return errors.ExceedsMinimum(path, in, min, exclusive)
+	}
+	return nil
+}
+
+// MinimumInt validates if a number is smaller than a given minimum
+func MinimumInt(path, in string, data, min int64, exclusive bool) *errors.Validation {
+	if (!exclusive && data < min) || (exclusive && data <= min) {
+		return errors.ExceedsMinimumInt(path, in, min, exclusive)
+	}
+	return nil
+}
+
+// MinimumUint validates if a number is smaller than a given minimum
+func MinimumUint(path, in string, data, min uint64, exclusive bool) *errors.Validation {
+	if (!exclusive && data < min) || (exclusive && data <= min) {
+		return errors.ExceedsMinimumUint(path, in, min, exclusive)
+	}
+	return nil
+}
+
+// MultipleOf validates if the provided number is a multiple of the factor
+func MultipleOf(path, in string, data, factor float64) *errors.Validation {
+	// multipleOf factor must be positive
+	if factor < 0 {
+		return errors.MultipleOfMustBePositive(path, in, factor)
+	}
+	var mult float64
+	if factor < 1 {
+		mult = 1 / factor * data
+	} else {
+		mult = data / factor
+	}
+	if !swag.IsFloat64AJSONInteger(mult) {
+		return errors.NotMultipleOf(path, in, factor)
+	}
+	return nil
+}
+
+// MultipleOfInt validates if the provided integer is a multiple of the factor
+func MultipleOfInt(path, in string, data int64, factor int64) *errors.Validation {
+	// multipleOf factor must be positive
+	if factor < 0 {
+		return errors.MultipleOfMustBePositive(path, in, factor)
+	}
+	mult := data / factor
+	if mult*factor != data {
+		return errors.NotMultipleOf(path, in, factor)
+	}
+	return nil
+}
+
+// MultipleOfUint validates if the provided unsigned integer is a multiple of the factor
+func MultipleOfUint(path, in string, data, factor uint64) *errors.Validation {
+	mult := data / factor
+	if mult*factor != data {
+		return errors.NotMultipleOf(path, in, factor)
+	}
+	return nil
+}
+
+// FormatOf validates if a string matches a format in the format registry
+func FormatOf(path, in, format, data string, registry strfmt.Registry) *errors.Validation {
+	if registry == nil {
+		registry = strfmt.Default
+	}
+	if ok := registry.ContainsName(format); !ok {
+		return errors.InvalidTypeName(format)
+	}
+	if ok := registry.Validates(format, data); !ok {
+		return errors.InvalidType(path, in, format, data)
+	}
+	return nil
+}
+
+// MaximumNativeType provides native type constraint validation as a facade
+// to various numeric types versions of Maximum constraint check.
+//
+// Assumes that any possible loss conversion during conversion has been
+// checked beforehand.
+//
+// NOTE: currently, the max value is marshalled as a float64, no matter what,
+// which means there may be a loss during conversions (e.g. for very large integers)
+//
+// TODO: Normally, a JSON MAX_SAFE_INTEGER check would ensure conversion remains loss-free
+func MaximumNativeType(path, in string, val interface{}, max float64, exclusive bool) *errors.Validation {
+	kind := reflect.ValueOf(val).Type().Kind()
+	switch kind {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		value := valueHelp.asInt64(val)
+		return MaximumInt(path, in, value, int64(max), exclusive)
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		value := valueHelp.asUint64(val)
+		if max < 0 {
+			return errors.ExceedsMaximum(path, in, max, exclusive)
+		}
+		return MaximumUint(path, in, value, uint64(max), exclusive)
+	case reflect.Float32, reflect.Float64:
+		fallthrough
+	default:
+		value := valueHelp.asFloat64(val)
+		return Maximum(path, in, value, max, exclusive)
+	}
+}
+
+// MinimumNativeType provides native type constraint validation as a facade
+// to various numeric types versions of Minimum constraint check.
+//
+// Assumes that any possible loss conversion during conversion has been
+// checked beforehand.
+//
+// NOTE: currently, the min value is marshalled as a float64, no matter what,
+// which means there may be a loss during conversions (e.g. for very large integers)
+//
+// TODO: Normally, a JSON MAX_SAFE_INTEGER check would ensure conversion remains loss-free
+func MinimumNativeType(path, in string, val interface{}, min float64, exclusive bool) *errors.Validation {
+	kind := reflect.ValueOf(val).Type().Kind()
+	switch kind {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		value := valueHelp.asInt64(val)
+		return MinimumInt(path, in, value, int64(min), exclusive)
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		value := valueHelp.asUint64(val)
+		if min < 0 {
+			return nil
+		}
+		return MinimumUint(path, in, value, uint64(min), exclusive)
+	case reflect.Float32, reflect.Float64:
+		fallthrough
+	default:
+		value := valueHelp.asFloat64(val)
+		return Minimum(path, in, value, min, exclusive)
+	}
+}
+
+// MultipleOfNativeType provides native type constraint validation as a facade
+// to various numeric types version of MultipleOf constraint check.
+//
+// Assumes that any possible loss conversion during conversion has been
+// checked beforehand.
+//
+// NOTE: currently, the multipleOf factor is marshalled as a float64, no matter what,
+// which means there may be a loss during conversions (e.g. for very large integers)
+//
+// TODO: Normally, a JSON MAX_SAFE_INTEGER check would ensure conversion remains loss-free
+func MultipleOfNativeType(path, in string, val interface{}, multipleOf float64) *errors.Validation {
+	kind := reflect.ValueOf(val).Type().Kind()
+	switch kind {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		value := valueHelp.asInt64(val)
+		return MultipleOfInt(path, in, value, int64(multipleOf))
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		value := valueHelp.asUint64(val)
+		return MultipleOfUint(path, in, value, uint64(multipleOf))
+	case reflect.Float32, reflect.Float64:
+		fallthrough
+	default:
+		value := valueHelp.asFloat64(val)
+		return MultipleOf(path, in, value, multipleOf)
+	}
+}
+
+// IsValueValidAgainstRange checks that a numeric value is compatible with
+// the range defined by Type and Format, that is, may be converted without loss.
+//
+// NOTE: this check is about type capacity and not formal verification such as: 1.0 != 1L
+func IsValueValidAgainstRange(val interface{}, typeName, format, prefix, path string) error {
+	kind := reflect.ValueOf(val).Type().Kind()
+
+	// What is the string representation of val
+	stringRep := ""
+	switch kind {
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		stringRep = swag.FormatUint64(valueHelp.asUint64(val))
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		stringRep = swag.FormatInt64(valueHelp.asInt64(val))
+	case reflect.Float32, reflect.Float64:
+		stringRep = swag.FormatFloat64(valueHelp.asFloat64(val))
+	default:
+		return fmt.Errorf("%s value number range checking called with invalid (non numeric) val type in %s", prefix, path)
+	}
+
+	var errVal error
+
+	switch typeName {
+	case "integer":
+		switch format {
+		case "int32":
+			_, errVal = swag.ConvertInt32(stringRep)
+		case "uint32":
+			_, errVal = swag.ConvertUint32(stringRep)
+		case "uint64":
+			_, errVal = swag.ConvertUint64(stringRep)
+		case "int64":
+			fallthrough
+		default:
+			_, errVal = swag.ConvertInt64(stringRep)
+		}
+	case "number":
+		fallthrough
+	default:
+		switch format {
+		case "float", "float32":
+			_, errVal = swag.ConvertFloat32(stringRep)
+		case "double", "float64":
+			fallthrough
+		default:
+			// No check can be performed here since
+			// no number beyond float64 is supported
+		}
+	}
+	if errVal != nil { // We don't report the actual errVal from strconv
+		if format != "" {
+			errVal = fmt.Errorf("%s value must be of type %s with format %s in %s", prefix, typeName, format, path)
+		} else {
+			errVal = fmt.Errorf("%s value must be of type %s (default format) in %s", prefix, typeName, path)
+		}
+	}
+	return errVal
+}
