vendorify
diff --git a/go/vendor/github.com/go-openapi/analysis/.gitignore b/go/vendor/github.com/go-openapi/analysis/.gitignore
new file mode 100644
index 0000000..87c3bd3
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/analysis/.gitignore
@@ -0,0 +1,5 @@
+secrets.yml
+coverage.out
+coverage.txt
+*.cov
+.idea
diff --git a/go/vendor/github.com/go-openapi/analysis/.golangci.yml b/go/vendor/github.com/go-openapi/analysis/.golangci.yml
new file mode 100644
index 0000000..922278c
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/analysis/.golangci.yml
@@ -0,0 +1,19 @@
+linters-settings:
+  govet:
+    check-shadowing: true
+  golint:
+    min-confidence: 0
+  gocyclo:
+    min-complexity: 30
+  maligned:
+    suggest-new: true
+  dupl:
+    threshold: 100
+  goconst:
+    min-len: 2
+    min-occurrences: 4
+
+linters:
+  enable-all: true
+  disable:
+    - maligned
diff --git a/go/vendor/github.com/go-openapi/analysis/.travis.yml b/go/vendor/github.com/go-openapi/analysis/.travis.yml
new file mode 100644
index 0000000..9243555
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/analysis/.travis.yml
@@ -0,0 +1,24 @@
+after_success:
+- bash <(curl -s https://codecov.io/bash)
+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/docker/go-units
+- go get -u github.com/stretchr/testify/assert
+- go get -u gopkg.in/yaml.v2
+- go get -u github.com/go-openapi/swag
+- go get -u github.com/go-openapi/jsonpointer
+- go get -u github.com/go-openapi/spec
+- go get -u github.com/go-openapi/strfmt
+- go get -u github.com/go-openapi/loads/fmts
+language: go
+notifications:
+  slack:
+    secure: Sf7kZf7ZGbnwWUMpffHwMu5A0cHkLK2MYY32LNTPj4+/3qC3Ghl7+9v4TSLOqOlCwdRNjOGblAq7s+GDJed6/xgRQl1JtCi1klzZNrYX4q01pgTPvvGcwbBkIYgeMaPeIRcK9OZnud7sRXdttozgTOpytps2U6Js32ip7uj5mHSg2ub0FwoSJwlS6dbezZ8+eDhoha0F/guY99BEwx8Bd+zROrT2TFGsSGOFGN6wFc7moCqTHO/YkWib13a2QNXqOxCCVBy/lt76Wp+JkeFppjHlzs/2lP3EAk13RIUAaesdEUHvIHrzCyNJEd3/+KO2DzsWOYfpktd+KBCvgaYOsoo7ubdT3IROeAegZdCgo/6xgCEsmFc9ZcqCfN5yNx2A+BZ2Vwmpws+bQ1E1+B5HDzzaiLcYfG4X2O210QVGVDLWsv1jqD+uPYeHY2WRfh5ZsIUFvaqgUEnwHwrK44/8REAhQavt1QAj5uJpsRd7CkRVPWRNK+yIky+wgbVUFEchRNmS55E7QWf+W4+4QZkQi7vUTMc9nbTUu2Es9NfvfudOpM2wZbn98fjpb/qq/nRv6Bk+ca+7XD5/IgNLMbWp2ouDdzbiHLCOfDUiHiDJhLfFZx9Bwo7ZwfzeOlbrQX66bx7xRKYmOe4DLrXhNcpbsMa8qbfxlZRCmYbubB/Y8h4=
+script:
+- hack/coverage
diff --git a/go/vendor/github.com/go-openapi/analysis/CODE_OF_CONDUCT.md b/go/vendor/github.com/go-openapi/analysis/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..9322b06
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/analysis/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/analysis/LICENSE b/go/vendor/github.com/go-openapi/analysis/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/analysis/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/analysis/README.md b/go/vendor/github.com/go-openapi/analysis/README.md
new file mode 100644
index 0000000..3724bfc
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/analysis/README.md
@@ -0,0 +1,9 @@
+# OpenAPI initiative analysis [![Build Status](https://travis-ci.org/go-openapi/analysis.svg?branch=master)](https://travis-ci.org/go-openapi/analysis) [![codecov](https://codecov.io/gh/go-openapi/analysis/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/analysis) [![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/analysis/master/LICENSE)
+[![GoDoc](https://godoc.org/github.com/go-openapi/analysis?status.svg)](http://godoc.org/github.com/go-openapi/analysis)
+[![GolangCI](https://golangci.com/badges/github.com/go-openapi/analysis.svg)](https://golangci.com)
+[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/analysis)](https://goreportcard.com/report/github.com/go-openapi/analysis)
+
+
+A foundational library to analyze an OAI specification document for easier reasoning about the content.
diff --git a/go/vendor/github.com/go-openapi/analysis/analyzer.go b/go/vendor/github.com/go-openapi/analysis/analyzer.go
new file mode 100644
index 0000000..81dc18f
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/analysis/analyzer.go
@@ -0,0 +1,892 @@
+// 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 analysis
+
+import (
+	"fmt"
+	slashpath "path"
+	"strconv"
+	"strings"
+
+	"github.com/go-openapi/jsonpointer"
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/swag"
+)
+
+type referenceAnalysis struct {
+	schemas        map[string]spec.Ref
+	responses      map[string]spec.Ref
+	parameters     map[string]spec.Ref
+	items          map[string]spec.Ref
+	headerItems    map[string]spec.Ref
+	parameterItems map[string]spec.Ref
+	allRefs        map[string]spec.Ref
+	pathItems      map[string]spec.Ref
+}
+
+func (r *referenceAnalysis) addRef(key string, ref spec.Ref) {
+	r.allRefs["#"+key] = ref
+}
+
+func (r *referenceAnalysis) addItemsRef(key string, items *spec.Items, location string) {
+	r.items["#"+key] = items.Ref
+	r.addRef(key, items.Ref)
+	if location == "header" {
+		// NOTE: in swagger 2.0, headers and parameters (but not body param schemas) are simple schemas
+		// and $ref are not supported here. However it is possible to analyze this.
+		r.headerItems["#"+key] = items.Ref
+	} else {
+		r.parameterItems["#"+key] = items.Ref
+	}
+}
+
+func (r *referenceAnalysis) addSchemaRef(key string, ref SchemaRef) {
+	r.schemas["#"+key] = ref.Schema.Ref
+	r.addRef(key, ref.Schema.Ref)
+}
+
+func (r *referenceAnalysis) addResponseRef(key string, resp *spec.Response) {
+	r.responses["#"+key] = resp.Ref
+	r.addRef(key, resp.Ref)
+}
+
+func (r *referenceAnalysis) addParamRef(key string, param *spec.Parameter) {
+	r.parameters["#"+key] = param.Ref
+	r.addRef(key, param.Ref)
+}
+
+func (r *referenceAnalysis) addPathItemRef(key string, pathItem *spec.PathItem) {
+	r.pathItems["#"+key] = pathItem.Ref
+	r.addRef(key, pathItem.Ref)
+}
+
+type patternAnalysis struct {
+	parameters  map[string]string
+	headers     map[string]string
+	items       map[string]string
+	schemas     map[string]string
+	allPatterns map[string]string
+}
+
+func (p *patternAnalysis) addPattern(key, pattern string) {
+	p.allPatterns["#"+key] = pattern
+}
+
+func (p *patternAnalysis) addParameterPattern(key, pattern string) {
+	p.parameters["#"+key] = pattern
+	p.addPattern(key, pattern)
+}
+
+func (p *patternAnalysis) addHeaderPattern(key, pattern string) {
+	p.headers["#"+key] = pattern
+	p.addPattern(key, pattern)
+}
+
+func (p *patternAnalysis) addItemsPattern(key, pattern string) {
+	p.items["#"+key] = pattern
+	p.addPattern(key, pattern)
+}
+
+func (p *patternAnalysis) addSchemaPattern(key, pattern string) {
+	p.schemas["#"+key] = pattern
+	p.addPattern(key, pattern)
+}
+
+// New takes a swagger spec object and returns an analyzed spec document.
+// The analyzed document contains a number of indices that make it easier to
+// reason about semantics of a swagger specification for use in code generation
+// or validation etc.
+func New(doc *spec.Swagger) *Spec {
+	a := &Spec{
+		spec:        doc,
+		consumes:    make(map[string]struct{}, 150),
+		produces:    make(map[string]struct{}, 150),
+		authSchemes: make(map[string]struct{}, 150),
+		operations:  make(map[string]map[string]*spec.Operation, 150),
+		allSchemas:  make(map[string]SchemaRef, 150),
+		allOfs:      make(map[string]SchemaRef, 150),
+		references: referenceAnalysis{
+			schemas:        make(map[string]spec.Ref, 150),
+			pathItems:      make(map[string]spec.Ref, 150),
+			responses:      make(map[string]spec.Ref, 150),
+			parameters:     make(map[string]spec.Ref, 150),
+			items:          make(map[string]spec.Ref, 150),
+			headerItems:    make(map[string]spec.Ref, 150),
+			parameterItems: make(map[string]spec.Ref, 150),
+			allRefs:        make(map[string]spec.Ref, 150),
+		},
+		patterns: patternAnalysis{
+			parameters:  make(map[string]string, 150),
+			headers:     make(map[string]string, 150),
+			items:       make(map[string]string, 150),
+			schemas:     make(map[string]string, 150),
+			allPatterns: make(map[string]string, 150),
+		},
+	}
+	a.initialize()
+	return a
+}
+
+// Spec is an analyzed specification object. It takes a swagger spec object and turns it into a registry
+// with a bunch of utility methods to act on the information in the spec.
+type Spec struct {
+	spec        *spec.Swagger
+	consumes    map[string]struct{}
+	produces    map[string]struct{}
+	authSchemes map[string]struct{}
+	operations  map[string]map[string]*spec.Operation
+	references  referenceAnalysis
+	patterns    patternAnalysis
+	allSchemas  map[string]SchemaRef
+	allOfs      map[string]SchemaRef
+}
+
+func (s *Spec) reset() {
+	s.consumes = make(map[string]struct{}, 150)
+	s.produces = make(map[string]struct{}, 150)
+	s.authSchemes = make(map[string]struct{}, 150)
+	s.operations = make(map[string]map[string]*spec.Operation, 150)
+	s.allSchemas = make(map[string]SchemaRef, 150)
+	s.allOfs = make(map[string]SchemaRef, 150)
+	s.references.schemas = make(map[string]spec.Ref, 150)
+	s.references.pathItems = make(map[string]spec.Ref, 150)
+	s.references.responses = make(map[string]spec.Ref, 150)
+	s.references.parameters = make(map[string]spec.Ref, 150)
+	s.references.items = make(map[string]spec.Ref, 150)
+	s.references.headerItems = make(map[string]spec.Ref, 150)
+	s.references.parameterItems = make(map[string]spec.Ref, 150)
+	s.references.allRefs = make(map[string]spec.Ref, 150)
+	s.patterns.parameters = make(map[string]string, 150)
+	s.patterns.headers = make(map[string]string, 150)
+	s.patterns.items = make(map[string]string, 150)
+	s.patterns.schemas = make(map[string]string, 150)
+	s.patterns.allPatterns = make(map[string]string, 150)
+}
+
+func (s *Spec) reload() {
+	s.reset()
+	s.initialize()
+}
+
+func (s *Spec) initialize() {
+	for _, c := range s.spec.Consumes {
+		s.consumes[c] = struct{}{}
+	}
+	for _, c := range s.spec.Produces {
+		s.produces[c] = struct{}{}
+	}
+	for _, ss := range s.spec.Security {
+		for k := range ss {
+			s.authSchemes[k] = struct{}{}
+		}
+	}
+	for path, pathItem := range s.AllPaths() {
+		s.analyzeOperations(path, &pathItem)
+	}
+
+	for name, parameter := range s.spec.Parameters {
+		refPref := slashpath.Join("/parameters", jsonpointer.Escape(name))
+		if parameter.Items != nil {
+			s.analyzeItems("items", parameter.Items, refPref, "parameter")
+		}
+		if parameter.In == "body" && parameter.Schema != nil {
+			s.analyzeSchema("schema", *parameter.Schema, refPref)
+		}
+		if parameter.Pattern != "" {
+			s.patterns.addParameterPattern(refPref, parameter.Pattern)
+		}
+	}
+
+	for name, response := range s.spec.Responses {
+		refPref := slashpath.Join("/responses", jsonpointer.Escape(name))
+		for k, v := range response.Headers {
+			hRefPref := slashpath.Join(refPref, "headers", k)
+			if v.Items != nil {
+				s.analyzeItems("items", v.Items, hRefPref, "header")
+			}
+			if v.Pattern != "" {
+				s.patterns.addHeaderPattern(hRefPref, v.Pattern)
+			}
+		}
+		if response.Schema != nil {
+			s.analyzeSchema("schema", *response.Schema, refPref)
+		}
+	}
+
+	for name, schema := range s.spec.Definitions {
+		s.analyzeSchema(name, schema, "/definitions")
+	}
+	// TODO: after analyzing all things and flattening schemas etc
+	// resolve all the collected references to their final representations
+	// best put in a separate method because this could get expensive
+}
+
+func (s *Spec) analyzeOperations(path string, pi *spec.PathItem) {
+	// TODO: resolve refs here?
+	// Currently, operations declared via pathItem $ref are known only after expansion
+	op := pi
+	if pi.Ref.String() != "" {
+		key := slashpath.Join("/paths", jsonpointer.Escape(path))
+		s.references.addPathItemRef(key, pi)
+	}
+	s.analyzeOperation("GET", path, op.Get)
+	s.analyzeOperation("PUT", path, op.Put)
+	s.analyzeOperation("POST", path, op.Post)
+	s.analyzeOperation("PATCH", path, op.Patch)
+	s.analyzeOperation("DELETE", path, op.Delete)
+	s.analyzeOperation("HEAD", path, op.Head)
+	s.analyzeOperation("OPTIONS", path, op.Options)
+	for i, param := range op.Parameters {
+		refPref := slashpath.Join("/paths", jsonpointer.Escape(path), "parameters", strconv.Itoa(i))
+		if param.Ref.String() != "" {
+			s.references.addParamRef(refPref, &param)
+		}
+		if param.Pattern != "" {
+			s.patterns.addParameterPattern(refPref, param.Pattern)
+		}
+		if param.Items != nil {
+			s.analyzeItems("items", param.Items, refPref, "parameter")
+		}
+		if param.Schema != nil {
+			s.analyzeSchema("schema", *param.Schema, refPref)
+		}
+	}
+}
+
+func (s *Spec) analyzeItems(name string, items *spec.Items, prefix, location string) {
+	if items == nil {
+		return
+	}
+	refPref := slashpath.Join(prefix, name)
+	s.analyzeItems(name, items.Items, refPref, location)
+	if items.Ref.String() != "" {
+		s.references.addItemsRef(refPref, items, location)
+	}
+	if items.Pattern != "" {
+		s.patterns.addItemsPattern(refPref, items.Pattern)
+	}
+}
+
+func (s *Spec) analyzeOperation(method, path string, op *spec.Operation) {
+	if op == nil {
+		return
+	}
+
+	for _, c := range op.Consumes {
+		s.consumes[c] = struct{}{}
+	}
+	for _, c := range op.Produces {
+		s.produces[c] = struct{}{}
+	}
+	for _, ss := range op.Security {
+		for k := range ss {
+			s.authSchemes[k] = struct{}{}
+		}
+	}
+	if _, ok := s.operations[method]; !ok {
+		s.operations[method] = make(map[string]*spec.Operation)
+	}
+	s.operations[method][path] = op
+	prefix := slashpath.Join("/paths", jsonpointer.Escape(path), strings.ToLower(method))
+	for i, param := range op.Parameters {
+		refPref := slashpath.Join(prefix, "parameters", strconv.Itoa(i))
+		if param.Ref.String() != "" {
+			s.references.addParamRef(refPref, &param)
+		}
+		if param.Pattern != "" {
+			s.patterns.addParameterPattern(refPref, param.Pattern)
+		}
+		s.analyzeItems("items", param.Items, refPref, "parameter")
+		if param.In == "body" && param.Schema != nil {
+			s.analyzeSchema("schema", *param.Schema, refPref)
+		}
+	}
+	if op.Responses != nil {
+		if op.Responses.Default != nil {
+			refPref := slashpath.Join(prefix, "responses", "default")
+			if op.Responses.Default.Ref.String() != "" {
+				s.references.addResponseRef(refPref, op.Responses.Default)
+			}
+			for k, v := range op.Responses.Default.Headers {
+				hRefPref := slashpath.Join(refPref, "headers", k)
+				s.analyzeItems("items", v.Items, hRefPref, "header")
+				if v.Pattern != "" {
+					s.patterns.addHeaderPattern(hRefPref, v.Pattern)
+				}
+			}
+			if op.Responses.Default.Schema != nil {
+				s.analyzeSchema("schema", *op.Responses.Default.Schema, refPref)
+			}
+		}
+		for k, res := range op.Responses.StatusCodeResponses {
+			refPref := slashpath.Join(prefix, "responses", strconv.Itoa(k))
+			if res.Ref.String() != "" {
+				s.references.addResponseRef(refPref, &res)
+			}
+			for k, v := range res.Headers {
+				hRefPref := slashpath.Join(refPref, "headers", k)
+				s.analyzeItems("items", v.Items, hRefPref, "header")
+				if v.Pattern != "" {
+					s.patterns.addHeaderPattern(hRefPref, v.Pattern)
+				}
+			}
+			if res.Schema != nil {
+				s.analyzeSchema("schema", *res.Schema, refPref)
+			}
+		}
+	}
+}
+
+func (s *Spec) analyzeSchema(name string, schema spec.Schema, prefix string) {
+	refURI := slashpath.Join(prefix, jsonpointer.Escape(name))
+	schRef := SchemaRef{
+		Name:     name,
+		Schema:   &schema,
+		Ref:      spec.MustCreateRef("#" + refURI),
+		TopLevel: prefix == "/definitions",
+	}
+
+	s.allSchemas["#"+refURI] = schRef
+
+	if schema.Ref.String() != "" {
+		s.references.addSchemaRef(refURI, schRef)
+	}
+	if schema.Pattern != "" {
+		s.patterns.addSchemaPattern(refURI, schema.Pattern)
+	}
+
+	for k, v := range schema.Definitions {
+		s.analyzeSchema(k, v, slashpath.Join(refURI, "definitions"))
+	}
+	for k, v := range schema.Properties {
+		s.analyzeSchema(k, v, slashpath.Join(refURI, "properties"))
+	}
+	for k, v := range schema.PatternProperties {
+		// NOTE: swagger 2.0 does not support PatternProperties.
+		// However it is possible to analyze this in a schema
+		s.analyzeSchema(k, v, slashpath.Join(refURI, "patternProperties"))
+	}
+	for i, v := range schema.AllOf {
+		s.analyzeSchema(strconv.Itoa(i), v, slashpath.Join(refURI, "allOf"))
+	}
+	if len(schema.AllOf) > 0 {
+		s.allOfs["#"+refURI] = schRef
+	}
+	for i, v := range schema.AnyOf {
+		// NOTE: swagger 2.0 does not support anyOf constructs.
+		// However it is possible to analyze this in a schema
+		s.analyzeSchema(strconv.Itoa(i), v, slashpath.Join(refURI, "anyOf"))
+	}
+	for i, v := range schema.OneOf {
+		// NOTE: swagger 2.0 does not support oneOf constructs.
+		// However it is possible to analyze this in a schema
+		s.analyzeSchema(strconv.Itoa(i), v, slashpath.Join(refURI, "oneOf"))
+	}
+	if schema.Not != nil {
+		// NOTE: swagger 2.0 does not support "not" constructs.
+		// However it is possible to analyze this in a schema
+		s.analyzeSchema("not", *schema.Not, refURI)
+	}
+	if schema.AdditionalProperties != nil && schema.AdditionalProperties.Schema != nil {
+		s.analyzeSchema("additionalProperties", *schema.AdditionalProperties.Schema, refURI)
+	}
+	if schema.AdditionalItems != nil && schema.AdditionalItems.Schema != nil {
+		// NOTE: swagger 2.0 does not support AdditionalItems.
+		// However it is possible to analyze this in a schema
+		s.analyzeSchema("additionalItems", *schema.AdditionalItems.Schema, refURI)
+	}
+	if schema.Items != nil {
+		if schema.Items.Schema != nil {
+			s.analyzeSchema("items", *schema.Items.Schema, refURI)
+		}
+		for i, sch := range schema.Items.Schemas {
+			s.analyzeSchema(strconv.Itoa(i), sch, slashpath.Join(refURI, "items"))
+		}
+	}
+}
+
+// SecurityRequirement is a representation of a security requirement for an operation
+type SecurityRequirement struct {
+	Name   string
+	Scopes []string
+}
+
+// SecurityRequirementsFor gets the security requirements for the operation
+func (s *Spec) SecurityRequirementsFor(operation *spec.Operation) [][]SecurityRequirement {
+	if s.spec.Security == nil && operation.Security == nil {
+		return nil
+	}
+
+	schemes := s.spec.Security
+	if operation.Security != nil {
+		schemes = operation.Security
+	}
+
+	result := [][]SecurityRequirement{}
+	for _, scheme := range schemes {
+		if len(scheme) == 0 {
+			// append a zero object for anonymous
+			result = append(result, []SecurityRequirement{{}})
+			continue
+		}
+		var reqs []SecurityRequirement
+		for k, v := range scheme {
+			if v == nil {
+				v = []string{}
+			}
+			reqs = append(reqs, SecurityRequirement{Name: k, Scopes: v})
+		}
+		result = append(result, reqs)
+	}
+	return result
+}
+
+// SecurityDefinitionsForRequirements gets the matching security definitions for a set of requirements
+func (s *Spec) SecurityDefinitionsForRequirements(requirements []SecurityRequirement) map[string]spec.SecurityScheme {
+	result := make(map[string]spec.SecurityScheme)
+
+	for _, v := range requirements {
+		if definition, ok := s.spec.SecurityDefinitions[v.Name]; ok {
+			if definition != nil {
+				result[v.Name] = *definition
+			}
+		}
+	}
+	return result
+}
+
+// SecurityDefinitionsFor gets the matching security definitions for a set of requirements
+func (s *Spec) SecurityDefinitionsFor(operation *spec.Operation) map[string]spec.SecurityScheme {
+	requirements := s.SecurityRequirementsFor(operation)
+	if len(requirements) == 0 {
+		return nil
+	}
+
+	result := make(map[string]spec.SecurityScheme)
+	for _, reqs := range requirements {
+		for _, v := range reqs {
+			if v.Name == "" {
+				// optional requirement
+				continue
+			}
+			if _, ok := result[v.Name]; ok {
+				// duplicate requirement
+				continue
+			}
+			if definition, ok := s.spec.SecurityDefinitions[v.Name]; ok {
+				if definition != nil {
+					result[v.Name] = *definition
+				}
+			}
+		}
+	}
+	return result
+}
+
+// ConsumesFor gets the mediatypes for the operation
+func (s *Spec) ConsumesFor(operation *spec.Operation) []string {
+
+	if len(operation.Consumes) == 0 {
+		cons := make(map[string]struct{}, len(s.spec.Consumes))
+		for _, k := range s.spec.Consumes {
+			cons[k] = struct{}{}
+		}
+		return s.structMapKeys(cons)
+	}
+
+	cons := make(map[string]struct{}, len(operation.Consumes))
+	for _, c := range operation.Consumes {
+		cons[c] = struct{}{}
+	}
+	return s.structMapKeys(cons)
+}
+
+// ProducesFor gets the mediatypes for the operation
+func (s *Spec) ProducesFor(operation *spec.Operation) []string {
+	if len(operation.Produces) == 0 {
+		prod := make(map[string]struct{}, len(s.spec.Produces))
+		for _, k := range s.spec.Produces {
+			prod[k] = struct{}{}
+		}
+		return s.structMapKeys(prod)
+	}
+
+	prod := make(map[string]struct{}, len(operation.Produces))
+	for _, c := range operation.Produces {
+		prod[c] = struct{}{}
+	}
+	return s.structMapKeys(prod)
+}
+
+func mapKeyFromParam(param *spec.Parameter) string {
+	return fmt.Sprintf("%s#%s", param.In, fieldNameFromParam(param))
+}
+
+func fieldNameFromParam(param *spec.Parameter) string {
+	// TODO: this should be x-go-name
+	if nm, ok := param.Extensions.GetString("go-name"); ok {
+		return nm
+	}
+	return swag.ToGoName(param.Name)
+}
+
+// ErrorOnParamFunc is a callback function to be invoked
+// whenever an error is encountered while resolving references
+// on parameters.
+//
+// This function takes as input the spec.Parameter which triggered the
+// error and the error itself.
+//
+// If the callback function returns false, the calling function should bail.
+//
+// If it returns true, the calling function should continue evaluating parameters.
+// A nil ErrorOnParamFunc must be evaluated as equivalent to panic().
+type ErrorOnParamFunc func(spec.Parameter, error) bool
+
+func (s *Spec) paramsAsMap(parameters []spec.Parameter, res map[string]spec.Parameter, callmeOnError ErrorOnParamFunc) {
+	for _, param := range parameters {
+		pr := param
+		if pr.Ref.String() != "" {
+			obj, _, err := pr.Ref.GetPointer().Get(s.spec)
+			if err != nil {
+				if callmeOnError != nil {
+					if callmeOnError(param, fmt.Errorf("invalid reference: %q", pr.Ref.String())) {
+						continue
+					}
+					break
+				} else {
+					panic(fmt.Sprintf("invalid reference: %q", pr.Ref.String()))
+				}
+			}
+			if objAsParam, ok := obj.(spec.Parameter); ok {
+				pr = objAsParam
+			} else {
+				if callmeOnError != nil {
+					if callmeOnError(param, fmt.Errorf("resolved reference is not a parameter: %q", pr.Ref.String())) {
+						continue
+					}
+					break
+				} else {
+					panic(fmt.Sprintf("resolved reference is not a parameter: %q", pr.Ref.String()))
+				}
+			}
+		}
+		res[mapKeyFromParam(&pr)] = pr
+	}
+}
+
+// ParametersFor the specified operation id.
+//
+// Assumes parameters properly resolve references if any and that
+// such references actually resolve to a parameter object.
+// Otherwise, panics.
+func (s *Spec) ParametersFor(operationID string) []spec.Parameter {
+	return s.SafeParametersFor(operationID, nil)
+}
+
+// SafeParametersFor the specified operation id.
+//
+// Does not assume parameters properly resolve references or that
+// such references actually resolve to a parameter object.
+//
+// Upon error, invoke a ErrorOnParamFunc callback with the erroneous
+// parameters. If the callback is set to nil, panics upon errors.
+func (s *Spec) SafeParametersFor(operationID string, callmeOnError ErrorOnParamFunc) []spec.Parameter {
+	gatherParams := func(pi *spec.PathItem, op *spec.Operation) []spec.Parameter {
+		bag := make(map[string]spec.Parameter)
+		s.paramsAsMap(pi.Parameters, bag, callmeOnError)
+		s.paramsAsMap(op.Parameters, bag, callmeOnError)
+
+		var res []spec.Parameter
+		for _, v := range bag {
+			res = append(res, v)
+		}
+		return res
+	}
+	for _, pi := range s.spec.Paths.Paths {
+		if pi.Get != nil && pi.Get.ID == operationID {
+			return gatherParams(&pi, pi.Get)
+		}
+		if pi.Head != nil && pi.Head.ID == operationID {
+			return gatherParams(&pi, pi.Head)
+		}
+		if pi.Options != nil && pi.Options.ID == operationID {
+			return gatherParams(&pi, pi.Options)
+		}
+		if pi.Post != nil && pi.Post.ID == operationID {
+			return gatherParams(&pi, pi.Post)
+		}
+		if pi.Patch != nil && pi.Patch.ID == operationID {
+			return gatherParams(&pi, pi.Patch)
+		}
+		if pi.Put != nil && pi.Put.ID == operationID {
+			return gatherParams(&pi, pi.Put)
+		}
+		if pi.Delete != nil && pi.Delete.ID == operationID {
+			return gatherParams(&pi, pi.Delete)
+		}
+	}
+	return nil
+}
+
+// ParamsFor the specified method and path. Aggregates them with the defaults etc, so it's all the params that
+// apply for the method and path.
+//
+// Assumes parameters properly resolve references if any and that
+// such references actually resolve to a parameter object.
+// Otherwise, panics.
+func (s *Spec) ParamsFor(method, path string) map[string]spec.Parameter {
+	return s.SafeParamsFor(method, path, nil)
+}
+
+// SafeParamsFor the specified method and path. Aggregates them with the defaults etc, so it's all the params that
+// apply for the method and path.
+//
+// Does not assume parameters properly resolve references or that
+// such references actually resolve to a parameter object.
+//
+// Upon error, invoke a ErrorOnParamFunc callback with the erroneous
+// parameters. If the callback is set to nil, panics upon errors.
+func (s *Spec) SafeParamsFor(method, path string, callmeOnError ErrorOnParamFunc) map[string]spec.Parameter {
+	res := make(map[string]spec.Parameter)
+	if pi, ok := s.spec.Paths.Paths[path]; ok {
+		s.paramsAsMap(pi.Parameters, res, callmeOnError)
+		s.paramsAsMap(s.operations[strings.ToUpper(method)][path].Parameters, res, callmeOnError)
+	}
+	return res
+}
+
+// OperationForName gets the operation for the given id
+func (s *Spec) OperationForName(operationID string) (string, string, *spec.Operation, bool) {
+	for method, pathItem := range s.operations {
+		for path, op := range pathItem {
+			if operationID == op.ID {
+				return method, path, op, true
+			}
+		}
+	}
+	return "", "", nil, false
+}
+
+// OperationFor the given method and path
+func (s *Spec) OperationFor(method, path string) (*spec.Operation, bool) {
+	if mp, ok := s.operations[strings.ToUpper(method)]; ok {
+		op, fn := mp[path]
+		return op, fn
+	}
+	return nil, false
+}
+
+// Operations gathers all the operations specified in the spec document
+func (s *Spec) Operations() map[string]map[string]*spec.Operation {
+	return s.operations
+}
+
+func (s *Spec) structMapKeys(mp map[string]struct{}) []string {
+	if len(mp) == 0 {
+		return nil
+	}
+
+	result := make([]string, 0, len(mp))
+	for k := range mp {
+		result = append(result, k)
+	}
+	return result
+}
+
+// AllPaths returns all the paths in the swagger spec
+func (s *Spec) AllPaths() map[string]spec.PathItem {
+	if s.spec == nil || s.spec.Paths == nil {
+		return nil
+	}
+	return s.spec.Paths.Paths
+}
+
+// OperationIDs gets all the operation ids based on method an dpath
+func (s *Spec) OperationIDs() []string {
+	if len(s.operations) == 0 {
+		return nil
+	}
+	result := make([]string, 0, len(s.operations))
+	for method, v := range s.operations {
+		for p, o := range v {
+			if o.ID != "" {
+				result = append(result, o.ID)
+			} else {
+				result = append(result, fmt.Sprintf("%s %s", strings.ToUpper(method), p))
+			}
+		}
+	}
+	return result
+}
+
+// OperationMethodPaths gets all the operation ids based on method an dpath
+func (s *Spec) OperationMethodPaths() []string {
+	if len(s.operations) == 0 {
+		return nil
+	}
+	result := make([]string, 0, len(s.operations))
+	for method, v := range s.operations {
+		for p := range v {
+			result = append(result, fmt.Sprintf("%s %s", strings.ToUpper(method), p))
+		}
+	}
+	return result
+}
+
+// RequiredConsumes gets all the distinct consumes that are specified in the specification document
+func (s *Spec) RequiredConsumes() []string {
+	return s.structMapKeys(s.consumes)
+}
+
+// RequiredProduces gets all the distinct produces that are specified in the specification document
+func (s *Spec) RequiredProduces() []string {
+	return s.structMapKeys(s.produces)
+}
+
+// RequiredSecuritySchemes gets all the distinct security schemes that are specified in the swagger spec
+func (s *Spec) RequiredSecuritySchemes() []string {
+	return s.structMapKeys(s.authSchemes)
+}
+
+// SchemaRef is a reference to a schema
+type SchemaRef struct {
+	Name     string
+	Ref      spec.Ref
+	Schema   *spec.Schema
+	TopLevel bool
+}
+
+// SchemasWithAllOf returns schema references to all schemas that are defined
+// with an allOf key
+func (s *Spec) SchemasWithAllOf() (result []SchemaRef) {
+	for _, v := range s.allOfs {
+		result = append(result, v)
+	}
+	return
+}
+
+// AllDefinitions returns schema references for all the definitions that were discovered
+func (s *Spec) AllDefinitions() (result []SchemaRef) {
+	for _, v := range s.allSchemas {
+		result = append(result, v)
+	}
+	return
+}
+
+// AllDefinitionReferences returns json refs for all the discovered schemas
+func (s *Spec) AllDefinitionReferences() (result []string) {
+	for _, v := range s.references.schemas {
+		result = append(result, v.String())
+	}
+	return
+}
+
+// AllParameterReferences returns json refs for all the discovered parameters
+func (s *Spec) AllParameterReferences() (result []string) {
+	for _, v := range s.references.parameters {
+		result = append(result, v.String())
+	}
+	return
+}
+
+// AllResponseReferences returns json refs for all the discovered responses
+func (s *Spec) AllResponseReferences() (result []string) {
+	for _, v := range s.references.responses {
+		result = append(result, v.String())
+	}
+	return
+}
+
+// AllPathItemReferences returns the references for all the items
+func (s *Spec) AllPathItemReferences() (result []string) {
+	for _, v := range s.references.pathItems {
+		result = append(result, v.String())
+	}
+	return
+}
+
+// AllItemsReferences returns the references for all the items in simple schemas (parameters or headers).
+//
+// NOTE: since Swagger 2.0 forbids $ref in simple params, this should always yield an empty slice for a valid
+// Swagger 2.0 spec.
+func (s *Spec) AllItemsReferences() (result []string) {
+	for _, v := range s.references.items {
+		result = append(result, v.String())
+	}
+	return
+}
+
+// AllReferences returns all the references found in the document, with possible duplicates
+func (s *Spec) AllReferences() (result []string) {
+	for _, v := range s.references.allRefs {
+		result = append(result, v.String())
+	}
+	return
+}
+
+// AllRefs returns all the unique references found in the document
+func (s *Spec) AllRefs() (result []spec.Ref) {
+	set := make(map[string]struct{})
+	for _, v := range s.references.allRefs {
+		a := v.String()
+		if a == "" {
+			continue
+		}
+		if _, ok := set[a]; !ok {
+			set[a] = struct{}{}
+			result = append(result, v)
+		}
+	}
+	return
+}
+
+func cloneStringMap(source map[string]string) map[string]string {
+	res := make(map[string]string, len(source))
+	for k, v := range source {
+		res[k] = v
+	}
+	return res
+}
+
+// ParameterPatterns returns all the patterns found in parameters
+// the map is cloned to avoid accidental changes
+func (s *Spec) ParameterPatterns() map[string]string {
+	return cloneStringMap(s.patterns.parameters)
+}
+
+// HeaderPatterns returns all the patterns found in response headers
+// the map is cloned to avoid accidental changes
+func (s *Spec) HeaderPatterns() map[string]string {
+	return cloneStringMap(s.patterns.headers)
+}
+
+// ItemsPatterns returns all the patterns found in simple array items
+// the map is cloned to avoid accidental changes
+func (s *Spec) ItemsPatterns() map[string]string {
+	return cloneStringMap(s.patterns.items)
+}
+
+// SchemaPatterns returns all the patterns found in schemas
+// the map is cloned to avoid accidental changes
+func (s *Spec) SchemaPatterns() map[string]string {
+	return cloneStringMap(s.patterns.schemas)
+}
+
+// AllPatterns returns all the patterns found in the spec
+// the map is cloned to avoid accidental changes
+func (s *Spec) AllPatterns() map[string]string {
+	return cloneStringMap(s.patterns.allPatterns)
+}
diff --git a/go/vendor/github.com/go-openapi/analysis/debug.go b/go/vendor/github.com/go-openapi/analysis/debug.go
new file mode 100644
index 0000000..84cc4e5
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/analysis/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 analysis
+
+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 the spec analyzer.
+	Debug = os.Getenv("SWAGGER_DEBUG") != ""
+	// analysisLogger is a debug logger for this package
+	analysisLogger *log.Logger
+)
+
+func init() {
+	debugOptions()
+}
+
+func debugOptions() {
+	analysisLogger = log.New(os.Stdout, "analysis:", 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)
+		analysisLogger.Printf("%s:%d: %s", filepath.Base(file1), pos1, fmt.Sprintf(msg, args...))
+	}
+}
diff --git a/go/vendor/github.com/go-openapi/analysis/doc.go b/go/vendor/github.com/go-openapi/analysis/doc.go
new file mode 100644
index 0000000..d5294c0
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/analysis/doc.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 analysis provides methods to work with a Swagger specification document from
+package go-openapi/spec.
+
+Analyzing a specification
+
+An analysed specification object (type Spec) provides methods to work with swagger definition.
+
+Flattening or expanding a specification
+
+Flattening a specification bundles all remote $ref in the main spec document.
+Depending on flattening options, additional preprocessing may take place:
+  - full flattening: replacing all inline complex constructs by a named entry in #/definitions
+  - expand: replace all $ref's in the document by their expanded content
+
+Merging several specifications
+
+Mixin several specifications merges all Swagger constructs, and warns about found conflicts.
+
+Fixing a specification
+
+Unmarshalling a specification with golang json unmarshalling may lead to
+some unwanted result on present but empty fields.
+
+Analyzing a Swagger schema
+
+Swagger schemas are analyzed to determine their complexity and qualify their content.
+*/
+package analysis
diff --git a/go/vendor/github.com/go-openapi/analysis/fixer.go b/go/vendor/github.com/go-openapi/analysis/fixer.go
new file mode 100644
index 0000000..bfe014c
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/analysis/fixer.go
@@ -0,0 +1,76 @@
+// 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 analysis
+
+import "github.com/go-openapi/spec"
+
+// FixEmptyResponseDescriptions replaces empty ("") response
+// descriptions in the input with "(empty)" to ensure that the
+// resulting Swagger is stays valid.  The problem appears to arise
+// from reading in valid specs that have a explicit response
+// description of "" (valid, response.description is required), but
+// due to zero values being omitted upon re-serializing (omitempty) we
+// lose them unless we stick some chars in there.
+func FixEmptyResponseDescriptions(s *spec.Swagger) {
+	if s.Paths != nil {
+		for _, v := range s.Paths.Paths {
+			if v.Get != nil {
+				FixEmptyDescs(v.Get.Responses)
+			}
+			if v.Put != nil {
+				FixEmptyDescs(v.Put.Responses)
+			}
+			if v.Post != nil {
+				FixEmptyDescs(v.Post.Responses)
+			}
+			if v.Delete != nil {
+				FixEmptyDescs(v.Delete.Responses)
+			}
+			if v.Options != nil {
+				FixEmptyDescs(v.Options.Responses)
+			}
+			if v.Head != nil {
+				FixEmptyDescs(v.Head.Responses)
+			}
+			if v.Patch != nil {
+				FixEmptyDescs(v.Patch.Responses)
+			}
+		}
+	}
+	for k, v := range s.Responses {
+		FixEmptyDesc(&v)
+		s.Responses[k] = v
+	}
+}
+
+// FixEmptyDescs adds "(empty)" as the description for any Response in
+// the given Responses object that doesn't already have one.
+func FixEmptyDescs(rs *spec.Responses) {
+	FixEmptyDesc(rs.Default)
+	for k, v := range rs.StatusCodeResponses {
+		FixEmptyDesc(&v)
+		rs.StatusCodeResponses[k] = v
+	}
+}
+
+// FixEmptyDesc adds "(empty)" as the description to the given
+// Response object if it doesn't already have one and isn't a
+// ref. No-op on nil input.
+func FixEmptyDesc(rs *spec.Response) {
+	if rs == nil || rs.Description != "" || rs.Ref.Ref.GetURL() != nil {
+		return
+	}
+	rs.Description = "(empty)"
+}
diff --git a/go/vendor/github.com/go-openapi/analysis/flatten.go b/go/vendor/github.com/go-openapi/analysis/flatten.go
new file mode 100644
index 0000000..5d98f21
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/analysis/flatten.go
@@ -0,0 +1,1500 @@
+// 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 analysis
+
+import (
+	"fmt"
+	"log"
+	"net/http"
+	"net/url"
+	"os"
+	slashpath "path"
+	"path/filepath"
+	"sort"
+	"strings"
+
+	"strconv"
+
+	"github.com/go-openapi/analysis/internal"
+	"github.com/go-openapi/jsonpointer"
+	swspec "github.com/go-openapi/spec"
+	"github.com/go-openapi/swag"
+)
+
+// FlattenOpts configuration for flattening a swagger specification.
+type FlattenOpts struct {
+	Spec           *Spec    // The analyzed spec to work with
+	flattenContext *context // Internal context to track flattening activity
+
+	BasePath string
+
+	// Flattening options
+	Expand       bool // If Expand is true, we skip flattening the spec and expand it instead
+	Minimal      bool
+	Verbose      bool
+	RemoveUnused bool
+
+	/* Extra keys */
+	_ struct{} // require keys
+}
+
+// ExpandOpts creates a spec.ExpandOptions to configure expanding a specification document.
+func (f *FlattenOpts) ExpandOpts(skipSchemas bool) *swspec.ExpandOptions {
+	return &swspec.ExpandOptions{RelativeBase: f.BasePath, SkipSchemas: skipSchemas}
+}
+
+// Swagger gets the swagger specification for this flatten operation
+func (f *FlattenOpts) Swagger() *swspec.Swagger {
+	return f.Spec.spec
+}
+
+// newRef stores information about refs created during the flattening process
+type newRef struct {
+	key      string
+	newName  string
+	path     string
+	isOAIGen bool
+	resolved bool
+	schema   *swspec.Schema
+	parents  []string
+}
+
+// context stores intermediary results from flatten
+type context struct {
+	newRefs  map[string]*newRef
+	warnings []string
+}
+
+func newContext() *context {
+	return &context{
+		newRefs:  make(map[string]*newRef, 150),
+		warnings: make([]string, 0),
+	}
+}
+
+// Flatten an analyzed spec and produce a self-contained spec bundle.
+//
+// There is a minimal and a full flattening mode.
+//
+// Minimally flattening a spec means:
+//  - Expanding parameters, responses, path items, parameter items and header items (references to schemas are left
+//    unscathed)
+//  - Importing external (http, file) references so they become internal to the document
+//  - Moving every JSON pointer to a $ref to a named definition (i.e. the reworked spec does not contain pointers
+//    like "$ref": "#/definitions/myObject/allOfs/1")
+//
+// A minimally flattened spec thus guarantees the following properties:
+//  - all $refs point to a local definition (i.e. '#/definitions/...')
+//  - definitions are unique
+//
+// NOTE: arbitrary JSON pointers (other than $refs to top level definitions) are rewritten as definitions if they
+// represent a complex schema or express commonality in the spec.
+// Otherwise, they are simply expanded.
+//
+// Minimal flattening is necessary and sufficient for codegen rendering using go-swagger.
+//
+// Fully flattening a spec means:
+//  - Moving every complex inline schema to be a definition with an auto-generated name in a depth-first fashion.
+//
+// By complex, we mean every JSON object with some properties.
+// Arrays, when they do not define a tuple,
+// or empty objects with or without additionalProperties, are not considered complex and remain inline.
+//
+// NOTE: rewritten schemas get a vendor extension x-go-gen-location so we know from which part of the spec definitions
+// have been created.
+//
+// Available flattening options:
+//  - Minimal: stops flattening after minimal $ref processing, leaving schema constructs untouched
+//  - Expand: expand all $ref's in the document (inoperant if Minimal set to true)
+//  - Verbose: croaks about name conflicts detected
+//  - RemoveUnused: removes unused parameters, responses and definitions after expansion/flattening
+//
+// NOTE: expansion removes all $ref save circular $ref, which remain in place
+//
+// TODO: additional options
+//  - ProgagateNameExtensions: ensure that created entries properly follow naming rules when their parent have set a
+//    x-go-name extension
+//  - LiftAllOfs:
+//     - limit the flattening of allOf members when simple objects
+//     - merge allOf with validation only
+//     - merge allOf with extensions only
+//     - ...
+//
+func Flatten(opts FlattenOpts) error {
+	// Make sure opts.BasePath is an absolute path
+	if !filepath.IsAbs(opts.BasePath) {
+		cwd, _ := os.Getwd()
+		opts.BasePath = filepath.Join(cwd, opts.BasePath)
+	}
+
+	opts.flattenContext = newContext()
+
+	// recursively expand responses, parameters, path items and items in simple schemas
+	// TODO: we should not expand discriminated types
+	if err := swspec.ExpandSpec(opts.Swagger(), opts.ExpandOpts(!opts.Expand)); err != nil {
+		return err
+	}
+
+	// strip current file from $ref's, so we can recognize them as proper definitions
+	// In particular, this works around for issue go-openapi/spec#76: leading absolute file in $ref is stripped
+	if err := normalizeRef(&opts); err != nil {
+		return err
+	}
+
+	if opts.RemoveUnused {
+		// optionally removes shared parameters and responses already expanded (now unused)
+		// default parameters (i.e. under paths) remain.
+		opts.Swagger().Parameters = nil
+		opts.Swagger().Responses = nil
+	}
+
+	opts.Spec.reload() // re-analyze
+
+	// at this point there are no other references left but schemas
+	if err := importExternalReferences(&opts); err != nil {
+		return err
+	}
+	opts.Spec.reload() // re-analyze
+
+	if !opts.Minimal && !opts.Expand {
+		// full flattening: rewrite inline schemas (schemas that aren't simple types or arrays or maps)
+		if err := nameInlinedSchemas(&opts); err != nil {
+			return err
+		}
+
+		opts.Spec.reload() // re-analyze
+	}
+
+	// rewrite JSON pointers other than $ref to named definitions
+	// and attempts to resolve conflicting names
+	if err := stripPointersAndOAIGen(&opts); err != nil {
+		return err
+	}
+
+	if opts.RemoveUnused {
+		// remove unused definitions
+		expected := make(map[string]struct{})
+		for k := range opts.Swagger().Definitions {
+			expected[slashpath.Join(definitionsPath, jsonpointer.Escape(k))] = struct{}{}
+		}
+		for _, k := range opts.Spec.AllDefinitionReferences() {
+			if _, ok := expected[k]; ok {
+				delete(expected, k)
+			}
+		}
+		for k := range expected {
+			debugLog("removing unused definition %s", slashpath.Base(k))
+			if opts.Verbose {
+				log.Printf("info: removing unused definition: %s", slashpath.Base(k))
+			}
+			delete(opts.Swagger().Definitions, slashpath.Base(k))
+		}
+		opts.Spec.reload() // re-analyze
+	}
+
+	// TODO: simplify known schema patterns to flat objects with properties
+	// examples:
+	//  - lift simple allOf object,
+	//  - empty allOf with validation only or extensions only
+	//  - rework allOf arrays
+	//  - rework allOf additionalProperties
+
+	if opts.Verbose {
+		// issue notifications
+		croak(&opts)
+	}
+	return nil
+}
+
+// isAnalyzedAsComplex determines if an analyzed schema is eligible to flattening (i.e. it is "complex").
+//
+// Complex means the schema is any of:
+//  - a simple type (primitive)
+//  - an array of something (items are possibly complex ; if this is the case, items will generate a definition)
+//  - a map of something (additionalProperties are possibly complex ; if this is the case, additionalProperties will
+//    generate a definition)
+func isAnalyzedAsComplex(asch *AnalyzedSchema) bool {
+	if !asch.IsSimpleSchema && !asch.IsArray && !asch.IsMap {
+		return true
+	}
+	return false
+}
+
+// nameInlinedSchemas replaces every complex inline construct by a named definition.
+func nameInlinedSchemas(opts *FlattenOpts) error {
+	debugLog("nameInlinedSchemas")
+	namer := &inlineSchemaNamer{
+		Spec:           opts.Swagger(),
+		Operations:     opRefsByRef(gatherOperations(opts.Spec, nil)),
+		flattenContext: opts.flattenContext,
+		opts:           opts,
+	}
+	depthFirst := sortDepthFirst(opts.Spec.allSchemas)
+	for _, key := range depthFirst {
+		sch := opts.Spec.allSchemas[key]
+		if sch.Schema != nil && sch.Schema.Ref.String() == "" && !sch.TopLevel { // inline schema
+			asch, err := Schema(SchemaOpts{Schema: sch.Schema, Root: opts.Swagger(), BasePath: opts.BasePath})
+			if err != nil {
+				return fmt.Errorf("schema analysis [%s]: %v", key, err)
+			}
+
+			if isAnalyzedAsComplex(asch) { // move complex schemas to definitions
+				if err := namer.Name(key, sch.Schema, asch); err != nil {
+					return err
+				}
+			}
+		}
+	}
+	return nil
+}
+
+var depthGroupOrder = []string{
+	"sharedParam", "sharedResponse", "sharedOpParam", "opParam", "codeResponse", "defaultResponse", "definition",
+}
+
+func sortDepthFirst(data map[string]SchemaRef) []string {
+	// group by category (shared params, op param, statuscode response, default response, definitions)
+	// sort groups internally by number of parts in the key and lexical names
+	// flatten groups into a single list of keys
+	sorted := make([]string, 0, len(data))
+	grouped := make(map[string]keys, len(data))
+	for k := range data {
+		split := keyParts(k)
+		var pk string
+		if split.IsSharedOperationParam() {
+			pk = "sharedOpParam"
+		}
+		if split.IsOperationParam() {
+			pk = "opParam"
+		}
+		if split.IsStatusCodeResponse() {
+			pk = "codeResponse"
+		}
+		if split.IsDefaultResponse() {
+			pk = "defaultResponse"
+		}
+		if split.IsDefinition() {
+			pk = "definition"
+		}
+		if split.IsSharedParam() {
+			pk = "sharedParam"
+		}
+		if split.IsSharedResponse() {
+			pk = "sharedResponse"
+		}
+		grouped[pk] = append(grouped[pk], key{Segments: len(split), Key: k})
+	}
+
+	for _, pk := range depthGroupOrder {
+		res := grouped[pk]
+		sort.Sort(res)
+		for _, v := range res {
+			sorted = append(sorted, v.Key)
+		}
+	}
+	return sorted
+}
+
+type key struct {
+	Segments int
+	Key      string
+}
+type keys []key
+
+func (k keys) Len() int      { return len(k) }
+func (k keys) Swap(i, j int) { k[i], k[j] = k[j], k[i] }
+func (k keys) Less(i, j int) bool {
+	return k[i].Segments > k[j].Segments || (k[i].Segments == k[j].Segments && k[i].Key < k[j].Key)
+}
+
+type inlineSchemaNamer struct {
+	Spec           *swspec.Swagger
+	Operations     map[string]opRef
+	flattenContext *context
+	opts           *FlattenOpts
+}
+
+func opRefsByRef(oprefs map[string]opRef) map[string]opRef {
+	result := make(map[string]opRef, len(oprefs))
+	for _, v := range oprefs {
+		result[v.Ref.String()] = v
+	}
+	return result
+}
+
+func (isn *inlineSchemaNamer) Name(key string, schema *swspec.Schema, aschema *AnalyzedSchema) error {
+	debugLog("naming inlined schema at %s", key)
+
+	parts := keyParts(key)
+	for _, name := range namesFromKey(parts, aschema, isn.Operations) {
+		if name != "" {
+			// create unique name
+			newName, isOAIGen := uniqifyName(isn.Spec.Definitions, swag.ToJSONName(name))
+
+			// clone schema
+			sch, err := cloneSchema(schema)
+			if err != nil {
+				return err
+			}
+
+			// replace values on schema
+			if err := rewriteSchemaToRef(isn.Spec, key,
+				swspec.MustCreateRef(slashpath.Join(definitionsPath, newName))); err != nil {
+				return fmt.Errorf("error while creating definition %q from inline schema: %v", newName, err)
+			}
+
+			// rewrite any dependent $ref pointing to this place,
+			// when not already pointing to a top-level definition.
+			// NOTE: this is important if such referers use arbitrary JSON pointers.
+			an := New(isn.Spec)
+			for k, v := range an.references.allRefs {
+				r, _, erd := deepestRef(isn.opts, v)
+				if erd != nil {
+					return fmt.Errorf("at %s, %v", k, erd)
+				}
+				if r.String() == key ||
+					r.String() == slashpath.Join(definitionsPath, newName) &&
+						slashpath.Dir(v.String()) != definitionsPath {
+					debugLog("found a $ref to a rewritten schema: %s points to %s", k, v.String())
+					// rewrite $ref to the new target
+					if err := updateRef(isn.Spec, k,
+						swspec.MustCreateRef(slashpath.Join(definitionsPath, newName))); err != nil {
+						return err
+					}
+				}
+			}
+
+			// NOTE: this extension is currently not used by go-swagger (provided for information only)
+			sch.AddExtension("x-go-gen-location", genLocation(parts))
+			// save cloned schema to definitions
+			saveSchema(isn.Spec, newName, sch)
+
+			// keep track of created refs
+			if isn.flattenContext != nil {
+				debugLog("track created ref: key=%s, newName=%s, isOAIGen=%t", key, newName, isOAIGen)
+				resolved := false
+				if _, ok := isn.flattenContext.newRefs[key]; ok {
+					resolved = isn.flattenContext.newRefs[key].resolved
+				}
+				isn.flattenContext.newRefs[key] = &newRef{
+					key:      key,
+					newName:  newName,
+					path:     slashpath.Join(definitionsPath, newName),
+					isOAIGen: isOAIGen,
+					resolved: resolved,
+					schema:   sch,
+				}
+			}
+		}
+	}
+	return nil
+}
+
+// genLocation indicates from which section of the specification (models or operations) a definition has been created.
+// This is reflected in the output spec with a "x-go-gen-location" extension. At the moment, this is is provided
+// for information only.
+func genLocation(parts splitKey) string {
+	if parts.IsOperation() {
+		return "operations"
+	}
+	if parts.IsDefinition() {
+		return "models"
+	}
+	return ""
+}
+
+func uniqifyName(definitions swspec.Definitions, name string) (string, bool) {
+	isOAIGen := false
+	if name == "" {
+		name = "oaiGen"
+		isOAIGen = true
+	}
+	if len(definitions) == 0 {
+		return name, isOAIGen
+	}
+
+	unq := true
+	for k := range definitions {
+		if strings.ToLower(k) == strings.ToLower(name) {
+			unq = false
+			break
+		}
+	}
+
+	if unq {
+		return name, isOAIGen
+	}
+
+	name += "OAIGen"
+	isOAIGen = true
+	var idx int
+	unique := name
+	_, known := definitions[unique]
+	for known {
+		idx++
+		unique = fmt.Sprintf("%s%d", name, idx)
+		_, known = definitions[unique]
+	}
+	return unique, isOAIGen
+}
+
+func namesFromKey(parts splitKey, aschema *AnalyzedSchema, operations map[string]opRef) []string {
+	var baseNames [][]string
+	var startIndex int
+	if parts.IsOperation() {
+		// params
+		if parts.IsOperationParam() || parts.IsSharedOperationParam() {
+			piref := parts.PathItemRef()
+			if piref.String() != "" && parts.IsOperationParam() {
+				if op, ok := operations[piref.String()]; ok {
+					startIndex = 5
+					baseNames = append(baseNames, []string{op.ID, "params", "body"})
+				}
+			} else if parts.IsSharedOperationParam() {
+				pref := parts.PathRef()
+				for k, v := range operations {
+					if strings.HasPrefix(k, pref.String()) {
+						startIndex = 4
+						baseNames = append(baseNames, []string{v.ID, "params", "body"})
+					}
+				}
+			}
+		}
+		// responses
+		if parts.IsOperationResponse() {
+			piref := parts.PathItemRef()
+			if piref.String() != "" {
+				if op, ok := operations[piref.String()]; ok {
+					startIndex = 6
+					baseNames = append(baseNames, []string{op.ID, parts.ResponseName(), "body"})
+				}
+			}
+		}
+	}
+
+	// definitions
+	if parts.IsDefinition() {
+		nm := parts.DefinitionName()
+		if nm != "" {
+			startIndex = 2
+			baseNames = append(baseNames, []string{parts.DefinitionName()})
+		}
+	}
+
+	var result []string
+	for _, segments := range baseNames {
+		nm := parts.BuildName(segments, startIndex, aschema)
+		if nm != "" {
+			result = append(result, nm)
+		}
+	}
+	sort.Strings(result)
+	return result
+}
+
+const (
+	paths           = "paths"
+	responses       = "responses"
+	parameters      = "parameters"
+	definitions     = "definitions"
+	definitionsPath = "#/definitions"
+)
+
+var ignoredKeys map[string]struct{}
+
+func init() {
+	ignoredKeys = map[string]struct{}{
+		"schema":     {},
+		"properties": {},
+		"not":        {},
+		"anyOf":      {},
+		"oneOf":      {},
+	}
+}
+
+type splitKey []string
+
+func (s splitKey) IsDefinition() bool {
+	return len(s) > 1 && s[0] == definitions
+}
+
+func (s splitKey) DefinitionName() string {
+	if !s.IsDefinition() {
+		return ""
+	}
+	return s[1]
+}
+
+func (s splitKey) isKeyName(i int) bool {
+	if i <= 0 {
+		return false
+	}
+	count := 0
+	for idx := i - 1; idx > 0; idx-- {
+		if s[idx] != "properties" {
+			break
+		}
+		count++
+	}
+
+	return count%2 != 0
+}
+
+func (s splitKey) BuildName(segments []string, startIndex int, aschema *AnalyzedSchema) string {
+	for i, part := range s[startIndex:] {
+		if _, ignored := ignoredKeys[part]; !ignored || s.isKeyName(startIndex+i) {
+			if part == "items" || part == "additionalItems" {
+				if aschema.IsTuple || aschema.IsTupleWithExtra {
+					segments = append(segments, "tuple")
+				} else {
+					segments = append(segments, "items")
+				}
+				if part == "additionalItems" {
+					segments = append(segments, part)
+				}
+				continue
+			}
+			segments = append(segments, part)
+		}
+	}
+	return strings.Join(segments, " ")
+}
+
+func (s splitKey) IsOperation() bool {
+	return len(s) > 1 && s[0] == paths
+}
+
+func (s splitKey) IsSharedOperationParam() bool {
+	return len(s) > 2 && s[0] == paths && s[2] == parameters
+}
+
+func (s splitKey) IsSharedParam() bool {
+	return len(s) > 1 && s[0] == parameters
+}
+
+func (s splitKey) IsOperationParam() bool {
+	return len(s) > 3 && s[0] == paths && s[3] == parameters
+}
+
+func (s splitKey) IsOperationResponse() bool {
+	return len(s) > 3 && s[0] == paths && s[3] == responses
+}
+
+func (s splitKey) IsSharedResponse() bool {
+	return len(s) > 1 && s[0] == responses
+}
+
+func (s splitKey) IsDefaultResponse() bool {
+	return len(s) > 4 && s[0] == paths && s[3] == responses && s[4] == "default"
+}
+
+func (s splitKey) IsStatusCodeResponse() bool {
+	isInt := func() bool {
+		_, err := strconv.Atoi(s[4])
+		return err == nil
+	}
+	return len(s) > 4 && s[0] == paths && s[3] == responses && isInt()
+}
+
+func (s splitKey) ResponseName() string {
+	if s.IsStatusCodeResponse() {
+		code, _ := strconv.Atoi(s[4])
+		return http.StatusText(code)
+	}
+	if s.IsDefaultResponse() {
+		return "Default"
+	}
+	return ""
+}
+
+var validMethods map[string]struct{}
+
+func init() {
+	validMethods = map[string]struct{}{
+		"GET":     {},
+		"HEAD":    {},
+		"OPTIONS": {},
+		"PATCH":   {},
+		"POST":    {},
+		"PUT":     {},
+		"DELETE":  {},
+	}
+}
+
+func (s splitKey) PathItemRef() swspec.Ref {
+	if len(s) < 3 {
+		return swspec.Ref{}
+	}
+	pth, method := s[1], s[2]
+	if _, validMethod := validMethods[strings.ToUpper(method)]; !validMethod && !strings.HasPrefix(method, "x-") {
+		return swspec.Ref{}
+	}
+	return swspec.MustCreateRef("#" + slashpath.Join("/", paths, jsonpointer.Escape(pth), strings.ToUpper(method)))
+}
+
+func (s splitKey) PathRef() swspec.Ref {
+	if !s.IsOperation() {
+		return swspec.Ref{}
+	}
+	return swspec.MustCreateRef("#" + slashpath.Join("/", paths, jsonpointer.Escape(s[1])))
+}
+
+func keyParts(key string) splitKey {
+	var res []string
+	for _, part := range strings.Split(key[1:], "/") {
+		if part != "" {
+			res = append(res, jsonpointer.Unescape(part))
+		}
+	}
+	return res
+}
+
+func rewriteSchemaToRef(spec *swspec.Swagger, key string, ref swspec.Ref) error {
+	debugLog("rewriting schema to ref for %s with %s", key, ref.String())
+	_, value, err := getPointerFromKey(spec, key)
+	if err != nil {
+		return err
+	}
+
+	switch refable := value.(type) {
+	case *swspec.Schema:
+		return rewriteParentRef(spec, key, ref)
+
+	case swspec.Schema:
+		return rewriteParentRef(spec, key, ref)
+
+	case *swspec.SchemaOrArray:
+		if refable.Schema != nil {
+			refable.Schema = &swspec.Schema{SchemaProps: swspec.SchemaProps{Ref: ref}}
+		}
+
+	case *swspec.SchemaOrBool:
+		if refable.Schema != nil {
+			refable.Schema = &swspec.Schema{SchemaProps: swspec.SchemaProps{Ref: ref}}
+		}
+	default:
+		return fmt.Errorf("no schema with ref found at %s for %T", key, value)
+	}
+
+	return nil
+}
+
+func rewriteParentRef(spec *swspec.Swagger, key string, ref swspec.Ref) error {
+	parent, entry, pvalue, err := getParentFromKey(spec, key)
+	if err != nil {
+		return err
+	}
+
+	debugLog("rewriting holder for %T", pvalue)
+	switch container := pvalue.(type) {
+	case swspec.Response:
+		if err := rewriteParentRef(spec, "#"+parent, ref); err != nil {
+			return err
+		}
+
+	case *swspec.Response:
+		container.Schema = &swspec.Schema{SchemaProps: swspec.SchemaProps{Ref: ref}}
+
+	case *swspec.Responses:
+		statusCode, err := strconv.Atoi(entry)
+		if err != nil {
+			return fmt.Errorf("%s not a number: %v", key[1:], err)
+		}
+		resp := container.StatusCodeResponses[statusCode]
+		resp.Schema = &swspec.Schema{SchemaProps: swspec.SchemaProps{Ref: ref}}
+		container.StatusCodeResponses[statusCode] = resp
+
+	case map[string]swspec.Response:
+		resp := container[entry]
+		resp.Schema = &swspec.Schema{SchemaProps: swspec.SchemaProps{Ref: ref}}
+		container[entry] = resp
+
+	case swspec.Parameter:
+		if err := rewriteParentRef(spec, "#"+parent, ref); err != nil {
+			return err
+		}
+
+	case map[string]swspec.Parameter:
+		param := container[entry]
+		param.Schema = &swspec.Schema{SchemaProps: swspec.SchemaProps{Ref: ref}}
+		container[entry] = param
+
+	case []swspec.Parameter:
+		idx, err := strconv.Atoi(entry)
+		if err != nil {
+			return fmt.Errorf("%s not a number: %v", key[1:], err)
+		}
+		param := container[idx]
+		param.Schema = &swspec.Schema{SchemaProps: swspec.SchemaProps{Ref: ref}}
+		container[idx] = param
+
+	case swspec.Definitions:
+		container[entry] = swspec.Schema{SchemaProps: swspec.SchemaProps{Ref: ref}}
+
+	case map[string]swspec.Schema:
+		container[entry] = swspec.Schema{SchemaProps: swspec.SchemaProps{Ref: ref}}
+
+	case []swspec.Schema:
+		idx, err := strconv.Atoi(entry)
+		if err != nil {
+			return fmt.Errorf("%s not a number: %v", key[1:], err)
+		}
+		container[idx] = swspec.Schema{SchemaProps: swspec.SchemaProps{Ref: ref}}
+
+	case *swspec.SchemaOrArray:
+		// NOTE: this is necessarily an array - otherwise, the parent would be *Schema
+		idx, err := strconv.Atoi(entry)
+		if err != nil {
+			return fmt.Errorf("%s not a number: %v", key[1:], err)
+		}
+		container.Schemas[idx] = swspec.Schema{SchemaProps: swspec.SchemaProps{Ref: ref}}
+
+	// NOTE: can't have case *swspec.SchemaOrBool = parent in this case is *Schema
+
+	default:
+		return fmt.Errorf("unhandled parent schema rewrite %s (%T)", key, pvalue)
+	}
+	return nil
+}
+
+func cloneSchema(schema *swspec.Schema) (*swspec.Schema, error) {
+	var sch swspec.Schema
+	if err := swag.FromDynamicJSON(schema, &sch); err != nil {
+		return nil, fmt.Errorf("cannot clone schema: %v", err)
+	}
+	return &sch, nil
+}
+
+func importExternalReferences(opts *FlattenOpts) error {
+	groupedRefs := reverseIndexForSchemaRefs(opts)
+	sortedRefStr := make([]string, 0, len(groupedRefs))
+
+	// sort $ref resolution to ensure deterministic name conflict resolution
+	for refStr := range groupedRefs {
+		sortedRefStr = append(sortedRefStr, refStr)
+	}
+	sort.Strings(sortedRefStr)
+
+	for _, refStr := range sortedRefStr {
+		entry := groupedRefs[refStr]
+		if !entry.Ref.HasFragmentOnly {
+			debugLog("importing external schema for [%s] from %s", strings.Join(entry.Keys, ", "), refStr)
+			// resolve to actual schema
+			sch := new(swspec.Schema)
+			sch.Ref = entry.Ref
+			if err := swspec.ExpandSchemaWithBasePath(sch, nil, opts.ExpandOpts(false)); err != nil {
+				return err
+			}
+			if sch == nil {
+				return fmt.Errorf("no schema found at %s for [%s]", refStr, strings.Join(entry.Keys, ", "))
+			}
+			debugLog("importing external schema for [%s] from %s", strings.Join(entry.Keys, ", "), refStr)
+
+			// generate a unique name - isOAIGen means that a naming conflict was resolved by changing the name
+			newName, isOAIGen := uniqifyName(opts.Swagger().Definitions, nameFromRef(entry.Ref))
+			debugLog("new name for [%s]: %s - with name conflict:%t",
+				strings.Join(entry.Keys, ", "), newName, isOAIGen)
+
+			// rewrite the external refs to local ones
+			for _, key := range entry.Keys {
+				if err := updateRef(opts.Swagger(), key,
+					swspec.MustCreateRef(slashpath.Join(definitionsPath, newName))); err != nil {
+					return err
+				}
+
+				// keep track of created refs
+				if opts.flattenContext != nil {
+					resolved := false
+					if _, ok := opts.flattenContext.newRefs[key]; ok {
+						resolved = opts.flattenContext.newRefs[key].resolved
+					}
+					opts.flattenContext.newRefs[key] = &newRef{
+						key:      key,
+						newName:  newName,
+						path:     slashpath.Join(definitionsPath, newName),
+						isOAIGen: isOAIGen,
+						resolved: resolved,
+						schema:   sch,
+					}
+				}
+			}
+
+			// add the resolved schema to the definitions
+			saveSchema(opts.Swagger(), newName, sch)
+		}
+	}
+	return nil
+}
+
+type refRevIdx struct {
+	Ref  swspec.Ref
+	Keys []string
+}
+
+// normalizePath renders absolute path on remote file refs
+func normalizePath(ref swspec.Ref, opts *FlattenOpts) (normalizedPath string) {
+	if ref.HasFragmentOnly || filepath.IsAbs(ref.String()) {
+		normalizedPath = ref.String()
+		return
+	}
+
+	refURL, _ := url.Parse(ref.String())
+	if refURL.Host != "" {
+		normalizedPath = ref.String()
+		return
+	}
+
+	parts := strings.Split(ref.String(), "#")
+	parts[0] = filepath.Join(filepath.Dir(opts.BasePath), parts[0])
+	normalizedPath = strings.Join(parts, "#")
+	return
+}
+
+func reverseIndexForSchemaRefs(opts *FlattenOpts) map[string]refRevIdx {
+	collected := make(map[string]refRevIdx)
+	for key, schRef := range opts.Spec.references.schemas {
+		// normalize paths before sorting,
+		// so we get together keys in same external file
+		normalizedPath := normalizePath(schRef, opts)
+		if entry, ok := collected[normalizedPath]; ok {
+			entry.Keys = append(entry.Keys, key)
+			collected[normalizedPath] = entry
+		} else {
+			collected[normalizedPath] = refRevIdx{
+				Ref:  schRef,
+				Keys: []string{key},
+			}
+		}
+	}
+	return collected
+}
+
+func nameFromRef(ref swspec.Ref) string {
+	u := ref.GetURL()
+	if u.Fragment != "" {
+		return swag.ToJSONName(slashpath.Base(u.Fragment))
+	}
+	if u.Path != "" {
+		bn := slashpath.Base(u.Path)
+		if bn != "" && bn != "/" {
+			ext := slashpath.Ext(bn)
+			if ext != "" {
+				return swag.ToJSONName(bn[:len(bn)-len(ext)])
+			}
+			return swag.ToJSONName(bn)
+		}
+	}
+	return swag.ToJSONName(strings.Replace(u.Host, ".", " ", -1))
+}
+
+func saveSchema(spec *swspec.Swagger, name string, schema *swspec.Schema) {
+	if schema == nil {
+		return
+	}
+	if spec.Definitions == nil {
+		spec.Definitions = make(map[string]swspec.Schema, 150)
+	}
+	spec.Definitions[name] = *schema
+}
+
+// getPointerFromKey retrieves the content of the JSON pointer "key"
+func getPointerFromKey(spec *swspec.Swagger, key string) (string, interface{}, error) {
+	// unescape chars in key, e.g. "{}" from path params
+	pth, _ := internal.PathUnescape(key[1:])
+	ptr, err := jsonpointer.New(pth)
+	if err != nil {
+		return "", nil, err
+	}
+
+	value, _, err := ptr.Get(spec)
+	if err != nil {
+		debugLog("error when getting key: %s with path: %s", key, pth)
+		return "", nil, err
+	}
+	return pth, value, nil
+}
+
+// getParentFromKey retrieves the container of the JSON pointer "key"
+func getParentFromKey(spec *swspec.Swagger, key string) (string, string, interface{}, error) {
+	// unescape chars in key, e.g. "{}" from path params
+	pth, _ := internal.PathUnescape(key[1:])
+
+	parent, entry := slashpath.Dir(pth), slashpath.Base(pth)
+	debugLog("getting schema holder at: %s, with entry: %s", parent, entry)
+
+	pptr, err := jsonpointer.New(parent)
+	if err != nil {
+		return "", "", nil, err
+	}
+	pvalue, _, err := pptr.Get(spec)
+	if err != nil {
+		return "", "", nil, fmt.Errorf("can't get parent for %s: %v", parent, err)
+	}
+	return parent, entry, pvalue, nil
+}
+
+// updateRef replaces a ref by another one
+func updateRef(spec *swspec.Swagger, key string, ref swspec.Ref) error {
+	debugLog("updating ref for %s with %s", key, ref.String())
+	pth, value, err := getPointerFromKey(spec, key)
+	if err != nil {
+		return err
+	}
+
+	switch refable := value.(type) {
+	case *swspec.Schema:
+		refable.Ref = ref
+	case *swspec.SchemaOrArray:
+		if refable.Schema != nil {
+			refable.Schema.Ref = ref
+		}
+	case *swspec.SchemaOrBool:
+		if refable.Schema != nil {
+			refable.Schema.Ref = ref
+		}
+	case swspec.Schema:
+		debugLog("rewriting holder for %T", refable)
+		_, entry, pvalue, erp := getParentFromKey(spec, key)
+		if erp != nil {
+			return err
+		}
+		switch container := pvalue.(type) {
+		case swspec.Definitions:
+			container[entry] = swspec.Schema{SchemaProps: swspec.SchemaProps{Ref: ref}}
+
+		case map[string]swspec.Schema:
+			container[entry] = swspec.Schema{SchemaProps: swspec.SchemaProps{Ref: ref}}
+
+		case []swspec.Schema:
+			idx, err := strconv.Atoi(entry)
+			if err != nil {
+				return fmt.Errorf("%s not a number: %v", pth, err)
+			}
+			container[idx] = swspec.Schema{SchemaProps: swspec.SchemaProps{Ref: ref}}
+
+		case *swspec.SchemaOrArray:
+			// NOTE: this is necessarily an array - otherwise, the parent would be *Schema
+			idx, err := strconv.Atoi(entry)
+			if err != nil {
+				return fmt.Errorf("%s not a number: %v", pth, err)
+			}
+			container.Schemas[idx] = swspec.Schema{SchemaProps: swspec.SchemaProps{Ref: ref}}
+
+		// NOTE: can't have case *swspec.SchemaOrBool = parent in this case is *Schema
+
+		default:
+			return fmt.Errorf("unhandled container type at %s: %T", key, value)
+		}
+
+	default:
+		return fmt.Errorf("no schema with ref found at %s for %T", key, value)
+	}
+
+	return nil
+}
+
+// updateRefWithSchema replaces a ref with a schema (i.e. re-inline schema)
+func updateRefWithSchema(spec *swspec.Swagger, key string, sch *swspec.Schema) error {
+	debugLog("updating ref for %s with schema", key)
+	pth, value, err := getPointerFromKey(spec, key)
+	if err != nil {
+		return err
+	}
+
+	switch refable := value.(type) {
+	case *swspec.Schema:
+		*refable = *sch
+	case swspec.Schema:
+		_, entry, pvalue, erp := getParentFromKey(spec, key)
+		if erp != nil {
+			return err
+		}
+		switch container := pvalue.(type) {
+		case swspec.Definitions:
+			container[entry] = *sch
+
+		case map[string]swspec.Schema:
+			container[entry] = *sch
+
+		case []swspec.Schema:
+			idx, err := strconv.Atoi(entry)
+			if err != nil {
+				return fmt.Errorf("%s not a number: %v", pth, err)
+			}
+			container[idx] = *sch
+
+		case *swspec.SchemaOrArray:
+			// NOTE: this is necessarily an array - otherwise, the parent would be *Schema
+			idx, err := strconv.Atoi(entry)
+			if err != nil {
+				return fmt.Errorf("%s not a number: %v", pth, err)
+			}
+			container.Schemas[idx] = *sch
+
+		// NOTE: can't have case *swspec.SchemaOrBool = parent in this case is *Schema
+
+		default:
+			return fmt.Errorf("unhandled type for parent of [%s]: %T", key, value)
+		}
+	case *swspec.SchemaOrArray:
+		*refable.Schema = *sch
+	// NOTE: can't have case *swspec.SchemaOrBool = parent in this case is *Schema
+	case *swspec.SchemaOrBool:
+		*refable.Schema = *sch
+	default:
+		return fmt.Errorf("no schema with ref found at %s for %T", key, value)
+	}
+
+	return nil
+}
+
+func containsString(names []string, name string) bool {
+	for _, nm := range names {
+		if nm == name {
+			return true
+		}
+	}
+	return false
+}
+
+type opRef struct {
+	Method string
+	Path   string
+	Key    string
+	ID     string
+	Op     *swspec.Operation
+	Ref    swspec.Ref
+}
+
+type opRefs []opRef
+
+func (o opRefs) Len() int           { return len(o) }
+func (o opRefs) Swap(i, j int)      { o[i], o[j] = o[j], o[i] }
+func (o opRefs) Less(i, j int) bool { return o[i].Key < o[j].Key }
+
+func gatherOperations(specDoc *Spec, operationIDs []string) map[string]opRef {
+	var oprefs opRefs
+
+	for method, pathItem := range specDoc.Operations() {
+		for pth, operation := range pathItem {
+			vv := *operation
+			oprefs = append(oprefs, opRef{
+				Key:    swag.ToGoName(strings.ToLower(method) + " " + pth),
+				Method: method,
+				Path:   pth,
+				ID:     vv.ID,
+				Op:     &vv,
+				Ref:    swspec.MustCreateRef("#" + slashpath.Join("/paths", jsonpointer.Escape(pth), method)),
+			})
+		}
+	}
+
+	sort.Sort(oprefs)
+
+	operations := make(map[string]opRef)
+	for _, opr := range oprefs {
+		nm := opr.ID
+		if nm == "" {
+			nm = opr.Key
+		}
+
+		oo, found := operations[nm]
+		if found && oo.Method != opr.Method && oo.Path != opr.Path {
+			nm = opr.Key
+		}
+		if len(operationIDs) == 0 || containsString(operationIDs, opr.ID) || containsString(operationIDs, nm) {
+			opr.ID = nm
+			opr.Op.ID = nm
+			operations[nm] = opr
+		}
+	}
+	return operations
+}
+
+// stripPointersAndOAIGen removes anonymous JSON pointers from spec and chain with name conflicts handler.
+// This loops until the spec has no such pointer and all name conflicts have been reduced as much as possible.
+func stripPointersAndOAIGen(opts *FlattenOpts) error {
+	// name all JSON pointers to anonymous documents
+	if err := namePointers(opts); err != nil {
+		return err
+	}
+
+	// remove unnecessary OAIGen ref (created when flattening external refs creates name conflicts)
+	hasIntroducedPointerOrInline, ers := stripOAIGen(opts)
+	if ers != nil {
+		return ers
+	}
+
+	// iterate as pointer or OAIGen resolution may introduce inline schemas or pointers
+	for hasIntroducedPointerOrInline {
+		if !opts.Minimal {
+			if err := nameInlinedSchemas(opts); err != nil {
+				return err
+			}
+		}
+
+		if err := namePointers(opts); err != nil {
+			return err
+		}
+
+		// restrip
+		if hasIntroducedPointerOrInline, ers = stripOAIGen(opts); ers != nil {
+			return ers
+		}
+	}
+	return nil
+}
+
+// stripOAIGen strips the spec from unnecessary OAIGen constructs, initially created to dedupe flattened definitions.
+// A dedupe is deemed unnecessary whenever:
+//  - the only conflict is with its (single) parent: OAIGen is merged into its parent
+//  - there is a conflict with multiple parents: merge OAIGen in first parent, the rewrite other parents to point to
+//    the first parent.
+//
+// This function returns a true bool whenever it re-inlined a complex schema, so the caller may chose to iterate
+// flattening again.
+//
+// NOTE: the OAIGen definition cannot be itself a $ref.
+func stripOAIGen(opts *FlattenOpts) (bool, error) {
+	debugLog("stripOAIGen")
+	replacedWithComplex := false
+	for k, v := range opts.Spec.references.allRefs {
+		// figure out referers of OAIGen definitions
+		for _, r := range opts.flattenContext.newRefs {
+			if r.isOAIGen && !r.resolved && r.path == v.String() { // bail on already resolved entries (avoid looping)
+				r.parents = append(r.parents, k)
+			}
+		}
+	}
+
+	for _, r := range opts.flattenContext.newRefs {
+		if r.isOAIGen && len(r.parents) >= 1 && r.schema.Ref.String() == "" {
+			pr := r.parents
+			sort.Strings(pr)
+			// rewrite first parent schema in lexicographical order
+			debugLog("rewrite first parent %s with schema", pr[0])
+			if err := updateRefWithSchema(opts.Swagger(), pr[0], r.schema); err != nil {
+				return false, err
+			}
+			// rewrite other parents to point to first parent
+			if len(pr) > 1 {
+				for _, p := range pr[1:] {
+					replacingRef := swspec.MustCreateRef(pr[0])
+					// Set complex when replacing ref is an anonymous jsonpointer: further processing may be required
+					replacedWithComplex = replacedWithComplex ||
+						slashpath.Dir(replacingRef.String()) != definitionsPath
+					debugLog("rewrite parent with ref: %s", replacingRef.String())
+					// NOTE: it is possible at this stage to introduce json pointers (to non-definitions places).
+					// Those are stripped later on.
+					if err := updateRef(opts.Swagger(), p, replacingRef); err != nil {
+						return false, err
+					}
+				}
+			}
+			// remove OAIGen definition
+			debugLog("removing definition %s", slashpath.Base(r.path))
+			delete(opts.Swagger().Definitions, slashpath.Base(r.path))
+			// mark naming conflict as resolved
+			opts.flattenContext.newRefs[r.key].isOAIGen = false
+			opts.flattenContext.newRefs[r.key].resolved = true
+
+			// determine if the previous substitution did inline a complex schema
+			if r.schema != nil && r.schema.Ref.String() == "" { // inline schema
+				asch, err := Schema(SchemaOpts{Schema: r.schema, Root: opts.Swagger(), BasePath: opts.BasePath})
+				if err != nil {
+					return false, err
+				}
+				debugLog("re-inline schema: parent: %s, %t", pr[0], isAnalyzedAsComplex(asch))
+				replacedWithComplex = replacedWithComplex ||
+					!(slashpath.Dir(pr[0]) == definitionsPath) && isAnalyzedAsComplex(asch)
+			}
+		}
+	}
+	opts.Spec.reload() // re-analyze
+	return replacedWithComplex, nil
+}
+
+// croak logs notifications and warnings about valid, but possibly unwanted constructs resulting
+// from flattening a spec
+func croak(opts *FlattenOpts) {
+	reported := make(map[string]bool, len(opts.flattenContext.newRefs))
+	for _, v := range opts.Spec.references.allRefs {
+		// warns about duplicate handling
+		for _, r := range opts.flattenContext.newRefs {
+			if r.isOAIGen && r.path == v.String() {
+				reported[r.newName] = true
+			}
+		}
+	}
+	for k := range reported {
+		log.Printf("warning: duplicate flattened definition name resolved as %s", k)
+	}
+	// warns about possible type mismatches
+	uniqueMsg := make(map[string]bool)
+	for _, msg := range opts.flattenContext.warnings {
+		if _, ok := uniqueMsg[msg]; ok {
+			continue
+		}
+		log.Printf("warning: %s", msg)
+		uniqueMsg[msg] = true
+	}
+}
+
+// namePointers replaces all JSON pointers to anonymous documents by a $ref to a new named definitions.
+//
+// This is carried on depth-first. Pointers to $refs which are top level definitions are replaced by the $ref itself.
+// Pointers to simple types are expanded, unless they express commonality (i.e. several such $ref are used).
+func namePointers(opts *FlattenOpts) error {
+	debugLog("name pointers")
+	refsToReplace := make(map[string]SchemaRef, len(opts.Spec.references.schemas))
+	//for k, ref := range opts.Spec.references.schemas {
+	for k, ref := range opts.Spec.references.allRefs {
+		if slashpath.Dir(ref.String()) == definitionsPath {
+			// this a ref to a top-level definition: ok
+			continue
+		}
+		replacingRef, sch, erd := deepestRef(opts, ref)
+		if erd != nil {
+			return fmt.Errorf("at %s, %v", k, erd)
+		}
+		debugLog("planning pointer to replace at %s: %s, resolved to: %s", k, ref.String(), replacingRef.String())
+		refsToReplace[k] = SchemaRef{
+			Name:     k,            // caller
+			Ref:      replacingRef, // callee
+			Schema:   sch,
+			TopLevel: slashpath.Dir(replacingRef.String()) == definitionsPath,
+		}
+	}
+	depthFirst := sortDepthFirst(refsToReplace)
+	namer := &inlineSchemaNamer{
+		Spec:           opts.Swagger(),
+		Operations:     opRefsByRef(gatherOperations(opts.Spec, nil)),
+		flattenContext: opts.flattenContext,
+		opts:           opts,
+	}
+
+	for _, key := range depthFirst {
+		v := refsToReplace[key]
+		// update current replacement, which may have been updated by previous changes of deeper elements
+		replacingRef, sch, erd := deepestRef(opts, v.Ref)
+		if erd != nil {
+			return fmt.Errorf("at %s, %v", key, erd)
+		}
+		v.Ref = replacingRef
+		v.Schema = sch
+		v.TopLevel = slashpath.Dir(replacingRef.String()) == definitionsPath
+		debugLog("replacing pointer at %s: resolved to: %s", key, v.Ref.String())
+
+		if v.TopLevel {
+			debugLog("replace pointer %s by canonical definition: %s", key, v.Ref.String())
+			// if the schema is a $ref to a top level definition, just rewrite the pointer to this $ref
+			if err := updateRef(opts.Swagger(), key, v.Ref); err != nil {
+				return err
+			}
+		} else {
+			// this is a JSON pointer to an anonymous document (internal or external):
+			// create a definition for this schema when:
+			// - it is a complex schema
+			// - or it is pointed by more than one $ref (i.e. expresses commonality)
+			// otherwise, expand the pointer (single reference to a simple type)
+			//
+			// The named definition for this follows the target's key, not the caller's
+			debugLog("namePointers at %s for %s", key, v.Ref.String())
+
+			// qualify the expanded schema
+			asch, ers := Schema(SchemaOpts{Schema: v.Schema, Root: opts.Swagger(), BasePath: opts.BasePath})
+			if ers != nil {
+				return fmt.Errorf("schema analysis [%s]: %v", key, ers)
+			}
+			callers := make([]string, 0, 64)
+
+			debugLog("looking for callers")
+			an := New(opts.Swagger())
+			for k, w := range an.references.allRefs {
+				r, _, erd := deepestRef(opts, w)
+				if erd != nil {
+					return fmt.Errorf("at %s, %v", key, erd)
+				}
+				if r.String() == v.Ref.String() {
+					callers = append(callers, k)
+				}
+			}
+			debugLog("callers for %s: %d", v.Ref.String(), len(callers))
+			if len(callers) == 0 {
+				// has already been updated and resolved
+				continue
+			}
+
+			parts := keyParts(v.Ref.String())
+			debugLog("number of callers for %s: %d", v.Ref.String(), len(callers))
+			// identifying edge case when the namer did nothing because we point to a non-schema object
+			// no definition is created and we expand the $ref for all callers
+			if (!asch.IsSimpleSchema || len(callers) > 1) && !parts.IsSharedParam() && !parts.IsSharedResponse() {
+				debugLog("replace JSON pointer at [%s] by definition: %s", key, v.Ref.String())
+				if err := namer.Name(v.Ref.String(), v.Schema, asch); err != nil {
+					return err
+				}
+
+				// regular case: we named the $ref as a definition, and we move all callers to this new $ref
+				for _, caller := range callers {
+					if caller != key {
+						// move $ref for next to resolve
+						debugLog("identified caller of %s at [%s]", v.Ref.String(), caller)
+						c := refsToReplace[caller]
+						c.Ref = v.Ref
+						refsToReplace[caller] = c
+					}
+				}
+			} else {
+				debugLog("expand JSON pointer for key=%s", key)
+				if err := updateRefWithSchema(opts.Swagger(), key, v.Schema); err != nil {
+					return err
+				}
+				// NOTE: there is no other caller to update
+			}
+		}
+	}
+	opts.Spec.reload() // re-analyze
+	return nil
+}
+
+// deepestRef finds the first definition ref, from a cascade of nested refs which are not definitions.
+//  - if no definition is found, returns the deepest ref.
+//  - pointers to external files are expanded
+//
+// NOTE: all external $ref's are assumed to be already expanded at this stage.
+func deepestRef(opts *FlattenOpts, ref swspec.Ref) (swspec.Ref, *swspec.Schema, error) {
+	if !ref.HasFragmentOnly {
+		// does nothing on external $refs
+		return ref, nil, nil
+	}
+	currentRef := ref
+	visited := make(map[string]bool, 64)
+DOWNREF:
+	for currentRef.String() != "" {
+		if slashpath.Dir(currentRef.String()) == definitionsPath {
+			// this is a top-level definition: stop here and return this ref
+			return currentRef, nil, nil
+		}
+		if _, beenThere := visited[currentRef.String()]; beenThere {
+			return swspec.Ref{}, nil,
+				fmt.Errorf("cannot resolve cyclic chain of pointers under %s", currentRef.String())
+		}
+		visited[currentRef.String()] = true
+		value, _, err := currentRef.GetPointer().Get(opts.Swagger())
+		if err != nil {
+			return swspec.Ref{}, nil, err
+		}
+		switch refable := value.(type) {
+		case *swspec.Schema:
+			if refable.Ref.String() == "" {
+				break DOWNREF
+			}
+			currentRef = refable.Ref
+
+		case swspec.Schema:
+			if refable.Ref.String() == "" {
+				break DOWNREF
+			}
+			currentRef = refable.Ref
+
+		case *swspec.SchemaOrArray:
+			if refable.Schema == nil || refable.Schema != nil && refable.Schema.Ref.String() == "" {
+				break DOWNREF
+			}
+			currentRef = refable.Schema.Ref
+
+		case *swspec.SchemaOrBool:
+			if refable.Schema == nil || refable.Schema != nil && refable.Schema.Ref.String() == "" {
+				break DOWNREF
+			}
+			currentRef = refable.Schema.Ref
+
+		case swspec.Response:
+			// a pointer points to a schema initially marshalled in responses section...
+			// Attempt to convert this to a schema. If this fails, the spec is invalid
+			asJSON, _ := refable.MarshalJSON()
+			var asSchema swspec.Schema
+			err := asSchema.UnmarshalJSON(asJSON)
+			if err != nil {
+				return swspec.Ref{}, nil,
+					fmt.Errorf("invalid type for resolved JSON pointer %s. Expected a schema a, got: %T",
+						currentRef.String(), value)
+
+			}
+			opts.flattenContext.warnings = append(opts.flattenContext.warnings,
+				fmt.Sprintf("found $ref %q (response) interpreted as schema", currentRef.String()))
+
+			if asSchema.Ref.String() == "" {
+				break DOWNREF
+			}
+			currentRef = asSchema.Ref
+
+		case swspec.Parameter:
+			// a pointer points to a schema initially marshalled in parameters section...
+			// Attempt to convert this to a schema. If this fails, the spec is invalid
+			asJSON, _ := refable.MarshalJSON()
+			var asSchema swspec.Schema
+			err := asSchema.UnmarshalJSON(asJSON)
+			if err != nil {
+				return swspec.Ref{}, nil,
+					fmt.Errorf("invalid type for resolved JSON pointer %s. Expected a schema a, got: %T",
+						currentRef.String(), value)
+
+			}
+			opts.flattenContext.warnings = append(opts.flattenContext.warnings,
+				fmt.Sprintf("found $ref %q (parameter) interpreted as schema", currentRef.String()))
+
+			if asSchema.Ref.String() == "" {
+				break DOWNREF
+			}
+			currentRef = asSchema.Ref
+
+		default:
+			return swspec.Ref{}, nil,
+				fmt.Errorf("unhandled type to resolve JSON pointer %s. Expected a Schema, got: %T",
+					currentRef.String(), value)
+
+		}
+	}
+	// assess what schema we're ending with
+	sch, erv := swspec.ResolveRefWithBase(opts.Swagger(), &currentRef, opts.ExpandOpts(false))
+	if erv != nil {
+		return swspec.Ref{}, nil, erv
+	}
+	if sch == nil {
+		return swspec.Ref{}, nil, fmt.Errorf("no schema found at %s", currentRef.String())
+	}
+	return currentRef, sch, nil
+}
+
+// normalizeRef strips the current file from any $ref. This works around issue go-openapi/spec#76:
+// leading absolute file in $ref is stripped
+func normalizeRef(opts *FlattenOpts) error {
+	debugLog("normalizeRef")
+	opts.Spec.reload() // re-analyze
+	for k, w := range opts.Spec.references.allRefs {
+		if strings.HasPrefix(w.String(), opts.BasePath+definitionsPath) { // may be a mix of / and \, depending on OS
+			// strip base path from definition
+			debugLog("stripping absolute path for: %s", w.String())
+			if err := updateRef(opts.Swagger(), k,
+				swspec.MustCreateRef(slashpath.Join(definitionsPath, slashpath.Base(w.String())))); err != nil {
+				return err
+			}
+		}
+	}
+	opts.Spec.reload() // re-analyze
+	return nil
+}
diff --git a/go/vendor/github.com/go-openapi/analysis/go.mod b/go/vendor/github.com/go-openapi/analysis/go.mod
new file mode 100644
index 0000000..1b03929
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/analysis/go.mod
@@ -0,0 +1,10 @@
+module github.com/go-openapi/analysis
+
+require (
+	github.com/go-openapi/jsonpointer v0.17.0
+	github.com/go-openapi/loads v0.17.0
+	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
+)
diff --git a/go/vendor/github.com/go-openapi/analysis/go.sum b/go/vendor/github.com/go-openapi/analysis/go.sum
new file mode 100644
index 0000000..5302ec9
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/analysis/go.sum
@@ -0,0 +1,37 @@
+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/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/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/analysis/internal/post_go18.go b/go/vendor/github.com/go-openapi/analysis/internal/post_go18.go
new file mode 100644
index 0000000..f96f55c
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/analysis/internal/post_go18.go
@@ -0,0 +1,29 @@
+// +build go1.8
+
+// 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 internal
+
+import "net/url"
+
+// PathUnescape provides url.PathUnescape(), with seamless
+// go version support for pre-go1.8
+//
+// TODO: this function is currently defined in go-openapi/swag,
+// but unexported. We might chose to export it, or simple phase
+// out pre-go1.8 support.
+func PathUnescape(path string) (string, error) {
+	return url.PathUnescape(path)
+}
diff --git a/go/vendor/github.com/go-openapi/analysis/internal/pre_go18.go b/go/vendor/github.com/go-openapi/analysis/internal/pre_go18.go
new file mode 100644
index 0000000..4cc6441
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/analysis/internal/pre_go18.go
@@ -0,0 +1,29 @@
+// +build !go1.8
+
+// 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 internal
+
+import "net/url"
+
+// PathUnescape provides url.PathUnescape(), with seamless
+// go version support for pre-go1.8
+//
+// TODO: this function is currently defined in go-openapi/swag,
+// but unexported. We might chose to export it, or simple phase
+// out pre-go1.8 support.
+func PathUnescape(path string) (string, error) {
+	return url.QueryUnescape(path)
+}
diff --git a/go/vendor/github.com/go-openapi/analysis/mixin.go b/go/vendor/github.com/go-openapi/analysis/mixin.go
new file mode 100644
index 0000000..49806b4
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/analysis/mixin.go
@@ -0,0 +1,334 @@
+// 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 analysis
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/go-openapi/spec"
+)
+
+// Mixin modifies the primary swagger spec by adding the paths and
+// definitions from the mixin specs. Top level parameters and
+// responses from the mixins are also carried over. Operation id
+// collisions are avoided by appending "Mixin<N>" but only if
+// needed.
+//
+// The following parts of primary are never modified by merging:
+//   - Info
+//   - BasePath
+//   - Host
+//   - ExternalDocs
+//
+// Consider calling FixEmptyResponseDescriptions() on the modified primary
+// if you read them from storage and they are valid to start with.
+//
+// Entries in "paths", "definitions", "parameters" and "responses" are
+// added to the primary in the order of the given mixins. If the entry
+// already exists in primary it is skipped with a warning message.
+//
+// The count of skipped entries (from collisions) is returned so any
+// deviation from the number expected can flag a warning in your build
+// scripts. Carefully review the collisions before accepting them;
+// consider renaming things if possible.
+//
+// No key normalization takes place (paths, type defs,
+// etc). Ensure they are canonical if your downstream tools do
+// key normalization of any form.
+//
+// Merging schemes (http, https), and consumers/producers do not account for
+// collisions.
+func Mixin(primary *spec.Swagger, mixins ...*spec.Swagger) []string {
+	skipped := make([]string, 0, len(mixins))
+	opIds := getOpIds(primary)
+	initPrimary(primary)
+
+	for i, m := range mixins {
+		skipped = append(skipped, mergeConsumes(primary, m)...)
+
+		skipped = append(skipped, mergeProduces(primary, m)...)
+
+		skipped = append(skipped, mergeTags(primary, m)...)
+
+		skipped = append(skipped, mergeSchemes(primary, m)...)
+
+		skipped = append(skipped, mergeSecurityDefinitions(primary, m)...)
+
+		skipped = append(skipped, mergeSecurityRequirements(primary, m)...)
+
+		skipped = append(skipped, mergeDefinitions(primary, m)...)
+
+		// merging paths requires a map of operationIDs to work with
+		skipped = append(skipped, mergePaths(primary, m, opIds, i)...)
+
+		skipped = append(skipped, mergeParameters(primary, m)...)
+
+		skipped = append(skipped, mergeResponses(primary, m)...)
+	}
+	return skipped
+}
+
+// getOpIds extracts all the paths.<path>.operationIds from the given
+// spec and returns them as the keys in a map with 'true' values.
+func getOpIds(s *spec.Swagger) map[string]bool {
+	rv := make(map[string]bool)
+	if s.Paths == nil {
+		return rv
+	}
+	for _, v := range s.Paths.Paths {
+		piops := pathItemOps(v)
+		for _, op := range piops {
+			rv[op.ID] = true
+		}
+	}
+	return rv
+}
+
+func pathItemOps(p spec.PathItem) []*spec.Operation {
+	var rv []*spec.Operation
+	rv = appendOp(rv, p.Get)
+	rv = appendOp(rv, p.Put)
+	rv = appendOp(rv, p.Post)
+	rv = appendOp(rv, p.Delete)
+	rv = appendOp(rv, p.Head)
+	rv = appendOp(rv, p.Patch)
+	return rv
+}
+
+func appendOp(ops []*spec.Operation, op *spec.Operation) []*spec.Operation {
+	if op == nil {
+		return ops
+	}
+	return append(ops, op)
+}
+
+func mergeSecurityDefinitions(primary *spec.Swagger, m *spec.Swagger) (skipped []string) {
+	for k, v := range m.SecurityDefinitions {
+		if _, exists := primary.SecurityDefinitions[k]; exists {
+			warn := fmt.Sprintf(
+				"SecurityDefinitions entry '%v' already exists in primary or higher priority mixin, skipping\n", k)
+			skipped = append(skipped, warn)
+			continue
+		}
+		primary.SecurityDefinitions[k] = v
+	}
+	return
+}
+
+func mergeSecurityRequirements(primary *spec.Swagger, m *spec.Swagger) (skipped []string) {
+	for _, v := range m.Security {
+		found := false
+		for _, vv := range primary.Security {
+			if reflect.DeepEqual(v, vv) {
+				found = true
+				break
+			}
+		}
+		if found {
+			warn := fmt.Sprintf(
+				"Security requirement: '%v' already exists in primary or higher priority mixin, skipping\n", v)
+			skipped = append(skipped, warn)
+			continue
+		}
+		primary.Security = append(primary.Security, v)
+	}
+	return
+}
+
+func mergeDefinitions(primary *spec.Swagger, m *spec.Swagger) (skipped []string) {
+	for k, v := range m.Definitions {
+		// assume name collisions represent IDENTICAL type. careful.
+		if _, exists := primary.Definitions[k]; exists {
+			warn := fmt.Sprintf(
+				"definitions entry '%v' already exists in primary or higher priority mixin, skipping\n", k)
+			skipped = append(skipped, warn)
+			continue
+		}
+		primary.Definitions[k] = v
+	}
+	return
+}
+
+func mergePaths(primary *spec.Swagger, m *spec.Swagger, opIds map[string]bool, mixIndex int) (skipped []string) {
+	if m.Paths != nil {
+		for k, v := range m.Paths.Paths {
+			if _, exists := primary.Paths.Paths[k]; exists {
+				warn := fmt.Sprintf(
+					"paths entry '%v' already exists in primary or higher priority mixin, skipping\n", k)
+				skipped = append(skipped, warn)
+				continue
+			}
+
+			// Swagger requires that operationIds be
+			// unique within a spec. If we find a
+			// collision we append "Mixin0" to the
+			// operatoinId we are adding, where 0 is mixin
+			// index.  We assume that operationIds with
+			// all the proivded specs are already unique.
+			piops := pathItemOps(v)
+			for _, piop := range piops {
+				if opIds[piop.ID] {
+					piop.ID = fmt.Sprintf("%v%v%v", piop.ID, "Mixin", mixIndex)
+				}
+				opIds[piop.ID] = true
+			}
+			primary.Paths.Paths[k] = v
+		}
+	}
+	return
+}
+
+func mergeParameters(primary *spec.Swagger, m *spec.Swagger) (skipped []string) {
+	for k, v := range m.Parameters {
+		// could try to rename on conflict but would
+		// have to fix $refs in the mixin. Complain
+		// for now
+		if _, exists := primary.Parameters[k]; exists {
+			warn := fmt.Sprintf(
+				"top level parameters entry '%v' already exists in primary or higher priority mixin, skipping\n", k)
+			skipped = append(skipped, warn)
+			continue
+		}
+		primary.Parameters[k] = v
+	}
+	return
+}
+
+func mergeResponses(primary *spec.Swagger, m *spec.Swagger) (skipped []string) {
+	for k, v := range m.Responses {
+		// could try to rename on conflict but would
+		// have to fix $refs in the mixin. Complain
+		// for now
+		if _, exists := primary.Responses[k]; exists {
+			warn := fmt.Sprintf(
+				"top level responses entry '%v' already exists in primary or higher priority mixin, skipping\n", k)
+			skipped = append(skipped, warn)
+			continue
+		}
+		primary.Responses[k] = v
+	}
+	return
+}
+
+func mergeConsumes(primary *spec.Swagger, m *spec.Swagger) (skipped []string) {
+	for _, v := range m.Consumes {
+		found := false
+		for _, vv := range primary.Consumes {
+			if v == vv {
+				found = true
+				break
+			}
+		}
+		if found {
+			// no warning here: we just skip it
+			continue
+		}
+		primary.Consumes = append(primary.Consumes, v)
+	}
+	return
+}
+
+func mergeProduces(primary *spec.Swagger, m *spec.Swagger) (skipped []string) {
+	for _, v := range m.Produces {
+		found := false
+		for _, vv := range primary.Produces {
+			if v == vv {
+				found = true
+				break
+			}
+		}
+		if found {
+			// no warning here: we just skip it
+			continue
+		}
+		primary.Produces = append(primary.Produces, v)
+	}
+	return
+}
+
+func mergeTags(primary *spec.Swagger, m *spec.Swagger) (skipped []string) {
+	for _, v := range m.Tags {
+		found := false
+		for _, vv := range primary.Tags {
+			if v.Name == vv.Name {
+				found = true
+				break
+			}
+		}
+		if found {
+			warn := fmt.Sprintf(
+				"top level tags entry with name '%v' already exists in primary or higher priority mixin, skipping\n", v.Name)
+			skipped = append(skipped, warn)
+			continue
+		}
+		primary.Tags = append(primary.Tags, v)
+	}
+	return
+}
+
+func mergeSchemes(primary *spec.Swagger, m *spec.Swagger) (skipped []string) {
+	for _, v := range m.Schemes {
+		found := false
+		for _, vv := range primary.Schemes {
+			if v == vv {
+				found = true
+				break
+			}
+		}
+		if found {
+			// no warning here: we just skip it
+			continue
+		}
+		primary.Schemes = append(primary.Schemes, v)
+	}
+	return
+}
+
+func initPrimary(primary *spec.Swagger) {
+	if primary.SecurityDefinitions == nil {
+		primary.SecurityDefinitions = make(map[string]*spec.SecurityScheme)
+	}
+	if primary.Security == nil {
+		primary.Security = make([]map[string][]string, 0, 10)
+	}
+	if primary.Produces == nil {
+		primary.Produces = make([]string, 0, 10)
+	}
+	if primary.Consumes == nil {
+		primary.Consumes = make([]string, 0, 10)
+	}
+	if primary.Tags == nil {
+		primary.Tags = make([]spec.Tag, 0, 10)
+	}
+	if primary.Schemes == nil {
+		primary.Schemes = make([]string, 0, 10)
+	}
+	if primary.Paths == nil {
+		primary.Paths = &spec.Paths{Paths: make(map[string]spec.PathItem)}
+	}
+	if primary.Paths.Paths == nil {
+		primary.Paths.Paths = make(map[string]spec.PathItem)
+	}
+	if primary.Definitions == nil {
+		primary.Definitions = make(spec.Definitions)
+	}
+	if primary.Parameters == nil {
+		primary.Parameters = make(map[string]spec.Parameter)
+	}
+	if primary.Responses == nil {
+		primary.Responses = make(map[string]spec.Response)
+	}
+}
diff --git a/go/vendor/github.com/go-openapi/analysis/schema.go b/go/vendor/github.com/go-openapi/analysis/schema.go
new file mode 100644
index 0000000..c0b77c5
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/analysis/schema.go
@@ -0,0 +1,234 @@
+package analysis
+
+import (
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/strfmt"
+)
+
+// SchemaOpts configures the schema analyzer
+type SchemaOpts struct {
+	Schema   *spec.Schema
+	Root     interface{}
+	BasePath string
+	_        struct{}
+}
+
+// Schema analysis, will classify the schema according to known
+// patterns.
+func Schema(opts SchemaOpts) (*AnalyzedSchema, error) {
+	a := &AnalyzedSchema{
+		schema:   opts.Schema,
+		root:     opts.Root,
+		basePath: opts.BasePath,
+	}
+
+	a.initializeFlags()
+	a.inferKnownType()
+	a.inferEnum()
+	a.inferBaseType()
+
+	if err := a.inferMap(); err != nil {
+		return nil, err
+	}
+	if err := a.inferArray(); err != nil {
+		return nil, err
+	}
+
+	if err := a.inferTuple(); err != nil {
+		// NOTE(fredbi): currently, inferTuple() never returns an error
+		return nil, err
+	}
+
+	if err := a.inferFromRef(); err != nil {
+		return nil, err
+	}
+
+	a.inferSimpleSchema()
+	return a, nil
+}
+
+// AnalyzedSchema indicates what the schema represents
+type AnalyzedSchema struct {
+	schema   *spec.Schema
+	root     interface{}
+	basePath string
+
+	hasProps           bool
+	hasAllOf           bool
+	hasItems           bool
+	hasAdditionalProps bool
+	hasAdditionalItems bool
+	hasRef             bool
+
+	IsKnownType      bool
+	IsSimpleSchema   bool
+	IsArray          bool
+	IsSimpleArray    bool
+	IsMap            bool
+	IsSimpleMap      bool
+	IsExtendedObject bool
+	IsTuple          bool
+	IsTupleWithExtra bool
+	IsBaseType       bool
+	IsEnum           bool
+}
+
+// Inherits copies value fields from other onto this schema
+func (a *AnalyzedSchema) inherits(other *AnalyzedSchema) {
+	if other == nil {
+		return
+	}
+	a.hasProps = other.hasProps
+	a.hasAllOf = other.hasAllOf
+	a.hasItems = other.hasItems
+	a.hasAdditionalItems = other.hasAdditionalItems
+	a.hasAdditionalProps = other.hasAdditionalProps
+	a.hasRef = other.hasRef
+
+	a.IsKnownType = other.IsKnownType
+	a.IsSimpleSchema = other.IsSimpleSchema
+	a.IsArray = other.IsArray
+	a.IsSimpleArray = other.IsSimpleArray
+	a.IsMap = other.IsMap
+	a.IsSimpleMap = other.IsSimpleMap
+	a.IsExtendedObject = other.IsExtendedObject
+	a.IsTuple = other.IsTuple
+	a.IsTupleWithExtra = other.IsTupleWithExtra
+	a.IsBaseType = other.IsBaseType
+	a.IsEnum = other.IsEnum
+}
+
+func (a *AnalyzedSchema) inferFromRef() error {
+	if a.hasRef {
+		sch := new(spec.Schema)
+		sch.Ref = a.schema.Ref
+		err := spec.ExpandSchema(sch, a.root, nil)
+		if err != nil {
+			return err
+		}
+		if sch != nil {
+			// NOTE(fredbi): currently the only cause for errors in
+			// unresolved ref. Since spec.ExpandSchema() expands the
+			// schema recursively, there is no chance to get there,
+			// until we add more causes for error in this schema analysis.
+			rsch, err := Schema(SchemaOpts{
+				Schema:   sch,
+				Root:     a.root,
+				BasePath: a.basePath,
+			})
+			if err != nil {
+				return err
+			}
+			a.inherits(rsch)
+		}
+	}
+	return nil
+}
+
+func (a *AnalyzedSchema) inferSimpleSchema() {
+	a.IsSimpleSchema = a.IsKnownType || a.IsSimpleArray || a.IsSimpleMap
+}
+
+func (a *AnalyzedSchema) inferKnownType() {
+	tpe := a.schema.Type
+	format := a.schema.Format
+	a.IsKnownType = tpe.Contains("boolean") ||
+		tpe.Contains("integer") ||
+		tpe.Contains("number") ||
+		tpe.Contains("string") ||
+		(format != "" && strfmt.Default.ContainsName(format)) ||
+		(a.isObjectType() && !a.hasProps && !a.hasAllOf && !a.hasAdditionalProps && !a.hasAdditionalItems)
+}
+
+func (a *AnalyzedSchema) inferMap() error {
+	if a.isObjectType() {
+		hasExtra := a.hasProps || a.hasAllOf
+		a.IsMap = a.hasAdditionalProps && !hasExtra
+		a.IsExtendedObject = a.hasAdditionalProps && hasExtra
+		if a.IsMap {
+			if a.schema.AdditionalProperties.Schema != nil {
+				msch, err := Schema(SchemaOpts{
+					Schema:   a.schema.AdditionalProperties.Schema,
+					Root:     a.root,
+					BasePath: a.basePath,
+				})
+				if err != nil {
+					return err
+				}
+				a.IsSimpleMap = msch.IsSimpleSchema
+			} else if a.schema.AdditionalProperties.Allows {
+				a.IsSimpleMap = true
+			}
+		}
+	}
+	return nil
+}
+
+func (a *AnalyzedSchema) inferArray() error {
+	// an array has Items defined as an object schema, otherwise we qualify this JSON array as a tuple
+	// (yes, even if the Items array contains only one element).
+	// arrays in JSON schema may be unrestricted (i.e no Items specified).
+	// Note that arrays in Swagger MUST have Items. Nonetheless, we analyze unrestricted arrays.
+	//
+	// NOTE: the spec package misses the distinction between:
+	// items: [] and items: {}, so we consider both arrays here.
+	a.IsArray = a.isArrayType() && (a.schema.Items == nil || a.schema.Items.Schemas == nil)
+	if a.IsArray && a.hasItems {
+		if a.schema.Items.Schema != nil {
+			itsch, err := Schema(SchemaOpts{
+				Schema:   a.schema.Items.Schema,
+				Root:     a.root,
+				BasePath: a.basePath,
+			})
+			if err != nil {
+				return err
+			}
+			a.IsSimpleArray = itsch.IsSimpleSchema
+		}
+	}
+	if a.IsArray && !a.hasItems {
+		a.IsSimpleArray = true
+	}
+	return nil
+}
+
+func (a *AnalyzedSchema) inferTuple() error {
+	tuple := a.hasItems && a.schema.Items.Schemas != nil
+	a.IsTuple = tuple && !a.hasAdditionalItems
+	a.IsTupleWithExtra = tuple && a.hasAdditionalItems
+	return nil
+}
+
+func (a *AnalyzedSchema) inferBaseType() {
+	if a.isObjectType() {
+		a.IsBaseType = a.schema.Discriminator != ""
+	}
+}
+
+func (a *AnalyzedSchema) inferEnum() {
+	a.IsEnum = len(a.schema.Enum) > 0
+}
+
+func (a *AnalyzedSchema) initializeFlags() {
+	a.hasProps = len(a.schema.Properties) > 0
+	a.hasAllOf = len(a.schema.AllOf) > 0
+	a.hasRef = a.schema.Ref.String() != ""
+
+	a.hasItems = a.schema.Items != nil &&
+		(a.schema.Items.Schema != nil || len(a.schema.Items.Schemas) > 0)
+
+	a.hasAdditionalProps = a.schema.AdditionalProperties != nil &&
+		(a.schema.AdditionalProperties != nil || a.schema.AdditionalProperties.Allows)
+
+	a.hasAdditionalItems = a.schema.AdditionalItems != nil &&
+		(a.schema.AdditionalItems.Schema != nil || a.schema.AdditionalItems.Allows)
+
+}
+
+func (a *AnalyzedSchema) isObjectType() bool {
+	return !a.hasRef && (a.schema.Type == nil || a.schema.Type.Contains("") || a.schema.Type.Contains("object"))
+}
+
+func (a *AnalyzedSchema) isArrayType() bool {
+	return !a.hasRef && (a.schema.Type != nil && a.schema.Type.Contains("array"))
+}
diff --git a/go/vendor/github.com/go-openapi/errors/.gitignore b/go/vendor/github.com/go-openapi/errors/.gitignore
new file mode 100644
index 0000000..dd91ed6
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/errors/.gitignore
@@ -0,0 +1,2 @@
+secrets.yml
+coverage.out
diff --git a/go/vendor/github.com/go-openapi/errors/.travis.yml b/go/vendor/github.com/go-openapi/errors/.travis.yml
new file mode 100644
index 0000000..801191d
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/errors/.travis.yml
@@ -0,0 +1,14 @@
+after_success:
+- bash <(curl -s https://codecov.io/bash)
+go:
+- '1.9'
+- 1.10.x
+- 1.11.x
+install:
+- go get -u github.com/stretchr/testify/assert
+language: go
+notifications:
+  slack:
+    secure: gZGp9NaHxi7zawlXJXKY92BGeDR1x0tbIcTyU5nMKLq0fhIaiEBJEeALwZ4VgqsSv3DytSSF5mLH8fevAM3ixE6hxjKQ+lQuf7V/w3btCN1CSWgoua5LOh1kTnqZQtJuRvO4pzoJcT3bJWBsVZ07VGNVzzJEy/zAKCHFqBUCXShw7QemlLBcYWFNqveTlvDIfCzvouoLnPoXwxEpkjxe9uz/ZKZgAnup/fXjC8RFctmgCnkCyvJTk0Y/fZCsufixJrJhshBWTnlrFCzRmgNkz2d+i1Ls3+MJ5EJJ2Tx/A5S63dL49J1f9Kr0AKHADmulSy8JNzIckKwbyFMYUecrsW+Lsu9DhnVMy1jj5pKsJDLRi2iIU3fXTMWbcyQbXjbbnBO2mPdP3Tzme75y4D9fc8hUPeyqVv2BU26NEbQ7EF2pKJ93OXvci7HlwRBgdJa8j6mP2LEDClcPQW00g7N/OZe0cTOMa8L5AwiBlbArwqt9wv6YLJoTG0wpDhzWsFvbCg5bJxe28Yn3fIDD0Lk1I7iSnBbp/5gzF19jmxqvcT8tHRkDL4xfjbENFTZjA5uB4Z4pj4WSyWQILLV/Jwhe3fi9uQwdviFHfj5pnVrmNUiGSOQL672K5wl2c3E9mGwejvsu2dfEz28n7Y/FUnOpY3/cBS0n27JJaerS0zMKNLE=
+script:
+- go test -v -race -cover -coverprofile=coverage.txt -covermode=atomic ./...
diff --git a/go/vendor/github.com/go-openapi/errors/CODE_OF_CONDUCT.md b/go/vendor/github.com/go-openapi/errors/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..9322b06
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/errors/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/errors/LICENSE b/go/vendor/github.com/go-openapi/errors/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/errors/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/errors/README.md b/go/vendor/github.com/go-openapi/errors/README.md
new file mode 100644
index 0000000..0ce50b2
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/errors/README.md
@@ -0,0 +1,8 @@
+# OpenAPI errors [![Build Status](https://travis-ci.org/go-openapi/errors.svg?branch=master)](https://travis-ci.org/go-openapi/errors) [![codecov](https://codecov.io/gh/go-openapi/errors/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/errors) [![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/errors/master/LICENSE)
+[![GoDoc](https://godoc.org/github.com/go-openapi/errors?status.svg)](http://godoc.org/github.com/go-openapi/errors)
+[![GolangCI](https://golangci.com/badges/github.com/go-openapi/errors.svg)](https://golangci.com)
+[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/errors)](https://goreportcard.com/report/github.com/go-openapi/errors)
+
+Shared errors and error interface used throughout the various libraries found in the go-openapi toolkit.
diff --git a/go/vendor/github.com/go-openapi/errors/api.go b/go/vendor/github.com/go-openapi/errors/api.go
new file mode 100644
index 0000000..d1a752c
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/errors/api.go
@@ -0,0 +1,166 @@
+// 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 errors
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+	"reflect"
+	"strings"
+)
+
+// DefaultHTTPCode is used when the error Code cannot be used as an HTTP code.
+var DefaultHTTPCode = 422
+
+// Error represents a error interface all swagger framework errors implement
+type Error interface {
+	error
+	Code() int32
+}
+
+type apiError struct {
+	code    int32
+	message string
+}
+
+func (a *apiError) Error() string {
+	return a.message
+}
+
+func (a *apiError) Code() int32 {
+	return a.code
+}
+
+// New creates a new API error with a code and a message
+func New(code int32, message string, args ...interface{}) Error {
+	if len(args) > 0 {
+		return &apiError{code, fmt.Sprintf(message, args...)}
+	}
+	return &apiError{code, message}
+}
+
+// NotFound creates a new not found error
+func NotFound(message string, args ...interface{}) Error {
+	if message == "" {
+		message = "Not found"
+	}
+	return New(http.StatusNotFound, fmt.Sprintf(message, args...))
+}
+
+// NotImplemented creates a new not implemented error
+func NotImplemented(message string) Error {
+	return New(http.StatusNotImplemented, message)
+}
+
+// MethodNotAllowedError represents an error for when the path matches but the method doesn't
+type MethodNotAllowedError struct {
+	code    int32
+	Allowed []string
+	message string
+}
+
+func (m *MethodNotAllowedError) Error() string {
+	return m.message
+}
+
+// Code the error code
+func (m *MethodNotAllowedError) Code() int32 {
+	return m.code
+}
+
+func errorAsJSON(err Error) []byte {
+	b, _ := json.Marshal(struct {
+		Code    int32  `json:"code"`
+		Message string `json:"message"`
+	}{err.Code(), err.Error()})
+	return b
+}
+
+func flattenComposite(errs *CompositeError) *CompositeError {
+	var res []error
+	for _, er := range errs.Errors {
+		switch e := er.(type) {
+		case *CompositeError:
+			if len(e.Errors) > 0 {
+				flat := flattenComposite(e)
+				if len(flat.Errors) > 0 {
+					res = append(res, flat.Errors...)
+				}
+			}
+		default:
+			if e != nil {
+				res = append(res, e)
+			}
+		}
+	}
+	return CompositeValidationError(res...)
+}
+
+// MethodNotAllowed creates a new method not allowed error
+func MethodNotAllowed(requested string, allow []string) Error {
+	msg := fmt.Sprintf("method %s is not allowed, but [%s] are", requested, strings.Join(allow, ","))
+	return &MethodNotAllowedError{code: http.StatusMethodNotAllowed, Allowed: allow, message: msg}
+}
+
+const head = "HEAD"
+
+// ServeError the error handler interface implementation
+func ServeError(rw http.ResponseWriter, r *http.Request, err error) {
+	rw.Header().Set("Content-Type", "application/json")
+	switch e := err.(type) {
+	case *CompositeError:
+		er := flattenComposite(e)
+		// strips composite errors to first element only
+		if len(er.Errors) > 0 {
+			ServeError(rw, r, er.Errors[0])
+		} else {
+			// guard against empty CompositeError (invalid construct)
+			ServeError(rw, r, nil)
+		}
+	case *MethodNotAllowedError:
+		rw.Header().Add("Allow", strings.Join(err.(*MethodNotAllowedError).Allowed, ","))
+		rw.WriteHeader(asHTTPCode(int(e.Code())))
+		if r == nil || r.Method != head {
+			rw.Write(errorAsJSON(e))
+		}
+	case Error:
+		value := reflect.ValueOf(e)
+		if value.Kind() == reflect.Ptr && value.IsNil() {
+			rw.WriteHeader(http.StatusInternalServerError)
+			rw.Write(errorAsJSON(New(http.StatusInternalServerError, "Unknown error")))
+			return
+		}
+		rw.WriteHeader(asHTTPCode(int(e.Code())))
+		if r == nil || r.Method != head {
+			rw.Write(errorAsJSON(e))
+		}
+	case nil:
+		rw.WriteHeader(http.StatusInternalServerError)
+		rw.Write(errorAsJSON(New(http.StatusInternalServerError, "Unknown error")))
+	default:
+		rw.WriteHeader(http.StatusInternalServerError)
+		if r == nil || r.Method != head {
+			rw.Write(errorAsJSON(New(http.StatusInternalServerError, err.Error())))
+		}
+	}
+}
+
+func asHTTPCode(input int) int {
+	if input >= 600 {
+		return DefaultHTTPCode
+	}
+	return input
+}
diff --git a/go/vendor/github.com/go-openapi/errors/auth.go b/go/vendor/github.com/go-openapi/errors/auth.go
new file mode 100644
index 0000000..70eb960
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/errors/auth.go
@@ -0,0 +1,20 @@
+// 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 errors
+
+// Unauthenticated returns an unauthenticated error
+func Unauthenticated(scheme string) Error {
+	return New(401, "unauthenticated for %s", scheme)
+}
diff --git a/go/vendor/github.com/go-openapi/errors/doc.go b/go/vendor/github.com/go-openapi/errors/doc.go
new file mode 100644
index 0000000..963d427
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/errors/doc.go
@@ -0,0 +1,28 @@
+// 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 errors provides an Error interface and several concrete types
+implementing this interface to manage API errors and JSON-schema validation
+errors.
+
+A middleware handler ServeError() is provided to serve the errors types
+it defines.
+
+It is used throughout the various go-openapi toolkit libraries
+(https://github.com/go-openapi).
+
+*/
+package errors
diff --git a/go/vendor/github.com/go-openapi/errors/go.mod b/go/vendor/github.com/go-openapi/errors/go.mod
new file mode 100644
index 0000000..3d57e9f
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/errors/go.mod
@@ -0,0 +1,7 @@
+module github.com/go-openapi/errors
+
+require (
+	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	github.com/stretchr/testify v1.2.2
+)
diff --git a/go/vendor/github.com/go-openapi/errors/go.sum b/go/vendor/github.com/go-openapi/errors/go.sum
new file mode 100644
index 0000000..2d048b6
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/errors/go.sum
@@ -0,0 +1,5 @@
+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/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=
diff --git a/go/vendor/github.com/go-openapi/errors/headers.go b/go/vendor/github.com/go-openapi/errors/headers.go
new file mode 100644
index 0000000..a80ddc9
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/errors/headers.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 errors
+
+import (
+	"fmt"
+	"net/http"
+)
+
+// Validation represents a failure of a precondition
+type Validation struct {
+	code    int32
+	Name    string
+	In      string
+	Value   interface{}
+	message string
+	Values  []interface{}
+}
+
+func (e *Validation) Error() string {
+	return e.message
+}
+
+// Code the error code
+func (e *Validation) Code() int32 {
+	return e.code
+}
+
+// ValidateName produces an error message name for an aliased property
+func (e *Validation) ValidateName(name string) *Validation {
+	if e.Name == "" && name != "" {
+		e.Name = name
+		e.message = name + e.message
+	}
+	return e
+}
+
+const (
+	contentTypeFail    = `unsupported media type %q, only %v are allowed`
+	responseFormatFail = `unsupported media type requested, only %v are available`
+)
+
+// InvalidContentType error for an invalid content type
+func InvalidContentType(value string, allowed []string) *Validation {
+	var values []interface{}
+	for _, v := range allowed {
+		values = append(values, v)
+	}
+	return &Validation{
+		code:    http.StatusUnsupportedMediaType,
+		Name:    "Content-Type",
+		In:      "header",
+		Value:   value,
+		Values:  values,
+		message: fmt.Sprintf(contentTypeFail, value, allowed),
+	}
+}
+
+// InvalidResponseFormat error for an unacceptable response format request
+func InvalidResponseFormat(value string, allowed []string) *Validation {
+	var values []interface{}
+	for _, v := range allowed {
+		values = append(values, v)
+	}
+	return &Validation{
+		code:    http.StatusNotAcceptable,
+		Name:    "Accept",
+		In:      "header",
+		Value:   value,
+		Values:  values,
+		message: fmt.Sprintf(responseFormatFail, allowed),
+	}
+}
diff --git a/go/vendor/github.com/go-openapi/errors/middleware.go b/go/vendor/github.com/go-openapi/errors/middleware.go
new file mode 100644
index 0000000..6390d46
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/errors/middleware.go
@@ -0,0 +1,51 @@
+// 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 errors
+
+import (
+	"bytes"
+	"fmt"
+	"strings"
+)
+
+// APIVerificationFailed is an error that contains all the missing info for a mismatched section
+// between the api registrations and the api spec
+type APIVerificationFailed struct {
+	Section              string
+	MissingSpecification []string
+	MissingRegistration  []string
+}
+
+//
+func (v *APIVerificationFailed) Error() string {
+	buf := bytes.NewBuffer(nil)
+
+	hasRegMissing := len(v.MissingRegistration) > 0
+	hasSpecMissing := len(v.MissingSpecification) > 0
+
+	if hasRegMissing {
+		buf.WriteString(fmt.Sprintf("missing [%s] %s registrations", strings.Join(v.MissingRegistration, ", "), v.Section))
+	}
+
+	if hasRegMissing && hasSpecMissing {
+		buf.WriteString("\n")
+	}
+
+	if hasSpecMissing {
+		buf.WriteString(fmt.Sprintf("missing from spec file [%s] %s", strings.Join(v.MissingSpecification, ", "), v.Section))
+	}
+
+	return buf.String()
+}
diff --git a/go/vendor/github.com/go-openapi/errors/parsing.go b/go/vendor/github.com/go-openapi/errors/parsing.go
new file mode 100644
index 0000000..1bae873
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/errors/parsing.go
@@ -0,0 +1,59 @@
+// 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 errors
+
+import "fmt"
+
+// ParseError respresents a parsing error
+type ParseError struct {
+	code    int32
+	Name    string
+	In      string
+	Value   string
+	Reason  error
+	message string
+}
+
+func (e *ParseError) Error() string {
+	return e.message
+}
+
+// Code returns the http status code for this error
+func (e *ParseError) Code() int32 {
+	return e.code
+}
+
+const (
+	parseErrorTemplContent     = `parsing %s %s from %q failed, because %s`
+	parseErrorTemplContentNoIn = `parsing %s from %q failed, because %s`
+)
+
+// NewParseError creates a new parse error
+func NewParseError(name, in, value string, reason error) *ParseError {
+	var msg string
+	if in == "" {
+		msg = fmt.Sprintf(parseErrorTemplContentNoIn, name, value, reason)
+	} else {
+		msg = fmt.Sprintf(parseErrorTemplContent, name, in, value, reason)
+	}
+	return &ParseError{
+		code:    400,
+		Name:    name,
+		In:      in,
+		Value:   value,
+		Reason:  reason,
+		message: msg,
+	}
+}
diff --git a/go/vendor/github.com/go-openapi/errors/schema.go b/go/vendor/github.com/go-openapi/errors/schema.go
new file mode 100644
index 0000000..14fb2c5
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/errors/schema.go
@@ -0,0 +1,562 @@
+// 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 errors
+
+import (
+	"fmt"
+	"strings"
+)
+
+const (
+	invalidType               = "%s is an invalid type name"
+	typeFail                  = "%s in %s must be of type %s"
+	typeFailWithData          = "%s in %s must be of type %s: %q"
+	typeFailWithError         = "%s in %s must be of type %s, because: %s"
+	requiredFail              = "%s in %s is required"
+	tooLongMessage            = "%s in %s should be at most %d chars long"
+	tooShortMessage           = "%s in %s should be at least %d chars long"
+	patternFail               = "%s in %s should match '%s'"
+	enumFail                  = "%s in %s should be one of %v"
+	multipleOfFail            = "%s in %s should be a multiple of %v"
+	maxIncFail                = "%s in %s should be less than or equal to %v"
+	maxExcFail                = "%s in %s should be less than %v"
+	minIncFail                = "%s in %s should be greater than or equal to %v"
+	minExcFail                = "%s in %s should be greater than %v"
+	uniqueFail                = "%s in %s shouldn't contain duplicates"
+	maxItemsFail              = "%s in %s should have at most %d items"
+	minItemsFail              = "%s in %s should have at least %d items"
+	typeFailNoIn              = "%s must be of type %s"
+	typeFailWithDataNoIn      = "%s must be of type %s: %q"
+	typeFailWithErrorNoIn     = "%s must be of type %s, because: %s"
+	requiredFailNoIn          = "%s is required"
+	tooLongMessageNoIn        = "%s should be at most %d chars long"
+	tooShortMessageNoIn       = "%s should be at least %d chars long"
+	patternFailNoIn           = "%s should match '%s'"
+	enumFailNoIn              = "%s should be one of %v"
+	multipleOfFailNoIn        = "%s should be a multiple of %v"
+	maxIncFailNoIn            = "%s should be less than or equal to %v"
+	maxExcFailNoIn            = "%s should be less than %v"
+	minIncFailNoIn            = "%s should be greater than or equal to %v"
+	minExcFailNoIn            = "%s should be greater than %v"
+	uniqueFailNoIn            = "%s shouldn't contain duplicates"
+	maxItemsFailNoIn          = "%s should have at most %d items"
+	minItemsFailNoIn          = "%s should have at least %d items"
+	noAdditionalItems         = "%s in %s can't have additional items"
+	noAdditionalItemsNoIn     = "%s can't have additional items"
+	tooFewProperties          = "%s in %s should have at least %d properties"
+	tooFewPropertiesNoIn      = "%s should have at least %d properties"
+	tooManyProperties         = "%s in %s should have at most %d properties"
+	tooManyPropertiesNoIn     = "%s should have at most %d properties"
+	unallowedProperty         = "%s.%s in %s is a forbidden property"
+	unallowedPropertyNoIn     = "%s.%s is a forbidden property"
+	failedAllPatternProps     = "%s.%s in %s failed all pattern properties"
+	failedAllPatternPropsNoIn = "%s.%s failed all pattern properties"
+	multipleOfMustBePositive  = "factor MultipleOf declared for %s must be positive: %v"
+)
+
+// All code responses can be used to differentiate errors for different handling
+// by the consuming program
+const (
+	// CompositeErrorCode remains 422 for backwards-compatibility
+	// and to separate it from validation errors with cause
+	CompositeErrorCode = 422
+	// InvalidTypeCode is used for any subclass of invalid types
+	InvalidTypeCode = 600 + iota
+	RequiredFailCode
+	TooLongFailCode
+	TooShortFailCode
+	PatternFailCode
+	EnumFailCode
+	MultipleOfFailCode
+	MaxFailCode
+	MinFailCode
+	UniqueFailCode
+	MaxItemsFailCode
+	MinItemsFailCode
+	NoAdditionalItemsCode
+	TooFewPropertiesCode
+	TooManyPropertiesCode
+	UnallowedPropertyCode
+	FailedAllPatternPropsCode
+	MultipleOfMustBePositiveCode
+)
+
+// CompositeError is an error that groups several errors together
+type CompositeError struct {
+	Errors  []error
+	code    int32
+	message string
+}
+
+// Code for this error
+func (c *CompositeError) Code() int32 {
+	return c.code
+}
+
+func (c *CompositeError) Error() string {
+	if len(c.Errors) > 0 {
+		msgs := []string{c.message + ":"}
+		for _, e := range c.Errors {
+			msgs = append(msgs, e.Error())
+		}
+		return strings.Join(msgs, "\n")
+	}
+	return c.message
+}
+
+// CompositeValidationError an error to wrap a bunch of other errors
+func CompositeValidationError(errors ...error) *CompositeError {
+	return &CompositeError{
+		code:    CompositeErrorCode,
+		Errors:  append([]error{}, errors...),
+		message: "validation failure list",
+	}
+}
+
+// FailedAllPatternProperties an error for when the property doesn't match a pattern
+func FailedAllPatternProperties(name, in, key string) *Validation {
+	msg := fmt.Sprintf(failedAllPatternProps, name, key, in)
+	if in == "" {
+		msg = fmt.Sprintf(failedAllPatternPropsNoIn, name, key)
+	}
+	return &Validation{
+		code:    FailedAllPatternPropsCode,
+		Name:    name,
+		In:      in,
+		Value:   key,
+		message: msg,
+	}
+}
+
+// PropertyNotAllowed an error for when the property doesn't match a pattern
+func PropertyNotAllowed(name, in, key string) *Validation {
+	msg := fmt.Sprintf(unallowedProperty, name, key, in)
+	if in == "" {
+		msg = fmt.Sprintf(unallowedPropertyNoIn, name, key)
+	}
+	return &Validation{
+		code:    UnallowedPropertyCode,
+		Name:    name,
+		In:      in,
+		Value:   key,
+		message: msg,
+	}
+}
+
+// TooFewProperties an error for an object with too few properties
+func TooFewProperties(name, in string, n int64) *Validation {
+	msg := fmt.Sprintf(tooFewProperties, name, in, n)
+	if in == "" {
+		msg = fmt.Sprintf(tooFewPropertiesNoIn, name, n)
+	}
+	return &Validation{
+		code:    TooFewPropertiesCode,
+		Name:    name,
+		In:      in,
+		Value:   n,
+		message: msg,
+	}
+}
+
+// TooManyProperties an error for an object with too many properties
+func TooManyProperties(name, in string, n int64) *Validation {
+	msg := fmt.Sprintf(tooManyProperties, name, in, n)
+	if in == "" {
+		msg = fmt.Sprintf(tooManyPropertiesNoIn, name, n)
+	}
+	return &Validation{
+		code:    TooManyPropertiesCode,
+		Name:    name,
+		In:      in,
+		Value:   n,
+		message: msg,
+	}
+}
+
+// AdditionalItemsNotAllowed an error for invalid additional items
+func AdditionalItemsNotAllowed(name, in string) *Validation {
+	msg := fmt.Sprintf(noAdditionalItems, name, in)
+	if in == "" {
+		msg = fmt.Sprintf(noAdditionalItemsNoIn, name)
+	}
+	return &Validation{
+		code:    NoAdditionalItemsCode,
+		Name:    name,
+		In:      in,
+		message: msg,
+	}
+}
+
+// InvalidCollectionFormat another flavor of invalid type error
+func InvalidCollectionFormat(name, in, format string) *Validation {
+	return &Validation{
+		code:    InvalidTypeCode,
+		Name:    name,
+		In:      in,
+		Value:   format,
+		message: fmt.Sprintf("the collection format %q is not supported for the %s param %q", format, in, name),
+	}
+}
+
+// InvalidTypeName an error for when the type is invalid
+func InvalidTypeName(typeName string) *Validation {
+	return &Validation{
+		code:    InvalidTypeCode,
+		Value:   typeName,
+		message: fmt.Sprintf(invalidType, typeName),
+	}
+}
+
+// InvalidType creates an error for when the type is invalid
+func InvalidType(name, in, typeName string, value interface{}) *Validation {
+	var message string
+
+	if in != "" {
+		switch value.(type) {
+		case string:
+			message = fmt.Sprintf(typeFailWithData, name, in, typeName, value)
+		case error:
+			message = fmt.Sprintf(typeFailWithError, name, in, typeName, value)
+		default:
+			message = fmt.Sprintf(typeFail, name, in, typeName)
+		}
+	} else {
+		switch value.(type) {
+		case string:
+			message = fmt.Sprintf(typeFailWithDataNoIn, name, typeName, value)
+		case error:
+			message = fmt.Sprintf(typeFailWithErrorNoIn, name, typeName, value)
+		default:
+			message = fmt.Sprintf(typeFailNoIn, name, typeName)
+		}
+	}
+
+	return &Validation{
+		code:    InvalidTypeCode,
+		Name:    name,
+		In:      in,
+		Value:   value,
+		message: message,
+	}
+
+}
+
+// DuplicateItems error for when an array contains duplicates
+func DuplicateItems(name, in string) *Validation {
+	msg := fmt.Sprintf(uniqueFail, name, in)
+	if in == "" {
+		msg = fmt.Sprintf(uniqueFailNoIn, name)
+	}
+	return &Validation{
+		code:    UniqueFailCode,
+		Name:    name,
+		In:      in,
+		message: msg,
+	}
+}
+
+// TooManyItems error for when an array contains too many items
+func TooManyItems(name, in string, max int64) *Validation {
+	msg := fmt.Sprintf(maxItemsFail, name, in, max)
+	if in == "" {
+		msg = fmt.Sprintf(maxItemsFailNoIn, name, max)
+	}
+
+	return &Validation{
+		code:    MaxItemsFailCode,
+		Name:    name,
+		In:      in,
+		message: msg,
+	}
+}
+
+// TooFewItems error for when an array contains too few items
+func TooFewItems(name, in string, min int64) *Validation {
+	msg := fmt.Sprintf(minItemsFail, name, in, min)
+	if in == "" {
+		msg = fmt.Sprintf(minItemsFailNoIn, name, min)
+	}
+	return &Validation{
+		code:    MinItemsFailCode,
+		Name:    name,
+		In:      in,
+		message: msg,
+	}
+}
+
+// ExceedsMaximumInt error for when maxinum validation fails
+func ExceedsMaximumInt(name, in string, max int64, exclusive bool) *Validation {
+	var message string
+	if in == "" {
+		m := maxIncFailNoIn
+		if exclusive {
+			m = maxExcFailNoIn
+		}
+		message = fmt.Sprintf(m, name, max)
+	} else {
+		m := maxIncFail
+		if exclusive {
+			m = maxExcFail
+		}
+		message = fmt.Sprintf(m, name, in, max)
+	}
+	return &Validation{
+		code:    MaxFailCode,
+		Name:    name,
+		In:      in,
+		Value:   max,
+		message: message,
+	}
+}
+
+// ExceedsMaximumUint error for when maxinum validation fails
+func ExceedsMaximumUint(name, in string, max uint64, exclusive bool) *Validation {
+	var message string
+	if in == "" {
+		m := maxIncFailNoIn
+		if exclusive {
+			m = maxExcFailNoIn
+		}
+		message = fmt.Sprintf(m, name, max)
+	} else {
+		m := maxIncFail
+		if exclusive {
+			m = maxExcFail
+		}
+		message = fmt.Sprintf(m, name, in, max)
+	}
+	return &Validation{
+		code:    MaxFailCode,
+		Name:    name,
+		In:      in,
+		Value:   max,
+		message: message,
+	}
+}
+
+// ExceedsMaximum error for when maxinum validation fails
+func ExceedsMaximum(name, in string, max float64, exclusive bool) *Validation {
+	var message string
+	if in == "" {
+		m := maxIncFailNoIn
+		if exclusive {
+			m = maxExcFailNoIn
+		}
+		message = fmt.Sprintf(m, name, max)
+	} else {
+		m := maxIncFail
+		if exclusive {
+			m = maxExcFail
+		}
+		message = fmt.Sprintf(m, name, in, max)
+	}
+	return &Validation{
+		code:    MaxFailCode,
+		Name:    name,
+		In:      in,
+		Value:   max,
+		message: message,
+	}
+}
+
+// ExceedsMinimumInt error for when maxinum validation fails
+func ExceedsMinimumInt(name, in string, min int64, exclusive bool) *Validation {
+	var message string
+	if in == "" {
+		m := minIncFailNoIn
+		if exclusive {
+			m = minExcFailNoIn
+		}
+		message = fmt.Sprintf(m, name, min)
+	} else {
+		m := minIncFail
+		if exclusive {
+			m = minExcFail
+		}
+		message = fmt.Sprintf(m, name, in, min)
+	}
+	return &Validation{
+		code:    MinFailCode,
+		Name:    name,
+		In:      in,
+		Value:   min,
+		message: message,
+	}
+}
+
+// ExceedsMinimumUint error for when maxinum validation fails
+func ExceedsMinimumUint(name, in string, min uint64, exclusive bool) *Validation {
+	var message string
+	if in == "" {
+		m := minIncFailNoIn
+		if exclusive {
+			m = minExcFailNoIn
+		}
+		message = fmt.Sprintf(m, name, min)
+	} else {
+		m := minIncFail
+		if exclusive {
+			m = minExcFail
+		}
+		message = fmt.Sprintf(m, name, in, min)
+	}
+	return &Validation{
+		code:    MinFailCode,
+		Name:    name,
+		In:      in,
+		Value:   min,
+		message: message,
+	}
+}
+
+// ExceedsMinimum error for when maxinum validation fails
+func ExceedsMinimum(name, in string, min float64, exclusive bool) *Validation {
+	var message string
+	if in == "" {
+		m := minIncFailNoIn
+		if exclusive {
+			m = minExcFailNoIn
+		}
+		message = fmt.Sprintf(m, name, min)
+	} else {
+		m := minIncFail
+		if exclusive {
+			m = minExcFail
+		}
+		message = fmt.Sprintf(m, name, in, min)
+	}
+	return &Validation{
+		code:    MinFailCode,
+		Name:    name,
+		In:      in,
+		Value:   min,
+		message: message,
+	}
+}
+
+// NotMultipleOf error for when multiple of validation fails
+func NotMultipleOf(name, in string, multiple interface{}) *Validation {
+	var msg string
+	if in == "" {
+		msg = fmt.Sprintf(multipleOfFailNoIn, name, multiple)
+	} else {
+		msg = fmt.Sprintf(multipleOfFail, name, in, multiple)
+	}
+	return &Validation{
+		code:    MultipleOfFailCode,
+		Name:    name,
+		In:      in,
+		Value:   multiple,
+		message: msg,
+	}
+}
+
+// EnumFail error for when an enum validation fails
+func EnumFail(name, in string, value interface{}, values []interface{}) *Validation {
+	var msg string
+	if in == "" {
+		msg = fmt.Sprintf(enumFailNoIn, name, values)
+	} else {
+		msg = fmt.Sprintf(enumFail, name, in, values)
+	}
+
+	return &Validation{
+		code:    EnumFailCode,
+		Name:    name,
+		In:      in,
+		Value:   value,
+		Values:  values,
+		message: msg,
+	}
+}
+
+// Required error for when a value is missing
+func Required(name, in string) *Validation {
+	var msg string
+	if in == "" {
+		msg = fmt.Sprintf(requiredFailNoIn, name)
+	} else {
+		msg = fmt.Sprintf(requiredFail, name, in)
+	}
+	return &Validation{
+		code:    RequiredFailCode,
+		Name:    name,
+		In:      in,
+		message: msg,
+	}
+}
+
+// TooLong error for when a string is too long
+func TooLong(name, in string, max int64) *Validation {
+	var msg string
+	if in == "" {
+		msg = fmt.Sprintf(tooLongMessageNoIn, name, max)
+	} else {
+		msg = fmt.Sprintf(tooLongMessage, name, in, max)
+	}
+	return &Validation{
+		code:    TooLongFailCode,
+		Name:    name,
+		In:      in,
+		message: msg,
+	}
+}
+
+// TooShort error for when a string is too short
+func TooShort(name, in string, min int64) *Validation {
+	var msg string
+	if in == "" {
+		msg = fmt.Sprintf(tooShortMessageNoIn, name, min)
+	} else {
+		msg = fmt.Sprintf(tooShortMessage, name, in, min)
+	}
+
+	return &Validation{
+		code:    TooShortFailCode,
+		Name:    name,
+		In:      in,
+		message: msg,
+	}
+}
+
+// FailedPattern error for when a string fails a regex pattern match
+// the pattern that is returned is the ECMA syntax version of the pattern not the golang version.
+func FailedPattern(name, in, pattern string) *Validation {
+	var msg string
+	if in == "" {
+		msg = fmt.Sprintf(patternFailNoIn, name, pattern)
+	} else {
+		msg = fmt.Sprintf(patternFail, name, in, pattern)
+	}
+
+	return &Validation{
+		code:    PatternFailCode,
+		Name:    name,
+		In:      in,
+		message: msg,
+	}
+}
+
+// MultipleOfMustBePositive error for when a
+// multipleOf factor is negative
+func MultipleOfMustBePositive(name, in string, factor interface{}) *Validation {
+	return &Validation{
+		code:    MultipleOfMustBePositiveCode,
+		Name:    name,
+		In:      in,
+		Value:   factor,
+		message: fmt.Sprintf(multipleOfMustBePositive, name, factor),
+	}
+}
diff --git a/go/vendor/github.com/go-openapi/jsonpointer/.editorconfig b/go/vendor/github.com/go-openapi/jsonpointer/.editorconfig
new file mode 100644
index 0000000..3152da6
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/jsonpointer/.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/jsonpointer/.gitignore b/go/vendor/github.com/go-openapi/jsonpointer/.gitignore
new file mode 100644
index 0000000..769c244
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/jsonpointer/.gitignore
@@ -0,0 +1 @@
+secrets.yml
diff --git a/go/vendor/github.com/go-openapi/jsonpointer/.travis.yml b/go/vendor/github.com/go-openapi/jsonpointer/.travis.yml
new file mode 100644
index 0000000..3436c45
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/jsonpointer/.travis.yml
@@ -0,0 +1,15 @@
+after_success:
+- bash <(curl -s https://codecov.io/bash)
+go:
+- '1.9'
+- 1.10.x
+- 1.11.x
+install:
+- go get -u github.com/stretchr/testify/assert
+- go get -u github.com/go-openapi/swag
+language: go
+notifications:
+  slack:
+    secure: a5VgoiwB1G/AZqzmephPZIhEB9avMlsWSlVnM1dSAtYAwdrQHGTQxAmpOxYIoSPDhWNN5bfZmjd29++UlTwLcHSR+e0kJhH6IfDlsHj/HplNCJ9tyI0zYc7XchtdKgeMxMzBKCzgwFXGSbQGydXTliDNBo0HOzmY3cou/daMFTP60K+offcjS+3LRAYb1EroSRXZqrk1nuF/xDL3792DZUdPMiFR/L/Df6y74D6/QP4sTkTDFQitz4Wy/7jbsfj8dG6qK2zivgV6/l+w4OVjFkxVpPXogDWY10vVXNVynqxfJ7to2d1I9lNCHE2ilBCkWMIPdyJF7hjF8pKW+82yP4EzRh0vu8Xn0HT5MZpQxdRY/YMxNrWaG7SxsoEaO4q5uhgdzAqLYY3TRa7MjIK+7Ur+aqOeTXn6OKwVi0CjvZ6mIU3WUKSwiwkFZMbjRAkSb5CYwMEfGFO/z964xz83qGt6WAtBXNotqCQpTIiKtDHQeLOMfksHImCg6JLhQcWBVxamVgu0G3Pdh8Y6DyPnxraXY95+QDavbjqv7TeYT9T/FNnrkXaTTK0s4iWE5H4ACU0Qvz0wUYgfQrZv0/Hp7V17+rabUwnzYySHCy9SWX/7OV9Cfh31iMp9ZIffr76xmmThtOEqs8TrTtU6BWI3rWwvA9cXQipZTVtL0oswrGw=
+script:
+- go test -v -race -cover -coverprofile=coverage.txt -covermode=atomic ./...
diff --git a/go/vendor/github.com/go-openapi/jsonpointer/CODE_OF_CONDUCT.md b/go/vendor/github.com/go-openapi/jsonpointer/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..9322b06
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/jsonpointer/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/jsonpointer/LICENSE b/go/vendor/github.com/go-openapi/jsonpointer/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/jsonpointer/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/jsonpointer/README.md b/go/vendor/github.com/go-openapi/jsonpointer/README.md
new file mode 100644
index 0000000..813788a
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/jsonpointer/README.md
@@ -0,0 +1,15 @@
+# gojsonpointer [![Build Status](https://travis-ci.org/go-openapi/jsonpointer.svg?branch=master)](https://travis-ci.org/go-openapi/jsonpointer) [![codecov](https://codecov.io/gh/go-openapi/jsonpointer/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/jsonpointer) [![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/jsonpointer/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/jsonpointer?status.svg)](http://godoc.org/github.com/go-openapi/jsonpointer)
+An implementation of JSON Pointer - Go language
+
+## Status
+Completed YES
+
+Tested YES
+
+## References
+http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07
+
+### Note
+The 4.Evaluation part of the previous reference, starting with 'If the currently referenced value is a JSON array, the reference token MUST contain either...' is not implemented.
diff --git a/go/vendor/github.com/go-openapi/jsonpointer/go.mod b/go/vendor/github.com/go-openapi/jsonpointer/go.mod
new file mode 100644
index 0000000..eb4d623
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/jsonpointer/go.mod
@@ -0,0 +1,10 @@
+module github.com/go-openapi/jsonpointer
+
+require (
+	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/go-openapi/swag v0.17.0
+	github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	github.com/stretchr/testify v1.2.2
+	gopkg.in/yaml.v2 v2.2.1 // indirect
+)
diff --git a/go/vendor/github.com/go-openapi/jsonpointer/go.sum b/go/vendor/github.com/go-openapi/jsonpointer/go.sum
new file mode 100644
index 0000000..c71f4d7
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/jsonpointer/go.sum
@@ -0,0 +1,11 @@
+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/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/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=
+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/jsonpointer/pointer.go b/go/vendor/github.com/go-openapi/jsonpointer/pointer.go
new file mode 100644
index 0000000..fe2d6ee
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/jsonpointer/pointer.go
@@ -0,0 +1,390 @@
+// Copyright 2013 sigu-399 ( https://github.com/sigu-399 )
+//
+// 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.
+
+// author       sigu-399
+// author-github  https://github.com/sigu-399
+// author-mail    sigu.399@gmail.com
+//
+// repository-name  jsonpointer
+// repository-desc  An implementation of JSON Pointer - Go language
+//
+// description    Main and unique file.
+//
+// created        25-02-2013
+
+package jsonpointer
+
+import (
+	"errors"
+	"fmt"
+	"reflect"
+	"strconv"
+	"strings"
+
+	"github.com/go-openapi/swag"
+)
+
+const (
+	emptyPointer     = ``
+	pointerSeparator = `/`
+
+	invalidStart = `JSON pointer must be empty or start with a "` + pointerSeparator
+)
+
+var jsonPointableType = reflect.TypeOf(new(JSONPointable)).Elem()
+var jsonSetableType = reflect.TypeOf(new(JSONSetable)).Elem()
+
+// JSONPointable is an interface for structs to implement when they need to customize the
+// json pointer process
+type JSONPointable interface {
+	JSONLookup(string) (interface{}, error)
+}
+
+// JSONSetable is an interface for structs to implement when they need to customize the
+// json pointer process
+type JSONSetable interface {
+	JSONSet(string, interface{}) error
+}
+
+// New creates a new json pointer for the given string
+func New(jsonPointerString string) (Pointer, error) {
+
+	var p Pointer
+	err := p.parse(jsonPointerString)
+	return p, err
+
+}
+
+// Pointer the json pointer reprsentation
+type Pointer struct {
+	referenceTokens []string
+}
+
+// "Constructor", parses the given string JSON pointer
+func (p *Pointer) parse(jsonPointerString string) error {
+
+	var err error
+
+	if jsonPointerString != emptyPointer {
+		if !strings.HasPrefix(jsonPointerString, pointerSeparator) {
+			err = errors.New(invalidStart)
+		} else {
+			referenceTokens := strings.Split(jsonPointerString, pointerSeparator)
+			for _, referenceToken := range referenceTokens[1:] {
+				p.referenceTokens = append(p.referenceTokens, referenceToken)
+			}
+		}
+	}
+
+	return err
+}
+
+// Get uses the pointer to retrieve a value from a JSON document
+func (p *Pointer) Get(document interface{}) (interface{}, reflect.Kind, error) {
+	return p.get(document, swag.DefaultJSONNameProvider)
+}
+
+// Set uses the pointer to set a value from a JSON document
+func (p *Pointer) Set(document interface{}, value interface{}) (interface{}, error) {
+	return document, p.set(document, value, swag.DefaultJSONNameProvider)
+}
+
+// GetForToken gets a value for a json pointer token 1 level deep
+func GetForToken(document interface{}, decodedToken string) (interface{}, reflect.Kind, error) {
+	return getSingleImpl(document, decodedToken, swag.DefaultJSONNameProvider)
+}
+
+// SetForToken gets a value for a json pointer token 1 level deep
+func SetForToken(document interface{}, decodedToken string, value interface{}) (interface{}, error) {
+	return document, setSingleImpl(document, value, decodedToken, swag.DefaultJSONNameProvider)
+}
+
+func getSingleImpl(node interface{}, decodedToken string, nameProvider *swag.NameProvider) (interface{}, reflect.Kind, error) {
+	rValue := reflect.Indirect(reflect.ValueOf(node))
+	kind := rValue.Kind()
+
+	switch kind {
+
+	case reflect.Struct:
+		if rValue.Type().Implements(jsonPointableType) {
+			r, err := node.(JSONPointable).JSONLookup(decodedToken)
+			if err != nil {
+				return nil, kind, err
+			}
+			return r, kind, nil
+		}
+		nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
+		if !ok {
+			return nil, kind, fmt.Errorf("object has no field %q", decodedToken)
+		}
+		fld := rValue.FieldByName(nm)
+		return fld.Interface(), kind, nil
+
+	case reflect.Map:
+		kv := reflect.ValueOf(decodedToken)
+		mv := rValue.MapIndex(kv)
+
+		if mv.IsValid() && !swag.IsZero(mv) {
+			return mv.Interface(), kind, nil
+		}
+		return nil, kind, fmt.Errorf("object has no key %q", decodedToken)
+
+	case reflect.Slice:
+		tokenIndex, err := strconv.Atoi(decodedToken)
+		if err != nil {
+			return nil, kind, err
+		}
+		sLength := rValue.Len()
+		if tokenIndex < 0 || tokenIndex >= sLength {
+			return nil, kind, fmt.Errorf("index out of bounds array[0,%d] index '%d'", sLength-1, tokenIndex)
+		}
+
+		elem := rValue.Index(tokenIndex)
+		return elem.Interface(), kind, nil
+
+	default:
+		return nil, kind, fmt.Errorf("invalid token reference %q", decodedToken)
+	}
+
+}
+
+func setSingleImpl(node, data interface{}, decodedToken string, nameProvider *swag.NameProvider) error {
+	rValue := reflect.Indirect(reflect.ValueOf(node))
+	switch rValue.Kind() {
+
+	case reflect.Struct:
+		if ns, ok := node.(JSONSetable); ok { // pointer impl
+			return ns.JSONSet(decodedToken, data)
+		}
+
+		if rValue.Type().Implements(jsonSetableType) {
+			return node.(JSONSetable).JSONSet(decodedToken, data)
+		}
+
+		nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
+		if !ok {
+			return fmt.Errorf("object has no field %q", decodedToken)
+		}
+		fld := rValue.FieldByName(nm)
+		if fld.IsValid() {
+			fld.Set(reflect.ValueOf(data))
+		}
+		return nil
+
+	case reflect.Map:
+		kv := reflect.ValueOf(decodedToken)
+		rValue.SetMapIndex(kv, reflect.ValueOf(data))
+		return nil
+
+	case reflect.Slice:
+		tokenIndex, err := strconv.Atoi(decodedToken)
+		if err != nil {
+			return err
+		}
+		sLength := rValue.Len()
+		if tokenIndex < 0 || tokenIndex >= sLength {
+			return fmt.Errorf("index out of bounds array[0,%d] index '%d'", sLength, tokenIndex)
+		}
+
+		elem := rValue.Index(tokenIndex)
+		if !elem.CanSet() {
+			return fmt.Errorf("can't set slice index %s to %v", decodedToken, data)
+		}
+		elem.Set(reflect.ValueOf(data))
+		return nil
+
+	default:
+		return fmt.Errorf("invalid token reference %q", decodedToken)
+	}
+
+}
+
+func (p *Pointer) get(node interface{}, nameProvider *swag.NameProvider) (interface{}, reflect.Kind, error) {
+
+	if nameProvider == nil {
+		nameProvider = swag.DefaultJSONNameProvider
+	}
+
+	kind := reflect.Invalid
+
+	// Full document when empty
+	if len(p.referenceTokens) == 0 {
+		return node, kind, nil
+	}
+
+	for _, token := range p.referenceTokens {
+
+		decodedToken := Unescape(token)
+
+		r, knd, err := getSingleImpl(node, decodedToken, nameProvider)
+		if err != nil {
+			return nil, knd, err
+		}
+		node, kind = r, knd
+
+	}
+
+	rValue := reflect.ValueOf(node)
+	kind = rValue.Kind()
+
+	return node, kind, nil
+}
+
+func (p *Pointer) set(node, data interface{}, nameProvider *swag.NameProvider) error {
+	knd := reflect.ValueOf(node).Kind()
+
+	if knd != reflect.Ptr && knd != reflect.Struct && knd != reflect.Map && knd != reflect.Slice && knd != reflect.Array {
+		return fmt.Errorf("only structs, pointers, maps and slices are supported for setting values")
+	}
+
+	if nameProvider == nil {
+		nameProvider = swag.DefaultJSONNameProvider
+	}
+
+	// Full document when empty
+	if len(p.referenceTokens) == 0 {
+		return nil
+	}
+
+	lastI := len(p.referenceTokens) - 1
+	for i, token := range p.referenceTokens {
+		isLastToken := i == lastI
+		decodedToken := Unescape(token)
+
+		if isLastToken {
+
+			return setSingleImpl(node, data, decodedToken, nameProvider)
+		}
+
+		rValue := reflect.Indirect(reflect.ValueOf(node))
+		kind := rValue.Kind()
+
+		switch kind {
+
+		case reflect.Struct:
+			if rValue.Type().Implements(jsonPointableType) {
+				r, err := node.(JSONPointable).JSONLookup(decodedToken)
+				if err != nil {
+					return err
+				}
+				fld := reflect.ValueOf(r)
+				if fld.CanAddr() && fld.Kind() != reflect.Interface && fld.Kind() != reflect.Map && fld.Kind() != reflect.Slice && fld.Kind() != reflect.Ptr {
+					node = fld.Addr().Interface()
+					continue
+				}
+				node = r
+				continue
+			}
+			nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)
+			if !ok {
+				return fmt.Errorf("object has no field %q", decodedToken)
+			}
+			fld := rValue.FieldByName(nm)
+			if fld.CanAddr() && fld.Kind() != reflect.Interface && fld.Kind() != reflect.Map && fld.Kind() != reflect.Slice && fld.Kind() != reflect.Ptr {
+				node = fld.Addr().Interface()
+				continue
+			}
+			node = fld.Interface()
+
+		case reflect.Map:
+			kv := reflect.ValueOf(decodedToken)
+			mv := rValue.MapIndex(kv)
+
+			if !mv.IsValid() {
+				return fmt.Errorf("object has no key %q", decodedToken)
+			}
+			if mv.CanAddr() && mv.Kind() != reflect.Interface && mv.Kind() != reflect.Map && mv.Kind() != reflect.Slice && mv.Kind() != reflect.Ptr {
+				node = mv.Addr().Interface()
+				continue
+			}
+			node = mv.Interface()
+
+		case reflect.Slice:
+			tokenIndex, err := strconv.Atoi(decodedToken)
+			if err != nil {
+				return err
+			}
+			sLength := rValue.Len()
+			if tokenIndex < 0 || tokenIndex >= sLength {
+				return fmt.Errorf("index out of bounds array[0,%d] index '%d'", sLength, tokenIndex)
+			}
+
+			elem := rValue.Index(tokenIndex)
+			if elem.CanAddr() && elem.Kind() != reflect.Interface && elem.Kind() != reflect.Map && elem.Kind() != reflect.Slice && elem.Kind() != reflect.Ptr {
+				node = elem.Addr().Interface()
+				continue
+			}
+			node = elem.Interface()
+
+		default:
+			return fmt.Errorf("invalid token reference %q", decodedToken)
+		}
+
+	}
+
+	return nil
+}
+
+// DecodedTokens returns the decoded tokens
+func (p *Pointer) DecodedTokens() []string {
+	result := make([]string, 0, len(p.referenceTokens))
+	for _, t := range p.referenceTokens {
+		result = append(result, Unescape(t))
+	}
+	return result
+}
+
+// IsEmpty returns true if this is an empty json pointer
+// this indicates that it points to the root document
+func (p *Pointer) IsEmpty() bool {
+	return len(p.referenceTokens) == 0
+}
+
+// Pointer to string representation function
+func (p *Pointer) String() string {
+
+	if len(p.referenceTokens) == 0 {
+		return emptyPointer
+	}
+
+	pointerString := pointerSeparator + strings.Join(p.referenceTokens, pointerSeparator)
+
+	return pointerString
+}
+
+// Specific JSON pointer encoding here
+// ~0 => ~
+// ~1 => /
+// ... and vice versa
+
+const (
+	encRefTok0 = `~0`
+	encRefTok1 = `~1`
+	decRefTok0 = `~`
+	decRefTok1 = `/`
+)
+
+// Unescape unescapes a json pointer reference token string to the original representation
+func Unescape(token string) string {
+	step1 := strings.Replace(token, encRefTok1, decRefTok1, -1)
+	step2 := strings.Replace(step1, encRefTok0, decRefTok0, -1)
+	return step2
+}
+
+// Escape escapes a pointer reference token string
+func Escape(token string) string {
+	step1 := strings.Replace(token, decRefTok0, encRefTok0, -1)
+	step2 := strings.Replace(step1, decRefTok1, encRefTok1, -1)
+	return step2
+}
diff --git a/go/vendor/github.com/go-openapi/jsonreference/.gitignore b/go/vendor/github.com/go-openapi/jsonreference/.gitignore
new file mode 100644
index 0000000..769c244
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/jsonreference/.gitignore
@@ -0,0 +1 @@
+secrets.yml
diff --git a/go/vendor/github.com/go-openapi/jsonreference/.travis.yml b/go/vendor/github.com/go-openapi/jsonreference/.travis.yml
new file mode 100644
index 0000000..40034d2
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/jsonreference/.travis.yml
@@ -0,0 +1,16 @@
+after_success:
+- bash <(curl -s https://codecov.io/bash)
+go:
+- '1.9'
+- 1.10.x
+- 1.11.x
+install:
+- go get -u github.com/stretchr/testify/assert
+- go get -u github.com/PuerkitoBio/purell
+- go get -u github.com/go-openapi/jsonpointer
+language: go
+notifications:
+  slack:
+    secure: OpQG/36F7DSF00HLm9WZMhyqFCYYyYTsVDObW226cWiR8PWYiNfLZiSEvIzT1Gx4dDjhigKTIqcLhG34CkL5iNXDjm9Yyo2RYhQPlK8NErNqUEXuBqn4RqYHW48VGhEhOyDd4Ei0E2FN5ZbgpvHgtpkdZ6XDi64r3Ac89isP9aPHXQTuv2Jog6b4/OKKiUTftLcTIst0p4Cp3gqOJWf1wnoj+IadWiECNVQT6zb47IYjtyw6+uV8iUjTzdKcRB6Zc6b4Dq7JAg1Zd7Jfxkql3hlKp4PNlRf9Cy7y5iA3G7MLyg3FcPX5z2kmcyPt2jOTRMBWUJ5zIQpOxizAcN8WsT3WWBL5KbuYK6k0PzujrIDLqdxGpNmjkkMfDBT9cKmZpm2FdW+oZgPFJP+oKmAo4u4KJz/vjiPTXgQlN5bmrLuRMCp+AwC5wkIohTqWZVPE2TK6ZSnMYcg/W39s+RP/9mJoyryAvPSpBOLTI+biCgaUCTOAZxNTWpMFc3tPYntc41WWkdKcooZ9JA5DwfcaVFyTGQ3YXz+HvX6G1z/gW0Q/A4dBi9mj2iE1xm7tRTT+4VQ2AXFvSEI1HJpfPgYnwAtwOD1v3Qm2EUHk9sCdtEDR4wVGEPIVn44GnwFMnGKx9JWppMPYwFu3SVDdHt+E+LOlhZUply11Aa+IVrT2KUQ=
+script:
+- go test -v -race -cover -coverprofile=coverage.txt -covermode=atomic ./...
diff --git a/go/vendor/github.com/go-openapi/jsonreference/CODE_OF_CONDUCT.md b/go/vendor/github.com/go-openapi/jsonreference/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..9322b06
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/jsonreference/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/jsonreference/LICENSE b/go/vendor/github.com/go-openapi/jsonreference/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/jsonreference/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/jsonreference/README.md b/go/vendor/github.com/go-openapi/jsonreference/README.md
new file mode 100644
index 0000000..66345f4
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/jsonreference/README.md
@@ -0,0 +1,15 @@
+# gojsonreference [![Build Status](https://travis-ci.org/go-openapi/jsonreference.svg?branch=master)](https://travis-ci.org/go-openapi/jsonreference) [![codecov](https://codecov.io/gh/go-openapi/jsonreference/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/jsonreference) [![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/jsonreference/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/jsonreference?status.svg)](http://godoc.org/github.com/go-openapi/jsonreference)
+An implementation of JSON Reference - Go language
+
+## Status
+Work in progress ( 90% done )
+
+## Dependencies
+https://github.com/go-openapi/jsonpointer
+
+## References
+http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07
+
+http://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03
diff --git a/go/vendor/github.com/go-openapi/jsonreference/go.mod b/go/vendor/github.com/go-openapi/jsonreference/go.mod
new file mode 100644
index 0000000..6d15a70
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/jsonreference/go.mod
@@ -0,0 +1,15 @@
+module github.com/go-openapi/jsonreference
+
+require (
+	github.com/PuerkitoBio/purell v1.1.0
+	github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
+	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/go-openapi/jsonpointer v0.17.0
+	github.com/go-openapi/swag v0.17.0 // indirect
+	github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	github.com/stretchr/testify v1.2.2
+	golang.org/x/net v0.0.0-20181005035420-146acd28ed58 // indirect
+	golang.org/x/text v0.3.0 // indirect
+	gopkg.in/yaml.v2 v2.2.1 // indirect
+)
diff --git a/go/vendor/github.com/go-openapi/jsonreference/go.sum b/go/vendor/github.com/go-openapi/jsonreference/go.sum
new file mode 100644
index 0000000..ec9bdbc
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/jsonreference/go.sum
@@ -0,0 +1,20 @@
+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/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/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/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/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/jsonreference/reference.go b/go/vendor/github.com/go-openapi/jsonreference/reference.go
new file mode 100644
index 0000000..3bc0a6e
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/jsonreference/reference.go
@@ -0,0 +1,156 @@
+// Copyright 2013 sigu-399 ( https://github.com/sigu-399 )
+//
+// 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.
+
+// author       sigu-399
+// author-github  https://github.com/sigu-399
+// author-mail    sigu.399@gmail.com
+//
+// repository-name  jsonreference
+// repository-desc  An implementation of JSON Reference - Go language
+//
+// description    Main and unique file.
+//
+// created        26-02-2013
+
+package jsonreference
+
+import (
+	"errors"
+	"net/url"
+	"strings"
+
+	"github.com/PuerkitoBio/purell"
+	"github.com/go-openapi/jsonpointer"
+)
+
+const (
+	fragmentRune = `#`
+)
+
+// New creates a new reference for the given string
+func New(jsonReferenceString string) (Ref, error) {
+
+	var r Ref
+	err := r.parse(jsonReferenceString)
+	return r, err
+
+}
+
+// MustCreateRef parses the ref string and panics when it's invalid.
+// Use the New method for a version that returns an error
+func MustCreateRef(ref string) Ref {
+	r, err := New(ref)
+	if err != nil {
+		panic(err)
+	}
+	return r
+}
+
+// Ref represents a json reference object
+type Ref struct {
+	referenceURL     *url.URL
+	referencePointer jsonpointer.Pointer
+
+	HasFullURL      bool
+	HasURLPathOnly  bool
+	HasFragmentOnly bool
+	HasFileScheme   bool
+	HasFullFilePath bool
+}
+
+// GetURL gets the URL for this reference
+func (r *Ref) GetURL() *url.URL {
+	return r.referenceURL
+}
+
+// GetPointer gets the json pointer for this reference
+func (r *Ref) GetPointer() *jsonpointer.Pointer {
+	return &r.referencePointer
+}
+
+// String returns the best version of the url for this reference
+func (r *Ref) String() string {
+
+	if r.referenceURL != nil {
+		return r.referenceURL.String()
+	}
+
+	if r.HasFragmentOnly {
+		return fragmentRune + r.referencePointer.String()
+	}
+
+	return r.referencePointer.String()
+}
+
+// IsRoot returns true if this reference is a root document
+func (r *Ref) IsRoot() bool {
+	return r.referenceURL != nil &&
+		!r.IsCanonical() &&
+		!r.HasURLPathOnly &&
+		r.referenceURL.Fragment == ""
+}
+
+// IsCanonical returns true when this pointer starts with http(s):// or file://
+func (r *Ref) IsCanonical() bool {
+	return (r.HasFileScheme && r.HasFullFilePath) || (!r.HasFileScheme && r.HasFullURL)
+}
+
+// "Constructor", parses the given string JSON reference
+func (r *Ref) parse(jsonReferenceString string) error {
+
+	parsed, err := url.Parse(jsonReferenceString)
+	if err != nil {
+		return err
+	}
+
+	r.referenceURL, _ = url.Parse(purell.NormalizeURL(parsed, purell.FlagsSafe|purell.FlagRemoveDuplicateSlashes))
+	refURL := r.referenceURL
+
+	if refURL.Scheme != "" && refURL.Host != "" {
+		r.HasFullURL = true
+	} else {
+		if refURL.Path != "" {
+			r.HasURLPathOnly = true
+		} else if refURL.RawQuery == "" && refURL.Fragment != "" {
+			r.HasFragmentOnly = true
+		}
+	}
+
+	r.HasFileScheme = refURL.Scheme == "file"
+	r.HasFullFilePath = strings.HasPrefix(refURL.Path, "/")
+
+	// invalid json-pointer error means url has no json-pointer fragment. simply ignore error
+	r.referencePointer, _ = jsonpointer.New(refURL.Fragment)
+
+	return nil
+}
+
+// Inherits creates a new reference from a parent and a child
+// If the child cannot inherit from the parent, an error is returned
+func (r *Ref) Inherits(child Ref) (*Ref, error) {
+	childURL := child.GetURL()
+	parentURL := r.GetURL()
+	if childURL == nil {
+		return nil, errors.New("child url is nil")
+	}
+	if parentURL == nil {
+		return &child, nil
+	}
+
+	ref, err := New(parentURL.ResolveReference(childURL).String())
+	if err != nil {
+		return nil, err
+	}
+	return &ref, nil
+}
diff --git a/go/vendor/github.com/go-openapi/loads/.drone.sec b/go/vendor/github.com/go-openapi/loads/.drone.sec
new file mode 100644
index 0000000..6d3e843
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/loads/.drone.sec
@@ -0,0 +1 @@
+eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.xUjixvmMMeampw0Doyr_XLvcV5ICmDgDFmlcWqgmO84O3Hwn6dqbMkwOjpKMOyEJW_98b5Om5ED59IFt2S0T_OarlrsJL8jOK5fqxSMNXy2w8LfI-e5l1URverW41ofAVK8m9wK05q2BSJM_M6PyyODaQeDBiCVK1HreMZBlXpuUDVtBMPILQoga0eSZOsTR3DYEpZIS0A0Rsa5yIhMYR5d5-JMYqbqOCB7tNJ-BM83OzYgL7Hrz0J15kqaJmhQ-GJoMJDzOemSO9KxLCOfSPp11R_G3Mfd48xYnuiRuPOTakbOCLxuYviH6uoGVIOhnMyY9qKiDKbOn4BQUi1-igA.6qjQzq9nzAxRRKV_.z79R5cMFAEuEaAh6U9ykiL8oIqzMbs_I2C-hSFRh3HYRJ4fTB-9LrcbF0uASIOq7bBn4OQzW-0QFwYOs1uaawmrByGngV5d0afiZf_LBKcmTF2vtxRi_A_nxD-EHoPmh3lKBU5WNDe_8kLjEeS89HeyyFPuv5iQbqhzdqPFohHKVigwVqVYYLjB8GWQ4t7tC4c8l5rHanaXf71W0e3op2m8bebpZL0JPGhnULVA1oU27TYeLsO112JkIYtBwZxzvAs--bBFoKeGJWVMFzrKN68UACGZ9RFw0uGJbBmVC4-jRuIc6XpqeEqw3KG-rjFzkeEor3575qW-8kiXYqpub9SFUc3SSZkxJ8hB3SrnMBOuDUSenrXNpAbltmV3KAALzN3_bMBQuihwSRIn0Hg7-Dpni8BieMe44RMDvRu6p_71aeU_KW4V7Umy_h8gpIvQFuKGdTQH2ahsyCXL0ojqjMbVMdoWpDQTQ2_Fy8Qt_p2kJ8BgDo-1Akd4a6BNU2NGqsdnrJmtVKcTqLBadf9ylCwxHdGVrtNYORALSms2T6Q1s-poQnMjIwN8lnUD8ABUBpt4uVtrYkiWPVwrwywLQeiHhR-pboe_53kWDAx4Hy4rpbKsaxanYhy_bEbAYKb3aIUA.75GD4kRBCQdcGFYP1QYdCg
\ No newline at end of file
diff --git a/go/vendor/github.com/go-openapi/loads/.drone.yml b/go/vendor/github.com/go-openapi/loads/.drone.yml
new file mode 100644
index 0000000..9822910
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/loads/.drone.yml
@@ -0,0 +1,39 @@
+clone:
+  path: github.com/go-openapi/loads
+
+matrix:
+  GO_VERSION:
+    - "1.6"
+
+build:
+  integration:
+    image: golang:$$GO_VERSION
+    pull: true
+    environment:
+      GOCOVMODE: "count"
+    commands:
+      - go get -u github.com/axw/gocov/gocov
+      - go get -u gopkg.in/matm/v1/gocov-html
+      - go get -u github.com/cee-dub/go-junit-report
+      - go get -u github.com/stretchr/testify/assert
+      - go get -u gopkg.in/yaml.v2
+      - go get -u github.com/go-openapi/swag
+      - go get -u github.com/go-openapi/analysis
+      - go get -u github.com/go-openapi/spec
+      - ./hack/build-drone.sh
+
+notify:
+  slack:
+    channel: bots
+    webhook_url: $$SLACK_URL
+    username: drone
+
+publish:
+  coverage:
+    server: https://coverage.vmware.run
+    token: $$GITHUB_TOKEN
+    # threshold: 70
+    # must_increase: true
+    when:
+      matrix:
+        GO_VERSION: "1.6"
diff --git a/go/vendor/github.com/go-openapi/loads/.editorconfig b/go/vendor/github.com/go-openapi/loads/.editorconfig
new file mode 100644
index 0000000..3152da6
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/loads/.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/loads/.gitignore b/go/vendor/github.com/go-openapi/loads/.gitignore
new file mode 100644
index 0000000..e4f15f1
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/loads/.gitignore
@@ -0,0 +1,4 @@
+secrets.yml
+coverage.out
+profile.cov
+profile.out
diff --git a/go/vendor/github.com/go-openapi/loads/.travis.yml b/go/vendor/github.com/go-openapi/loads/.travis.yml
new file mode 100644
index 0000000..1555a03
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/loads/.travis.yml
@@ -0,0 +1,18 @@
+after_success:
+- bash <(curl -s https://codecov.io/bash)
+go:
+- '1.9'
+- 1.10.x
+- 1.11.x
+install:
+- go get -u github.com/stretchr/testify
+- go get -u github.com/go-openapi/analysis
+- go get -u github.com/go-openapi/spec
+- go get -u github.com/go-openapi/swag
+- go get -u gopkg.in/yaml.v2
+language: go
+notifications:
+  slack:
+    secure: OxkPwVp35qBTUilgWC8xykSj+sGMcj0h8IIOKD+Rflx2schZVlFfdYdyVBM+s9OqeOfvtuvnR9v1Ye2rPKAvcjWdC4LpRGUsgmItZaI6Um8Aj6+K9udCw5qrtZVfOVmRu8LieH//XznWWKdOultUuniW0MLqw5+II87Gd00RWbCGi0hk0PykHe7uK+PDA2BEbqyZ2WKKYCvfB3j+0nrFOHScXqnh0V05l2E83J4+Sgy1fsPy+1WdX58ZlNBG333ibaC1FS79XvKSmTgKRkx3+YBo97u6ZtUmJa5WZjf2OdLG3KIckGWAv6R5xgxeU31N0Ng8L332w/Edpp2O/M2bZwdnKJ8hJQikXIAQbICbr+lTDzsoNzMdEIYcHpJ5hjPbiUl3Bmd+Jnsjf5McgAZDiWIfpCKZ29tPCEkVwRsOCqkyPRMNMzHHmoja495P5jR+ODS7+J8RFg5xgcnOgpP9D4Wlhztlf5WyZMpkLxTUD+bZq2SRf50HfHFXTkfq22zPl3d1eq0yrLwh/Z/fWKkfb6SyysROL8y6s8u3dpFX1YHSg0BR6i913h4aoZw9B2BG27cafLLTwKYsp2dFo1PWl4O6u9giFJIeqwloZHLKKrwh0cBFhB7RH0I58asxkZpCH6uWjJierahmHe7iS+E6i+9oCHkOZ59hmCYNimIs3hM=
+script:
+- ./hack/coverage
diff --git a/go/vendor/github.com/go-openapi/loads/CODE_OF_CONDUCT.md b/go/vendor/github.com/go-openapi/loads/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..9322b06
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/loads/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/loads/LICENSE b/go/vendor/github.com/go-openapi/loads/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/loads/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/loads/README.md b/go/vendor/github.com/go-openapi/loads/README.md
new file mode 100644
index 0000000..6dbb834
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/loads/README.md
@@ -0,0 +1,5 @@
+# Loads OAI specs  [![Build Status](https://travis-ci.org/go-openapi/loads.svg?branch=master)](https://travis-ci.org/go-openapi/loads) [![codecov](https://codecov.io/gh/go-openapi/loads/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/loads) [![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/loads/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/loads?status.svg)](http://godoc.org/github.com/go-openapi/loads)
+
+Loading of OAI specification documents from local or remote locations.
diff --git a/go/vendor/github.com/go-openapi/loads/go.mod b/go/vendor/github.com/go-openapi/loads/go.mod
new file mode 100644
index 0000000..10ea8d2
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/loads/go.mod
@@ -0,0 +1,23 @@
+module github.com/go-openapi/loads
+
+require (
+	github.com/PuerkitoBio/purell v1.1.0 // indirect
+	github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
+	github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf // indirect
+	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb // indirect
+	github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277
+	github.com/go-openapi/errors v0.17.0 // indirect
+	github.com/go-openapi/jsonpointer v0.17.0 // indirect
+	github.com/go-openapi/jsonreference v0.17.0 // indirect
+	github.com/go-openapi/spec v0.17.0
+	github.com/go-openapi/strfmt v0.17.0 // indirect
+	github.com/go-openapi/swag v0.17.0
+	github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 // indirect
+	github.com/mitchellh/mapstructure v1.1.2 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	github.com/stretchr/testify v1.2.2
+	golang.org/x/net v0.0.0-20181005035420-146acd28ed58 // indirect
+	golang.org/x/text v0.3.0 // indirect
+	gopkg.in/yaml.v2 v2.2.1
+)
diff --git a/go/vendor/github.com/go-openapi/loads/go.sum b/go/vendor/github.com/go-openapi/loads/go.sum
new file mode 100644
index 0000000..ef11953
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/loads/go.sum
@@ -0,0 +1,36 @@
+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 h1:Cjl5yf/RidkszNOmV0+rf35yjOocQ1UTTVwEmxnr6Ls=
+github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
+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/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/loads/spec.go b/go/vendor/github.com/go-openapi/loads/spec.go
new file mode 100644
index 0000000..649ca06
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/loads/spec.go
@@ -0,0 +1,279 @@
+// 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 loads
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"net/url"
+
+	"github.com/go-openapi/analysis"
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/swag"
+)
+
+// JSONDoc loads a json document from either a file or a remote url
+func JSONDoc(path string) (json.RawMessage, error) {
+	data, err := swag.LoadFromFileOrHTTP(path)
+	if err != nil {
+		return nil, err
+	}
+	return json.RawMessage(data), nil
+}
+
+// DocLoader represents a doc loader type
+type DocLoader func(string) (json.RawMessage, error)
+
+// DocMatcher represents a predicate to check if a loader matches
+type DocMatcher func(string) bool
+
+var (
+	loaders       *loader
+	defaultLoader *loader
+)
+
+func init() {
+	defaultLoader = &loader{Match: func(_ string) bool { return true }, Fn: JSONDoc}
+	loaders = defaultLoader
+	spec.PathLoader = loaders.Fn
+	AddLoader(swag.YAMLMatcher, swag.YAMLDoc)
+}
+
+// AddLoader for a document
+func AddLoader(predicate DocMatcher, load DocLoader) {
+	prev := loaders
+	loaders = &loader{
+		Match: predicate,
+		Fn:    load,
+		Next:  prev,
+	}
+	spec.PathLoader = loaders.Fn
+}
+
+type loader struct {
+	Fn    DocLoader
+	Match DocMatcher
+	Next  *loader
+}
+
+// JSONSpec loads a spec from a json document
+func JSONSpec(path string) (*Document, error) {
+	data, err := JSONDoc(path)
+	if err != nil {
+		return nil, err
+	}
+	// convert to json
+	return Analyzed(json.RawMessage(data), "")
+}
+
+// Document represents a swagger spec document
+type Document struct {
+	// specAnalyzer
+	Analyzer     *analysis.Spec
+	spec         *spec.Swagger
+	specFilePath string
+	origSpec     *spec.Swagger
+	schema       *spec.Schema
+	raw          json.RawMessage
+}
+
+// Embedded returns a Document based on embedded specs. No analysis is required
+func Embedded(orig, flat json.RawMessage) (*Document, error) {
+	var origSpec, flatSpec spec.Swagger
+	if err := json.Unmarshal(orig, &origSpec); err != nil {
+		return nil, err
+	}
+	if err := json.Unmarshal(flat, &flatSpec); err != nil {
+		return nil, err
+	}
+	return &Document{
+		raw:      orig,
+		origSpec: &origSpec,
+		spec:     &flatSpec,
+	}, nil
+}
+
+// Spec loads a new spec document
+func Spec(path string) (*Document, error) {
+	specURL, err := url.Parse(path)
+	if err != nil {
+		return nil, err
+	}
+	var lastErr error
+	for l := loaders.Next; l != nil; l = l.Next {
+		if loaders.Match(specURL.Path) {
+			b, err2 := loaders.Fn(path)
+			if err2 != nil {
+				lastErr = err2
+				continue
+			}
+			doc, err := Analyzed(b, "")
+			if err != nil {
+				return nil, err
+			}
+			if doc != nil {
+				doc.specFilePath = path
+			}
+			return doc, nil
+		}
+	}
+	if lastErr != nil {
+		return nil, lastErr
+	}
+	b, err := defaultLoader.Fn(path)
+	if err != nil {
+		return nil, err
+	}
+
+	document, err := Analyzed(b, "")
+	if document != nil {
+		document.specFilePath = path
+	}
+
+	return document, err
+}
+
+// Analyzed creates a new analyzed spec document
+func Analyzed(data json.RawMessage, version string) (*Document, error) {
+	if version == "" {
+		version = "2.0"
+	}
+	if version != "2.0" {
+		return nil, fmt.Errorf("spec version %q is not supported", version)
+	}
+
+	raw := data
+	trimmed := bytes.TrimSpace(data)
+	if len(trimmed) > 0 {
+		if trimmed[0] != '{' && trimmed[0] != '[' {
+			yml, err := swag.BytesToYAMLDoc(trimmed)
+			if err != nil {
+				return nil, fmt.Errorf("analyzed: %v", err)
+			}
+			d, err := swag.YAMLToJSON(yml)
+			if err != nil {
+				return nil, fmt.Errorf("analyzed: %v", err)
+			}
+			raw = d
+		}
+	}
+
+	swspec := new(spec.Swagger)
+	if err := json.Unmarshal(raw, swspec); err != nil {
+		return nil, err
+	}
+
+	origsqspec := new(spec.Swagger)
+	if err := json.Unmarshal(raw, origsqspec); err != nil {
+		return nil, err
+	}
+
+	d := &Document{
+		Analyzer: analysis.New(swspec),
+		schema:   spec.MustLoadSwagger20Schema(),
+		spec:     swspec,
+		raw:      raw,
+		origSpec: origsqspec,
+	}
+	return d, nil
+}
+
+// Expanded expands the ref fields in the spec document and returns a new spec document
+func (d *Document) Expanded(options ...*spec.ExpandOptions) (*Document, error) {
+	swspec := new(spec.Swagger)
+	if err := json.Unmarshal(d.raw, swspec); err != nil {
+		return nil, err
+	}
+
+	var expandOptions *spec.ExpandOptions
+	if len(options) > 0 {
+		expandOptions = options[0]
+	} else {
+		expandOptions = &spec.ExpandOptions{
+			RelativeBase: d.specFilePath,
+		}
+	}
+
+	if err := spec.ExpandSpec(swspec, expandOptions); err != nil {
+		return nil, err
+	}
+
+	dd := &Document{
+		Analyzer:     analysis.New(swspec),
+		spec:         swspec,
+		specFilePath: d.specFilePath,
+		schema:       spec.MustLoadSwagger20Schema(),
+		raw:          d.raw,
+		origSpec:     d.origSpec,
+	}
+	return dd, nil
+}
+
+// BasePath the base path for this spec
+func (d *Document) BasePath() string {
+	return d.spec.BasePath
+}
+
+// Version returns the version of this spec
+func (d *Document) Version() string {
+	return d.spec.Swagger
+}
+
+// Schema returns the swagger 2.0 schema
+func (d *Document) Schema() *spec.Schema {
+	return d.schema
+}
+
+// Spec returns the swagger spec object model
+func (d *Document) Spec() *spec.Swagger {
+	return d.spec
+}
+
+// Host returns the host for the API
+func (d *Document) Host() string {
+	return d.spec.Host
+}
+
+// Raw returns the raw swagger spec as json bytes
+func (d *Document) Raw() json.RawMessage {
+	return d.raw
+}
+
+func (d *Document) OrigSpec() *spec.Swagger {
+	return d.origSpec
+}
+
+// ResetDefinitions gives a shallow copy with the models reset
+func (d *Document) ResetDefinitions() *Document {
+	defs := make(map[string]spec.Schema, len(d.origSpec.Definitions))
+	for k, v := range d.origSpec.Definitions {
+		defs[k] = v
+	}
+
+	d.spec.Definitions = defs
+	return d
+}
+
+// Pristine creates a new pristine document instance based on the input data
+func (d *Document) Pristine() *Document {
+	dd, _ := Analyzed(d.Raw(), d.Version())
+	return dd
+}
+
+// SpecFilePath returns the file path of the spec if one is defined
+func (d *Document) SpecFilePath() string {
+	return d.specFilePath
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/.editorconfig b/go/vendor/github.com/go-openapi/runtime/.editorconfig
new file mode 100644
index 0000000..3152da6
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/.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/runtime/.gitignore b/go/vendor/github.com/go-openapi/runtime/.gitignore
new file mode 100644
index 0000000..fea8b84
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/.gitignore
@@ -0,0 +1,5 @@
+secrets.yml
+coverage.out
+*.cov
+*.out
+playground
diff --git a/go/vendor/github.com/go-openapi/runtime/.travis.yml b/go/vendor/github.com/go-openapi/runtime/.travis.yml
new file mode 100644
index 0000000..de70d07
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/.travis.yml
@@ -0,0 +1,24 @@
+after_success:
+- bash <(curl -s https://codecov.io/bash)
+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 gopkg.in/yaml.v2
+- 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/validate
+- go get -u github.com/docker/go-units
+language: go
+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:
+- ./hack/coverage
diff --git a/go/vendor/github.com/go-openapi/runtime/CODE_OF_CONDUCT.md b/go/vendor/github.com/go-openapi/runtime/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..9322b06
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/CODE_OF_CONDUCT.md
@@ -0,0 +1,74 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, gender identity and expression, level of experience,
+nationality, personal appearance, race, religion, or sexual identity and
+orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic
+  address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+  professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or
+reject comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any contributor for other behaviors that they deem inappropriate,
+threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. Examples of
+representing a project or community include using an official project e-mail
+address, posting via an official social media account, or acting as an appointed
+representative at an online or offline event. Representation of a project may be
+further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting the project team at ivan+abuse@flanders.co.nz. All
+complaints will be reviewed and investigated and will result in a response that
+is deemed necessary and appropriate to the circumstances. The project team is
+obligated to maintain confidentiality with regard to the reporter of an incident.
+Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good
+faith may face temporary or permanent repercussions as determined by other
+members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
+available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/
diff --git a/go/vendor/github.com/go-openapi/runtime/LICENSE b/go/vendor/github.com/go-openapi/runtime/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/go/vendor/github.com/go-openapi/runtime/README.md b/go/vendor/github.com/go-openapi/runtime/README.md
new file mode 100644
index 0000000..92c4070
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/README.md
@@ -0,0 +1,5 @@
+# runtime [![Build Status](https://travis-ci.org/go-openapi/runtime.svg?branch=client-context)](https://travis-ci.org/go-openapi/runtime) [![codecov](https://codecov.io/gh/go-openapi/runtime/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/runtime) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)
+
+[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/runtime/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/runtime?status.svg)](http://godoc.org/github.com/go-openapi/runtime)
+
+The runtime component for use in codegeneration or as untyped usage.
diff --git a/go/vendor/github.com/go-openapi/runtime/bytestream.go b/go/vendor/github.com/go-openapi/runtime/bytestream.go
new file mode 100644
index 0000000..9845e10
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/bytestream.go
@@ -0,0 +1,151 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package runtime
+
+import (
+	"bytes"
+	"encoding"
+	"errors"
+	"fmt"
+	"io"
+	"reflect"
+
+	"github.com/go-openapi/swag"
+)
+
+func defaultCloser() error { return nil }
+
+type byteStreamOpt func(opts *byteStreamOpts)
+
+// ClosesStream when the bytestream consumer or producer is finished
+func ClosesStream(opts *byteStreamOpts) {
+	opts.Close = true
+}
+
+type byteStreamOpts struct {
+	Close bool
+}
+
+// ByteStreamConsumer creates a consmer for byte streams,
+// takes a Writer/BinaryUnmarshaler interface or binary slice by reference,
+// and reads from the provided reader
+func ByteStreamConsumer(opts ...byteStreamOpt) Consumer {
+	var vals byteStreamOpts
+	for _, opt := range opts {
+		opt(&vals)
+	}
+
+	return ConsumerFunc(func(reader io.Reader, data interface{}) error {
+		if reader == nil {
+			return errors.New("ByteStreamConsumer requires a reader") // early exit
+		}
+
+		close := defaultCloser
+		if vals.Close {
+			if cl, ok := reader.(io.Closer); ok {
+				close = cl.Close
+			}
+		}
+		defer close()
+
+		if wrtr, ok := data.(io.Writer); ok {
+			_, err := io.Copy(wrtr, reader)
+			return err
+		}
+
+		buf := new(bytes.Buffer)
+		_, err := buf.ReadFrom(reader)
+		if err != nil {
+			return err
+		}
+		b := buf.Bytes()
+
+		if bu, ok := data.(encoding.BinaryUnmarshaler); ok {
+			return bu.UnmarshalBinary(b)
+		}
+
+		if t := reflect.TypeOf(data); data != nil && t.Kind() == reflect.Ptr {
+			v := reflect.Indirect(reflect.ValueOf(data))
+			if t = v.Type(); t.Kind() == reflect.Slice && t.Elem().Kind() == reflect.Uint8 {
+				v.SetBytes(b)
+				return nil
+			}
+		}
+
+		return fmt.Errorf("%v (%T) is not supported by the ByteStreamConsumer, %s",
+			data, data, "can be resolved by supporting Writer/BinaryUnmarshaler interface")
+	})
+}
+
+// ByteStreamProducer creates a producer for byte streams,
+// takes a Reader/BinaryMarshaler interface or binary slice,
+// and writes to a writer (essentially a pipe)
+func ByteStreamProducer(opts ...byteStreamOpt) Producer {
+	var vals byteStreamOpts
+	for _, opt := range opts {
+		opt(&vals)
+	}
+	return ProducerFunc(func(writer io.Writer, data interface{}) error {
+		if writer == nil {
+			return errors.New("ByteStreamProducer requires a writer") // early exit
+		}
+		close := defaultCloser
+		if vals.Close {
+			if cl, ok := writer.(io.Closer); ok {
+				close = cl.Close
+			}
+		}
+		defer close()
+
+		if rdr, ok := data.(io.Reader); ok {
+			_, err := io.Copy(writer, rdr)
+			return err
+		}
+
+		if bm, ok := data.(encoding.BinaryMarshaler); ok {
+			bytes, err := bm.MarshalBinary()
+			if err != nil {
+				return err
+			}
+
+			_, err = writer.Write(bytes)
+			return err
+		}
+
+		if data != nil {
+			if e, ok := data.(error); ok {
+				_, err := writer.Write([]byte(e.Error()))
+				return err
+			}
+
+			v := reflect.Indirect(reflect.ValueOf(data))
+			if t := v.Type(); t.Kind() == reflect.Slice && t.Elem().Kind() == reflect.Uint8 {
+				_, err := writer.Write(v.Bytes())
+				return err
+			}
+			if t := v.Type(); t.Kind() == reflect.Struct || t.Kind() == reflect.Slice {
+				b, err := swag.WriteJSON(data)
+				if err != nil {
+					return err
+				}
+				_, err = writer.Write(b)
+				return err
+			}
+		}
+
+		return fmt.Errorf("%v (%T) is not supported by the ByteStreamProducer, %s",
+			data, data, "can be resolved by supporting Reader/BinaryMarshaler interface")
+	})
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/client/auth_info.go b/go/vendor/github.com/go-openapi/runtime/client/auth_info.go
new file mode 100644
index 0000000..9e18222
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/client/auth_info.go
@@ -0,0 +1,60 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package client
+
+import (
+	"encoding/base64"
+
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/strfmt"
+)
+
+// PassThroughAuth never manipulates the request
+var PassThroughAuth runtime.ClientAuthInfoWriter
+
+func init() {
+	PassThroughAuth = runtime.ClientAuthInfoWriterFunc(func(_ runtime.ClientRequest, _ strfmt.Registry) error { return nil })
+}
+
+// BasicAuth provides a basic auth info writer
+func BasicAuth(username, password string) runtime.ClientAuthInfoWriter {
+	return runtime.ClientAuthInfoWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
+		encoded := base64.StdEncoding.EncodeToString([]byte(username + ":" + password))
+		return r.SetHeaderParam("Authorization", "Basic "+encoded)
+	})
+}
+
+// APIKeyAuth provides an API key auth info writer
+func APIKeyAuth(name, in, value string) runtime.ClientAuthInfoWriter {
+	if in == "query" {
+		return runtime.ClientAuthInfoWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
+			return r.SetQueryParam(name, value)
+		})
+	}
+
+	if in == "header" {
+		return runtime.ClientAuthInfoWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
+			return r.SetHeaderParam(name, value)
+		})
+	}
+	return nil
+}
+
+// BearerToken provides a header based oauth2 bearer access token auth info writer
+func BearerToken(token string) runtime.ClientAuthInfoWriter {
+	return runtime.ClientAuthInfoWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
+		return r.SetHeaderParam("Authorization", "Bearer "+token)
+	})
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/client/keepalive.go b/go/vendor/github.com/go-openapi/runtime/client/keepalive.go
new file mode 100644
index 0000000..f832545
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/client/keepalive.go
@@ -0,0 +1,53 @@
+package client
+
+import (
+	"io"
+	"io/ioutil"
+	"net/http"
+	"sync/atomic"
+)
+
+// KeepAliveTransport drains the remaining body from a response
+// so that go will reuse the TCP connections.
+// This is not enabled by default because there are servers where
+// the response never gets closed and that would make the code hang forever.
+// So instead it's provided as a http client middleware that can be used to override
+// any request.
+func KeepAliveTransport(rt http.RoundTripper) http.RoundTripper {
+	return &keepAliveTransport{wrapped: rt}
+}
+
+type keepAliveTransport struct {
+	wrapped http.RoundTripper
+}
+
+func (k *keepAliveTransport) RoundTrip(r *http.Request) (*http.Response, error) {
+	resp, err := k.wrapped.RoundTrip(r)
+	if err != nil {
+		return resp, err
+	}
+	resp.Body = &drainingReadCloser{rdr: resp.Body}
+	return resp, nil
+}
+
+type drainingReadCloser struct {
+	rdr     io.ReadCloser
+	seenEOF uint32
+}
+
+func (d *drainingReadCloser) Read(p []byte) (n int, err error) {
+	n, err = d.rdr.Read(p)
+	if err == io.EOF || n == 0 {
+		atomic.StoreUint32(&d.seenEOF, 1)
+	}
+	return
+}
+
+func (d *drainingReadCloser) Close() error {
+	// drain buffer
+	if atomic.LoadUint32(&d.seenEOF) != 1 {
+		//#nosec
+		io.Copy(ioutil.Discard, d.rdr)
+	}
+	return d.rdr.Close()
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/client/request.go b/go/vendor/github.com/go-openapi/runtime/client/request.go
new file mode 100644
index 0000000..a1c1915
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/client/request.go
@@ -0,0 +1,374 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package client
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"log"
+	"mime/multipart"
+	"net/http"
+	"net/url"
+	"os"
+	"path"
+	"path/filepath"
+	"strings"
+	"time"
+
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/strfmt"
+)
+
+// NewRequest creates a new swagger http client request
+func newRequest(method, pathPattern string, writer runtime.ClientRequestWriter) (*request, error) {
+	return &request{
+		pathPattern: pathPattern,
+		method:      method,
+		writer:      writer,
+		header:      make(http.Header),
+		query:       make(url.Values),
+		timeout:     DefaultTimeout,
+	}, nil
+}
+
+// Request represents a swagger client request.
+//
+// This Request struct converts to a HTTP request.
+// There might be others that convert to other transports.
+// There is no error checking here, it is assumed to be used after a spec has been validated.
+// so impossible combinations should not arise (hopefully).
+//
+// The main purpose of this struct is to hide the machinery of adding params to a transport request.
+// The generated code only implements what is necessary to turn a param into a valid value for these methods.
+type request struct {
+	pathPattern string
+	method      string
+	writer      runtime.ClientRequestWriter
+
+	pathParams map[string]string
+	header     http.Header
+	query      url.Values
+	formFields url.Values
+	fileFields map[string][]runtime.NamedReadCloser
+	payload    interface{}
+	timeout    time.Duration
+	buf        *bytes.Buffer
+}
+
+var (
+	// ensure interface compliance
+	_ runtime.ClientRequest = new(request)
+)
+
+func (r *request) isMultipart(mediaType string) bool {
+	if len(r.fileFields) > 0 {
+		return true
+	}
+
+	return runtime.MultipartFormMime == mediaType
+}
+
+// BuildHTTP creates a new http request based on the data from the params
+func (r *request) BuildHTTP(mediaType, basePath string, producers map[string]runtime.Producer, registry strfmt.Registry) (*http.Request, error) {
+	return r.buildHTTP(mediaType, basePath, producers, registry, nil)
+}
+
+func (r *request) buildHTTP(mediaType, basePath string, producers map[string]runtime.Producer, registry strfmt.Registry, auth runtime.ClientAuthInfoWriter) (*http.Request, error) {
+	// build the data
+	if err := r.writer.WriteToRequest(r, registry); err != nil {
+		return nil, err
+	}
+
+	if auth != nil {
+		if err := auth.AuthenticateRequest(r, registry); err != nil {
+			return nil, err
+		}
+	}
+
+	// create http request
+	var reinstateSlash bool
+	if r.pathPattern != "" && r.pathPattern != "/" && r.pathPattern[len(r.pathPattern)-1] == '/' {
+		reinstateSlash = true
+	}
+	urlPath := path.Join(basePath, r.pathPattern)
+	for k, v := range r.pathParams {
+		urlPath = strings.Replace(urlPath, "{"+k+"}", url.PathEscape(v), -1)
+	}
+	if reinstateSlash {
+		urlPath = urlPath + "/"
+	}
+
+	var body io.ReadCloser
+	var pr *io.PipeReader
+	var pw *io.PipeWriter
+
+	r.buf = bytes.NewBuffer(nil)
+	if r.payload != nil || len(r.formFields) > 0 || len(r.fileFields) > 0 {
+		body = ioutil.NopCloser(r.buf)
+		if r.isMultipart(mediaType) {
+			pr, pw = io.Pipe()
+			body = pr
+		}
+	}
+	req, err := http.NewRequest(r.method, urlPath, body)
+
+	if err != nil {
+		return nil, err
+	}
+
+	req.URL.RawQuery = r.query.Encode()
+	req.Header = r.header
+
+	// check if this is a form type request
+	if len(r.formFields) > 0 || len(r.fileFields) > 0 {
+		if !r.isMultipart(mediaType) {
+			req.Header.Set(runtime.HeaderContentType, mediaType)
+			formString := r.formFields.Encode()
+			// set content length before writing to the buffer
+			req.ContentLength = int64(len(formString))
+			// write the form values as the body
+			r.buf.WriteString(formString)
+			return req, nil
+		}
+
+		mp := multipart.NewWriter(pw)
+		req.Header.Set(runtime.HeaderContentType, mangleContentType(mediaType, mp.Boundary()))
+
+		go func() {
+			defer func() {
+				mp.Close()
+				pw.Close()
+			}()
+
+			for fn, v := range r.formFields {
+				for _, vi := range v {
+					if err := mp.WriteField(fn, vi); err != nil {
+						pw.CloseWithError(err)
+						log.Println(err)
+					}
+				}
+			}
+
+			defer func() {
+				for _, ff := range r.fileFields {
+					for _, ffi := range ff {
+						ffi.Close()
+					}
+				}
+			}()
+			for fn, f := range r.fileFields {
+				for _, fi := range f {
+					wrtr, err := mp.CreateFormFile(fn, filepath.Base(fi.Name()))
+					if err != nil {
+						pw.CloseWithError(err)
+						log.Println(err)
+					} else if _, err := io.Copy(wrtr, fi); err != nil {
+						pw.CloseWithError(err)
+						log.Println(err)
+					}
+				}
+			}
+
+		}()
+		return req, nil
+
+	}
+
+	// if there is payload, use the producer to write the payload, and then
+	// set the header to the content-type appropriate for the payload produced
+	if r.payload != nil {
+		// TODO: infer most appropriate content type based on the producer used,
+		// and the `consumers` section of the spec/operation
+		req.Header.Set(runtime.HeaderContentType, mediaType)
+		if rdr, ok := r.payload.(io.ReadCloser); ok {
+			req.Body = rdr
+
+			return req, nil
+		}
+
+		if rdr, ok := r.payload.(io.Reader); ok {
+			req.Body = ioutil.NopCloser(rdr)
+
+			return req, nil
+		}
+
+		req.GetBody = func() (io.ReadCloser, error) {
+			var b bytes.Buffer
+			producer := producers[mediaType]
+			if err := producer.Produce(&b, r.payload); err != nil {
+				return nil, err
+			}
+
+			if _, err := r.buf.Write(b.Bytes()); err != nil {
+				return nil, err
+			}
+			return ioutil.NopCloser(&b), nil
+		}
+
+		// set the content length of the request or else a chunked transfer is
+		// declared, and this corrupts outgoing JSON payloads. the content's
+		// length must be set prior to the body being written per the spec at
+		// https://golang.org/pkg/net/http
+		//
+		//     If Body is present, Content-Length is <= 0 and TransferEncoding
+		//     hasn't been set to "identity", Write adds
+		//     "Transfer-Encoding: chunked" to the header. Body is closed
+		//     after it is sent.
+		//
+		// to that end a temporary buffer, b, is created to produce the payload
+		// body, and then its size is used to set the request's content length
+		var b bytes.Buffer
+		producer := producers[mediaType]
+		if err := producer.Produce(&b, r.payload); err != nil {
+			return nil, err
+		}
+		req.ContentLength = int64(b.Len())
+		if _, err := r.buf.Write(b.Bytes()); err != nil {
+			return nil, err
+		}
+	}
+
+	if runtime.CanHaveBody(req.Method) && req.Body == nil && req.Header.Get(runtime.HeaderContentType) == "" {
+		req.Header.Set(runtime.HeaderContentType, mediaType)
+	}
+
+	return req, nil
+}
+
+func mangleContentType(mediaType, boundary string) string {
+	if strings.ToLower(mediaType) == runtime.URLencodedFormMime {
+		return fmt.Sprintf("%s; boundary=%s", mediaType, boundary)
+	}
+	return "multipart/form-data; boundary=" + boundary
+}
+
+func (r *request) GetMethod() string {
+	return r.method
+}
+
+func (r *request) GetPath() string {
+	path := r.pathPattern
+	for k, v := range r.pathParams {
+		path = strings.Replace(path, "{"+k+"}", v, -1)
+	}
+	return path
+}
+
+func (r *request) GetBody() []byte {
+	if r.buf == nil {
+		return nil
+	}
+	return r.buf.Bytes()
+}
+
+// SetHeaderParam adds a header param to the request
+// when there is only 1 value provided for the varargs, it will set it.
+// when there are several values provided for the varargs it will add it (no overriding)
+func (r *request) SetHeaderParam(name string, values ...string) error {
+	if r.header == nil {
+		r.header = make(http.Header)
+	}
+	r.header[http.CanonicalHeaderKey(name)] = values
+	return nil
+}
+
+// SetQueryParam adds a query param to the request
+// when there is only 1 value provided for the varargs, it will set it.
+// when there are several values provided for the varargs it will add it (no overriding)
+func (r *request) SetQueryParam(name string, values ...string) error {
+	if r.query == nil {
+		r.query = make(url.Values)
+	}
+	r.query[name] = values
+	return nil
+}
+
+// GetQueryParams returns a copy of all query params currently set for the request
+func (r *request) GetQueryParams() url.Values {
+	var result = make(url.Values)
+	for key, value := range r.query {
+		result[key] = append([]string{}, value...)
+	}
+	return result
+}
+
+// SetFormParam adds a forn param to the request
+// when there is only 1 value provided for the varargs, it will set it.
+// when there are several values provided for the varargs it will add it (no overriding)
+func (r *request) SetFormParam(name string, values ...string) error {
+	if r.formFields == nil {
+		r.formFields = make(url.Values)
+	}
+	r.formFields[name] = values
+	return nil
+}
+
+// SetPathParam adds a path param to the request
+func (r *request) SetPathParam(name string, value string) error {
+	if r.pathParams == nil {
+		r.pathParams = make(map[string]string)
+	}
+
+	r.pathParams[name] = value
+	return nil
+}
+
+// SetFileParam adds a file param to the request
+func (r *request) SetFileParam(name string, files ...runtime.NamedReadCloser) error {
+	for _, file := range files {
+		if actualFile, ok := file.(*os.File); ok {
+			fi, err := os.Stat(actualFile.Name())
+			if err != nil {
+				return err
+			}
+			if fi.IsDir() {
+				return fmt.Errorf("%q is a directory, only files are supported", file.Name())
+			}
+		}
+	}
+
+	if r.fileFields == nil {
+		r.fileFields = make(map[string][]runtime.NamedReadCloser)
+	}
+	if r.formFields == nil {
+		r.formFields = make(url.Values)
+	}
+
+	r.fileFields[name] = files
+	return nil
+}
+
+func (r *request) GetFileParam() map[string][]runtime.NamedReadCloser {
+	return r.fileFields
+}
+
+// SetBodyParam sets a body parameter on the request.
+// This does not yet serialze the object, this happens as late as possible.
+func (r *request) SetBodyParam(payload interface{}) error {
+	r.payload = payload
+	return nil
+}
+
+func (r *request) GetBodyParam() interface{} {
+	return r.payload
+}
+
+// SetTimeout sets the timeout for a request
+func (r *request) SetTimeout(timeout time.Duration) error {
+	r.timeout = timeout
+	return nil
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/client/response.go b/go/vendor/github.com/go-openapi/runtime/client/response.go
new file mode 100644
index 0000000..bd23858
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/client/response.go
@@ -0,0 +1,44 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package client
+
+import (
+	"io"
+	"net/http"
+
+	"github.com/go-openapi/runtime"
+)
+
+var _ runtime.ClientResponse = response{}
+
+type response struct {
+	resp *http.Response
+}
+
+func (r response) Code() int {
+	return r.resp.StatusCode
+}
+
+func (r response) Message() string {
+	return r.resp.Status
+}
+
+func (r response) GetHeader(name string) string {
+	return r.resp.Header.Get(name)
+}
+
+func (r response) Body() io.ReadCloser {
+	return r.resp.Body
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/client/runtime.go b/go/vendor/github.com/go-openapi/runtime/client/runtime.go
new file mode 100644
index 0000000..c222d94
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/client/runtime.go
@@ -0,0 +1,437 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package client
+
+import (
+	"context"
+	"crypto"
+	"crypto/ecdsa"
+	"crypto/rsa"
+	"crypto/tls"
+	"crypto/x509"
+	"encoding/pem"
+	"fmt"
+	"io/ioutil"
+	"mime"
+	"net/http"
+	"net/http/httputil"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/runtime/logger"
+	"github.com/go-openapi/runtime/middleware"
+	"github.com/go-openapi/strfmt"
+)
+
+// TLSClientOptions to configure client authentication with mutual TLS
+type TLSClientOptions struct {
+	// Certificate is the path to a PEM-encoded certificate to be used for
+	// client authentication. If set then Key must also be set.
+	Certificate string
+
+	// LoadedCertificate is the certificate to be used for client authentication.
+	// This field is ignored if Certificate is set. If this field is set, LoadedKey
+	// is also required.
+	LoadedCertificate *x509.Certificate
+
+	// Key is the path to an unencrypted PEM-encoded private key for client
+	// authentication. This field is required if Certificate is set.
+	Key string
+
+	// LoadedKey is the key for client authentication. This field is required if
+	// LoadedCertificate is set.
+	LoadedKey crypto.PrivateKey
+
+	// CA is a path to a PEM-encoded certificate that specifies the root certificate
+	// to use when validating the TLS certificate presented by the server. If this field
+	// (and LoadedCA) is not set, the system certificate pool is used. This field is ignored if LoadedCA
+	// is set.
+	CA string
+
+	// LoadedCA specifies the root certificate to use when validating the server's TLS certificate.
+	// If this field (and CA) is not set, the system certificate pool is used.
+	LoadedCA *x509.Certificate
+
+	// ServerName specifies the hostname to use when verifying the server certificate.
+	// If this field is set then InsecureSkipVerify will be ignored and treated as
+	// false.
+	ServerName string
+
+	// InsecureSkipVerify controls whether the certificate chain and hostname presented
+	// by the server are validated. If false, any certificate is accepted.
+	InsecureSkipVerify bool
+
+	// Prevents callers using unkeyed fields.
+	_ struct{}
+}
+
+// TLSClientAuth creates a tls.Config for mutual auth
+func TLSClientAuth(opts TLSClientOptions) (*tls.Config, error) {
+	// create client tls config
+	cfg := &tls.Config{}
+
+	// load client cert if specified
+	if opts.Certificate != "" {
+		cert, err := tls.LoadX509KeyPair(opts.Certificate, opts.Key)
+		if err != nil {
+			return nil, fmt.Errorf("tls client cert: %v", err)
+		}
+		cfg.Certificates = []tls.Certificate{cert}
+	} else if opts.LoadedCertificate != nil {
+		block := pem.Block{Type: "CERTIFICATE", Bytes: opts.LoadedCertificate.Raw}
+		certPem := pem.EncodeToMemory(&block)
+
+		var keyBytes []byte
+		switch k := opts.LoadedKey.(type) {
+		case *rsa.PrivateKey:
+			keyBytes = x509.MarshalPKCS1PrivateKey(k)
+		case *ecdsa.PrivateKey:
+			var err error
+			keyBytes, err = x509.MarshalECPrivateKey(k)
+			if err != nil {
+				return nil, fmt.Errorf("tls client priv key: %v", err)
+			}
+		default:
+			return nil, fmt.Errorf("tls client priv key: unsupported key type")
+		}
+
+		block = pem.Block{Type: "PRIVATE KEY", Bytes: keyBytes}
+		keyPem := pem.EncodeToMemory(&block)
+
+		cert, err := tls.X509KeyPair(certPem, keyPem)
+		if err != nil {
+			return nil, fmt.Errorf("tls client cert: %v", err)
+		}
+		cfg.Certificates = []tls.Certificate{cert}
+	}
+
+	cfg.InsecureSkipVerify = opts.InsecureSkipVerify
+
+	// When no CA certificate is provided, default to the system cert pool
+	// that way when a request is made to a server known by the system trust store,
+	// the name is still verified
+	if opts.LoadedCA != nil {
+		caCertPool := x509.NewCertPool()
+		caCertPool.AddCert(opts.LoadedCA)
+		cfg.RootCAs = caCertPool
+	} else if opts.CA != "" {
+		// load ca cert
+		caCert, err := ioutil.ReadFile(opts.CA)
+		if err != nil {
+			return nil, fmt.Errorf("tls client ca: %v", err)
+		}
+		caCertPool := x509.NewCertPool()
+		caCertPool.AppendCertsFromPEM(caCert)
+		cfg.RootCAs = caCertPool
+	}
+
+	// apply servername overrride
+	if opts.ServerName != "" {
+		cfg.InsecureSkipVerify = false
+		cfg.ServerName = opts.ServerName
+	}
+
+	cfg.BuildNameToCertificate()
+
+	return cfg, nil
+}
+
+// TLSTransport creates a http client transport suitable for mutual tls auth
+func TLSTransport(opts TLSClientOptions) (http.RoundTripper, error) {
+	cfg, err := TLSClientAuth(opts)
+	if err != nil {
+		return nil, err
+	}
+
+	return &http.Transport{TLSClientConfig: cfg}, nil
+}
+
+// TLSClient creates a http.Client for mutual auth
+func TLSClient(opts TLSClientOptions) (*http.Client, error) {
+	transport, err := TLSTransport(opts)
+	if err != nil {
+		return nil, err
+	}
+	return &http.Client{Transport: transport}, nil
+}
+
+// DefaultTimeout the default request timeout
+var DefaultTimeout = 30 * time.Second
+
+// Runtime represents an API client that uses the transport
+// to make http requests based on a swagger specification.
+type Runtime struct {
+	DefaultMediaType      string
+	DefaultAuthentication runtime.ClientAuthInfoWriter
+	Consumers             map[string]runtime.Consumer
+	Producers             map[string]runtime.Producer
+
+	Transport http.RoundTripper
+	Jar       http.CookieJar
+	//Spec      *spec.Document
+	Host     string
+	BasePath string
+	Formats  strfmt.Registry
+	Context  context.Context
+
+	Debug  bool
+	logger logger.Logger
+
+	clientOnce *sync.Once
+	client     *http.Client
+	schemes    []string
+}
+
+// New creates a new default runtime for a swagger api runtime.Client
+func New(host, basePath string, schemes []string) *Runtime {
+	var rt Runtime
+	rt.DefaultMediaType = runtime.JSONMime
+
+	// TODO: actually infer this stuff from the spec
+	rt.Consumers = map[string]runtime.Consumer{
+		runtime.JSONMime:    runtime.JSONConsumer(),
+		runtime.XMLMime:     runtime.XMLConsumer(),
+		runtime.TextMime:    runtime.TextConsumer(),
+		runtime.HTMLMime:    runtime.TextConsumer(),
+		runtime.DefaultMime: runtime.ByteStreamConsumer(),
+	}
+	rt.Producers = map[string]runtime.Producer{
+		runtime.JSONMime:    runtime.JSONProducer(),
+		runtime.XMLMime:     runtime.XMLProducer(),
+		runtime.TextMime:    runtime.TextProducer(),
+		runtime.HTMLMime:    runtime.TextProducer(),
+		runtime.DefaultMime: runtime.ByteStreamProducer(),
+	}
+	rt.Transport = http.DefaultTransport
+	rt.Jar = nil
+	rt.Host = host
+	rt.BasePath = basePath
+	rt.Context = context.Background()
+	rt.clientOnce = new(sync.Once)
+	if !strings.HasPrefix(rt.BasePath, "/") {
+		rt.BasePath = "/" + rt.BasePath
+	}
+
+	rt.Debug = logger.DebugEnabled()
+	rt.logger = logger.StandardLogger{}
+
+	if len(schemes) > 0 {
+		rt.schemes = schemes
+	}
+	return &rt
+}
+
+// NewWithClient allows you to create a new transport with a configured http.Client
+func NewWithClient(host, basePath string, schemes []string, client *http.Client) *Runtime {
+	rt := New(host, basePath, schemes)
+	if client != nil {
+		rt.clientOnce.Do(func() {
+			rt.client = client
+		})
+	}
+	return rt
+}
+
+func (r *Runtime) pickScheme(schemes []string) string {
+	if v := r.selectScheme(r.schemes); v != "" {
+		return v
+	}
+	if v := r.selectScheme(schemes); v != "" {
+		return v
+	}
+	return "http"
+}
+
+func (r *Runtime) selectScheme(schemes []string) string {
+	schLen := len(schemes)
+	if schLen == 0 {
+		return ""
+	}
+
+	scheme := schemes[0]
+	// prefer https, but skip when not possible
+	if scheme != "https" && schLen > 1 {
+		for _, sch := range schemes {
+			if sch == "https" {
+				scheme = sch
+				break
+			}
+		}
+	}
+	return scheme
+}
+func transportOrDefault(left, right http.RoundTripper) http.RoundTripper {
+	if left == nil {
+		return right
+	}
+	return left
+}
+
+// EnableConnectionReuse drains the remaining body from a response
+// so that go will reuse the TCP connections.
+//
+// This is not enabled by default because there are servers where
+// the response never gets closed and that would make the code hang forever.
+// So instead it's provided as a http client middleware that can be used to override
+// any request.
+func (r *Runtime) EnableConnectionReuse() {
+	if r.client == nil {
+		r.Transport = KeepAliveTransport(
+			transportOrDefault(r.Transport, http.DefaultTransport),
+		)
+		return
+	}
+
+	r.client.Transport = KeepAliveTransport(
+		transportOrDefault(r.client.Transport,
+			transportOrDefault(r.Transport, http.DefaultTransport),
+		),
+	)
+}
+
+// Submit a request and when there is a body on success it will turn that into the result
+// all other things are turned into an api error for swagger which retains the status code
+func (r *Runtime) Submit(operation *runtime.ClientOperation) (interface{}, error) {
+	params, readResponse, auth := operation.Params, operation.Reader, operation.AuthInfo
+
+	request, err := newRequest(operation.Method, operation.PathPattern, params)
+	if err != nil {
+		return nil, err
+	}
+
+	var accept []string
+	accept = append(accept, operation.ProducesMediaTypes...)
+	if err = request.SetHeaderParam(runtime.HeaderAccept, accept...); err != nil {
+		return nil, err
+	}
+
+	if auth == nil && r.DefaultAuthentication != nil {
+		auth = r.DefaultAuthentication
+	}
+	//if auth != nil {
+	//	if err := auth.AuthenticateRequest(request, r.Formats); err != nil {
+	//		return nil, err
+	//	}
+	//}
+
+	// TODO: pick appropriate media type
+	cmt := r.DefaultMediaType
+	for _, mediaType := range operation.ConsumesMediaTypes {
+		// Pick first non-empty media type
+		if mediaType != "" {
+			cmt = mediaType
+			break
+		}
+	}
+
+	if _, ok := r.Producers[cmt]; !ok && cmt != runtime.MultipartFormMime && cmt != runtime.URLencodedFormMime {
+		return nil, fmt.Errorf("none of producers: %v registered. try %s", r.Producers, cmt)
+	}
+
+	req, err := request.buildHTTP(cmt, r.BasePath, r.Producers, r.Formats, auth)
+	if err != nil {
+		return nil, err
+	}
+	req.URL.Scheme = r.pickScheme(operation.Schemes)
+	req.URL.Host = r.Host
+
+	r.clientOnce.Do(func() {
+		r.client = &http.Client{
+			Transport: r.Transport,
+			Jar:       r.Jar,
+		}
+	})
+
+	if r.Debug {
+		b, err2 := httputil.DumpRequestOut(req, true)
+		if err2 != nil {
+			return nil, err2
+		}
+		r.logger.Debugf("%s\n", string(b))
+	}
+
+	var hasTimeout bool
+	pctx := operation.Context
+	if pctx == nil {
+		pctx = r.Context
+	} else {
+		hasTimeout = true
+	}
+	if pctx == nil {
+		pctx = context.Background()
+	}
+	var ctx context.Context
+	var cancel context.CancelFunc
+	if hasTimeout {
+		ctx, cancel = context.WithCancel(pctx)
+	} else {
+		ctx, cancel = context.WithTimeout(pctx, request.timeout)
+	}
+	defer cancel()
+
+	client := operation.Client
+	if client == nil {
+		client = r.client
+	}
+	req = req.WithContext(ctx)
+	res, err := client.Do(req) // make requests, by default follows 10 redirects before failing
+	if err != nil {
+		return nil, err
+	}
+	defer res.Body.Close()
+
+	if r.Debug {
+		b, err2 := httputil.DumpResponse(res, true)
+		if err2 != nil {
+			return nil, err2
+		}
+		r.logger.Debugf("%s\n", string(b))
+	}
+
+	ct := res.Header.Get(runtime.HeaderContentType)
+	if ct == "" { // this should really really never occur
+		ct = r.DefaultMediaType
+	}
+
+	mt, _, err := mime.ParseMediaType(ct)
+	if err != nil {
+		return nil, fmt.Errorf("parse content type: %s", err)
+	}
+
+	cons, ok := r.Consumers[mt]
+	if !ok {
+		if cons, ok = r.Consumers["*/*"]; !ok {
+			// scream about not knowing what to do
+			return nil, fmt.Errorf("no consumer: %q", ct)
+		}
+	}
+	return readResponse.ReadResponse(response{res}, cons)
+}
+
+// SetDebug changes the debug flag.
+// It ensures that client and middlewares have the set debug level.
+func (r *Runtime) SetDebug(debug bool) {
+	r.Debug = debug
+	middleware.Debug = debug
+}
+
+// SetLogger changes the logger stream.
+// It ensures that client and middlewares use the same logger.
+func (r *Runtime) SetLogger(logger logger.Logger) {
+	r.logger = logger
+	middleware.Logger = logger
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/client_auth_info.go b/go/vendor/github.com/go-openapi/runtime/client_auth_info.go
new file mode 100644
index 0000000..c6c97d9
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/client_auth_info.go
@@ -0,0 +1,30 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package runtime
+
+import "github.com/go-openapi/strfmt"
+
+// A ClientAuthInfoWriterFunc converts a function to a request writer interface
+type ClientAuthInfoWriterFunc func(ClientRequest, strfmt.Registry) error
+
+// AuthenticateRequest adds authentication data to the request
+func (fn ClientAuthInfoWriterFunc) AuthenticateRequest(req ClientRequest, reg strfmt.Registry) error {
+	return fn(req, reg)
+}
+
+// A ClientAuthInfoWriter implementor knows how to write authentication info to a request
+type ClientAuthInfoWriter interface {
+	AuthenticateRequest(ClientRequest, strfmt.Registry) error
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/client_operation.go b/go/vendor/github.com/go-openapi/runtime/client_operation.go
new file mode 100644
index 0000000..fa21eac
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/client_operation.go
@@ -0,0 +1,41 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package runtime
+
+import (
+	"context"
+	"net/http"
+)
+
+// ClientOperation represents the context for a swagger operation to be submitted to the transport
+type ClientOperation struct {
+	ID                 string
+	Method             string
+	PathPattern        string
+	ProducesMediaTypes []string
+	ConsumesMediaTypes []string
+	Schemes            []string
+	AuthInfo           ClientAuthInfoWriter
+	Params             ClientRequestWriter
+	Reader             ClientResponseReader
+	Context            context.Context
+	Client             *http.Client
+}
+
+// A ClientTransport implementor knows how to submit Request objects to some destination
+type ClientTransport interface {
+	//Submit(string, RequestWriter, ResponseReader, AuthInfoWriter) (interface{}, error)
+	Submit(*ClientOperation) (interface{}, error)
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/client_request.go b/go/vendor/github.com/go-openapi/runtime/client_request.go
new file mode 100644
index 0000000..4aef7ed
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/client_request.go
@@ -0,0 +1,100 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package runtime
+
+import (
+	"io"
+	"io/ioutil"
+	"net/url"
+	"time"
+
+	"github.com/go-openapi/strfmt"
+)
+
+// ClientRequestWriterFunc converts a function to a request writer interface
+type ClientRequestWriterFunc func(ClientRequest, strfmt.Registry) error
+
+// WriteToRequest adds data to the request
+func (fn ClientRequestWriterFunc) WriteToRequest(req ClientRequest, reg strfmt.Registry) error {
+	return fn(req, reg)
+}
+
+// ClientRequestWriter is an interface for things that know how to write to a request
+type ClientRequestWriter interface {
+	WriteToRequest(ClientRequest, strfmt.Registry) error
+}
+
+// ClientRequest is an interface for things that know how to
+// add information to a swagger client request
+type ClientRequest interface {
+	SetHeaderParam(string, ...string) error
+
+	SetQueryParam(string, ...string) error
+
+	SetFormParam(string, ...string) error
+
+	SetPathParam(string, string) error
+
+	GetQueryParams() url.Values
+
+	SetFileParam(string, ...NamedReadCloser) error
+
+	SetBodyParam(interface{}) error
+
+	SetTimeout(time.Duration) error
+
+	GetMethod() string
+
+	GetPath() string
+
+	GetBody() []byte
+
+	GetBodyParam() interface{}
+
+	GetFileParam() map[string][]NamedReadCloser
+}
+
+// NamedReadCloser represents a named ReadCloser interface
+type NamedReadCloser interface {
+	io.ReadCloser
+	Name() string
+}
+
+// NamedReader creates a NamedReadCloser for use as file upload
+func NamedReader(name string, rdr io.Reader) NamedReadCloser {
+	rc, ok := rdr.(io.ReadCloser)
+	if !ok {
+		rc = ioutil.NopCloser(rdr)
+	}
+	return &namedReadCloser{
+		name: name,
+		cr:   rc,
+	}
+}
+
+type namedReadCloser struct {
+	name string
+	cr   io.ReadCloser
+}
+
+func (n *namedReadCloser) Close() error {
+	return n.cr.Close()
+}
+func (n *namedReadCloser) Read(p []byte) (int, error) {
+	return n.cr.Read(p)
+}
+func (n *namedReadCloser) Name() string {
+	return n.name
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/client_response.go b/go/vendor/github.com/go-openapi/runtime/client_response.go
new file mode 100644
index 0000000..729e18b
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/client_response.go
@@ -0,0 +1,63 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package runtime
+
+import (
+	"fmt"
+	"io"
+)
+
+// A ClientResponse represents a client response
+// This bridges between responses obtained from different transports
+type ClientResponse interface {
+	Code() int
+	Message() string
+	GetHeader(string) string
+	Body() io.ReadCloser
+}
+
+// A ClientResponseReaderFunc turns a function into a ClientResponseReader interface implementation
+type ClientResponseReaderFunc func(ClientResponse, Consumer) (interface{}, error)
+
+// ReadResponse reads the response
+func (read ClientResponseReaderFunc) ReadResponse(resp ClientResponse, consumer Consumer) (interface{}, error) {
+	return read(resp, consumer)
+}
+
+// A ClientResponseReader is an interface for things want to read a response.
+// An application of this is to create structs from response values
+type ClientResponseReader interface {
+	ReadResponse(ClientResponse, Consumer) (interface{}, error)
+}
+
+// NewAPIError creates a new API error
+func NewAPIError(opName string, payload interface{}, code int) *APIError {
+	return &APIError{
+		OperationName: opName,
+		Response:      payload,
+		Code:          code,
+	}
+}
+
+// APIError wraps an error model and captures the status code
+type APIError struct {
+	OperationName string
+	Response      interface{}
+	Code          int
+}
+
+func (a *APIError) Error() string {
+	return fmt.Sprintf("%s (status %d): %+v ", a.OperationName, a.Code, a.Response)
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/constants.go b/go/vendor/github.com/go-openapi/runtime/constants.go
new file mode 100644
index 0000000..30f36fa
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/constants.go
@@ -0,0 +1,45 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package runtime
+
+const (
+	// HeaderContentType represents a http content-type header, it's value is supposed to be a mime type
+	HeaderContentType = "Content-Type"
+
+	// HeaderTransferEncoding represents a http transfer-encoding header.
+	HeaderTransferEncoding = "Transfer-Encoding"
+
+	// HeaderAccept the Accept header
+	HeaderAccept = "Accept"
+
+	charsetKey = "charset"
+
+	// DefaultMime the default fallback mime type
+	DefaultMime = "application/octet-stream"
+	// JSONMime the json mime type
+	JSONMime = "application/json"
+	// YAMLMime the yaml mime type
+	YAMLMime = "application/x-yaml"
+	// XMLMime the xml mime type
+	XMLMime = "application/xml"
+	// TextMime the text mime type
+	TextMime = "text/plain"
+	// HTMLMime the html mime type
+	HTMLMime = "text/html"
+	// MultipartFormMime the multipart form mime type
+	MultipartFormMime = "multipart/form-data"
+	// URLencodedFormMime the url encoded form mime type
+	URLencodedFormMime = "application/x-www-form-urlencoded"
+)
diff --git a/go/vendor/github.com/go-openapi/runtime/discard.go b/go/vendor/github.com/go-openapi/runtime/discard.go
new file mode 100644
index 0000000..0d390cf
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/discard.go
@@ -0,0 +1,9 @@
+package runtime
+
+import "io"
+
+// DiscardConsumer does absolutely nothing, it's a black hole.
+var DiscardConsumer = ConsumerFunc(func(_ io.Reader, _ interface{}) error { return nil })
+
+// DiscardProducer does absolutely nothing, it's a black hole.
+var DiscardProducer = ProducerFunc(func(_ io.Writer, _ interface{}) error { return nil })
diff --git a/go/vendor/github.com/go-openapi/runtime/file.go b/go/vendor/github.com/go-openapi/runtime/file.go
new file mode 100644
index 0000000..85971c1
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/file.go
@@ -0,0 +1,33 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package runtime
+
+import "mime/multipart"
+
+// File represents an uploaded file.
+type File struct {
+	Data   multipart.File
+	Header *multipart.FileHeader
+}
+
+// Read bytes from the file
+func (f *File) Read(p []byte) (n int, err error) {
+	return f.Data.Read(p)
+}
+
+// Close the file
+func (f *File) Close() error {
+	return f.Data.Close()
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/go.mod b/go/vendor/github.com/go-openapi/runtime/go.mod
new file mode 100644
index 0000000..2ca8e13
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/go.mod
@@ -0,0 +1,14 @@
+module github.com/go-openapi/runtime
+
+require (
+	github.com/docker/go-units v0.3.3
+	github.com/go-openapi/analysis v0.17.0
+	github.com/go-openapi/errors v0.17.0
+	github.com/go-openapi/loads v0.17.0
+	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/go-openapi/validate 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/runtime/go.sum b/go/vendor/github.com/go-openapi/runtime/go.sum
new file mode 100644
index 0000000..d2e908a
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/go.sum
@@ -0,0 +1,43 @@
+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/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
+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/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/go-openapi/validate v0.17.0 h1:pqoViQz3YLOGIhAmD0N4Lt6pa/3Gnj3ymKqQwq8iS6U=
+github.com/go-openapi/validate v0.17.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
+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/runtime/headers.go b/go/vendor/github.com/go-openapi/runtime/headers.go
new file mode 100644
index 0000000..4d111db
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/headers.go
@@ -0,0 +1,45 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package runtime
+
+import (
+	"mime"
+	"net/http"
+
+	"github.com/go-openapi/errors"
+)
+
+// ContentType parses a content type header
+func ContentType(headers http.Header) (string, string, error) {
+	ct := headers.Get(HeaderContentType)
+	orig := ct
+	if ct == "" {
+		ct = DefaultMime
+	}
+	if ct == "" {
+		return "", "", nil
+	}
+
+	mt, opts, err := mime.ParseMediaType(ct)
+	if err != nil {
+		return "", "", errors.NewParseError(HeaderContentType, "header", orig, err)
+	}
+
+	if cs, ok := opts[charsetKey]; ok {
+		return mt, cs, nil
+	}
+
+	return mt, "", nil
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/interfaces.go b/go/vendor/github.com/go-openapi/runtime/interfaces.go
new file mode 100644
index 0000000..65de0aa
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/interfaces.go
@@ -0,0 +1,103 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package runtime
+
+import (
+	"io"
+	"net/http"
+
+	"github.com/go-openapi/strfmt"
+)
+
+// OperationHandlerFunc an adapter for a function to the OperationHandler interface
+type OperationHandlerFunc func(interface{}) (interface{}, error)
+
+// Handle implements the operation handler interface
+func (s OperationHandlerFunc) Handle(data interface{}) (interface{}, error) {
+	return s(data)
+}
+
+// OperationHandler a handler for a swagger operation
+type OperationHandler interface {
+	Handle(interface{}) (interface{}, error)
+}
+
+// ConsumerFunc represents a function that can be used as a consumer
+type ConsumerFunc func(io.Reader, interface{}) error
+
+// Consume consumes the reader into the data parameter
+func (fn ConsumerFunc) Consume(reader io.Reader, data interface{}) error {
+	return fn(reader, data)
+}
+
+// Consumer implementations know how to bind the values on the provided interface to
+// data provided by the request body
+type Consumer interface {
+	// Consume performs the binding of request values
+	Consume(io.Reader, interface{}) error
+}
+
+// ProducerFunc represents a function that can be used as a producer
+type ProducerFunc func(io.Writer, interface{}) error
+
+// Produce produces the response for the provided data
+func (f ProducerFunc) Produce(writer io.Writer, data interface{}) error {
+	return f(writer, data)
+}
+
+// Producer implementations know how to turn the provided interface into a valid
+// HTTP response
+type Producer interface {
+	// Produce writes to the http response
+	Produce(io.Writer, interface{}) error
+}
+
+// AuthenticatorFunc turns a function into an authenticator
+type AuthenticatorFunc func(interface{}) (bool, interface{}, error)
+
+// Authenticate authenticates the request with the provided data
+func (f AuthenticatorFunc) Authenticate(params interface{}) (bool, interface{}, error) {
+	return f(params)
+}
+
+// Authenticator represents an authentication strategy
+// implementations of Authenticator know how to authenticate the
+// request data and translate that into a valid principal object or an error
+type Authenticator interface {
+	Authenticate(interface{}) (bool, interface{}, error)
+}
+
+// AuthorizerFunc turns a function into an authorizer
+type AuthorizerFunc func(*http.Request, interface{}) error
+
+// Authorize authorizes the processing of the request for the principal
+func (f AuthorizerFunc) Authorize(r *http.Request, principal interface{}) error {
+	return f(r, principal)
+}
+
+// Authorizer represents an authorization strategy
+// implementations of Authorizer know how to authorize the principal object
+// using the request data and returns error if unauthorized
+type Authorizer interface {
+	Authorize(*http.Request, interface{}) error
+}
+
+// Validatable types implementing this interface allow customizing their validation
+// this will be used instead of the reflective validation based on the spec document.
+// the implementations are assumed to have been generated by the swagger tool so they should
+// contain all the validations obtained from the spec
+type Validatable interface {
+	Validate(strfmt.Registry) error
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/json.go b/go/vendor/github.com/go-openapi/runtime/json.go
new file mode 100644
index 0000000..81ee360
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/json.go
@@ -0,0 +1,37 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package runtime
+
+import (
+	"encoding/json"
+	"io"
+)
+
+// JSONConsumer creates a new JSON consumer
+func JSONConsumer() Consumer {
+	return ConsumerFunc(func(reader io.Reader, data interface{}) error {
+		dec := json.NewDecoder(reader)
+		dec.UseNumber() // preserve number formats
+		return dec.Decode(data)
+	})
+}
+
+// JSONProducer creates a new JSON producer
+func JSONProducer() Producer {
+	return ProducerFunc(func(writer io.Writer, data interface{}) error {
+		enc := json.NewEncoder(writer)
+		return enc.Encode(data)
+	})
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/logger/logger.go b/go/vendor/github.com/go-openapi/runtime/logger/logger.go
new file mode 100644
index 0000000..d62c1f7
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/logger/logger.go
@@ -0,0 +1,12 @@
+package logger
+
+import "os"
+
+type Logger interface {
+	Printf(format string, args ...interface{})
+	Debugf(format string, args ...interface{})
+}
+
+func DebugEnabled() bool {
+	return os.Getenv("SWAGGER_DEBUG") != "" || os.Getenv("DEBUG") != ""
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/logger/standard.go b/go/vendor/github.com/go-openapi/runtime/logger/standard.go
new file mode 100644
index 0000000..f7e67eb
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/logger/standard.go
@@ -0,0 +1,22 @@
+package logger
+
+import (
+	"fmt"
+	"os"
+)
+
+type StandardLogger struct{}
+
+func (StandardLogger) Printf(format string, args ...interface{}) {
+	if len(format) == 0 || format[len(format)-1] != '\n' {
+		format += "\n"
+	}
+	fmt.Fprintf(os.Stderr, format, args...)
+}
+
+func (StandardLogger) Debugf(format string, args ...interface{}) {
+	if len(format) == 0 || format[len(format)-1] != '\n' {
+		format += "\n"
+	}
+	fmt.Fprintf(os.Stderr, format, args...)
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/middleware/context.go b/go/vendor/github.com/go-openapi/runtime/middleware/context.go
new file mode 100644
index 0000000..48d7150
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/middleware/context.go
@@ -0,0 +1,582 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package middleware
+
+import (
+	stdContext "context"
+	"net/http"
+	"strings"
+	"sync"
+
+	"github.com/go-openapi/analysis"
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/loads"
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/runtime/logger"
+	"github.com/go-openapi/runtime/middleware/untyped"
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/strfmt"
+)
+
+// Debug when true turns on verbose logging
+var Debug = logger.DebugEnabled()
+var Logger logger.Logger = logger.StandardLogger{}
+
+func debugLog(format string, args ...interface{}) {
+	if Debug {
+		Logger.Printf(format, args...)
+	}
+}
+
+// A Builder can create middlewares
+type Builder func(http.Handler) http.Handler
+
+// PassthroughBuilder returns the handler, aka the builder identity function
+func PassthroughBuilder(handler http.Handler) http.Handler { return handler }
+
+// RequestBinder is an interface for types to implement
+// when they want to be able to bind from a request
+type RequestBinder interface {
+	BindRequest(*http.Request, *MatchedRoute) error
+}
+
+// Responder is an interface for types to implement
+// when they want to be considered for writing HTTP responses
+type Responder interface {
+	WriteResponse(http.ResponseWriter, runtime.Producer)
+}
+
+// ResponderFunc wraps a func as a Responder interface
+type ResponderFunc func(http.ResponseWriter, runtime.Producer)
+
+// WriteResponse writes to the response
+func (fn ResponderFunc) WriteResponse(rw http.ResponseWriter, pr runtime.Producer) {
+	fn(rw, pr)
+}
+
+// Context is a type safe wrapper around an untyped request context
+// used throughout to store request context with the standard context attached
+// to the http.Request
+type Context struct {
+	spec     *loads.Document
+	analyzer *analysis.Spec
+	api      RoutableAPI
+	router   Router
+}
+
+type routableUntypedAPI struct {
+	api             *untyped.API
+	hlock           *sync.Mutex
+	handlers        map[string]map[string]http.Handler
+	defaultConsumes string
+	defaultProduces string
+}
+
+func newRoutableUntypedAPI(spec *loads.Document, api *untyped.API, context *Context) *routableUntypedAPI {
+	var handlers map[string]map[string]http.Handler
+	if spec == nil || api == nil {
+		return nil
+	}
+	analyzer := analysis.New(spec.Spec())
+	for method, hls := range analyzer.Operations() {
+		um := strings.ToUpper(method)
+		for path, op := range hls {
+			schemes := analyzer.SecurityRequirementsFor(op)
+
+			if oh, ok := api.OperationHandlerFor(method, path); ok {
+				if handlers == nil {
+					handlers = make(map[string]map[string]http.Handler)
+				}
+				if b, ok := handlers[um]; !ok || b == nil {
+					handlers[um] = make(map[string]http.Handler)
+				}
+
+				var handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+					// lookup route info in the context
+					route, rCtx, _ := context.RouteInfo(r)
+					if rCtx != nil {
+						r = rCtx
+					}
+
+					// bind and validate the request using reflection
+					var bound interface{}
+					var validation error
+					bound, r, validation = context.BindAndValidate(r, route)
+					if validation != nil {
+						context.Respond(w, r, route.Produces, route, validation)
+						return
+					}
+
+					// actually handle the request
+					result, err := oh.Handle(bound)
+					if err != nil {
+						// respond with failure
+						context.Respond(w, r, route.Produces, route, err)
+						return
+					}
+
+					// respond with success
+					context.Respond(w, r, route.Produces, route, result)
+				})
+
+				if len(schemes) > 0 {
+					handler = newSecureAPI(context, handler)
+				}
+				handlers[um][path] = handler
+			}
+		}
+	}
+
+	return &routableUntypedAPI{
+		api:             api,
+		hlock:           new(sync.Mutex),
+		handlers:        handlers,
+		defaultProduces: api.DefaultProduces,
+		defaultConsumes: api.DefaultConsumes,
+	}
+}
+
+func (r *routableUntypedAPI) HandlerFor(method, path string) (http.Handler, bool) {
+	r.hlock.Lock()
+	paths, ok := r.handlers[strings.ToUpper(method)]
+	if !ok {
+		r.hlock.Unlock()
+		return nil, false
+	}
+	handler, ok := paths[path]
+	r.hlock.Unlock()
+	return handler, ok
+}
+func (r *routableUntypedAPI) ServeErrorFor(operationID string) func(http.ResponseWriter, *http.Request, error) {
+	return r.api.ServeError
+}
+func (r *routableUntypedAPI) ConsumersFor(mediaTypes []string) map[string]runtime.Consumer {
+	return r.api.ConsumersFor(mediaTypes)
+}
+func (r *routableUntypedAPI) ProducersFor(mediaTypes []string) map[string]runtime.Producer {
+	return r.api.ProducersFor(mediaTypes)
+}
+func (r *routableUntypedAPI) AuthenticatorsFor(schemes map[string]spec.SecurityScheme) map[string]runtime.Authenticator {
+	return r.api.AuthenticatorsFor(schemes)
+}
+func (r *routableUntypedAPI) Authorizer() runtime.Authorizer {
+	return r.api.Authorizer()
+}
+func (r *routableUntypedAPI) Formats() strfmt.Registry {
+	return r.api.Formats()
+}
+
+func (r *routableUntypedAPI) DefaultProduces() string {
+	return r.defaultProduces
+}
+
+func (r *routableUntypedAPI) DefaultConsumes() string {
+	return r.defaultConsumes
+}
+
+// NewRoutableContext creates a new context for a routable API
+func NewRoutableContext(spec *loads.Document, routableAPI RoutableAPI, routes Router) *Context {
+	var an *analysis.Spec
+	if spec != nil {
+		an = analysis.New(spec.Spec())
+	}
+	ctx := &Context{spec: spec, api: routableAPI, analyzer: an, router: routes}
+	return ctx
+}
+
+// NewContext creates a new context wrapper
+func NewContext(spec *loads.Document, api *untyped.API, routes Router) *Context {
+	var an *analysis.Spec
+	if spec != nil {
+		an = analysis.New(spec.Spec())
+	}
+	ctx := &Context{spec: spec, analyzer: an}
+	ctx.api = newRoutableUntypedAPI(spec, api, ctx)
+	ctx.router = routes
+	return ctx
+}
+
+// Serve serves the specified spec with the specified api registrations as a http.Handler
+func Serve(spec *loads.Document, api *untyped.API) http.Handler {
+	return ServeWithBuilder(spec, api, PassthroughBuilder)
+}
+
+// ServeWithBuilder serves the specified spec with the specified api registrations as a http.Handler that is decorated
+// by the Builder
+func ServeWithBuilder(spec *loads.Document, api *untyped.API, builder Builder) http.Handler {
+	context := NewContext(spec, api, nil)
+	return context.APIHandler(builder)
+}
+
+type contextKey int8
+
+const (
+	_ contextKey = iota
+	ctxContentType
+	ctxResponseFormat
+	ctxMatchedRoute
+	ctxBoundParams
+	ctxSecurityPrincipal
+	ctxSecurityScopes
+)
+
+// MatchedRouteFrom request context value.
+func MatchedRouteFrom(req *http.Request) *MatchedRoute {
+	mr := req.Context().Value(ctxMatchedRoute)
+	if mr == nil {
+		return nil
+	}
+	if res, ok := mr.(*MatchedRoute); ok {
+		return res
+	}
+	return nil
+}
+
+// SecurityPrincipalFrom request context value.
+func SecurityPrincipalFrom(req *http.Request) interface{} {
+	return req.Context().Value(ctxSecurityPrincipal)
+}
+
+// SecurityScopesFrom request context value.
+func SecurityScopesFrom(req *http.Request) []string {
+	rs := req.Context().Value(ctxSecurityScopes)
+	if res, ok := rs.([]string); ok {
+		return res
+	}
+	return nil
+}
+
+type contentTypeValue struct {
+	MediaType string
+	Charset   string
+}
+
+// BasePath returns the base path for this API
+func (c *Context) BasePath() string {
+	return c.spec.BasePath()
+}
+
+// RequiredProduces returns the accepted content types for responses
+func (c *Context) RequiredProduces() []string {
+	return c.analyzer.RequiredProduces()
+}
+
+// BindValidRequest binds a params object to a request but only when the request is valid
+// if the request is not valid an error will be returned
+func (c *Context) BindValidRequest(request *http.Request, route *MatchedRoute, binder RequestBinder) error {
+	var res []error
+
+	requestContentType := "*/*"
+	// check and validate content type, select consumer
+	if runtime.HasBody(request) {
+		ct, _, err := runtime.ContentType(request.Header)
+		if err != nil {
+			res = append(res, err)
+		} else {
+			if err := validateContentType(route.Consumes, ct); err != nil {
+				res = append(res, err)
+			}
+			if len(res) == 0 {
+				cons, ok := route.Consumers[ct]
+				if !ok {
+					res = append(res, errors.New(500, "no consumer registered for %s", ct))
+				} else {
+					route.Consumer = cons
+					requestContentType = ct
+				}
+			}
+		}
+	}
+
+	// check and validate the response format
+	if len(res) == 0 && runtime.HasBody(request) {
+		if str := NegotiateContentType(request, route.Produces, requestContentType); str == "" {
+			res = append(res, errors.InvalidResponseFormat(request.Header.Get(runtime.HeaderAccept), route.Produces))
+		}
+	}
+
+	// now bind the request with the provided binder
+	// it's assumed the binder will also validate the request and return an error if the
+	// request is invalid
+	if binder != nil && len(res) == 0 {
+		if err := binder.BindRequest(request, route); err != nil {
+			return err
+		}
+	}
+
+	if len(res) > 0 {
+		return errors.CompositeValidationError(res...)
+	}
+	return nil
+}
+
+// ContentType gets the parsed value of a content type
+// Returns the media type, its charset and a shallow copy of the request
+// when its context doesn't contain the content type value, otherwise it returns
+// the same request
+// Returns the error that runtime.ContentType may retunrs.
+func (c *Context) ContentType(request *http.Request) (string, string, *http.Request, error) {
+	var rCtx = request.Context()
+
+	if v, ok := rCtx.Value(ctxContentType).(*contentTypeValue); ok {
+		return v.MediaType, v.Charset, request, nil
+	}
+
+	mt, cs, err := runtime.ContentType(request.Header)
+	if err != nil {
+		return "", "", nil, err
+	}
+	rCtx = stdContext.WithValue(rCtx, ctxContentType, &contentTypeValue{mt, cs})
+	return mt, cs, request.WithContext(rCtx), nil
+}
+
+// LookupRoute looks a route up and returns true when it is found
+func (c *Context) LookupRoute(request *http.Request) (*MatchedRoute, bool) {
+	if route, ok := c.router.Lookup(request.Method, request.URL.EscapedPath()); ok {
+		return route, ok
+	}
+	return nil, false
+}
+
+// RouteInfo tries to match a route for this request
+// Returns the matched route, a shallow copy of the request if its context
+// contains the matched router, otherwise the same request, and a bool to
+// indicate if it the request matches one of the routes, if it doesn't
+// then it returns false and nil for the other two return values
+func (c *Context) RouteInfo(request *http.Request) (*MatchedRoute, *http.Request, bool) {
+	var rCtx = request.Context()
+
+	if v, ok := rCtx.Value(ctxMatchedRoute).(*MatchedRoute); ok {
+		return v, request, ok
+	}
+
+	if route, ok := c.LookupRoute(request); ok {
+		rCtx = stdContext.WithValue(rCtx, ctxMatchedRoute, route)
+		return route, request.WithContext(rCtx), ok
+	}
+
+	return nil, nil, false
+}
+
+// ResponseFormat negotiates the response content type
+// Returns the response format and a shallow copy of the request if its context
+// doesn't contain the response format, otherwise the same request
+func (c *Context) ResponseFormat(r *http.Request, offers []string) (string, *http.Request) {
+	var rCtx = r.Context()
+
+	if v, ok := rCtx.Value(ctxResponseFormat).(string); ok {
+		debugLog("[%s %s] found response format %q in context", r.Method, r.URL.Path, v)
+		return v, r
+	}
+
+	format := NegotiateContentType(r, offers, "")
+	if format != "" {
+		debugLog("[%s %s] set response format %q in context", r.Method, r.URL.Path, format)
+		r = r.WithContext(stdContext.WithValue(rCtx, ctxResponseFormat, format))
+	}
+	debugLog("[%s %s] negotiated response format %q", r.Method, r.URL.Path, format)
+	return format, r
+}
+
+// AllowedMethods gets the allowed methods for the path of this request
+func (c *Context) AllowedMethods(request *http.Request) []string {
+	return c.router.OtherMethods(request.Method, request.URL.EscapedPath())
+}
+
+// ResetAuth removes the current principal from the request context
+func (c *Context) ResetAuth(request *http.Request) *http.Request {
+	rctx := request.Context()
+	rctx = stdContext.WithValue(rctx, ctxSecurityPrincipal, nil)
+	rctx = stdContext.WithValue(rctx, ctxSecurityScopes, nil)
+	return request.WithContext(rctx)
+}
+
+// Authorize authorizes the request
+// Returns the principal object and a shallow copy of the request when its
+// context doesn't contain the principal, otherwise the same request or an error
+// (the last) if one of the authenticators returns one or an Unauthenticated error
+func (c *Context) Authorize(request *http.Request, route *MatchedRoute) (interface{}, *http.Request, error) {
+	if route == nil || !route.HasAuth() {
+		return nil, nil, nil
+	}
+
+	var rCtx = request.Context()
+	if v := rCtx.Value(ctxSecurityPrincipal); v != nil {
+		return v, request, nil
+	}
+
+	applies, usr, err := route.Authenticators.Authenticate(request, route)
+	if !applies || err != nil || !route.Authenticators.AllowsAnonymous() && usr == nil {
+		if err != nil {
+			return nil, nil, err
+		}
+		return nil, nil, errors.Unauthenticated("invalid credentials")
+	}
+	if route.Authorizer != nil {
+		if err := route.Authorizer.Authorize(request, usr); err != nil {
+			return nil, nil, errors.New(http.StatusForbidden, err.Error())
+		}
+	}
+
+	rCtx = stdContext.WithValue(rCtx, ctxSecurityPrincipal, usr)
+	rCtx = stdContext.WithValue(rCtx, ctxSecurityScopes, route.Authenticator.AllScopes())
+	return usr, request.WithContext(rCtx), nil
+}
+
+// BindAndValidate binds and validates the request
+// Returns the validation map and a shallow copy of the request when its context
+// doesn't contain the validation, otherwise it returns the same request or an
+// CompositeValidationError error
+func (c *Context) BindAndValidate(request *http.Request, matched *MatchedRoute) (interface{}, *http.Request, error) {
+	var rCtx = request.Context()
+
+	if v, ok := rCtx.Value(ctxBoundParams).(*validation); ok {
+		debugLog("got cached validation (valid: %t)", len(v.result) == 0)
+		if len(v.result) > 0 {
+			return v.bound, request, errors.CompositeValidationError(v.result...)
+		}
+		return v.bound, request, nil
+	}
+	result := validateRequest(c, request, matched)
+	rCtx = stdContext.WithValue(rCtx, ctxBoundParams, result)
+	request = request.WithContext(rCtx)
+	if len(result.result) > 0 {
+		return result.bound, request, errors.CompositeValidationError(result.result...)
+	}
+	debugLog("no validation errors found")
+	return result.bound, request, nil
+}
+
+// NotFound the default not found responder for when no route has been matched yet
+func (c *Context) NotFound(rw http.ResponseWriter, r *http.Request) {
+	c.Respond(rw, r, []string{c.api.DefaultProduces()}, nil, errors.NotFound("not found"))
+}
+
+// Respond renders the response after doing some content negotiation
+func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []string, route *MatchedRoute, data interface{}) {
+	debugLog("responding to %s %s with produces: %v", r.Method, r.URL.Path, produces)
+	offers := []string{}
+	for _, mt := range produces {
+		if mt != c.api.DefaultProduces() {
+			offers = append(offers, mt)
+		}
+	}
+	// the default producer is last so more specific producers take precedence
+	offers = append(offers, c.api.DefaultProduces())
+	debugLog("offers: %v", offers)
+
+	var format string
+	format, r = c.ResponseFormat(r, offers)
+	rw.Header().Set(runtime.HeaderContentType, format)
+
+	if resp, ok := data.(Responder); ok {
+		producers := route.Producers
+		prod, ok := producers[format]
+		if !ok {
+			prods := c.api.ProducersFor(normalizeOffers([]string{c.api.DefaultProduces()}))
+			pr, ok := prods[c.api.DefaultProduces()]
+			if !ok {
+				panic(errors.New(http.StatusInternalServerError, "can't find a producer for "+format))
+			}
+			prod = pr
+		}
+		resp.WriteResponse(rw, prod)
+		return
+	}
+
+	if err, ok := data.(error); ok {
+		if format == "" {
+			rw.Header().Set(runtime.HeaderContentType, runtime.JSONMime)
+		}
+		if route == nil || route.Operation == nil {
+			c.api.ServeErrorFor("")(rw, r, err)
+			return
+		}
+		c.api.ServeErrorFor(route.Operation.ID)(rw, r, err)
+		return
+	}
+
+	if route == nil || route.Operation == nil {
+		rw.WriteHeader(200)
+		if r.Method == "HEAD" {
+			return
+		}
+		producers := c.api.ProducersFor(normalizeOffers(offers))
+		prod, ok := producers[format]
+		if !ok {
+			panic(errors.New(http.StatusInternalServerError, "can't find a producer for "+format))
+		}
+		if err := prod.Produce(rw, data); err != nil {
+			panic(err) // let the recovery middleware deal with this
+		}
+		return
+	}
+
+	if _, code, ok := route.Operation.SuccessResponse(); ok {
+		rw.WriteHeader(code)
+		if code == 204 || r.Method == "HEAD" {
+			return
+		}
+
+		producers := route.Producers
+		prod, ok := producers[format]
+		if !ok {
+			if !ok {
+				prods := c.api.ProducersFor(normalizeOffers([]string{c.api.DefaultProduces()}))
+				pr, ok := prods[c.api.DefaultProduces()]
+				if !ok {
+					panic(errors.New(http.StatusInternalServerError, "can't find a producer for "+format))
+				}
+				prod = pr
+			}
+		}
+		if err := prod.Produce(rw, data); err != nil {
+			panic(err) // let the recovery middleware deal with this
+		}
+		return
+	}
+
+	c.api.ServeErrorFor(route.Operation.ID)(rw, r, errors.New(http.StatusInternalServerError, "can't produce response"))
+}
+
+// APIHandler returns a handler to serve the API, this includes a swagger spec, router and the contract defined in the swagger spec
+func (c *Context) APIHandler(builder Builder) http.Handler {
+	b := builder
+	if b == nil {
+		b = PassthroughBuilder
+	}
+
+	var title string
+	sp := c.spec.Spec()
+	if sp != nil && sp.Info != nil && sp.Info.Title != "" {
+		title = sp.Info.Title
+	}
+
+	redocOpts := RedocOpts{
+		BasePath: c.BasePath(),
+		Title:    title,
+	}
+
+	return Spec("", c.spec.Raw(), Redoc(redocOpts, c.RoutesHandler(b)))
+}
+
+// RoutesHandler returns a handler to serve the API, just the routes and the contract defined in the swagger spec
+func (c *Context) RoutesHandler(builder Builder) http.Handler {
+	b := builder
+	if b == nil {
+		b = PassthroughBuilder
+	}
+	return NewRouter(c, b(NewOperationExecutor(c)))
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/middleware/denco/LICENSE b/go/vendor/github.com/go-openapi/runtime/middleware/denco/LICENSE
new file mode 100755
index 0000000..e65039a
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/middleware/denco/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2014 Naoya Inada <naoina@kuune.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/go/vendor/github.com/go-openapi/runtime/middleware/denco/README.md b/go/vendor/github.com/go-openapi/runtime/middleware/denco/README.md
new file mode 100755
index 0000000..30109e1
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/middleware/denco/README.md
@@ -0,0 +1,180 @@
+# Denco [![Build Status](https://travis-ci.org/naoina/denco.png?branch=master)](https://travis-ci.org/naoina/denco)
+
+The fast and flexible HTTP request router for [Go](http://golang.org).
+
+Denco is based on Double-Array implementation of [Kocha-urlrouter](https://github.com/naoina/kocha-urlrouter).
+However, Denco is optimized and some features added.
+
+## Features
+
+* Fast (See [go-http-routing-benchmark](https://github.com/naoina/go-http-routing-benchmark))
+* [URL patterns](#url-patterns) (`/foo/:bar` and `/foo/*wildcard`)
+* Small (but enough) URL router API
+* HTTP request multiplexer like `http.ServeMux`
+
+## Installation
+
+    go get -u github.com/go-openapi/runtime/middleware/denco
+
+## Using as HTTP request multiplexer
+
+```go
+package main
+
+import (
+    "fmt"
+    "log"
+    "net/http"
+
+    "github.com/go-openapi/runtime/middleware/denco"
+)
+
+func Index(w http.ResponseWriter, r *http.Request, params denco.Params) {
+    fmt.Fprintf(w, "Welcome to Denco!\n")
+}
+
+func User(w http.ResponseWriter, r *http.Request, params denco.Params) {
+    fmt.Fprintf(w, "Hello %s!\n", params.Get("name"))
+}
+
+func main() {
+    mux := denco.NewMux()
+    handler, err := mux.Build([]denco.Handler{
+        mux.GET("/", Index),
+        mux.GET("/user/:name", User),
+        mux.POST("/user/:name", User),
+    })
+    if err != nil {
+        panic(err)
+    }
+    log.Fatal(http.ListenAndServe(":8080", handler))
+}
+```
+
+## Using as URL router
+
+```go
+package main
+
+import (
+	"fmt"
+
+	"github.com/go-openapi/runtime/middleware/denco"
+)
+
+type route struct {
+	name string
+}
+
+func main() {
+	router := denco.New()
+	router.Build([]denco.Record{
+		{"/", &route{"root"}},
+		{"/user/:id", &route{"user"}},
+		{"/user/:name/:id", &route{"username"}},
+		{"/static/*filepath", &route{"static"}},
+	})
+
+	data, params, found := router.Lookup("/")
+	// print `&main.route{name:"root"}, denco.Params(nil), true`.
+	fmt.Printf("%#v, %#v, %#v\n", data, params, found)
+
+	data, params, found = router.Lookup("/user/hoge")
+	// print `&main.route{name:"user"}, denco.Params{denco.Param{Name:"id", Value:"hoge"}}, true`.
+	fmt.Printf("%#v, %#v, %#v\n", data, params, found)
+
+	data, params, found = router.Lookup("/user/hoge/7")
+	// print `&main.route{name:"username"}, denco.Params{denco.Param{Name:"name", Value:"hoge"}, denco.Param{Name:"id", Value:"7"}}, true`.
+	fmt.Printf("%#v, %#v, %#v\n", data, params, found)
+
+	data, params, found = router.Lookup("/static/path/to/file")
+	// print `&main.route{name:"static"}, denco.Params{denco.Param{Name:"filepath", Value:"path/to/file"}}, true`.
+	fmt.Printf("%#v, %#v, %#v\n", data, params, found)
+}
+```
+
+See [Godoc](http://godoc.org/github.com/go-openapi/runtime/middleware/denco) for more details.
+
+## Getting the value of path parameter
+
+You can get the value of path parameter by 2 ways.
+
+1. Using [`denco.Params.Get`](http://godoc.org/github.com/go-openapi/runtime/middleware/denco#Params.Get) method
+2. Find by loop
+
+```go
+package main
+
+import (
+    "fmt"
+
+    "github.com/go-openapi/runtime/middleware/denco"
+)
+
+func main() {
+    router := denco.New()
+    if err := router.Build([]denco.Record{
+        {"/user/:name/:id", "route1"},
+    }); err != nil {
+        panic(err)
+    }
+
+    // 1. Using denco.Params.Get method.
+    _, params, _ := router.Lookup("/user/alice/1")
+    name := params.Get("name")
+    if name != "" {
+        fmt.Printf("Hello %s.\n", name) // prints "Hello alice.".
+    }
+
+    // 2. Find by loop.
+    for _, param := range params {
+        if param.Name == "name" {
+            fmt.Printf("Hello %s.\n", name) // prints "Hello alice.".
+        }
+    }
+}
+```
+
+## URL patterns
+
+Denco's route matching strategy is "most nearly matching".
+
+When routes `/:name` and `/alice` have been built, URI `/alice` matches the route `/alice`, not `/:name`.
+Because URI `/alice` is more match with the route `/alice` than `/:name`.
+
+For more example, when routes below have been built:
+
+```
+/user/alice
+/user/:name
+/user/:name/:id
+/user/alice/:id
+/user/:id/bob
+```
+
+Routes matching are:
+
+```
+/user/alice      => "/user/alice" (no match with "/user/:name")
+/user/bob        => "/user/:name"
+/user/naoina/1   => "/user/:name/1"
+/user/alice/1    => "/user/alice/:id" (no match with "/user/:name/:id")
+/user/1/bob      => "/user/:id/bob"   (no match with "/user/:name/:id")
+/user/alice/bob  => "/user/alice/:id" (no match with "/user/:name/:id" and "/user/:id/bob")
+```
+
+## Limitation
+
+Denco has some limitations below.
+
+* Number of param records (such as `/:name`) must be less than 2^22
+* Number of elements of internal slice must be less than 2^22
+
+## Benchmarks
+
+    cd $GOPATH/github.com/go-openapi/runtime/middleware/denco
+    go test -bench . -benchmem
+
+## License
+
+Denco is licensed under the MIT License.
diff --git a/go/vendor/github.com/go-openapi/runtime/middleware/denco/router.go b/go/vendor/github.com/go-openapi/runtime/middleware/denco/router.go
new file mode 100755
index 0000000..73703fd
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/middleware/denco/router.go
@@ -0,0 +1,452 @@
+// Package denco provides fast URL router.
+package denco
+
+import (
+	"fmt"
+	"sort"
+	"strings"
+)
+
+const (
+	// ParamCharacter is a special character for path parameter.
+	ParamCharacter = ':'
+
+	// WildcardCharacter is a special character for wildcard path parameter.
+	WildcardCharacter = '*'
+
+	// TerminationCharacter is a special character for end of path.
+	TerminationCharacter = '#'
+
+	// MaxSize is max size of records and internal slice.
+	MaxSize = (1 << 22) - 1
+)
+
+// Router represents a URL router.
+type Router struct {
+	// SizeHint expects the maximum number of path parameters in records to Build.
+	// SizeHint will be used to determine the capacity of the memory to allocate.
+	// By default, SizeHint will be determined from given records to Build.
+	SizeHint int
+
+	static map[string]interface{}
+	param  *doubleArray
+}
+
+// New returns a new Router.
+func New() *Router {
+	return &Router{
+		SizeHint: -1,
+		static:   make(map[string]interface{}),
+		param:    newDoubleArray(),
+	}
+}
+
+// Lookup returns data and path parameters that associated with path.
+// params is a slice of the Param that arranged in the order in which parameters appeared.
+// e.g. when built routing path is "/path/to/:id/:name" and given path is "/path/to/1/alice". params order is [{"id": "1"}, {"name": "alice"}], not [{"name": "alice"}, {"id": "1"}].
+func (rt *Router) Lookup(path string) (data interface{}, params Params, found bool) {
+	if data, found := rt.static[path]; found {
+		return data, nil, true
+	}
+	if len(rt.param.node) == 1 {
+		return nil, nil, false
+	}
+	nd, params, found := rt.param.lookup(path, make([]Param, 0, rt.SizeHint), 1)
+	if !found {
+		return nil, nil, false
+	}
+	for i := 0; i < len(params); i++ {
+		params[i].Name = nd.paramNames[i]
+	}
+	return nd.data, params, true
+}
+
+// Build builds URL router from records.
+func (rt *Router) Build(records []Record) error {
+	statics, params := makeRecords(records)
+	if len(params) > MaxSize {
+		return fmt.Errorf("denco: too many records")
+	}
+	if rt.SizeHint < 0 {
+		rt.SizeHint = 0
+		for _, p := range params {
+			size := 0
+			for _, k := range p.Key {
+				if k == ParamCharacter || k == WildcardCharacter {
+					size++
+				}
+			}
+			if size > rt.SizeHint {
+				rt.SizeHint = size
+			}
+		}
+	}
+	for _, r := range statics {
+		rt.static[r.Key] = r.Value
+	}
+	if err := rt.param.build(params, 1, 0, make(map[int]struct{})); err != nil {
+		return err
+	}
+	return nil
+}
+
+// Param represents name and value of path parameter.
+type Param struct {
+	Name  string
+	Value string
+}
+
+// Params represents the name and value of path parameters.
+type Params []Param
+
+// Get gets the first value associated with the given name.
+// If there are no values associated with the key, Get returns "".
+func (ps Params) Get(name string) string {
+	for _, p := range ps {
+		if p.Name == name {
+			return p.Value
+		}
+	}
+	return ""
+}
+
+type doubleArray struct {
+	bc   []baseCheck
+	node []*node
+}
+
+func newDoubleArray() *doubleArray {
+	return &doubleArray{
+		bc:   []baseCheck{0},
+		node: []*node{nil}, // A start index is adjusting to 1 because 0 will be used as a mark of non-existent node.
+	}
+}
+
+// baseCheck contains BASE, CHECK and Extra flags.
+// From the top, 22bits of BASE, 2bits of Extra flags and 8bits of CHECK.
+//
+//  BASE (22bit) | Extra flags (2bit) | CHECK (8bit)
+// |----------------------|--|--------|
+// 32                    10  8         0
+type baseCheck uint32
+
+func (bc baseCheck) Base() int {
+	return int(bc >> 10)
+}
+
+func (bc *baseCheck) SetBase(base int) {
+	*bc |= baseCheck(base) << 10
+}
+
+func (bc baseCheck) Check() byte {
+	return byte(bc)
+}
+
+func (bc *baseCheck) SetCheck(check byte) {
+	*bc |= baseCheck(check)
+}
+
+func (bc baseCheck) IsEmpty() bool {
+	return bc&0xfffffcff == 0
+}
+
+func (bc baseCheck) IsSingleParam() bool {
+	return bc&paramTypeSingle == paramTypeSingle
+}
+
+func (bc baseCheck) IsWildcardParam() bool {
+	return bc&paramTypeWildcard == paramTypeWildcard
+}
+
+func (bc baseCheck) IsAnyParam() bool {
+	return bc&paramTypeAny != 0
+}
+
+func (bc *baseCheck) SetSingleParam() {
+	*bc |= (1 << 8)
+}
+
+func (bc *baseCheck) SetWildcardParam() {
+	*bc |= (1 << 9)
+}
+
+const (
+	paramTypeSingle   = 0x0100
+	paramTypeWildcard = 0x0200
+	paramTypeAny      = 0x0300
+)
+
+func (da *doubleArray) lookup(path string, params []Param, idx int) (*node, []Param, bool) {
+	indices := make([]uint64, 0, 1)
+	for i := 0; i < len(path); i++ {
+		if da.bc[idx].IsAnyParam() {
+			indices = append(indices, (uint64(i)<<32)|(uint64(idx)&0xffffffff))
+		}
+		c := path[i]
+		if idx = nextIndex(da.bc[idx].Base(), c); idx >= len(da.bc) || da.bc[idx].Check() != c {
+			goto BACKTRACKING
+		}
+	}
+	if next := nextIndex(da.bc[idx].Base(), TerminationCharacter); next < len(da.bc) && da.bc[next].Check() == TerminationCharacter {
+		return da.node[da.bc[next].Base()], params, true
+	}
+BACKTRACKING:
+	for j := len(indices) - 1; j >= 0; j-- {
+		i, idx := int(indices[j]>>32), int(indices[j]&0xffffffff)
+		if da.bc[idx].IsSingleParam() {
+			idx := nextIndex(da.bc[idx].Base(), ParamCharacter)
+			if idx >= len(da.bc) {
+				break
+			}
+			next := NextSeparator(path, i)
+			params := append(params, Param{Value: path[i:next]})
+			if nd, params, found := da.lookup(path[next:], params, idx); found {
+				return nd, params, true
+			}
+		}
+		if da.bc[idx].IsWildcardParam() {
+			idx := nextIndex(da.bc[idx].Base(), WildcardCharacter)
+			params := append(params, Param{Value: path[i:]})
+			return da.node[da.bc[idx].Base()], params, true
+		}
+	}
+	return nil, nil, false
+}
+
+// build builds double-array from records.
+func (da *doubleArray) build(srcs []*record, idx, depth int, usedBase map[int]struct{}) error {
+	sort.Stable(recordSlice(srcs))
+	base, siblings, leaf, err := da.arrange(srcs, idx, depth, usedBase)
+	if err != nil {
+		return err
+	}
+	if leaf != nil {
+		nd, err := makeNode(leaf)
+		if err != nil {
+			return err
+		}
+		da.bc[idx].SetBase(len(da.node))
+		da.node = append(da.node, nd)
+	}
+	for _, sib := range siblings {
+		da.setCheck(nextIndex(base, sib.c), sib.c)
+	}
+	for _, sib := range siblings {
+		records := srcs[sib.start:sib.end]
+		switch sib.c {
+		case ParamCharacter:
+			for _, r := range records {
+				next := NextSeparator(r.Key, depth+1)
+				name := r.Key[depth+1 : next]
+				r.paramNames = append(r.paramNames, name)
+				r.Key = r.Key[next:]
+			}
+			da.bc[idx].SetSingleParam()
+			if err := da.build(records, nextIndex(base, sib.c), 0, usedBase); err != nil {
+				return err
+			}
+		case WildcardCharacter:
+			r := records[0]
+			name := r.Key[depth+1 : len(r.Key)-1]
+			r.paramNames = append(r.paramNames, name)
+			r.Key = ""
+			da.bc[idx].SetWildcardParam()
+			if err := da.build(records, nextIndex(base, sib.c), 0, usedBase); err != nil {
+				return err
+			}
+		default:
+			if err := da.build(records, nextIndex(base, sib.c), depth+1, usedBase); err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+// setBase sets BASE.
+func (da *doubleArray) setBase(i, base int) {
+	da.bc[i].SetBase(base)
+}
+
+// setCheck sets CHECK.
+func (da *doubleArray) setCheck(i int, check byte) {
+	da.bc[i].SetCheck(check)
+}
+
+// findEmptyIndex returns an index of unused BASE/CHECK node.
+func (da *doubleArray) findEmptyIndex(start int) int {
+	i := start
+	for ; i < len(da.bc); i++ {
+		if da.bc[i].IsEmpty() {
+			break
+		}
+	}
+	return i
+}
+
+// findBase returns good BASE.
+func (da *doubleArray) findBase(siblings []sibling, start int, usedBase map[int]struct{}) (base int) {
+	for idx, firstChar := start+1, siblings[0].c; ; idx = da.findEmptyIndex(idx + 1) {
+		base = nextIndex(idx, firstChar)
+		if _, used := usedBase[base]; used {
+			continue
+		}
+		i := 0
+		for ; i < len(siblings); i++ {
+			next := nextIndex(base, siblings[i].c)
+			if len(da.bc) <= next {
+				da.bc = append(da.bc, make([]baseCheck, next-len(da.bc)+1)...)
+			}
+			if !da.bc[next].IsEmpty() {
+				break
+			}
+		}
+		if i == len(siblings) {
+			break
+		}
+	}
+	usedBase[base] = struct{}{}
+	return base
+}
+
+func (da *doubleArray) arrange(records []*record, idx, depth int, usedBase map[int]struct{}) (base int, siblings []sibling, leaf *record, err error) {
+	siblings, leaf, err = makeSiblings(records, depth)
+	if err != nil {
+		return -1, nil, nil, err
+	}
+	if len(siblings) < 1 {
+		return -1, nil, leaf, nil
+	}
+	base = da.findBase(siblings, idx, usedBase)
+	if base > MaxSize {
+		return -1, nil, nil, fmt.Errorf("denco: too many elements of internal slice")
+	}
+	da.setBase(idx, base)
+	return base, siblings, leaf, err
+}
+
+// node represents a node of Double-Array.
+type node struct {
+	data interface{}
+
+	// Names of path parameters.
+	paramNames []string
+}
+
+// makeNode returns a new node from record.
+func makeNode(r *record) (*node, error) {
+	dups := make(map[string]bool)
+	for _, name := range r.paramNames {
+		if dups[name] {
+			return nil, fmt.Errorf("denco: path parameter `%v' is duplicated in the key `%v'", name, r.Key)
+		}
+		dups[name] = true
+	}
+	return &node{data: r.Value, paramNames: r.paramNames}, nil
+}
+
+// sibling represents an intermediate data of build for Double-Array.
+type sibling struct {
+	// An index of start of duplicated characters.
+	start int
+
+	// An index of end of duplicated characters.
+	end int
+
+	// A character of sibling.
+	c byte
+}
+
+// nextIndex returns a next index of array of BASE/CHECK.
+func nextIndex(base int, c byte) int {
+	return base ^ int(c)
+}
+
+// makeSiblings returns slice of sibling.
+func makeSiblings(records []*record, depth int) (sib []sibling, leaf *record, err error) {
+	var (
+		pc byte
+		n  int
+	)
+	for i, r := range records {
+		if len(r.Key) <= depth {
+			leaf = r
+			continue
+		}
+		c := r.Key[depth]
+		switch {
+		case pc < c:
+			sib = append(sib, sibling{start: i, c: c})
+		case pc == c:
+			continue
+		default:
+			return nil, nil, fmt.Errorf("denco: BUG: routing table hasn't been sorted")
+		}
+		if n > 0 {
+			sib[n-1].end = i
+		}
+		pc = c
+		n++
+	}
+	if n == 0 {
+		return nil, leaf, nil
+	}
+	sib[n-1].end = len(records)
+	return sib, leaf, nil
+}
+
+// Record represents a record data for router construction.
+type Record struct {
+	// Key for router construction.
+	Key string
+
+	// Result value for Key.
+	Value interface{}
+}
+
+// NewRecord returns a new Record.
+func NewRecord(key string, value interface{}) Record {
+	return Record{
+		Key:   key,
+		Value: value,
+	}
+}
+
+// record represents a record that use to build the Double-Array.
+type record struct {
+	Record
+	paramNames []string
+}
+
+// makeRecords returns the records that use to build Double-Arrays.
+func makeRecords(srcs []Record) (statics, params []*record) {
+	spChars := string([]byte{ParamCharacter, WildcardCharacter})
+	termChar := string(TerminationCharacter)
+	for _, r := range srcs {
+		if strings.ContainsAny(r.Key, spChars) {
+			r.Key += termChar
+			params = append(params, &record{Record: r})
+		} else {
+			statics = append(statics, &record{Record: r})
+		}
+	}
+	return statics, params
+}
+
+// recordSlice represents a slice of Record for sort and implements the sort.Interface.
+type recordSlice []*record
+
+// Len implements the sort.Interface.Len.
+func (rs recordSlice) Len() int {
+	return len(rs)
+}
+
+// Less implements the sort.Interface.Less.
+func (rs recordSlice) Less(i, j int) bool {
+	return rs[i].Key < rs[j].Key
+}
+
+// Swap implements the sort.Interface.Swap.
+func (rs recordSlice) Swap(i, j int) {
+	rs[i], rs[j] = rs[j], rs[i]
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/middleware/denco/server.go b/go/vendor/github.com/go-openapi/runtime/middleware/denco/server.go
new file mode 100755
index 0000000..0886713
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/middleware/denco/server.go
@@ -0,0 +1,106 @@
+package denco
+
+import (
+	"net/http"
+)
+
+// Mux represents a multiplexer for HTTP request.
+type Mux struct{}
+
+// NewMux returns a new Mux.
+func NewMux() *Mux {
+	return &Mux{}
+}
+
+// GET is shorthand of Mux.Handler("GET", path, handler).
+func (m *Mux) GET(path string, handler HandlerFunc) Handler {
+	return m.Handler("GET", path, handler)
+}
+
+// POST is shorthand of Mux.Handler("POST", path, handler).
+func (m *Mux) POST(path string, handler HandlerFunc) Handler {
+	return m.Handler("POST", path, handler)
+}
+
+// PUT is shorthand of Mux.Handler("PUT", path, handler).
+func (m *Mux) PUT(path string, handler HandlerFunc) Handler {
+	return m.Handler("PUT", path, handler)
+}
+
+// HEAD is shorthand of Mux.Handler("HEAD", path, handler).
+func (m *Mux) HEAD(path string, handler HandlerFunc) Handler {
+	return m.Handler("HEAD", path, handler)
+}
+
+// Handler returns a handler for HTTP method.
+func (m *Mux) Handler(method, path string, handler HandlerFunc) Handler {
+	return Handler{
+		Method: method,
+		Path:   path,
+		Func:   handler,
+	}
+}
+
+// Build builds a http.Handler.
+func (m *Mux) Build(handlers []Handler) (http.Handler, error) {
+	recordMap := make(map[string][]Record)
+	for _, h := range handlers {
+		recordMap[h.Method] = append(recordMap[h.Method], NewRecord(h.Path, h.Func))
+	}
+	mux := newServeMux()
+	for m, records := range recordMap {
+		router := New()
+		if err := router.Build(records); err != nil {
+			return nil, err
+		}
+		mux.routers[m] = router
+	}
+	return mux, nil
+}
+
+// Handler represents a handler of HTTP request.
+type Handler struct {
+	// Method is an HTTP method.
+	Method string
+
+	// Path is a routing path for handler.
+	Path string
+
+	// Func is a function of handler of HTTP request.
+	Func HandlerFunc
+}
+
+// The HandlerFunc type is aliased to type of handler function.
+type HandlerFunc func(w http.ResponseWriter, r *http.Request, params Params)
+
+type serveMux struct {
+	routers map[string]*Router
+}
+
+func newServeMux() *serveMux {
+	return &serveMux{
+		routers: make(map[string]*Router),
+	}
+}
+
+// ServeHTTP implements http.Handler interface.
+func (mux *serveMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	handler, params := mux.handler(r.Method, r.URL.Path)
+	handler(w, r, params)
+}
+
+func (mux *serveMux) handler(method, path string) (HandlerFunc, []Param) {
+	if router, found := mux.routers[method]; found {
+		if handler, params, found := router.Lookup(path); found {
+			return handler.(HandlerFunc), params
+		}
+	}
+	return NotFound, nil
+}
+
+// NotFound replies to the request with an HTTP 404 not found error.
+// NotFound is called when unknown HTTP method or a handler not found.
+// If you want to use the your own NotFound handler, please overwrite this variable.
+var NotFound = func(w http.ResponseWriter, r *http.Request, _ Params) {
+	http.NotFound(w, r)
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/middleware/denco/util.go b/go/vendor/github.com/go-openapi/runtime/middleware/denco/util.go
new file mode 100755
index 0000000..edc1f6a
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/middleware/denco/util.go
@@ -0,0 +1,12 @@
+package denco
+
+// NextSeparator returns an index of next separator in path.
+func NextSeparator(path string, start int) int {
+	for start < len(path) {
+		if c := path[start]; c == '/' || c == TerminationCharacter {
+			break
+		}
+		start++
+	}
+	return start
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/middleware/doc.go b/go/vendor/github.com/go-openapi/runtime/middleware/doc.go
new file mode 100644
index 0000000..eaf9060
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/middleware/doc.go
@@ -0,0 +1,62 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/*Package middleware provides the library with helper functions for serving swagger APIs.
+
+Pseudo middleware handler
+
+  import (
+  	"net/http"
+
+  	"github.com/go-openapi/errors"
+  )
+
+  func newCompleteMiddleware(ctx *Context) http.Handler {
+  	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+  		// use context to lookup routes
+  		if matched, ok := ctx.RouteInfo(r); ok {
+
+  			if matched.NeedsAuth() {
+  				if _, err := ctx.Authorize(r, matched); err != nil {
+  					ctx.Respond(rw, r, matched.Produces, matched, err)
+  					return
+  				}
+  			}
+
+  			bound, validation := ctx.BindAndValidate(r, matched)
+  			if validation != nil {
+  				ctx.Respond(rw, r, matched.Produces, matched, validation)
+  				return
+  			}
+
+  			result, err := matched.Handler.Handle(bound)
+  			if err != nil {
+  				ctx.Respond(rw, r, matched.Produces, matched, err)
+  				return
+  			}
+
+  			ctx.Respond(rw, r, matched.Produces, matched, result)
+  			return
+  		}
+
+  		// Not found, check if it exists in the other methods first
+  		if others := ctx.AllowedMethods(r); len(others) > 0 {
+  			ctx.Respond(rw, r, ctx.spec.RequiredProduces(), nil, errors.MethodNotAllowed(r.Method, others))
+  			return
+  		}
+  		ctx.Respond(rw, r, ctx.spec.RequiredProduces(), nil, errors.NotFound("path %s was not found", r.URL.Path))
+  	})
+  }
+*/
+package middleware
diff --git a/go/vendor/github.com/go-openapi/runtime/middleware/go18.go b/go/vendor/github.com/go-openapi/runtime/middleware/go18.go
new file mode 100644
index 0000000..75c762c
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/middleware/go18.go
@@ -0,0 +1,9 @@
+// +build go1.8
+
+package middleware
+
+import "net/url"
+
+func pathUnescape(path string) (string, error) {
+	return url.PathUnescape(path)
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/middleware/header/header.go b/go/vendor/github.com/go-openapi/runtime/middleware/header/header.go
new file mode 100644
index 0000000..3e34225
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/middleware/header/header.go
@@ -0,0 +1,326 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file or at
+// https://developers.google.com/open-source/licenses/bsd.
+
+// this file was taken from the github.com/golang/gddo repository
+
+// Package header provides functions for parsing HTTP headers.
+package header
+
+import (
+	"net/http"
+	"strings"
+	"time"
+)
+
+// Octet types from RFC 2616.
+var octetTypes [256]octetType
+
+type octetType byte
+
+const (
+	isToken octetType = 1 << iota
+	isSpace
+)
+
+func init() {
+	// OCTET      = <any 8-bit sequence of data>
+	// CHAR       = <any US-ASCII character (octets 0 - 127)>
+	// CTL        = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
+	// CR         = <US-ASCII CR, carriage return (13)>
+	// LF         = <US-ASCII LF, linefeed (10)>
+	// SP         = <US-ASCII SP, space (32)>
+	// HT         = <US-ASCII HT, horizontal-tab (9)>
+	// <">        = <US-ASCII double-quote mark (34)>
+	// CRLF       = CR LF
+	// LWS        = [CRLF] 1*( SP | HT )
+	// TEXT       = <any OCTET except CTLs, but including LWS>
+	// separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <">
+	//              | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT
+	// token      = 1*<any CHAR except CTLs or separators>
+	// qdtext     = <any TEXT except <">>
+
+	for c := 0; c < 256; c++ {
+		var t octetType
+		isCtl := c <= 31 || c == 127
+		isChar := 0 <= c && c <= 127
+		isSeparator := strings.ContainsRune(" \t\"(),/:;<=>?@[]\\{}", rune(c))
+		if strings.ContainsRune(" \t\r\n", rune(c)) {
+			t |= isSpace
+		}
+		if isChar && !isCtl && !isSeparator {
+			t |= isToken
+		}
+		octetTypes[c] = t
+	}
+}
+
+// Copy returns a shallow copy of the header.
+func Copy(header http.Header) http.Header {
+	h := make(http.Header)
+	for k, vs := range header {
+		h[k] = vs
+	}
+	return h
+}
+
+var timeLayouts = []string{"Mon, 02 Jan 2006 15:04:05 GMT", time.RFC850, time.ANSIC}
+
+// ParseTime parses the header as time. The zero value is returned if the
+// header is not present or there is an error parsing the
+// header.
+func ParseTime(header http.Header, key string) time.Time {
+	if s := header.Get(key); s != "" {
+		for _, layout := range timeLayouts {
+			if t, err := time.Parse(layout, s); err == nil {
+				return t.UTC()
+			}
+		}
+	}
+	return time.Time{}
+}
+
+// ParseList parses a comma separated list of values. Commas are ignored in
+// quoted strings. Quoted values are not unescaped or unquoted. Whitespace is
+// trimmed.
+func ParseList(header http.Header, key string) []string {
+	var result []string
+	for _, s := range header[http.CanonicalHeaderKey(key)] {
+		begin := 0
+		end := 0
+		escape := false
+		quote := false
+		for i := 0; i < len(s); i++ {
+			b := s[i]
+			switch {
+			case escape:
+				escape = false
+				end = i + 1
+			case quote:
+				switch b {
+				case '\\':
+					escape = true
+				case '"':
+					quote = false
+				}
+				end = i + 1
+			case b == '"':
+				quote = true
+				end = i + 1
+			case octetTypes[b]&isSpace != 0:
+				if begin == end {
+					begin = i + 1
+					end = begin
+				}
+			case b == ',':
+				if begin < end {
+					result = append(result, s[begin:end])
+				}
+				begin = i + 1
+				end = begin
+			default:
+				end = i + 1
+			}
+		}
+		if begin < end {
+			result = append(result, s[begin:end])
+		}
+	}
+	return result
+}
+
+// ParseValueAndParams parses a comma separated list of values with optional
+// semicolon separated name-value pairs. Content-Type and Content-Disposition
+// headers are in this format.
+func ParseValueAndParams(header http.Header, key string) (string, map[string]string) {
+	return parseValueAndParams(header.Get(key))
+}
+
+func parseValueAndParams(s string) (value string, params map[string]string) {
+	params = make(map[string]string)
+	value, s = expectTokenSlash(s)
+	if value == "" {
+		return
+	}
+	value = strings.ToLower(value)
+	s = skipSpace(s)
+	for strings.HasPrefix(s, ";") {
+		var pkey string
+		pkey, s = expectToken(skipSpace(s[1:]))
+		if pkey == "" {
+			return
+		}
+		if !strings.HasPrefix(s, "=") {
+			return
+		}
+		var pvalue string
+		pvalue, s = expectTokenOrQuoted(s[1:])
+		if pvalue == "" {
+			return
+		}
+		pkey = strings.ToLower(pkey)
+		params[pkey] = pvalue
+		s = skipSpace(s)
+	}
+	return
+}
+
+// AcceptSpec ...
+type AcceptSpec struct {
+	Value string
+	Q     float64
+}
+
+// ParseAccept2 ...
+func ParseAccept2(header http.Header, key string) (specs []AcceptSpec) {
+	for _, en := range ParseList(header, key) {
+		v, p := parseValueAndParams(en)
+		var spec AcceptSpec
+		spec.Value = v
+		spec.Q = 1.0
+		if p != nil {
+			if q, ok := p["q"]; ok {
+				spec.Q, _ = expectQuality(q)
+			}
+		}
+		if spec.Q < 0.0 {
+			continue
+		}
+		specs = append(specs, spec)
+	}
+
+	return
+}
+
+// ParseAccept parses Accept* headers.
+func ParseAccept(header http.Header, key string) (specs []AcceptSpec) {
+loop:
+	for _, s := range header[key] {
+		for {
+			var spec AcceptSpec
+			spec.Value, s = expectTokenSlash(s)
+			if spec.Value == "" {
+				continue loop
+			}
+			spec.Q = 1.0
+			s = skipSpace(s)
+			if strings.HasPrefix(s, ";") {
+				s = skipSpace(s[1:])
+				for !strings.HasPrefix(s, "q=") && s != "" && !strings.HasPrefix(s, ",") {
+					s = skipSpace(s[1:])
+				}
+				if strings.HasPrefix(s, "q=") {
+					spec.Q, s = expectQuality(s[2:])
+					if spec.Q < 0.0 {
+						continue loop
+					}
+				}
+			}
+			specs = append(specs, spec)
+			s = skipSpace(s)
+			if !strings.HasPrefix(s, ",") {
+				continue loop
+			}
+			s = skipSpace(s[1:])
+		}
+	}
+	return
+}
+
+func skipSpace(s string) (rest string) {
+	i := 0
+	for ; i < len(s); i++ {
+		if octetTypes[s[i]]&isSpace == 0 {
+			break
+		}
+	}
+	return s[i:]
+}
+
+func expectToken(s string) (token, rest string) {
+	i := 0
+	for ; i < len(s); i++ {
+		if octetTypes[s[i]]&isToken == 0 {
+			break
+		}
+	}
+	return s[:i], s[i:]
+}
+
+func expectTokenSlash(s string) (token, rest string) {
+	i := 0
+	for ; i < len(s); i++ {
+		b := s[i]
+		if (octetTypes[b]&isToken == 0) && b != '/' {
+			break
+		}
+	}
+	return s[:i], s[i:]
+}
+
+func expectQuality(s string) (q float64, rest string) {
+	switch {
+	case len(s) == 0:
+		return -1, ""
+	case s[0] == '0':
+		q = 0
+	case s[0] == '1':
+		q = 1
+	default:
+		return -1, ""
+	}
+	s = s[1:]
+	if !strings.HasPrefix(s, ".") {
+		return q, s
+	}
+	s = s[1:]
+	i := 0
+	n := 0
+	d := 1
+	for ; i < len(s); i++ {
+		b := s[i]
+		if b < '0' || b > '9' {
+			break
+		}
+		n = n*10 + int(b) - '0'
+		d *= 10
+	}
+	return q + float64(n)/float64(d), s[i:]
+}
+
+func expectTokenOrQuoted(s string) (value string, rest string) {
+	if !strings.HasPrefix(s, "\"") {
+		return expectToken(s)
+	}
+	s = s[1:]
+	for i := 0; i < len(s); i++ {
+		switch s[i] {
+		case '"':
+			return s[:i], s[i+1:]
+		case '\\':
+			p := make([]byte, len(s)-1)
+			j := copy(p, s[:i])
+			escape := true
+			for i = i + 1; i < len(s); i++ {
+				b := s[i]
+				switch {
+				case escape:
+					escape = false
+					p[j] = b
+					j++
+				case b == '\\':
+					escape = true
+				case b == '"':
+					return string(p[:j]), s[i+1:]
+				default:
+					p[j] = b
+					j++
+				}
+			}
+			return "", ""
+		}
+	}
+	return "", ""
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/middleware/negotiate.go b/go/vendor/github.com/go-openapi/runtime/middleware/negotiate.go
new file mode 100644
index 0000000..a9b6f27
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/middleware/negotiate.go
@@ -0,0 +1,98 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file or at
+// https://developers.google.com/open-source/licenses/bsd.
+
+// this file was taken from the github.com/golang/gddo repository
+
+package middleware
+
+import (
+	"net/http"
+	"strings"
+
+	"github.com/go-openapi/runtime/middleware/header"
+)
+
+// NegotiateContentEncoding returns the best offered content encoding for the
+// request's Accept-Encoding header. If two offers match with equal weight and
+// then the offer earlier in the list is preferred. If no offers are
+// acceptable, then "" is returned.
+func NegotiateContentEncoding(r *http.Request, offers []string) string {
+	bestOffer := "identity"
+	bestQ := -1.0
+	specs := header.ParseAccept(r.Header, "Accept-Encoding")
+	for _, offer := range offers {
+		for _, spec := range specs {
+			if spec.Q > bestQ &&
+				(spec.Value == "*" || spec.Value == offer) {
+				bestQ = spec.Q
+				bestOffer = offer
+			}
+		}
+	}
+	if bestQ == 0 {
+		bestOffer = ""
+	}
+	return bestOffer
+}
+
+// NegotiateContentType returns the best offered content type for the request's
+// Accept header. If two offers match with equal weight, then the more specific
+// offer is preferred.  For example, text/* trumps */*. If two offers match
+// with equal weight and specificity, then the offer earlier in the list is
+// preferred. If no offers match, then defaultOffer is returned.
+func NegotiateContentType(r *http.Request, offers []string, defaultOffer string) string {
+	bestOffer := defaultOffer
+	bestQ := -1.0
+	bestWild := 3
+	specs := header.ParseAccept(r.Header, "Accept")
+	for _, rawOffer := range offers {
+		offer := normalizeOffer(rawOffer)
+		// No Accept header: just return the first offer.
+		if len(specs) == 0 {
+			return rawOffer
+		}
+		for _, spec := range specs {
+			switch {
+			case spec.Q == 0.0:
+				// ignore
+			case spec.Q < bestQ:
+				// better match found
+			case spec.Value == "*/*":
+				if spec.Q > bestQ || bestWild > 2 {
+					bestQ = spec.Q
+					bestWild = 2
+					bestOffer = rawOffer
+				}
+			case strings.HasSuffix(spec.Value, "/*"):
+				if strings.HasPrefix(offer, spec.Value[:len(spec.Value)-1]) &&
+					(spec.Q > bestQ || bestWild > 1) {
+					bestQ = spec.Q
+					bestWild = 1
+					bestOffer = rawOffer
+				}
+			default:
+				if spec.Value == offer &&
+					(spec.Q > bestQ || bestWild > 0) {
+					bestQ = spec.Q
+					bestWild = 0
+					bestOffer = rawOffer
+				}
+			}
+		}
+	}
+	return bestOffer
+}
+
+func normalizeOffers(orig []string) (norm []string) {
+	for _, o := range orig {
+		norm = append(norm, normalizeOffer(o))
+	}
+	return
+}
+
+func normalizeOffer(orig string) string {
+	return strings.SplitN(orig, ";", 2)[0]
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/middleware/not_implemented.go b/go/vendor/github.com/go-openapi/runtime/middleware/not_implemented.go
new file mode 100644
index 0000000..466f553
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/middleware/not_implemented.go
@@ -0,0 +1,48 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package middleware
+
+import (
+	"net/http"
+
+	"github.com/go-openapi/runtime"
+)
+
+type errorResp struct {
+	code     int
+	response interface{}
+	headers  http.Header
+}
+
+func (e *errorResp) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
+	for k, v := range e.headers {
+		for _, val := range v {
+			rw.Header().Add(k, val)
+		}
+	}
+	if e.code > 0 {
+		rw.WriteHeader(e.code)
+	} else {
+		rw.WriteHeader(http.StatusInternalServerError)
+	}
+	if err := producer.Produce(rw, e.response); err != nil {
+		panic(err)
+	}
+}
+
+// NotImplemented the error response when the response is not implemented
+func NotImplemented(message string) Responder {
+	return &errorResp{http.StatusNotImplemented, message, make(http.Header)}
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/middleware/operation.go b/go/vendor/github.com/go-openapi/runtime/middleware/operation.go
new file mode 100644
index 0000000..1175a63
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/middleware/operation.go
@@ -0,0 +1,30 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package middleware
+
+import "net/http"
+
+// NewOperationExecutor creates a context aware middleware that handles the operations after routing
+func NewOperationExecutor(ctx *Context) http.Handler {
+	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+		// use context to lookup routes
+		route, rCtx, _ := ctx.RouteInfo(r)
+		if rCtx != nil {
+			r = rCtx
+		}
+
+		route.Handler.ServeHTTP(rw, r)
+	})
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/middleware/parameter.go b/go/vendor/github.com/go-openapi/runtime/middleware/parameter.go
new file mode 100644
index 0000000..8975b6e
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/middleware/parameter.go
@@ -0,0 +1,480 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package middleware
+
+import (
+	"encoding"
+	"encoding/base64"
+	"fmt"
+	"io"
+	"net/http"
+	"reflect"
+	"strconv"
+
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/strfmt"
+	"github.com/go-openapi/swag"
+	"github.com/go-openapi/validate"
+)
+
+const defaultMaxMemory = 32 << 20
+
+var textUnmarshalType = reflect.TypeOf(new(encoding.TextUnmarshaler)).Elem()
+
+func newUntypedParamBinder(param spec.Parameter, spec *spec.Swagger, formats strfmt.Registry) *untypedParamBinder {
+	binder := new(untypedParamBinder)
+	binder.Name = param.Name
+	binder.parameter = &param
+	binder.formats = formats
+	if param.In != "body" {
+		binder.validator = validate.NewParamValidator(&param, formats)
+	} else {
+		binder.validator = validate.NewSchemaValidator(param.Schema, spec, param.Name, formats)
+	}
+
+	return binder
+}
+
+type untypedParamBinder struct {
+	parameter *spec.Parameter
+	formats   strfmt.Registry
+	Name      string
+	validator validate.EntityValidator
+}
+
+func (p *untypedParamBinder) Type() reflect.Type {
+	return p.typeForSchema(p.parameter.Type, p.parameter.Format, p.parameter.Items)
+}
+
+func (p *untypedParamBinder) typeForSchema(tpe, format string, items *spec.Items) reflect.Type {
+	switch tpe {
+	case "boolean":
+		return reflect.TypeOf(true)
+
+	case "string":
+		if tt, ok := p.formats.GetType(format); ok {
+			return tt
+		}
+		return reflect.TypeOf("")
+
+	case "integer":
+		switch format {
+		case "int8":
+			return reflect.TypeOf(int8(0))
+		case "int16":
+			return reflect.TypeOf(int16(0))
+		case "int32":
+			return reflect.TypeOf(int32(0))
+		case "int64":
+			return reflect.TypeOf(int64(0))
+		default:
+			return reflect.TypeOf(int64(0))
+		}
+
+	case "number":
+		switch format {
+		case "float":
+			return reflect.TypeOf(float32(0))
+		case "double":
+			return reflect.TypeOf(float64(0))
+		}
+
+	case "array":
+		if items == nil {
+			return nil
+		}
+		itemsType := p.typeForSchema(items.Type, items.Format, items.Items)
+		if itemsType == nil {
+			return nil
+		}
+		return reflect.MakeSlice(reflect.SliceOf(itemsType), 0, 0).Type()
+
+	case "file":
+		return reflect.TypeOf(&runtime.File{}).Elem()
+
+	case "object":
+		return reflect.TypeOf(map[string]interface{}{})
+	}
+	return nil
+}
+
+func (p *untypedParamBinder) allowsMulti() bool {
+	return p.parameter.In == "query" || p.parameter.In == "formData"
+}
+
+func (p *untypedParamBinder) readValue(values runtime.Gettable, target reflect.Value) ([]string, bool, bool, error) {
+	name, in, cf, tpe := p.parameter.Name, p.parameter.In, p.parameter.CollectionFormat, p.parameter.Type
+	if tpe == "array" {
+		if cf == "multi" {
+			if !p.allowsMulti() {
+				return nil, false, false, errors.InvalidCollectionFormat(name, in, cf)
+			}
+			vv, hasKey, _ := values.GetOK(name)
+			return vv, false, hasKey, nil
+		}
+
+		v, hk, hv := values.GetOK(name)
+		if !hv {
+			return nil, false, hk, nil
+		}
+		d, c, e := p.readFormattedSliceFieldValue(v[len(v)-1], target)
+		return d, c, hk, e
+	}
+
+	vv, hk, _ := values.GetOK(name)
+	return vv, false, hk, nil
+}
+
+func (p *untypedParamBinder) Bind(request *http.Request, routeParams RouteParams, consumer runtime.Consumer, target reflect.Value) error {
+	// fmt.Println("binding", p.name, "as", p.Type())
+	switch p.parameter.In {
+	case "query":
+		data, custom, hasKey, err := p.readValue(runtime.Values(request.URL.Query()), target)
+		if err != nil {
+			return err
+		}
+		if custom {
+			return nil
+		}
+
+		return p.bindValue(data, hasKey, target)
+
+	case "header":
+		data, custom, hasKey, err := p.readValue(runtime.Values(request.Header), target)
+		if err != nil {
+			return err
+		}
+		if custom {
+			return nil
+		}
+		return p.bindValue(data, hasKey, target)
+
+	case "path":
+		data, custom, hasKey, err := p.readValue(routeParams, target)
+		if err != nil {
+			return err
+		}
+		if custom {
+			return nil
+		}
+		return p.bindValue(data, hasKey, target)
+
+	case "formData":
+		var err error
+		var mt string
+
+		mt, _, e := runtime.ContentType(request.Header)
+		if e != nil {
+			// because of the interface conversion go thinks the error is not nil
+			// so we first check for nil and then set the err var if it's not nil
+			err = e
+		}
+
+		if err != nil {
+			return errors.InvalidContentType("", []string{"multipart/form-data", "application/x-www-form-urlencoded"})
+		}
+
+		if mt != "multipart/form-data" && mt != "application/x-www-form-urlencoded" {
+			return errors.InvalidContentType(mt, []string{"multipart/form-data", "application/x-www-form-urlencoded"})
+		}
+
+		if mt == "multipart/form-data" {
+			if err = request.ParseMultipartForm(defaultMaxMemory); err != nil {
+				return errors.NewParseError(p.Name, p.parameter.In, "", err)
+			}
+		}
+
+		if err = request.ParseForm(); err != nil {
+			return errors.NewParseError(p.Name, p.parameter.In, "", err)
+		}
+
+		if p.parameter.Type == "file" {
+			file, header, ffErr := request.FormFile(p.parameter.Name)
+			if ffErr != nil {
+				return errors.NewParseError(p.Name, p.parameter.In, "", ffErr)
+			}
+			target.Set(reflect.ValueOf(runtime.File{Data: file, Header: header}))
+			return nil
+		}
+
+		if request.MultipartForm != nil {
+			data, custom, hasKey, rvErr := p.readValue(runtime.Values(request.MultipartForm.Value), target)
+			if rvErr != nil {
+				return rvErr
+			}
+			if custom {
+				return nil
+			}
+			return p.bindValue(data, hasKey, target)
+		}
+		data, custom, hasKey, err := p.readValue(runtime.Values(request.PostForm), target)
+		if err != nil {
+			return err
+		}
+		if custom {
+			return nil
+		}
+		return p.bindValue(data, hasKey, target)
+
+	case "body":
+		newValue := reflect.New(target.Type())
+		if !runtime.HasBody(request) {
+			if p.parameter.Default != nil {
+				target.Set(reflect.ValueOf(p.parameter.Default))
+			}
+
+			return nil
+		}
+		if err := consumer.Consume(request.Body, newValue.Interface()); err != nil {
+			if err == io.EOF && p.parameter.Default != nil {
+				target.Set(reflect.ValueOf(p.parameter.Default))
+				return nil
+			}
+			tpe := p.parameter.Type
+			if p.parameter.Format != "" {
+				tpe = p.parameter.Format
+			}
+			return errors.InvalidType(p.Name, p.parameter.In, tpe, nil)
+		}
+		target.Set(reflect.Indirect(newValue))
+		return nil
+	default:
+		return errors.New(500, fmt.Sprintf("invalid parameter location %q", p.parameter.In))
+	}
+}
+
+func (p *untypedParamBinder) bindValue(data []string, hasKey bool, target reflect.Value) error {
+	if p.parameter.Type == "array" {
+		return p.setSliceFieldValue(target, p.parameter.Default, data, hasKey)
+	}
+	var d string
+	if len(data) > 0 {
+		d = data[len(data)-1]
+	}
+	return p.setFieldValue(target, p.parameter.Default, d, hasKey)
+}
+
+func (p *untypedParamBinder) setFieldValue(target reflect.Value, defaultValue interface{}, data string, hasKey bool) error {
+	tpe := p.parameter.Type
+	if p.parameter.Format != "" {
+		tpe = p.parameter.Format
+	}
+
+	if (!hasKey || (!p.parameter.AllowEmptyValue && data == "")) && p.parameter.Required && p.parameter.Default == nil {
+		return errors.Required(p.Name, p.parameter.In)
+	}
+
+	ok, err := p.tryUnmarshaler(target, defaultValue, data)
+	if err != nil {
+		return errors.InvalidType(p.Name, p.parameter.In, tpe, data)
+	}
+	if ok {
+		return nil
+	}
+
+	defVal := reflect.Zero(target.Type())
+	if defaultValue != nil {
+		defVal = reflect.ValueOf(defaultValue)
+	}
+
+	if tpe == "byte" {
+		if data == "" {
+			if target.CanSet() {
+				target.SetBytes(defVal.Bytes())
+			}
+			return nil
+		}
+
+		b, err := base64.StdEncoding.DecodeString(data)
+		if err != nil {
+			b, err = base64.URLEncoding.DecodeString(data)
+			if err != nil {
+				return errors.InvalidType(p.Name, p.parameter.In, tpe, data)
+			}
+		}
+		if target.CanSet() {
+			target.SetBytes(b)
+		}
+		return nil
+	}
+
+	switch target.Kind() {
+	case reflect.Bool:
+		if data == "" {
+			if target.CanSet() {
+				target.SetBool(defVal.Bool())
+			}
+			return nil
+		}
+		b, err := swag.ConvertBool(data)
+		if err != nil {
+			return err
+		}
+		if target.CanSet() {
+			target.SetBool(b)
+		}
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		if data == "" {
+			if target.CanSet() {
+				rd := defVal.Convert(reflect.TypeOf(int64(0)))
+				target.SetInt(rd.Int())
+			}
+			return nil
+		}
+		i, err := strconv.ParseInt(data, 10, 64)
+		if err != nil {
+			return errors.InvalidType(p.Name, p.parameter.In, tpe, data)
+		}
+		if target.OverflowInt(i) {
+			return errors.InvalidType(p.Name, p.parameter.In, tpe, data)
+		}
+		if target.CanSet() {
+			target.SetInt(i)
+		}
+
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		if data == "" {
+			if target.CanSet() {
+				rd := defVal.Convert(reflect.TypeOf(uint64(0)))
+				target.SetUint(rd.Uint())
+			}
+			return nil
+		}
+		u, err := strconv.ParseUint(data, 10, 64)
+		if err != nil {
+			return errors.InvalidType(p.Name, p.parameter.In, tpe, data)
+		}
+		if target.OverflowUint(u) {
+			return errors.InvalidType(p.Name, p.parameter.In, tpe, data)
+		}
+		if target.CanSet() {
+			target.SetUint(u)
+		}
+
+	case reflect.Float32, reflect.Float64:
+		if data == "" {
+			if target.CanSet() {
+				rd := defVal.Convert(reflect.TypeOf(float64(0)))
+				target.SetFloat(rd.Float())
+			}
+			return nil
+		}
+		f, err := strconv.ParseFloat(data, 64)
+		if err != nil {
+			return errors.InvalidType(p.Name, p.parameter.In, tpe, data)
+		}
+		if target.OverflowFloat(f) {
+			return errors.InvalidType(p.Name, p.parameter.In, tpe, data)
+		}
+		if target.CanSet() {
+			target.SetFloat(f)
+		}
+
+	case reflect.String:
+		value := data
+		if value == "" {
+			value = defVal.String()
+		}
+		// validate string
+		if target.CanSet() {
+			target.SetString(value)
+		}
+
+	case reflect.Ptr:
+		if data == "" && defVal.Kind() == reflect.Ptr {
+			if target.CanSet() {
+				target.Set(defVal)
+			}
+			return nil
+		}
+		newVal := reflect.New(target.Type().Elem())
+		if err := p.setFieldValue(reflect.Indirect(newVal), defVal, data, hasKey); err != nil {
+			return err
+		}
+		if target.CanSet() {
+			target.Set(newVal)
+		}
+
+	default:
+		return errors.InvalidType(p.Name, p.parameter.In, tpe, data)
+	}
+	return nil
+}
+
+func (p *untypedParamBinder) tryUnmarshaler(target reflect.Value, defaultValue interface{}, data string) (bool, error) {
+	if !target.CanSet() {
+		return false, nil
+	}
+	// When a type implements encoding.TextUnmarshaler we'll use that instead of reflecting some more
+	if reflect.PtrTo(target.Type()).Implements(textUnmarshalType) {
+		if defaultValue != nil && len(data) == 0 {
+			target.Set(reflect.ValueOf(defaultValue))
+			return true, nil
+		}
+		value := reflect.New(target.Type())
+		if err := value.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(data)); err != nil {
+			return true, err
+		}
+		target.Set(reflect.Indirect(value))
+		return true, nil
+	}
+	return false, nil
+}
+
+func (p *untypedParamBinder) readFormattedSliceFieldValue(data string, target reflect.Value) ([]string, bool, error) {
+	ok, err := p.tryUnmarshaler(target, p.parameter.Default, data)
+	if err != nil {
+		return nil, true, err
+	}
+	if ok {
+		return nil, true, nil
+	}
+
+	return swag.SplitByFormat(data, p.parameter.CollectionFormat), false, nil
+}
+
+func (p *untypedParamBinder) setSliceFieldValue(target reflect.Value, defaultValue interface{}, data []string, hasKey bool) error {
+	sz := len(data)
+	if (!hasKey || (!p.parameter.AllowEmptyValue && (sz == 0 || (sz == 1 && data[0] == "")))) && p.parameter.Required && defaultValue == nil {
+		return errors.Required(p.Name, p.parameter.In)
+	}
+
+	defVal := reflect.Zero(target.Type())
+	if defaultValue != nil {
+		defVal = reflect.ValueOf(defaultValue)
+	}
+
+	if !target.CanSet() {
+		return nil
+	}
+	if sz == 0 {
+		target.Set(defVal)
+		return nil
+	}
+
+	value := reflect.MakeSlice(reflect.SliceOf(target.Type().Elem()), sz, sz)
+
+	for i := 0; i < sz; i++ {
+		if err := p.setFieldValue(value.Index(i), nil, data[i], hasKey); err != nil {
+			return err
+		}
+	}
+
+	target.Set(value)
+
+	return nil
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/middleware/pre_go18.go b/go/vendor/github.com/go-openapi/runtime/middleware/pre_go18.go
new file mode 100644
index 0000000..0338525
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/middleware/pre_go18.go
@@ -0,0 +1,9 @@
+// +build !go1.8
+
+package middleware
+
+import "net/url"
+
+func pathUnescape(path string) (string, error) {
+	return url.QueryUnescape(path)
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/middleware/redoc.go b/go/vendor/github.com/go-openapi/runtime/middleware/redoc.go
new file mode 100644
index 0000000..2127794
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/middleware/redoc.go
@@ -0,0 +1,101 @@
+package middleware
+
+import (
+	"bytes"
+	"fmt"
+	"html/template"
+	"net/http"
+	"path"
+)
+
+// RedocOpts configures the Redoc middlewares
+type RedocOpts struct {
+	// BasePath for the UI path, defaults to: /
+	BasePath string
+	// Path combines with BasePath for the full UI path, defaults to: docs
+	Path string
+	// SpecURL the url to find the spec for
+	SpecURL string
+	// RedocURL for the js that generates the redoc site, defaults to: https://rebilly.github.io/ReDoc/releases/latest/redoc.min.js
+	RedocURL string
+	// Title for the documentation site, default to: API documentation
+	Title string
+}
+
+// EnsureDefaults in case some options are missing
+func (r *RedocOpts) EnsureDefaults() {
+	if r.BasePath == "" {
+		r.BasePath = "/"
+	}
+	if r.Path == "" {
+		r.Path = "docs"
+	}
+	if r.SpecURL == "" {
+		r.SpecURL = "/swagger.json"
+	}
+	if r.RedocURL == "" {
+		r.RedocURL = redocLatest
+	}
+	if r.Title == "" {
+		r.Title = "API documentation"
+	}
+}
+
+// Redoc creates a middleware to serve a documentation site for a swagger spec.
+// This allows for altering the spec before starting the http listener.
+//
+func Redoc(opts RedocOpts, next http.Handler) http.Handler {
+	opts.EnsureDefaults()
+
+	pth := path.Join(opts.BasePath, opts.Path)
+	tmpl := template.Must(template.New("redoc").Parse(redocTemplate))
+
+	buf := bytes.NewBuffer(nil)
+	_ = tmpl.Execute(buf, opts)
+	b := buf.Bytes()
+
+	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+		if r.URL.Path == pth {
+			rw.Header().Set("Content-Type", "text/html; charset=utf-8")
+			rw.WriteHeader(http.StatusOK)
+
+			_, _ = rw.Write(b)
+			return
+		}
+
+		if next == nil {
+			rw.Header().Set("Content-Type", "text/plain")
+			rw.WriteHeader(http.StatusNotFound)
+			_, _ = rw.Write([]byte(fmt.Sprintf("%q not found", pth)))
+			return
+		}
+		next.ServeHTTP(rw, r)
+	})
+}
+
+const (
+	redocLatest   = "https://rebilly.github.io/ReDoc/releases/latest/redoc.min.js"
+	redocTemplate = `<!DOCTYPE html>
+<html>
+  <head>
+    <title>{{ .Title }}</title>
+    <!-- needed for adaptive design -->
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+
+    <!--
+    ReDoc doesn't change outer page styles
+    -->
+    <style>
+      body {
+        margin: 0;
+        padding: 0;
+      }
+    </style>
+  </head>
+  <body>
+    <redoc spec-url='{{ .SpecURL }}'></redoc>
+    <script src="{{ .RedocURL }}"> </script>
+  </body>
+</html>
+`
+)
diff --git a/go/vendor/github.com/go-openapi/runtime/middleware/request.go b/go/vendor/github.com/go-openapi/runtime/middleware/request.go
new file mode 100644
index 0000000..ee725f5
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/middleware/request.go
@@ -0,0 +1,104 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package middleware
+
+import (
+	"net/http"
+	"reflect"
+
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/strfmt"
+)
+
+// RequestBinder binds and validates the data from a http request
+type untypedRequestBinder struct {
+	Spec         *spec.Swagger
+	Parameters   map[string]spec.Parameter
+	Formats      strfmt.Registry
+	paramBinders map[string]*untypedParamBinder
+}
+
+// NewRequestBinder creates a new binder for reading a request.
+func newUntypedRequestBinder(parameters map[string]spec.Parameter, spec *spec.Swagger, formats strfmt.Registry) *untypedRequestBinder {
+	binders := make(map[string]*untypedParamBinder)
+	for fieldName, param := range parameters {
+		binders[fieldName] = newUntypedParamBinder(param, spec, formats)
+	}
+	return &untypedRequestBinder{
+		Parameters:   parameters,
+		paramBinders: binders,
+		Spec:         spec,
+		Formats:      formats,
+	}
+}
+
+// Bind perform the databinding and validation
+func (o *untypedRequestBinder) Bind(request *http.Request, routeParams RouteParams, consumer runtime.Consumer, data interface{}) error {
+	val := reflect.Indirect(reflect.ValueOf(data))
+	isMap := val.Kind() == reflect.Map
+	var result []error
+	debugLog("binding %d parameters for %s %s", len(o.Parameters), request.Method, request.URL.EscapedPath())
+	for fieldName, param := range o.Parameters {
+		binder := o.paramBinders[fieldName]
+		debugLog("binding parameter %s for %s %s", fieldName, request.Method, request.URL.EscapedPath())
+		var target reflect.Value
+		if !isMap {
+			binder.Name = fieldName
+			target = val.FieldByName(fieldName)
+		}
+
+		if isMap {
+			tpe := binder.Type()
+			if tpe == nil {
+				if param.Schema.Type.Contains("array") {
+					tpe = reflect.TypeOf([]interface{}{})
+				} else {
+					tpe = reflect.TypeOf(map[string]interface{}{})
+				}
+			}
+			target = reflect.Indirect(reflect.New(tpe))
+
+		}
+
+		if !target.IsValid() {
+			result = append(result, errors.New(500, "parameter name %q is an unknown field", binder.Name))
+			continue
+		}
+
+		if err := binder.Bind(request, routeParams, consumer, target); err != nil {
+			result = append(result, err)
+			continue
+		}
+
+		if binder.validator != nil {
+			rr := binder.validator.Validate(target.Interface())
+			if rr != nil && rr.HasErrors() {
+				result = append(result, rr.AsError())
+			}
+		}
+
+		if isMap {
+			val.SetMapIndex(reflect.ValueOf(param.Name), target)
+		}
+	}
+
+	if len(result) > 0 {
+		return errors.CompositeValidationError(result...)
+	}
+
+	return nil
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/middleware/router.go b/go/vendor/github.com/go-openapi/runtime/middleware/router.go
new file mode 100644
index 0000000..73c8eeb
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/middleware/router.go
@@ -0,0 +1,478 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package middleware
+
+import (
+	"fmt"
+	"net/http"
+	fpath "path"
+	"regexp"
+	"strings"
+
+	"github.com/go-openapi/runtime/security"
+
+	"github.com/go-openapi/analysis"
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/loads"
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/runtime/middleware/denco"
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/strfmt"
+)
+
+// RouteParam is a object to capture route params in a framework agnostic way.
+// implementations of the muxer should use these route params to communicate with the
+// swagger framework
+type RouteParam struct {
+	Name  string
+	Value string
+}
+
+// RouteParams the collection of route params
+type RouteParams []RouteParam
+
+// Get gets the value for the route param for the specified key
+func (r RouteParams) Get(name string) string {
+	vv, _, _ := r.GetOK(name)
+	if len(vv) > 0 {
+		return vv[len(vv)-1]
+	}
+	return ""
+}
+
+// GetOK gets the value but also returns booleans to indicate if a key or value
+// is present. This aids in validation and satisfies an interface in use there
+//
+// The returned values are: data, has key, has value
+func (r RouteParams) GetOK(name string) ([]string, bool, bool) {
+	for _, p := range r {
+		if p.Name == name {
+			return []string{p.Value}, true, p.Value != ""
+		}
+	}
+	return nil, false, false
+}
+
+// NewRouter creates a new context aware router middleware
+func NewRouter(ctx *Context, next http.Handler) http.Handler {
+	if ctx.router == nil {
+		ctx.router = DefaultRouter(ctx.spec, ctx.api)
+	}
+
+	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+		if _, rCtx, ok := ctx.RouteInfo(r); ok {
+			next.ServeHTTP(rw, rCtx)
+			return
+		}
+
+		// Not found, check if it exists in the other methods first
+		if others := ctx.AllowedMethods(r); len(others) > 0 {
+			ctx.Respond(rw, r, ctx.analyzer.RequiredProduces(), nil, errors.MethodNotAllowed(r.Method, others))
+			return
+		}
+
+		ctx.Respond(rw, r, ctx.analyzer.RequiredProduces(), nil, errors.NotFound("path %s was not found", r.URL.EscapedPath()))
+	})
+}
+
+// RoutableAPI represents an interface for things that can serve
+// as a provider of implementations for the swagger router
+type RoutableAPI interface {
+	HandlerFor(string, string) (http.Handler, bool)
+	ServeErrorFor(string) func(http.ResponseWriter, *http.Request, error)
+	ConsumersFor([]string) map[string]runtime.Consumer
+	ProducersFor([]string) map[string]runtime.Producer
+	AuthenticatorsFor(map[string]spec.SecurityScheme) map[string]runtime.Authenticator
+	Authorizer() runtime.Authorizer
+	Formats() strfmt.Registry
+	DefaultProduces() string
+	DefaultConsumes() string
+}
+
+// Router represents a swagger aware router
+type Router interface {
+	Lookup(method, path string) (*MatchedRoute, bool)
+	OtherMethods(method, path string) []string
+}
+
+type defaultRouteBuilder struct {
+	spec     *loads.Document
+	analyzer *analysis.Spec
+	api      RoutableAPI
+	records  map[string][]denco.Record
+}
+
+type defaultRouter struct {
+	spec    *loads.Document
+	routers map[string]*denco.Router
+}
+
+func newDefaultRouteBuilder(spec *loads.Document, api RoutableAPI) *defaultRouteBuilder {
+	return &defaultRouteBuilder{
+		spec:     spec,
+		analyzer: analysis.New(spec.Spec()),
+		api:      api,
+		records:  make(map[string][]denco.Record),
+	}
+}
+
+// DefaultRouter creates a default implemenation of the router
+func DefaultRouter(spec *loads.Document, api RoutableAPI) Router {
+	builder := newDefaultRouteBuilder(spec, api)
+	if spec != nil {
+		for method, paths := range builder.analyzer.Operations() {
+			for path, operation := range paths {
+				fp := fpath.Join(spec.BasePath(), path)
+				debugLog("adding route %s %s %q", method, fp, operation.ID)
+				builder.AddRoute(method, fp, operation)
+			}
+		}
+	}
+	return builder.Build()
+}
+
+// RouteAuthenticator is an authenticator that can compose several authenticators together.
+// It also knows when it contains an authenticator that allows for anonymous pass through.
+// Contains a group of 1 or more authenticators that have a logical AND relationship
+type RouteAuthenticator struct {
+	Authenticator  map[string]runtime.Authenticator
+	Schemes        []string
+	Scopes         map[string][]string
+	allScopes      []string
+	commonScopes   []string
+	allowAnonymous bool
+}
+
+func (ra *RouteAuthenticator) AllowsAnonymous() bool {
+	return ra.allowAnonymous
+}
+
+// AllScopes returns a list of unique scopes that is the combination
+// of all the scopes in the requirements
+func (ra *RouteAuthenticator) AllScopes() []string {
+	return ra.allScopes
+}
+
+// CommonScopes returns a list of unique scopes that are common in all the
+// scopes in the requirements
+func (ra *RouteAuthenticator) CommonScopes() []string {
+	return ra.commonScopes
+}
+
+// Authenticate Authenticator interface implementation
+func (ra *RouteAuthenticator) Authenticate(req *http.Request, route *MatchedRoute) (bool, interface{}, error) {
+	if ra.allowAnonymous {
+		route.Authenticator = ra
+		return true, nil, nil
+	}
+	// iterate in proper order
+	var lastResult interface{}
+	for _, scheme := range ra.Schemes {
+		if authenticator, ok := ra.Authenticator[scheme]; ok {
+			applies, princ, err := authenticator.Authenticate(&security.ScopedAuthRequest{
+				Request:        req,
+				RequiredScopes: ra.Scopes[scheme],
+			})
+			if !applies {
+				return false, nil, nil
+			}
+
+			if err != nil {
+				route.Authenticator = ra
+				return true, nil, err
+			}
+			lastResult = princ
+		}
+	}
+	route.Authenticator = ra
+	return true, lastResult, nil
+}
+
+func stringSliceUnion(slices ...[]string) []string {
+	unique := make(map[string]struct{})
+	var result []string
+	for _, slice := range slices {
+		for _, entry := range slice {
+			if _, ok := unique[entry]; ok {
+				continue
+			}
+			unique[entry] = struct{}{}
+			result = append(result, entry)
+		}
+	}
+	return result
+}
+
+func stringSliceIntersection(slices ...[]string) []string {
+	unique := make(map[string]int)
+	var intersection []string
+
+	total := len(slices)
+	var emptyCnt int
+	for _, slice := range slices {
+		if len(slice) == 0 {
+			emptyCnt++
+			continue
+		}
+
+		for _, entry := range slice {
+			unique[entry]++
+			if unique[entry] == total-emptyCnt { // this entry appeared in all the non-empty slices
+				intersection = append(intersection, entry)
+			}
+		}
+	}
+
+	return intersection
+}
+
+// RouteAuthenticators represents a group of authenticators that represent a logical OR
+type RouteAuthenticators []RouteAuthenticator
+
+// AllowsAnonymous returns true when there is an authenticator that means optional auth
+func (ras RouteAuthenticators) AllowsAnonymous() bool {
+	for _, ra := range ras {
+		if ra.AllowsAnonymous() {
+			return true
+		}
+	}
+	return false
+}
+
+// Authenticate method implemention so this collection can be used as authenticator
+func (ras RouteAuthenticators) Authenticate(req *http.Request, route *MatchedRoute) (bool, interface{}, error) {
+	var lastError error
+	var allowsAnon bool
+	var anonAuth RouteAuthenticator
+
+	for _, ra := range ras {
+		if ra.AllowsAnonymous() {
+			anonAuth = ra
+			allowsAnon = true
+			continue
+		}
+		applies, usr, err := ra.Authenticate(req, route)
+		if !applies || err != nil || usr == nil {
+			if err != nil {
+				lastError = err
+			}
+			continue
+		}
+		return applies, usr, nil
+	}
+
+	if allowsAnon && lastError == nil {
+		route.Authenticator = &anonAuth
+		return true, nil, lastError
+	}
+	return lastError != nil, nil, lastError
+}
+
+type routeEntry struct {
+	PathPattern    string
+	BasePath       string
+	Operation      *spec.Operation
+	Consumes       []string
+	Consumers      map[string]runtime.Consumer
+	Produces       []string
+	Producers      map[string]runtime.Producer
+	Parameters     map[string]spec.Parameter
+	Handler        http.Handler
+	Formats        strfmt.Registry
+	Binder         *untypedRequestBinder
+	Authenticators RouteAuthenticators
+	Authorizer     runtime.Authorizer
+}
+
+// MatchedRoute represents the route that was matched in this request
+type MatchedRoute struct {
+	routeEntry
+	Params        RouteParams
+	Consumer      runtime.Consumer
+	Producer      runtime.Producer
+	Authenticator *RouteAuthenticator
+}
+
+// HasAuth returns true when the route has a security requirement defined
+func (m *MatchedRoute) HasAuth() bool {
+	return len(m.Authenticators) > 0
+}
+
+// NeedsAuth returns true when the request still
+// needs to perform authentication
+func (m *MatchedRoute) NeedsAuth() bool {
+	return m.HasAuth() && m.Authenticator == nil
+}
+
+func (d *defaultRouter) Lookup(method, path string) (*MatchedRoute, bool) {
+	mth := strings.ToUpper(method)
+	debugLog("looking up route for %s %s", method, path)
+	if Debug {
+		if len(d.routers) == 0 {
+			debugLog("there are no known routers")
+		}
+		for meth := range d.routers {
+			debugLog("got a router for %s", meth)
+		}
+	}
+	if router, ok := d.routers[mth]; ok {
+		if m, rp, ok := router.Lookup(fpath.Clean(path)); ok && m != nil {
+			if entry, ok := m.(*routeEntry); ok {
+				debugLog("found a route for %s %s with %d parameters", method, path, len(entry.Parameters))
+				var params RouteParams
+				for _, p := range rp {
+					v, err := pathUnescape(p.Value)
+					if err != nil {
+						debugLog("failed to escape %q: %v", p.Value, err)
+						v = p.Value
+					}
+					// a workaround to handle fragment/composing parameters until they are supported in denco router
+					// check if this parameter is a fragment within a path segment
+					if xpos := strings.Index(entry.PathPattern, fmt.Sprintf("{%s}", p.Name)) + len(p.Name) + 2; xpos < len(entry.PathPattern) && entry.PathPattern[xpos] != '/' {
+						// extract fragment parameters
+						ep := strings.Split(entry.PathPattern[xpos:], "/")[0]
+						pnames, pvalues := decodeCompositParams(p.Name, v, ep, nil, nil)
+						for i, pname := range pnames {
+							params = append(params, RouteParam{Name: pname, Value: pvalues[i]})
+						}
+					} else {
+						// use the parameter directly
+						params = append(params, RouteParam{Name: p.Name, Value: v})
+					}
+				}
+				return &MatchedRoute{routeEntry: *entry, Params: params}, true
+			}
+		} else {
+			debugLog("couldn't find a route by path for %s %s", method, path)
+		}
+	} else {
+		debugLog("couldn't find a route by method for %s %s", method, path)
+	}
+	return nil, false
+}
+
+func (d *defaultRouter) OtherMethods(method, path string) []string {
+	mn := strings.ToUpper(method)
+	var methods []string
+	for k, v := range d.routers {
+		if k != mn {
+			if _, _, ok := v.Lookup(fpath.Clean(path)); ok {
+				methods = append(methods, k)
+				continue
+			}
+		}
+	}
+	return methods
+}
+
+// convert swagger parameters per path segment into a denco parameter as multiple parameters per segment are not supported in denco
+var pathConverter = regexp.MustCompile(`{(.+?)}([^/]*)`)
+
+func decodeCompositParams(name string, value string, pattern string, names []string, values []string) ([]string, []string) {
+	pleft := strings.Index(pattern, "{")
+	names = append(names, name)
+	if pleft < 0 {
+		if strings.HasSuffix(value, pattern) {
+			values = append(values, value[:len(value)-len(pattern)])
+		} else {
+			values = append(values, "")
+		}
+	} else {
+		toskip := pattern[:pleft]
+		pright := strings.Index(pattern, "}")
+		vright := strings.Index(value, toskip)
+		if vright >= 0 {
+			values = append(values, value[:vright])
+		} else {
+			values = append(values, "")
+			value = ""
+		}
+		return decodeCompositParams(pattern[pleft+1:pright], value[vright+len(toskip):], pattern[pright+1:], names, values)
+	}
+	return names, values
+}
+
+func (d *defaultRouteBuilder) AddRoute(method, path string, operation *spec.Operation) {
+	mn := strings.ToUpper(method)
+
+	bp := fpath.Clean(d.spec.BasePath())
+	if len(bp) > 0 && bp[len(bp)-1] == '/' {
+		bp = bp[:len(bp)-1]
+	}
+
+	debugLog("operation: %#v", *operation)
+	if handler, ok := d.api.HandlerFor(method, strings.TrimPrefix(path, bp)); ok {
+		consumes := d.analyzer.ConsumesFor(operation)
+		produces := d.analyzer.ProducesFor(operation)
+		parameters := d.analyzer.ParamsFor(method, strings.TrimPrefix(path, bp))
+
+		record := denco.NewRecord(pathConverter.ReplaceAllString(path, ":$1"), &routeEntry{
+			BasePath:       bp,
+			PathPattern:    path,
+			Operation:      operation,
+			Handler:        handler,
+			Consumes:       consumes,
+			Produces:       produces,
+			Consumers:      d.api.ConsumersFor(normalizeOffers(consumes)),
+			Producers:      d.api.ProducersFor(normalizeOffers(produces)),
+			Parameters:     parameters,
+			Formats:        d.api.Formats(),
+			Binder:         newUntypedRequestBinder(parameters, d.spec.Spec(), d.api.Formats()),
+			Authenticators: d.buildAuthenticators(operation),
+			Authorizer:     d.api.Authorizer(),
+		})
+		d.records[mn] = append(d.records[mn], record)
+	}
+}
+
+func (d *defaultRouteBuilder) buildAuthenticators(operation *spec.Operation) RouteAuthenticators {
+	requirements := d.analyzer.SecurityRequirementsFor(operation)
+	var auths []RouteAuthenticator
+	for _, reqs := range requirements {
+		var schemes []string
+		scopes := make(map[string][]string, len(reqs))
+		var scopeSlices [][]string
+		for _, req := range reqs {
+			schemes = append(schemes, req.Name)
+			scopes[req.Name] = req.Scopes
+			scopeSlices = append(scopeSlices, req.Scopes)
+		}
+
+		definitions := d.analyzer.SecurityDefinitionsForRequirements(reqs)
+		authenticators := d.api.AuthenticatorsFor(definitions)
+		auths = append(auths, RouteAuthenticator{
+			Authenticator:  authenticators,
+			Schemes:        schemes,
+			Scopes:         scopes,
+			allScopes:      stringSliceUnion(scopeSlices...),
+			commonScopes:   stringSliceIntersection(scopeSlices...),
+			allowAnonymous: len(reqs) == 1 && reqs[0].Name == "",
+		})
+	}
+	return auths
+}
+
+func (d *defaultRouteBuilder) Build() *defaultRouter {
+	routers := make(map[string]*denco.Router)
+	for method, records := range d.records {
+		router := denco.New()
+		_ = router.Build(records)
+		routers[method] = router
+	}
+	return &defaultRouter{
+		spec:    d.spec,
+		routers: routers,
+	}
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/middleware/security.go b/go/vendor/github.com/go-openapi/runtime/middleware/security.go
new file mode 100644
index 0000000..2b061ca
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/middleware/security.go
@@ -0,0 +1,39 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package middleware
+
+import "net/http"
+
+func newSecureAPI(ctx *Context, next http.Handler) http.Handler {
+	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+		route, rCtx, _ := ctx.RouteInfo(r)
+		if rCtx != nil {
+			r = rCtx
+		}
+		if route != nil && !route.NeedsAuth() {
+			next.ServeHTTP(rw, r)
+			return
+		}
+
+		_, rCtx, err := ctx.Authorize(r, route)
+		if err != nil {
+			ctx.Respond(rw, r, route.Produces, route, err)
+			return
+		}
+		r = rCtx
+
+		next.ServeHTTP(rw, r)
+	})
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/middleware/spec.go b/go/vendor/github.com/go-openapi/runtime/middleware/spec.go
new file mode 100644
index 0000000..6e02b83
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/middleware/spec.go
@@ -0,0 +1,48 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package middleware
+
+import (
+	"net/http"
+	"path"
+)
+
+// Spec creates a middleware to serve a swagger spec.
+// This allows for altering the spec before starting the http listener.
+// This can be useful if you want to serve the swagger spec from another path than /swagger.json
+//
+func Spec(basePath string, b []byte, next http.Handler) http.Handler {
+	if basePath == "" {
+		basePath = "/"
+	}
+	pth := path.Join(basePath, "swagger.json")
+
+	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+		if r.URL.Path == pth {
+			rw.Header().Set("Content-Type", "application/json")
+			rw.WriteHeader(http.StatusOK)
+			//#nosec
+			rw.Write(b)
+			return
+		}
+
+		if next == nil {
+			rw.Header().Set("Content-Type", "application/json")
+			rw.WriteHeader(http.StatusNotFound)
+			return
+		}
+		next.ServeHTTP(rw, r)
+	})
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/middleware/untyped/api.go b/go/vendor/github.com/go-openapi/runtime/middleware/untyped/api.go
new file mode 100644
index 0000000..3b0cd4e
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/middleware/untyped/api.go
@@ -0,0 +1,286 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package untyped
+
+import (
+	"fmt"
+	"net/http"
+	"sort"
+	"strings"
+
+	"github.com/go-openapi/analysis"
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/loads"
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/strfmt"
+)
+
+// NewAPI creates the default untyped API
+func NewAPI(spec *loads.Document) *API {
+	var an *analysis.Spec
+	if spec != nil && spec.Spec() != nil {
+		an = analysis.New(spec.Spec())
+	}
+	api := &API{
+		spec:           spec,
+		analyzer:       an,
+		consumers:      make(map[string]runtime.Consumer, 10),
+		producers:      make(map[string]runtime.Producer, 10),
+		authenticators: make(map[string]runtime.Authenticator),
+		operations:     make(map[string]map[string]runtime.OperationHandler),
+		ServeError:     errors.ServeError,
+		Models:         make(map[string]func() interface{}),
+		formats:        strfmt.NewFormats(),
+	}
+	return api.WithJSONDefaults()
+}
+
+// API represents an untyped mux for a swagger spec
+type API struct {
+	spec            *loads.Document
+	analyzer        *analysis.Spec
+	DefaultProduces string
+	DefaultConsumes string
+	consumers       map[string]runtime.Consumer
+	producers       map[string]runtime.Producer
+	authenticators  map[string]runtime.Authenticator
+	authorizer      runtime.Authorizer
+	operations      map[string]map[string]runtime.OperationHandler
+	ServeError      func(http.ResponseWriter, *http.Request, error)
+	Models          map[string]func() interface{}
+	formats         strfmt.Registry
+}
+
+// WithJSONDefaults loads the json defaults for this api
+func (d *API) WithJSONDefaults() *API {
+	d.DefaultConsumes = runtime.JSONMime
+	d.DefaultProduces = runtime.JSONMime
+	d.consumers[runtime.JSONMime] = runtime.JSONConsumer()
+	d.producers[runtime.JSONMime] = runtime.JSONProducer()
+	return d
+}
+
+// WithoutJSONDefaults clears the json defaults for this api
+func (d *API) WithoutJSONDefaults() *API {
+	d.DefaultConsumes = ""
+	d.DefaultProduces = ""
+	delete(d.consumers, runtime.JSONMime)
+	delete(d.producers, runtime.JSONMime)
+	return d
+}
+
+// Formats returns the registered string formats
+func (d *API) Formats() strfmt.Registry {
+	if d.formats == nil {
+		d.formats = strfmt.NewFormats()
+	}
+	return d.formats
+}
+
+// RegisterFormat registers a custom format validator
+func (d *API) RegisterFormat(name string, format strfmt.Format, validator strfmt.Validator) {
+	if d.formats == nil {
+		d.formats = strfmt.NewFormats()
+	}
+	d.formats.Add(name, format, validator)
+}
+
+// RegisterAuth registers an auth handler in this api
+func (d *API) RegisterAuth(scheme string, handler runtime.Authenticator) {
+	if d.authenticators == nil {
+		d.authenticators = make(map[string]runtime.Authenticator)
+	}
+	d.authenticators[scheme] = handler
+}
+
+// RegisterAuthorizer registers an authorizer handler in this api
+func (d *API) RegisterAuthorizer(handler runtime.Authorizer) {
+	d.authorizer = handler
+}
+
+// RegisterConsumer registers a consumer for a media type.
+func (d *API) RegisterConsumer(mediaType string, handler runtime.Consumer) {
+	if d.consumers == nil {
+		d.consumers = make(map[string]runtime.Consumer, 10)
+	}
+	d.consumers[strings.ToLower(mediaType)] = handler
+}
+
+// RegisterProducer registers a producer for a media type
+func (d *API) RegisterProducer(mediaType string, handler runtime.Producer) {
+	if d.producers == nil {
+		d.producers = make(map[string]runtime.Producer, 10)
+	}
+	d.producers[strings.ToLower(mediaType)] = handler
+}
+
+// RegisterOperation registers an operation handler for an operation name
+func (d *API) RegisterOperation(method, path string, handler runtime.OperationHandler) {
+	if d.operations == nil {
+		d.operations = make(map[string]map[string]runtime.OperationHandler, 30)
+	}
+	um := strings.ToUpper(method)
+	if b, ok := d.operations[um]; !ok || b == nil {
+		d.operations[um] = make(map[string]runtime.OperationHandler)
+	}
+	d.operations[um][path] = handler
+}
+
+// OperationHandlerFor returns the operation handler for the specified id if it can be found
+func (d *API) OperationHandlerFor(method, path string) (runtime.OperationHandler, bool) {
+	if d.operations == nil {
+		return nil, false
+	}
+	if pi, ok := d.operations[strings.ToUpper(method)]; ok {
+		h, ok := pi[path]
+		return h, ok
+	}
+	return nil, false
+}
+
+// ConsumersFor gets the consumers for the specified media types
+func (d *API) ConsumersFor(mediaTypes []string) map[string]runtime.Consumer {
+	result := make(map[string]runtime.Consumer)
+	for _, mt := range mediaTypes {
+		if consumer, ok := d.consumers[mt]; ok {
+			result[mt] = consumer
+		}
+	}
+	return result
+}
+
+// ProducersFor gets the producers for the specified media types
+func (d *API) ProducersFor(mediaTypes []string) map[string]runtime.Producer {
+	result := make(map[string]runtime.Producer)
+	for _, mt := range mediaTypes {
+		if producer, ok := d.producers[mt]; ok {
+			result[mt] = producer
+		}
+	}
+	return result
+}
+
+// AuthenticatorsFor gets the authenticators for the specified security schemes
+func (d *API) AuthenticatorsFor(schemes map[string]spec.SecurityScheme) map[string]runtime.Authenticator {
+	result := make(map[string]runtime.Authenticator)
+	for k := range schemes {
+		if a, ok := d.authenticators[k]; ok {
+			result[k] = a
+		}
+	}
+	return result
+}
+
+// AuthorizersFor returns the registered authorizer
+func (d *API) Authorizer() runtime.Authorizer {
+	return d.authorizer
+}
+
+// Validate validates this API for any missing items
+func (d *API) Validate() error {
+	return d.validate()
+}
+
+// validateWith validates the registrations in this API against the provided spec analyzer
+func (d *API) validate() error {
+	var consumes []string
+	for k := range d.consumers {
+		consumes = append(consumes, k)
+	}
+
+	var produces []string
+	for k := range d.producers {
+		produces = append(produces, k)
+	}
+
+	var authenticators []string
+	for k := range d.authenticators {
+		authenticators = append(authenticators, k)
+	}
+
+	var operations []string
+	for m, v := range d.operations {
+		for p := range v {
+			operations = append(operations, fmt.Sprintf("%s %s", strings.ToUpper(m), p))
+		}
+	}
+
+	var definedAuths []string
+	for k := range d.spec.Spec().SecurityDefinitions {
+		definedAuths = append(definedAuths, k)
+	}
+
+	if err := d.verify("consumes", consumes, d.analyzer.RequiredConsumes()); err != nil {
+		return err
+	}
+	if err := d.verify("produces", produces, d.analyzer.RequiredProduces()); err != nil {
+		return err
+	}
+	if err := d.verify("operation", operations, d.analyzer.OperationMethodPaths()); err != nil {
+		return err
+	}
+
+	requiredAuths := d.analyzer.RequiredSecuritySchemes()
+	if err := d.verify("auth scheme", authenticators, requiredAuths); err != nil {
+		return err
+	}
+	if err := d.verify("security definitions", definedAuths, requiredAuths); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d *API) verify(name string, registrations []string, expectations []string) error {
+
+	sort.Sort(sort.StringSlice(registrations))
+	sort.Sort(sort.StringSlice(expectations))
+
+	expected := map[string]struct{}{}
+	seen := map[string]struct{}{}
+
+	for _, v := range expectations {
+		expected[v] = struct{}{}
+	}
+
+	var unspecified []string
+	for _, v := range registrations {
+		seen[v] = struct{}{}
+		if _, ok := expected[v]; !ok {
+			unspecified = append(unspecified, v)
+		}
+	}
+
+	for k := range seen {
+		delete(expected, k)
+	}
+
+	var unregistered []string
+	for k := range expected {
+		unregistered = append(unregistered, k)
+	}
+	sort.Sort(sort.StringSlice(unspecified))
+	sort.Sort(sort.StringSlice(unregistered))
+
+	if len(unregistered) > 0 || len(unspecified) > 0 {
+		return &errors.APIVerificationFailed{
+			Section:              name,
+			MissingSpecification: unspecified,
+			MissingRegistration:  unregistered,
+		}
+	}
+
+	return nil
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/middleware/validation.go b/go/vendor/github.com/go-openapi/runtime/middleware/validation.go
new file mode 100644
index 0000000..bb8df3c
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/middleware/validation.go
@@ -0,0 +1,122 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package middleware
+
+import (
+	"mime"
+	"net/http"
+	"strings"
+
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/swag"
+)
+
+type validation struct {
+	context *Context
+	result  []error
+	request *http.Request
+	route   *MatchedRoute
+	bound   map[string]interface{}
+}
+
+// ContentType validates the content type of a request
+func validateContentType(allowed []string, actual string) error {
+	debugLog("validating content type for %q against [%s]", actual, strings.Join(allowed, ", "))
+	if len(allowed) == 0 {
+		return nil
+	}
+	mt, _, err := mime.ParseMediaType(actual)
+	if err != nil {
+		return errors.InvalidContentType(actual, allowed)
+	}
+	if swag.ContainsStringsCI(allowed, mt) {
+		return nil
+	}
+	if swag.ContainsStringsCI(allowed, "*/*") {
+		return nil
+	}
+	parts := strings.Split(actual, "/")
+	if len(parts) == 2 && swag.ContainsStringsCI(allowed, parts[0]+"/*") {
+		return nil
+	}
+	return errors.InvalidContentType(actual, allowed)
+}
+
+func validateRequest(ctx *Context, request *http.Request, route *MatchedRoute) *validation {
+	debugLog("validating request %s %s", request.Method, request.URL.EscapedPath())
+	validate := &validation{
+		context: ctx,
+		request: request,
+		route:   route,
+		bound:   make(map[string]interface{}),
+	}
+
+	validate.contentType()
+	if len(validate.result) == 0 {
+		validate.responseFormat()
+	}
+	if len(validate.result) == 0 {
+		validate.parameters()
+	}
+
+	return validate
+}
+
+func (v *validation) parameters() {
+	debugLog("validating request parameters for %s %s", v.request.Method, v.request.URL.EscapedPath())
+	if result := v.route.Binder.Bind(v.request, v.route.Params, v.route.Consumer, v.bound); result != nil {
+		if result.Error() == "validation failure list" {
+			for _, e := range result.(*errors.Validation).Value.([]interface{}) {
+				v.result = append(v.result, e.(error))
+			}
+			return
+		}
+		v.result = append(v.result, result)
+	}
+}
+
+func (v *validation) contentType() {
+	if len(v.result) == 0 && runtime.HasBody(v.request) {
+		debugLog("validating body content type for %s %s", v.request.Method, v.request.URL.EscapedPath())
+		ct, _, req, err := v.context.ContentType(v.request)
+		if err != nil {
+			v.result = append(v.result, err)
+		} else {
+			v.request = req
+		}
+
+		if len(v.result) == 0 {
+			if err := validateContentType(v.route.Consumes, ct); err != nil {
+				v.result = append(v.result, err)
+			}
+		}
+		if ct != "" && v.route.Consumer == nil {
+			cons, ok := v.route.Consumers[ct]
+			if !ok {
+				v.result = append(v.result, errors.New(500, "no consumer registered for %s", ct))
+			} else {
+				v.route.Consumer = cons
+			}
+		}
+	}
+}
+
+func (v *validation) responseFormat() {
+	if str, rCtx := v.context.ResponseFormat(v.request, v.route.Produces); str == "" && runtime.HasBody(v.request) {
+		v.request = rCtx
+		v.result = append(v.result, errors.InvalidResponseFormat(v.request.Header.Get(runtime.HeaderAccept), v.route.Produces))
+	}
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/request.go b/go/vendor/github.com/go-openapi/runtime/request.go
new file mode 100644
index 0000000..87b73da
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/request.go
@@ -0,0 +1,77 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package runtime
+
+import (
+	"io"
+	"net/http"
+	"strings"
+
+	"github.com/go-openapi/swag"
+)
+
+// CanHaveBody returns true if this method can have a body
+func CanHaveBody(method string) bool {
+	mn := strings.ToUpper(method)
+	return mn == "POST" || mn == "PUT" || mn == "PATCH" || mn == "DELETE"
+}
+
+// IsSafe returns true if this is a request with a safe method
+func IsSafe(r *http.Request) bool {
+	mn := strings.ToUpper(r.Method)
+	return mn == "GET" || mn == "HEAD"
+}
+
+// AllowsBody returns true if the request allows for a body
+func AllowsBody(r *http.Request) bool {
+	mn := strings.ToUpper(r.Method)
+	return mn != "HEAD"
+}
+
+// HasBody returns true if this method needs a content-type
+func HasBody(r *http.Request) bool {
+	return len(r.TransferEncoding) > 0 || r.ContentLength > 0
+}
+
+// JSONRequest creates a new http request with json headers set
+func JSONRequest(method, urlStr string, body io.Reader) (*http.Request, error) {
+	req, err := http.NewRequest(method, urlStr, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header.Add(HeaderContentType, JSONMime)
+	req.Header.Add(HeaderAccept, JSONMime)
+	return req, nil
+}
+
+// Gettable for things with a method GetOK(string) (data string, hasKey bool, hasValue bool)
+type Gettable interface {
+	GetOK(string) ([]string, bool, bool)
+}
+
+// ReadSingleValue reads a single value from the source
+func ReadSingleValue(values Gettable, name string) string {
+	vv, _, hv := values.GetOK(name)
+	if hv {
+		return vv[len(vv)-1]
+	}
+	return ""
+}
+
+// ReadCollectionValue reads a collection value from a string data source
+func ReadCollectionValue(values Gettable, name, collectionFormat string) []string {
+	v := ReadSingleValue(values, name)
+	return swag.SplitByFormat(v, collectionFormat)
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/security/authenticator.go b/go/vendor/github.com/go-openapi/runtime/security/authenticator.go
new file mode 100644
index 0000000..3c624d7
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/security/authenticator.go
@@ -0,0 +1,215 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package security
+
+import (
+	"context"
+	"net/http"
+	"strings"
+
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/runtime"
+)
+
+const (
+	query  = "query"
+	header = "header"
+)
+
+// HttpAuthenticator is a function that authenticates a HTTP request
+func HttpAuthenticator(handler func(*http.Request) (bool, interface{}, error)) runtime.Authenticator {
+	return runtime.AuthenticatorFunc(func(params interface{}) (bool, interface{}, error) {
+		if request, ok := params.(*http.Request); ok {
+			return handler(request)
+		}
+		if scoped, ok := params.(*ScopedAuthRequest); ok {
+			return handler(scoped.Request)
+		}
+		return false, nil, nil
+	})
+}
+
+// ScopedAuthenticator is a function that authenticates a HTTP request against a list of valid scopes
+func ScopedAuthenticator(handler func(*ScopedAuthRequest) (bool, interface{}, error)) runtime.Authenticator {
+	return runtime.AuthenticatorFunc(func(params interface{}) (bool, interface{}, error) {
+		if request, ok := params.(*ScopedAuthRequest); ok {
+			return handler(request)
+		}
+		return false, nil, nil
+	})
+}
+
+// UserPassAuthentication authentication function
+type UserPassAuthentication func(string, string) (interface{}, error)
+
+// UserPassAuthenticationCtx authentication function with context.Context
+type UserPassAuthenticationCtx func(context.Context, string, string) (context.Context, interface{}, error)
+
+// TokenAuthentication authentication function
+type TokenAuthentication func(string) (interface{}, error)
+
+// TokenAuthenticationCtx authentication function with context.Context
+type TokenAuthenticationCtx func(context.Context, string) (context.Context, interface{}, error)
+
+// ScopedTokenAuthentication authentication function
+type ScopedTokenAuthentication func(string, []string) (interface{}, error)
+
+// ScopedTokenAuthenticationCtx authentication function with context.Context
+type ScopedTokenAuthenticationCtx func(context.Context, string, []string) (context.Context, interface{}, error)
+
+// BasicAuth creates a basic auth authenticator with the provided authentication function
+func BasicAuth(authenticate UserPassAuthentication) runtime.Authenticator {
+	return HttpAuthenticator(func(r *http.Request) (bool, interface{}, error) {
+		if usr, pass, ok := r.BasicAuth(); ok {
+			p, err := authenticate(usr, pass)
+			return true, p, err
+		}
+
+		return false, nil, nil
+	})
+}
+
+// BasicAuthCtx creates a basic auth authenticator with the provided authentication function with support for context.Context
+func BasicAuthCtx(authenticate UserPassAuthenticationCtx) runtime.Authenticator {
+	return HttpAuthenticator(func(r *http.Request) (bool, interface{}, error) {
+		if usr, pass, ok := r.BasicAuth(); ok {
+			ctx, p, err := authenticate(r.Context(), usr, pass)
+			*r = *r.WithContext(ctx)
+			return true, p, err
+		}
+
+		return false, nil, nil
+	})
+}
+
+// APIKeyAuth creates an authenticator that uses a token for authorization.
+// This token can be obtained from either a header or a query string
+func APIKeyAuth(name, in string, authenticate TokenAuthentication) runtime.Authenticator {
+	inl := strings.ToLower(in)
+	if inl != query && inl != header {
+		// panic because this is most likely a typo
+		panic(errors.New(500, "api key auth: in value needs to be either \"query\" or \"header\"."))
+	}
+
+	var getToken func(*http.Request) string
+	switch inl {
+	case header:
+		getToken = func(r *http.Request) string { return r.Header.Get(name) }
+	case query:
+		getToken = func(r *http.Request) string { return r.URL.Query().Get(name) }
+	}
+
+	return HttpAuthenticator(func(r *http.Request) (bool, interface{}, error) {
+		token := getToken(r)
+		if token == "" {
+			return false, nil, nil
+		}
+
+		p, err := authenticate(token)
+		return true, p, err
+	})
+}
+
+// APIKeyAuthCtx creates an authenticator that uses a token for authorization with support for context.Context.
+// This token can be obtained from either a header or a query string
+func APIKeyAuthCtx(name, in string, authenticate TokenAuthenticationCtx) runtime.Authenticator {
+	inl := strings.ToLower(in)
+	if inl != query && inl != header {
+		// panic because this is most likely a typo
+		panic(errors.New(500, "api key auth: in value needs to be either \"query\" or \"header\"."))
+	}
+
+	var getToken func(*http.Request) string
+	switch inl {
+	case header:
+		getToken = func(r *http.Request) string { return r.Header.Get(name) }
+	case query:
+		getToken = func(r *http.Request) string { return r.URL.Query().Get(name) }
+	}
+
+	return HttpAuthenticator(func(r *http.Request) (bool, interface{}, error) {
+		token := getToken(r)
+		if token == "" {
+			return false, nil, nil
+		}
+
+		ctx, p, err := authenticate(r.Context(), token)
+		*r = *r.WithContext(ctx)
+		return true, p, err
+	})
+}
+
+// ScopedAuthRequest contains both a http request and the required scopes for a particular operation
+type ScopedAuthRequest struct {
+	Request        *http.Request
+	RequiredScopes []string
+}
+
+// BearerAuth for use with oauth2 flows
+func BearerAuth(name string, authenticate ScopedTokenAuthentication) runtime.Authenticator {
+	const prefix = "Bearer "
+	return ScopedAuthenticator(func(r *ScopedAuthRequest) (bool, interface{}, error) {
+		var token string
+		hdr := r.Request.Header.Get("Authorization")
+		if strings.HasPrefix(hdr, prefix) {
+			token = strings.TrimPrefix(hdr, prefix)
+		}
+		if token == "" {
+			qs := r.Request.URL.Query()
+			token = qs.Get("access_token")
+		}
+		//#nosec
+		ct, _, _ := runtime.ContentType(r.Request.Header)
+		if token == "" && (ct == "application/x-www-form-urlencoded" || ct == "multipart/form-data") {
+			token = r.Request.FormValue("access_token")
+		}
+
+		if token == "" {
+			return false, nil, nil
+		}
+
+		p, err := authenticate(token, r.RequiredScopes)
+		return true, p, err
+	})
+}
+
+// BearerAuthCtx for use with oauth2 flows with support for context.Context.
+func BearerAuthCtx(name string, authenticate ScopedTokenAuthenticationCtx) runtime.Authenticator {
+	const prefix = "Bearer "
+	return ScopedAuthenticator(func(r *ScopedAuthRequest) (bool, interface{}, error) {
+		var token string
+		hdr := r.Request.Header.Get("Authorization")
+		if strings.HasPrefix(hdr, prefix) {
+			token = strings.TrimPrefix(hdr, prefix)
+		}
+		if token == "" {
+			qs := r.Request.URL.Query()
+			token = qs.Get("access_token")
+		}
+		//#nosec
+		ct, _, _ := runtime.ContentType(r.Request.Header)
+		if token == "" && (ct == "application/x-www-form-urlencoded" || ct == "multipart/form-data") {
+			token = r.Request.FormValue("access_token")
+		}
+
+		if token == "" {
+			return false, nil, nil
+		}
+
+		ctx, p, err := authenticate(r.Request.Context(), token, r.RequiredScopes)
+		*r.Request = *r.Request.WithContext(ctx)
+		return true, p, err
+	})
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/security/authorizer.go b/go/vendor/github.com/go-openapi/runtime/security/authorizer.go
new file mode 100644
index 0000000..00c1a4d
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/security/authorizer.go
@@ -0,0 +1,27 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package security
+
+import (
+	"net/http"
+
+	"github.com/go-openapi/runtime"
+)
+
+// Authorized provides a default implementation of the Authorizer interface where all
+// requests are authorized (successful)
+func Authorized() runtime.Authorizer {
+	return runtime.AuthorizerFunc(func(_ *http.Request, _ interface{}) error { return nil })
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/statuses.go b/go/vendor/github.com/go-openapi/runtime/statuses.go
new file mode 100644
index 0000000..3b011a0
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/statuses.go
@@ -0,0 +1,90 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package runtime
+
+// Statuses lists the most common HTTP status codes to default message
+// taken from https://httpstatuses.com/
+var Statuses = map[int]string{
+	100: "Continue",
+	101: "Switching Protocols",
+	102: "Processing",
+	103: "Checkpoint",
+	122: "URI too long",
+	200: "OK",
+	201: "Created",
+	202: "Accepted",
+	203: "Request Processed",
+	204: "No Content",
+	205: "Reset Content",
+	206: "Partial Content",
+	207: "Multi-Status",
+	208: "Already Reported",
+	226: "IM Used",
+	300: "Multiple Choices",
+	301: "Moved Permanently",
+	302: "Found",
+	303: "See Other",
+	304: "Not Modified",
+	305: "Use Proxy",
+	306: "Switch Proxy",
+	307: "Temporary Redirect",
+	308: "Permanent Redirect",
+	400: "Bad Request",
+	401: "Unauthorized",
+	402: "Payment Required",
+	403: "Forbidden",
+	404: "Not Found",
+	405: "Method Not Allowed",
+	406: "Not Acceptable",
+	407: "Proxy Authentication Required",
+	408: "Request Timeout",
+	409: "Conflict",
+	410: "Gone",
+	411: "Length Required",
+	412: "Precondition Failed",
+	413: "Request Entity Too Large",
+	414: "Request-URI Too Long",
+	415: "Unsupported Media Type",
+	416: "Request Range Not Satisfiable",
+	417: "Expectation Failed",
+	418: "I'm a teapot",
+	420: "Enhance Your Calm",
+	422: "Unprocessable Entity",
+	423: "Locked",
+	424: "Failed Dependency",
+	426: "Upgrade Required",
+	428: "Precondition Required",
+	429: "Too Many Requests",
+	431: "Request Header Fields Too Large",
+	444: "No Response",
+	449: "Retry With",
+	450: "Blocked by Windows Parental Controls",
+	451: "Wrong Exchange Server",
+	499: "Client Closed Request",
+	500: "Internal Server Error",
+	501: "Not Implemented",
+	502: "Bad Gateway",
+	503: "Service Unavailable",
+	504: "Gateway Timeout",
+	505: "HTTP Version Not Supported",
+	506: "Variant Also Negotiates",
+	507: "Insufficient Storage",
+	508: "Loop Detected",
+	509: "Bandwidth Limit Exceeded",
+	510: "Not Extended",
+	511: "Network Authentication Required",
+	598: "Network read timeout error",
+	599: "Network connect timeout error",
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/text.go b/go/vendor/github.com/go-openapi/runtime/text.go
new file mode 100644
index 0000000..77099fe
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/text.go
@@ -0,0 +1,111 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package runtime
+
+import (
+	"bytes"
+	"encoding"
+	"errors"
+	"fmt"
+	"io"
+	"reflect"
+
+	"github.com/go-openapi/swag"
+)
+
+// TextConsumer creates a new text consumer
+func TextConsumer() Consumer {
+	return ConsumerFunc(func(reader io.Reader, data interface{}) error {
+		if reader == nil {
+			return errors.New("TextConsumer requires a reader") // early exit
+		}
+
+		buf := new(bytes.Buffer)
+		_, err := buf.ReadFrom(reader)
+		if err != nil {
+			return err
+		}
+		b := buf.Bytes()
+
+		if tu, ok := data.(encoding.TextUnmarshaler); ok {
+			err := tu.UnmarshalText(b)
+			if err != nil {
+				return fmt.Errorf("text consumer: %v", err)
+			}
+
+			return nil
+		}
+
+		t := reflect.TypeOf(data)
+		if data != nil && t.Kind() == reflect.Ptr {
+			v := reflect.Indirect(reflect.ValueOf(data))
+			if t.Elem().Kind() == reflect.String {
+				v.SetString(string(b))
+				return nil
+			}
+		}
+
+		return fmt.Errorf("%v (%T) is not supported by the TextConsumer, %s",
+			data, data, "can be resolved by supporting TextUnmarshaler interface")
+	})
+}
+
+// TextProducer creates a new text producer
+func TextProducer() Producer {
+	return ProducerFunc(func(writer io.Writer, data interface{}) error {
+		if writer == nil {
+			return errors.New("TextProducer requires a writer") // early exit
+		}
+
+		if data == nil {
+			return errors.New("no data given to produce text from")
+		}
+
+		if tm, ok := data.(encoding.TextMarshaler); ok {
+			txt, err := tm.MarshalText()
+			if err != nil {
+				return fmt.Errorf("text producer: %v", err)
+			}
+			_, err = writer.Write(txt)
+			return err
+		}
+
+		if str, ok := data.(error); ok {
+			_, err := writer.Write([]byte(str.Error()))
+			return err
+		}
+
+		if str, ok := data.(fmt.Stringer); ok {
+			_, err := writer.Write([]byte(str.String()))
+			return err
+		}
+
+		v := reflect.Indirect(reflect.ValueOf(data))
+		if t := v.Type(); t.Kind() == reflect.Struct || t.Kind() == reflect.Slice {
+			b, err := swag.WriteJSON(data)
+			if err != nil {
+				return err
+			}
+			_, err = writer.Write(b)
+			return err
+		}
+		if v.Kind() != reflect.String {
+			return fmt.Errorf("%T is not a supported type by the TextProducer", data)
+		}
+
+		_, err := writer.Write([]byte(v.String()))
+		return err
+	})
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/values.go b/go/vendor/github.com/go-openapi/runtime/values.go
new file mode 100644
index 0000000..11f5732
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/values.go
@@ -0,0 +1,19 @@
+package runtime
+
+// Values typically represent parameters on a http request.
+type Values map[string][]string
+
+// GetOK returns the values collection for the given key.
+// When the key is present in the map it will return true for hasKey.
+// When the value is not empty it will return true for hasValue.
+func (v Values) GetOK(key string) (value []string, hasKey bool, hasValue bool) {
+	value, hasKey = v[key]
+	if !hasKey {
+		return
+	}
+	if len(value) == 0 {
+		return
+	}
+	hasValue = true
+	return
+}
diff --git a/go/vendor/github.com/go-openapi/runtime/xml.go b/go/vendor/github.com/go-openapi/runtime/xml.go
new file mode 100644
index 0000000..821c739
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/xml.go
@@ -0,0 +1,36 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package runtime
+
+import (
+	"encoding/xml"
+	"io"
+)
+
+// XMLConsumer creates a new XML consumer
+func XMLConsumer() Consumer {
+	return ConsumerFunc(func(reader io.Reader, data interface{}) error {
+		dec := xml.NewDecoder(reader)
+		return dec.Decode(data)
+	})
+}
+
+// XMLProducer creates a new XML producer
+func XMLProducer() Producer {
+	return ProducerFunc(func(writer io.Writer, data interface{}) error {
+		enc := xml.NewEncoder(writer)
+		return enc.Encode(data)
+	})
+}
diff --git a/go/vendor/github.com/go-openapi/spec/.editorconfig b/go/vendor/github.com/go-openapi/spec/.editorconfig
new file mode 100644
index 0000000..3152da6
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/.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/spec/.gitignore b/go/vendor/github.com/go-openapi/spec/.gitignore
new file mode 100644
index 0000000..dd91ed6
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/.gitignore
@@ -0,0 +1,2 @@
+secrets.yml
+coverage.out
diff --git a/go/vendor/github.com/go-openapi/spec/.golangci.yml b/go/vendor/github.com/go-openapi/spec/.golangci.yml
new file mode 100644
index 0000000..ed53e5c
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/.golangci.yml
@@ -0,0 +1,21 @@
+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
+    - unparam
+    - lll
diff --git a/go/vendor/github.com/go-openapi/spec/.travis.yml b/go/vendor/github.com/go-openapi/spec/.travis.yml
new file mode 100644
index 0000000..a4f0348
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/.travis.yml
@@ -0,0 +1,18 @@
+after_success:
+- bash <(curl -s https://codecov.io/bash)
+go:
+- '1.9'
+- 1.10.x
+- 1.11.x
+install:
+- go get -u github.com/stretchr/testify
+- go get -u github.com/go-openapi/swag
+- go get -u gopkg.in/yaml.v2
+- go get -u github.com/go-openapi/jsonpointer
+- go get -u github.com/go-openapi/jsonreference
+language: go
+notifications:
+  slack:
+    secure: QUWvCkBBK09GF7YtEvHHVt70JOkdlNBG0nIKu/5qc4/nW5HP8I2w0SEf/XR2je0eED1Qe3L/AfMCWwrEj+IUZc3l4v+ju8X8R3Lomhme0Eb0jd1MTMCuPcBT47YCj0M7RON7vXtbFfm1hFJ/jLe5+9FXz0hpXsR24PJc5ZIi/ogNwkaPqG4BmndzecpSh0vc2FJPZUD9LT0I09REY/vXR0oQAalLkW0asGD5taHZTUZq/kBpsNxaAFrLM23i4mUcf33M5fjLpvx5LRICrX/57XpBrDh2TooBU6Qj3CgoY0uPRYUmSNxbVx1czNzl2JtEpb5yjoxfVPQeg0BvQM00G8LJINISR+ohrjhkZmAqchDupAX+yFrxTtORa78CtnIL6z/aTNlgwwVD8kvL/1pFA/JWYmKDmz93mV/+6wubGzNSQCstzjkFA4/iZEKewKUoRIAi/fxyscP6L/rCpmY/4llZZvrnyTqVbt6URWpopUpH4rwYqreXAtJxJsfBJIeSmUIiDIOMGkCTvyTEW3fWGmGoqWtSHLoaWDyAIGb7azb+KvfpWtEcoPFWfSWU+LGee0A/YsUhBl7ADB9A0CJEuR8q4BPpKpfLwPKSiKSAXL7zDkyjExyhtgqbSl2jS+rKIHOZNL8JkCcTP2MKMVd563C5rC5FMKqu3S9m2b6380E=
+script:
+- go test -v -race -cover -coverprofile=coverage.txt -covermode=atomic ./...
diff --git a/go/vendor/github.com/go-openapi/spec/CODE_OF_CONDUCT.md b/go/vendor/github.com/go-openapi/spec/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..9322b06
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/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/spec/LICENSE b/go/vendor/github.com/go-openapi/spec/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/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/spec/README.md b/go/vendor/github.com/go-openapi/spec/README.md
new file mode 100644
index 0000000..6354742
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/README.md
@@ -0,0 +1,10 @@
+# OAI object model [![Build Status](https://travis-ci.org/go-openapi/spec.svg?branch=master)](https://travis-ci.org/go-openapi/spec) [![codecov](https://codecov.io/gh/go-openapi/spec/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/spec) [![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/spec/master/LICENSE)
+[![GoDoc](https://godoc.org/github.com/go-openapi/spec?status.svg)](http://godoc.org/github.com/go-openapi/spec)
+[![GolangCI](https://golangci.com/badges/github.com/go-openapi/spec.svg)](https://golangci.com)
+[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/spec)](https://goreportcard.com/report/github.com/go-openapi/spec)
+
+The object model for OpenAPI specification documents.
+
+Currently supports Swagger 2.0.
diff --git a/go/vendor/github.com/go-openapi/spec/bindata.go b/go/vendor/github.com/go-openapi/spec/bindata.go
new file mode 100644
index 0000000..1717ea1
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/bindata.go
@@ -0,0 +1,260 @@
+// Code generated by go-bindata.
+// sources:
+// schemas/jsonschema-draft-04.json
+// schemas/v2/schema.json
+// DO NOT EDIT!
+
+package spec
+
+import (
+	"bytes"
+	"compress/gzip"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"strings"
+	"time"
+)
+
+func bindataRead(data []byte, name string) ([]byte, error) {
+	gz, err := gzip.NewReader(bytes.NewBuffer(data))
+	if err != nil {
+		return nil, fmt.Errorf("Read %q: %v", name, err)
+	}
+
+	var buf bytes.Buffer
+	_, err = io.Copy(&buf, gz)
+	clErr := gz.Close()
+
+	if err != nil {
+		return nil, fmt.Errorf("Read %q: %v", name, err)
+	}
+	if clErr != nil {
+		return nil, err
+	}
+
+	return buf.Bytes(), nil
+}
+
+type asset struct {
+	bytes []byte
+	info  os.FileInfo
+}
+
+type bindataFileInfo struct {
+	name    string
+	size    int64
+	mode    os.FileMode
+	modTime time.Time
+}
+
+func (fi bindataFileInfo) Name() string {
+	return fi.name
+}
+func (fi bindataFileInfo) Size() int64 {
+	return fi.size
+}
+func (fi bindataFileInfo) Mode() os.FileMode {
+	return fi.mode
+}
+func (fi bindataFileInfo) ModTime() time.Time {
+	return fi.modTime
+}
+func (fi bindataFileInfo) IsDir() bool {
+	return false
+}
+func (fi bindataFileInfo) Sys() interface{} {
+	return nil
+}
+
+var _jsonschemaDraft04JSON = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x57\x3d\x6f\xdb\x3c\x10\xde\xf3\x2b\x08\x26\x63\xf2\x2a\x2f\xd0\xc9\x5b\xd1\x2e\x01\x5a\x34\x43\x37\x23\x03\x6d\x9d\x6c\x06\x14\xa9\x50\x54\x60\xc3\xd0\x7f\x2f\x28\x4a\x14\x29\x91\x92\x2d\xa7\x8d\x97\x28\xbc\xaf\xe7\x8e\xf7\xc5\xd3\x0d\x42\x08\x61\x9a\xe2\x15\xc2\x7b\xa5\x8a\x55\x92\xbc\x96\x82\x3f\x94\xdb\x3d\xe4\xe4\x3f\x21\x77\x49\x2a\x49\xa6\x1e\x1e\xbf\x24\xe6\xec\x16\xdf\x1b\xa1\x3b\xf3\xff\x02\xc9\x14\xca\xad\xa4\x85\xa2\x82\x6b\xe9\x6f\x42\x02\x32\x2c\x28\x07\x45\x5a\x15\x3d\x77\x46\x39\xd5\xcc\x25\x5e\x21\x83\xb8\x21\x18\xb6\xaf\x52\x92\xa3\x47\x68\x88\xea\x58\x80\x56\x4e\x1a\xf2\xbd\x4f\xcc\x29\x7f\x52\x90\x6b\x7d\xff\x0f\x48\xb4\x3d\x3f\x21\x7c\x27\x21\xd3\x2a\x6e\x31\xaa\x2d\x53\xdd\xf3\xe3\x42\x94\x54\xd1\x77\x78\xe2\x0a\x76\x20\xe3\x20\x68\xcb\x30\x86\x41\xf3\x2a\xc7\x2b\xf4\x78\x8e\xfe\xef\x90\x91\x8a\xa9\xc7\xb1\x1d\xc2\xd8\x2f\x0d\x75\xed\xc1\x4e\x9c\xc8\x25\x43\xac\xa8\xbe\xd7\xcc\xa9\xd1\xa9\x21\xa0\x1a\xbd\x04\x61\x94\x34\x2f\x18\xfc\x3e\x16\x50\x8e\x4d\x03\x6f\x1c\x58\xdb\x48\x23\xbc\x11\x82\x01\xe1\xfa\xd3\x3a\x8e\x30\xaf\x18\x33\x7f\xf3\x8d\x39\x11\x9b\x57\xd8\x2a\xfd\x55\x2a\x49\xf9\x0e\xc7\xec\x37\xd4\x25\xf7\xec\x5c\x66\xc7\xd7\x99\xaa\xcf\x4f\x89\x8a\xd3\xb7\x0a\x3a\xaa\x92\x15\xf4\x30\x6f\x1c\xb0\xd6\x46\xe7\x98\x39\x2d\xa4\x28\x40\x2a\x3a\x88\x9e\x29\xba\x88\x37\x2d\xca\x60\x38\xfa\xba\x5b\x20\xac\xa8\x62\xb0\x4c\xd4\xaf\xda\x45\x0a\xba\x5c\x3b\xb9\xc7\x79\xc5\x14\x2d\x18\x34\x19\x1c\x51\xdb\x25\x4d\xb4\x7e\x06\x14\x38\x6c\x59\x55\xd2\x77\xf8\x69\x59\xfc\x7b\x73\xed\x93\x43\xcb\x32\x6d\x3c\x28\xdc\x1b\x9a\xd3\x62\xab\xc2\x27\xf7\x41\xc9\x08\x2b\x23\x08\xad\x13\x57\x21\x9c\xd3\x72\x0d\x42\x72\xf8\x01\x7c\xa7\xf6\x83\xce\x39\xd7\x82\x3c\x1f\x2f\xd6\x60\x1b\xa2\xdf\x35\x89\x52\x20\xe7\x73\x74\xe0\x66\x26\x64\x4e\xb4\x97\x58\xc2\x0e\x0e\xe1\x60\x92\x34\x6d\xa0\x10\xd6\xb5\x83\x61\x27\xe6\x47\xd3\x89\xbd\x63\xfd\x3b\x8d\x03\x3d\x6c\x42\x2d\x5b\x70\xee\xe8\xdf\x4b\xf4\x66\x4e\xe1\x01\x45\x17\x80\x74\xad\x4f\xc3\xf3\xae\xc6\x1d\xc6\xd7\xc2\xce\xc9\xe1\x29\x30\x86\x2f\x4a\xa6\x4b\x15\x84\x73\xc9\x6f\xfd\x7f\xa5\x6e\x9e\xbd\xf1\xb0\xd4\xdd\x45\x5a\xc2\x3e\x4b\x78\xab\xa8\x84\x74\x4a\x91\x3b\x92\x23\x05\xf2\x1c\x1e\x7b\xf3\x09\xf8\xcf\xab\x24\xb6\x60\xa2\xe8\x4c\x9f\x75\x77\xaa\x8c\xe6\x01\x45\x36\x86\xcf\xc3\x63\x3a\xea\xd4\x8d\x7e\x06\xac\x14\x0a\xe0\x29\xf0\xed\x07\x22\x1a\x65\xda\x44\xae\xa2\x73\x1a\xe6\x90\x69\xa2\x8c\x46\xb2\x2f\xde\x49\x38\x08\xed\xfe\xfd\x41\xaf\x9f\xa9\x55\xd7\xdd\x22\x8d\xfa\x45\x63\xc5\x0f\x80\xf3\xb4\x08\xd6\x79\x30\x9e\x93\xee\x59\xa6\xd0\x4b\xee\x22\xe3\x33\xc1\x3a\x27\x68\x36\x78\x7e\x87\x0a\x06\xd5\x2e\x20\xd3\xaf\x15\xfb\xd8\x3b\x73\x14\xbb\x92\xed\x05\x5d\x2e\x29\x38\x2c\x94\xe4\x42\x45\x5e\xd3\xb5\x7d\xdf\x47\xca\x38\xb4\x5c\xaf\xfb\x7d\xdd\x6d\xf4\xa1\x2d\x77\xdd\x2f\xce\x6d\xc4\x7b\x8b\x4e\x67\xa9\x6f\xfe\x04\x00\x00\xff\xff\xb1\xd1\x27\x78\x05\x11\x00\x00")
+
+func jsonschemaDraft04JSONBytes() ([]byte, error) {
+	return bindataRead(
+		_jsonschemaDraft04JSON,
+		"jsonschema-draft-04.json",
+	)
+}
+
+func jsonschemaDraft04JSON() (*asset, error) {
+	bytes, err := jsonschemaDraft04JSONBytes()
+	if err != nil {
+		return nil, err
+	}
+
+	info := bindataFileInfo{name: "jsonschema-draft-04.json", size: 4357, mode: os.FileMode(420), modTime: time.Unix(1523760398, 0)}
+	a := &asset{bytes: bytes, info: info}
+	return a, nil
+}
+
+var _v2SchemaJSON = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5d\x4f\x93\xdb\x36\xb2\xbf\xfb\x53\xa0\x14\x57\xd9\xae\xd8\x92\xe3\xf7\x2e\xcf\x97\xd4\xbc\xd8\x49\x66\x37\x5e\x4f\x79\x26\xbb\x87\x78\x5c\x05\x91\x2d\x09\x09\x09\x30\x00\x38\x33\x5a\xef\x7c\xf7\x2d\xf0\x9f\x08\x02\x20\x41\x8a\xd2\xc8\x0e\x0f\xa9\x78\x28\xa0\xd1\xdd\x68\x34\x7e\xdd\xf8\xf7\xf9\x11\x42\x33\x49\x64\x04\xb3\xd7\x68\x76\x86\xfe\x76\xf9\xfe\x1f\xe8\x32\xd8\x40\x8c\xd1\x8a\x71\x74\x79\x8b\xd7\x6b\xe0\xe8\xd5\xfc\x25\x3a\xbb\x38\x9f\xcf\x9e\xab\x0a\x24\x54\xa5\x37\x52\x26\xaf\x17\x0b\x91\x17\x99\x13\xb6\xb8\x79\xb5\x10\x59\xdd\xf9\xef\x82\xd1\x6f\xf2\xc2\x8f\xf3\x4f\xb5\x1a\xea\xc7\x17\x45\x41\xc6\xd7\x8b\x90\xe3\x95\x7c\xf1\xf2\x7f\x8b\xca\x45\x3d\xb9\x4d\x32\xa6\xd8\xf2\x77\x08\x64\xfe\x8d\xc3\x9f\x29\xe1\xa0\x9a\xff\xed\x11\x42\x08\xcd\x8a\xd6\xb3\x9f\x15\x67\x74\xc5\xca\x7f\x27\x58\x6e\xc4\xec\x11\x42\xd7\x59\x5d\x1c\x86\x44\x12\x46\x71\x74\xc1\x59\x02\x5c\x12\x10\xb3\xd7\x68\x85\x23\x01\x59\x81\x04\x4b\x09\x9c\x6a\xbf\x7e\xce\x49\x7d\xba\x7b\x51\xfd\xa1\x44\xe2\xb0\x52\xac\x7d\xb3\x08\x61\x45\x68\x46\x56\x2c\x6e\x80\x86\x8c\xbf\xbd\x93\x40\x05\x61\x74\x96\x95\xbe\x7f\x84\xd0\x7d\x4e\xde\x42\xb7\xe4\xbe\x46\xbb\x14\x5b\x48\x4e\xe8\xba\x90\x05\xa1\x19\xd0\x34\xae\xc4\xce\xbe\xbc\x9a\xbf\x9c\x15\x7f\x5d\x57\xc5\x42\x10\x01\x27\x89\xe2\x48\x51\xb9\xda\x40\xd5\x87\x37\xc0\x15\x5f\x88\xad\x90\xdc\x10\x81\x42\x16\xa4\x31\x50\x39\x2f\x38\xad\xab\xb0\x53\xd8\xac\x94\x56\x6f\xc3\x84\xf4\x11\xa4\x50\xb3\xfa\xe9\xd3\x6f\x9f\x3e\xdf\x2f\xd0\xeb\x8f\x1f\x3f\x7e\xbc\xfe\xf6\xe9\xf7\xaf\x5f\x7f\xfc\x18\x7e\xfb\xec\xfb\xc7\xb3\x36\x79\x54\x43\xe8\x29\xc5\x31\x20\xc6\x11\x49\x9e\xe5\x12\x41\x66\xa0\xe8\xed\x1d\x8e\x93\x08\x5e\xa3\x27\x3b\xc3\x7c\xa2\x73\xba\xc4\x02\x2e\xb0\xdc\xf4\xe5\x76\xd1\xca\x96\xa2\x8a\x94\xcd\x21\xc9\x6c\xec\x2c\x70\x42\x9e\x34\x74\x9d\x19\x7c\xcd\x20\x9c\xea\x2e\x0a\xfe\x42\x84\xd4\x29\x04\x8c\x8a\xb4\x41\xa2\xc1\xdc\x19\x8a\x88\x90\x4a\x49\xef\xce\xdf\xbd\x45\x4a\x52\x81\x70\x10\x40\x22\x21\x44\xcb\x6d\xc5\xec\x4e\x3c\x1c\x45\xef\x57\x9a\xb5\x7d\xae\xfe\xe5\xe4\x31\x86\x90\xe0\xab\x6d\x02\x3b\x2e\xcb\x11\x90\xd9\xa8\xc6\x77\xc2\x59\x98\x06\xfd\xf9\x2e\x78\x45\x01\xa6\xa8\xa0\x71\x5c\xbe\x33\xa7\xd2\xd9\x5f\x95\xef\xd9\xd5\xac\xfd\xdc\x5d\xbf\x5e\xb8\xd1\x3e\xc7\x31\x48\xe0\x5e\x4c\x14\x65\xdf\xb8\xa8\x71\x10\x09\xa3\xc2\xc7\x02\xcb\xa2\x4e\x5a\x02\x82\x94\x13\xb9\xf5\x30\xe6\xb2\xa4\xb5\xfe\x9b\x3e\x7a\xb2\x55\xd2\xa8\x4a\xbc\x16\xb6\x71\x8e\x39\xc7\xdb\x9d\xe1\x10\x09\x71\xbd\x9c\xb3\x41\x89\xd7\xa5\x89\xdc\x57\xb5\x53\x4a\xfe\x4c\xe1\xbc\xa0\x21\x79\x0a\x1a\x0f\x70\xa7\x5c\x08\x8e\xde\xb0\xc0\x43\x24\xad\x74\x63\x0e\xb1\xd9\x90\xe1\xb0\x2d\x13\xa7\x6d\x78\xfd\x04\x14\x38\x8e\x90\xaa\xce\x63\xac\x3e\x23\xbc\x64\xa9\xb4\xf8\x03\x63\xde\xcd\xbe\x16\x13\x4a\x55\xac\x82\x12\xc6\xac\xd4\x35\xf7\x22\xd4\x3a\xff\x22\x73\x0e\x6e\x51\xa0\x75\x1e\xae\x8f\xe8\x5d\xc7\x59\xe6\xe4\x9a\x18\x8d\xd6\x1c\x53\x84\x4d\xb7\x67\x28\x37\x09\x84\x69\x88\x12\x0e\x01\x11\x80\x32\xa2\xf5\xb9\xaa\xc6\xd9\x73\x53\xab\xfb\xb4\x2e\x20\xc6\x54\x92\xa0\x9a\xf3\x69\x1a\x2f\x81\x77\x37\xae\x53\x1a\xce\x40\xc4\xa8\x82\x1c\xb5\xef\xda\x24\x7d\xb9\x61\x69\x14\xa2\x25\xa0\x90\xac\x56\xc0\x81\x4a\xb4\xe2\x2c\xce\x4a\x64\x7a\x9a\x23\xf4\x13\x91\x3f\xa7\x4b\xf4\x63\x84\x6f\x18\x87\x10\xbd\xc3\xfc\x8f\x90\xdd\x52\x44\x04\xc2\x51\xc4\x6e\x21\x74\x48\x21\x81\xc7\xe2\xfd\xea\x12\xf8\x0d\x09\xf6\xe9\x47\x35\xaf\x67\xc4\x14\xf7\x22\x27\x97\xe1\xe2\x76\x2d\x06\x8c\x4a\x1c\x48\x3f\x73\x2d\x0b\x5b\x29\x45\x24\x00\x2a\x0c\x11\xec\x94\xca\xc2\xa6\xc1\x37\x21\x43\x83\x3b\x5f\x97\xf1\x43\x5e\x53\x73\x19\xa5\x36\xd8\x2d\x05\x2e\x34\x0b\xeb\x39\xfc\x1d\x63\x51\x01\xbd\x3d\xbb\x90\x84\x40\x25\x59\x6d\x09\x5d\xa3\x1c\x37\xe6\x5c\x16\x9a\x40\x09\x70\xc1\xe8\x82\xf1\x35\xa6\xe4\xdf\x99\x5c\x8e\x9e\x4d\x79\xb4\x27\x2f\xbf\x7e\xf8\x05\x25\x8c\x50\xa9\x98\x29\x90\x62\x60\xea\x75\xae\x13\xca\xbf\x2b\x1a\x29\x27\x76\xd6\x20\xc6\x64\x5f\xe6\x32\x1a\x08\x87\x21\x07\x21\xbc\xb4\xe4\xe0\x32\x67\xa6\xcd\xf3\x1e\xcd\xd9\x6b\xb6\x6f\x8e\x27\xa7\xed\xdb\xe7\xbc\xcc\x1a\x07\xce\x6f\x87\x33\xf0\xba\x51\x17\x22\x66\x78\x79\x8e\xce\xe5\x13\x81\x80\x06\x2c\xe5\x78\x0d\xa1\xb2\xb8\x54\xa8\x79\x09\xbd\xbf\x3c\x47\x01\x8b\x13\x2c\xc9\x32\xaa\xaa\x1d\xd5\xee\xab\x36\xbd\x6c\xfd\x54\x6c\xc8\x08\x01\x3c\xbd\xe7\x07\x88\xb0\x24\x37\x79\x90\x28\x4a\x1d\x10\x1a\x92\x1b\x12\xa6\x38\x42\x40\xc3\x4c\x43\x62\x8e\xae\x36\xb0\x45\x71\x2a\xa4\x9a\x23\x79\x59\xb1\xa8\xf2\xa4\x0c\x60\x9f\xcc\x8d\x40\xf5\x80\xca\xa8\x99\xc3\xa7\x85\x1f\x31\x25\xa9\x82\xc5\x6d\xbd\xd8\x36\x76\x7c\x02\x28\x97\xf6\x1d\x74\x3b\x11\x7e\x91\xae\x32\xf8\x6c\xf4\xe6\x7b\x9a\xa5\x1f\x62\xc6\x21\xcf\x9a\xe5\xed\x8b\x02\xf3\x2c\x33\x33\xdf\x00\xca\xc9\x09\xb4\x04\xf5\xa5\x08\xd7\xc3\x02\x18\x66\xf1\xab\x1e\x83\x37\x4c\xcd\x12\xc1\x1d\x50\xf6\xaa\xbd\xfe\xe2\x73\x48\x38\x08\xa0\x32\x9b\x18\x44\x86\x0b\x6a\xc1\xaa\x26\x96\x2d\x96\x3c\xa0\x54\x65\x73\x87\x15\xca\x15\xe5\xf5\x94\x46\x9f\x33\x1a\x0c\x9a\xb1\x5a\xd9\x6a\x95\xcd\xcb\x7e\xec\x9a\xc5\x94\x3b\x37\x26\x31\xd7\xfc\xe4\x1f\x13\x8c\x31\x75\x9c\xba\xf7\x87\x3c\xa1\xb7\x4f\x17\x1b\x09\x82\x98\xc4\x70\x95\xd3\xe8\x4c\x48\x5a\xa6\xd6\x2a\x3d\x56\x42\x80\x9f\xaf\xae\x2e\x50\x0c\x42\xe0\x35\x34\x3c\x8a\x62\x03\x37\xba\xb2\x27\x04\xda\x25\x8d\x06\xe2\xa0\x13\x8a\xf3\xf5\xec\x10\x72\x67\x88\x90\x3d\x4b\x64\xeb\xaa\xda\x8f\xf7\x5a\x75\x47\x9a\xa8\x51\x70\x26\xd2\x38\xc6\x7c\xbb\x57\xfc\xbd\xe4\x04\x56\xa8\xa0\x54\x9a\x45\xd5\xf7\x0f\x16\xfc\x57\x1c\x3c\xdf\x23\xba\x77\x38\xda\x16\x4b\x31\x53\x6a\x4d\x9a\x15\x63\xe7\xe1\x18\x69\x9f\x22\xe0\x24\xbb\x94\x4b\x97\xee\x2d\xf9\x70\x87\x72\x7b\xe6\xc4\x33\x2a\x66\x5e\x1c\x35\x72\xe3\x2d\xda\x73\xe4\xc7\x51\x6d\xa4\xa1\x2a\x4f\xde\x94\xcb\xb2\x3e\x31\x48\xae\x82\xce\xc9\xc8\x65\xcd\xc3\xb7\x34\xb6\x2b\xdf\x58\x65\x78\x6e\x73\xac\x5e\x24\x0d\x3f\xdc\x70\x23\xc6\xda\x52\x0b\x2d\x63\x7d\xa9\x49\x2d\x54\x48\x28\xc0\x12\x9c\xe3\x63\xc9\x58\x04\x98\x36\x07\xc8\x0a\xa7\x91\xd4\xf0\xbc\xc1\xa8\xb9\x70\xd0\xc6\xa9\xb6\x78\x80\x5a\xa3\xb4\x2c\xf4\x18\x0b\x8a\x9d\xd0\xb4\x55\x10\xee\x0d\xc5\xd6\xe0\x99\x93\xdc\xa1\x04\xbb\xf1\xa7\x23\xd1\xd1\x97\x8c\x87\x13\x0a\x21\x02\xe9\x99\x25\xed\x20\xc5\x92\x66\x3c\x32\x9c\xd6\x06\xb0\x31\x5c\x86\x29\x0a\xcb\x60\x33\x12\xa5\x91\xfc\x96\x75\xd0\x59\xd7\x13\xbd\xd3\x23\x79\xdd\x2a\x90\xa6\x38\x06\x91\x39\x7f\x20\x72\x03\x1c\x2d\x01\x61\xba\x45\x37\x38\x22\x61\x8e\x71\x85\xc4\x32\x15\x28\x60\x61\x16\xb8\x3d\x29\xdc\x4d\x3d\x2f\x12\x13\x7d\xc8\x7e\x37\xee\xa8\x7f\xfa\xdb\xcb\x17\xff\x77\xfd\xf9\x7f\xee\x9f\x3d\xfe\xcf\xa7\xa7\x45\xfb\xcf\x1e\xf7\xf3\xe0\xff\xc4\x51\x0a\x8e\x4c\xcb\x01\xdc\x0a\x65\xb2\x01\x83\xed\x3d\xe4\xa9\xa3\x4e\x2d\x59\xc5\xe8\x2f\x48\x7d\x5a\x6e\x37\xbf\x5c\x9f\x35\x13\x64\x14\xfa\xef\x0b\x68\xa6\x0d\xb4\x8e\xf1\xa8\xff\xbb\x60\xf4\x03\x64\xab\x5b\x81\x65\x51\xe6\xda\xca\xfa\xf0\xb0\xac\x3e\x9c\xca\x26\x0e\x1d\xdb\x57\x5b\xbb\xb4\x9a\xa6\xb6\x9b\x1a\x6b\xd1\x9a\x9e\x7e\x33\x9a\xec\x41\x69\x45\x22\xb8\xb4\x51\xeb\x04\x77\xca\x6f\x7b\x7b\xc8\xb2\xb0\x95\x92\x25\x5b\xd0\x42\xaa\x2a\xdd\x32\x78\x4f\x0c\xab\x68\x46\x6c\xea\x6d\xf4\x5c\x5e\xde\xc4\xac\xa5\xf9\xd1\x00\x9f\x7d\x98\x65\x24\xbd\xc7\x97\xd4\xb3\x3a\xa8\x2b\xa0\x34\x76\xf9\x65\x5f\x2d\x25\x95\x1b\xcf\xd6\xf4\x9b\x5f\x09\x95\xb0\x36\x3f\xdb\xd0\x39\x2a\x93\x1c\x9d\x03\xa2\x4a\xca\xf5\xf6\x10\xb6\x94\x89\x0b\x6a\x70\x12\x13\x49\x6e\x40\xe4\x29\x12\x2b\xbd\x80\x45\x11\x04\xaa\xc2\x8f\x56\x9e\x5c\x6b\xec\x8d\x5a\x0e\x14\x59\x06\x2b\x1e\x24\xcb\xc2\x56\x4a\x31\xbe\x23\x71\x1a\xfb\x51\x2a\x0b\x3b\x1c\x48\x10\xa5\x82\xdc\xc0\xbb\x3e\x24\x8d\x5a\x76\x2e\x09\xed\xc1\x65\x51\xb8\x83\xcb\x3e\x24\x8d\x5a\x2e\x5d\xfe\x02\x74\x2d\x3d\xf1\xef\xae\xb8\x4b\xe6\x5e\xd4\xaa\xe2\x2e\x5c\x5e\xec\x0e\xf5\x5b\x0c\xcb\x0a\xbb\xa4\x3c\xf7\x1f\x2a\x55\x69\x97\x8c\x7d\x68\x95\xa5\xad\xb4\xf4\x9c\xa5\x07\xb9\x7a\x05\xbb\xad\x50\x6f\xfb\xa0\x4e\x9b\x48\x23\x49\x92\x28\x87\x19\x3e\x32\xee\xca\x3b\x46\x7e\x7f\x18\x64\xcc\xcc\x0f\x34\xe9\x36\x8b\xb7\x6c\xa8\xa5\x5b\x54\x4c\x54\x5b\x15\x3a\xf1\x6c\x2d\xfe\x96\xc8\x0d\xba\x7b\x81\x88\xc8\x23\xab\xee\x7d\x3b\x92\xa7\x60\x29\xe3\xdc\xff\xb8\x64\xe1\xf6\xa2\x5a\x59\xdc\x6f\xeb\x45\x7d\x6a\xd1\x76\x1e\xea\xb8\xf1\xfa\x14\xd3\x36\x63\xe5\xd7\xf3\xe4\xbe\x25\xbd\x5e\x05\xeb\x73\x74\xb5\x21\x2a\x2e\x4e\xa3\x30\xdf\xbf\x43\x28\x2a\xd1\xa5\x2a\x9d\x8a\xfd\x76\xd8\x8d\xbc\x67\x65\xc7\xb8\x03\x45\xec\xa3\xb0\x37\x8a\x70\x4c\x68\x91\x51\x8e\x58\x80\xed\x4a\xf3\x81\x62\xca\x96\xbb\xf1\x52\xcd\x80\xfb\xe4\x4a\x5d\x6c\xdf\x6e\x20\x4b\x80\x30\x8e\x28\x93\xf9\xe9\x8d\x8a\x6d\xd5\x59\x65\x7b\xaa\x44\x9e\xc0\xc2\xd1\x7c\x40\x26\xd6\x1a\xce\xf9\xc5\x69\x7b\x6c\xec\xc8\x71\x7b\xe5\x21\x2e\xd3\xe5\x65\x93\x91\x53\x0b\x7b\x3a\xc7\xfa\x17\x6a\x01\xa7\x33\xd0\xf4\x40\x0f\x39\x87\xda\xe4\x54\x87\x3a\xd5\xe3\xc7\xa6\x8e\x20\xd4\x11\xb2\x4e\xb1\xe9\x14\x9b\x4e\xb1\xe9\x14\x9b\xfe\x15\x63\xd3\x47\xf5\xff\x97\x38\xe9\xcf\x14\xf8\x76\x82\x49\x13\x4c\xaa\x7d\xcd\x6c\x62\x42\x49\x87\x43\x49\x19\x33\x6f\xe3\x44\x6e\x9b\xab\x8a\x3e\x86\xaa\x99\x52\x1b\x5b\x59\x33\x02\x09\xa0\x21\xa1\x6b\x84\x6b\x66\xbb\xdc\x16\x0c\xd3\x68\xab\xec\x36\x4b\xd8\x60\x8a\x40\x31\x85\x6e\x14\x57\x13\xc2\xfb\x92\x10\xde\xbf\x88\xdc\xbc\x53\x5e\x7f\x82\x7a\x13\xd4\x9b\xa0\xde\x04\xf5\x90\x01\xf5\x94\xcb\x7b\x83\x25\x9e\xd0\xde\x84\xf6\x6a\x5f\x4b\xb3\x98\x00\xdf\x04\xf8\x6c\xbc\x7f\x19\x80\xaf\xf1\x71\x45\x22\x98\x40\xe0\x04\x02\x27\x10\xd8\x29\xf5\x04\x02\xff\x4a\x20\x30\xc1\x72\xf3\x65\x02\x40\xd7\xc1\xd1\xe2\x6b\xf1\xa9\x7b\xfb\xe4\x20\xc0\x68\x9d\xd4\xb4\xd3\x96\xb5\xa6\xd1\x41\x20\xe6\x89\xc3\x48\x65\x58\x13\x84\x9c\x56\x56\x3b\x0c\xe0\x6b\x83\x5c\x13\xd2\x9a\x90\xd6\x84\xb4\x26\xa4\x85\x0c\xa4\x45\x19\xfd\xff\x63\x6c\x52\xb5\x1f\x1e\x19\x74\x3a\xcd\xb9\x69\xce\xa6\x3a\x0f\x7a\x2d\x19\xc7\x81\x14\x5d\xcb\xd5\x03\xc9\x39\xd0\xb0\xd1\xb3\xcd\xfb\x7a\x2d\x5d\x3a\x48\xe1\xfa\x2e\xe6\x81\x42\x18\x86\xd6\xc1\xbe\xb1\x23\xd3\xf7\x34\xed\x19\x0a\x0b\xc4\x48\x44\xfd\x22\x50\xb6\x42\x58\xbb\xe5\x3d\xa7\x73\xd4\x8b\xc4\x8c\x70\x61\xec\x73\xee\xc3\x81\x8b\xf5\xe2\xd7\x52\x3e\xcf\xeb\xeb\x17\x3b\x71\x16\xda\x7d\xb8\xde\xf0\x7a\x8f\x06\x2d\xa7\x40\x7b\xc1\x9d\x41\x4d\xb6\x61\xa2\x4e\x9f\x3d\xa0\xc5\xae\xe3\x1c\x1d\x40\x6c\x48\x8b\x63\xa0\xb5\x01\xed\x8e\x02\xe9\x86\xc8\x3b\x06\xee\xdb\x4b\xde\xbd\xc0\xa1\x6f\xcb\xda\xfc\xc2\x44\x16\x87\x9c\x17\x31\xd3\x30\x20\x39\x42\xcb\x6f\xf2\xf1\xf4\x72\x10\xf8\x1c\xa0\xf3\xbd\x10\xea\x21\x35\x7d\xe8\x86\xdb\x15\xed\x81\x81\x07\x28\xbb\x13\x28\xc7\xf8\xce\x7d\x8d\xc2\x31\xb4\x7e\x94\xd6\xdb\x55\xef\x4a\xfb\xed\xc3\x40\x3e\xeb\x9f\xe9\x99\x0f\xdf\x08\x65\x88\x27\x73\x86\x31\x9d\x47\xdf\x55\x19\xba\x3d\xee\x15\x0a\xcd\x8c\xaa\x5e\xb9\xf6\x57\x33\x73\x5a\xa1\x89\x7b\x3b\xa0\xb2\xa4\xc2\xf6\xc1\x53\xb5\x00\xca\x23\xe5\xf4\x60\x6a\xb4\x2d\x74\xea\x4e\xed\x3b\xe3\x47\xfb\xed\x82\x3d\x19\xd4\x3b\x6b\xaf\xae\x2b\x2f\x57\xb3\x82\x68\xcb\xed\x88\x2e\xe1\x5c\xd7\x26\xfa\x0a\x65\xe7\xce\x11\x33\xb4\xdd\x66\xe3\x37\xf6\xfa\x70\xd6\x4f\xa1\x21\x51\xd8\x3c\x26\x14\x4b\xc6\x87\x44\x27\x1c\x70\xf8\x9e\x46\xce\xab\x21\x07\x5f\xc1\x76\x17\x1b\x77\xb4\xda\x75\xa0\x0a\x3a\x30\xe1\xf8\x97\x32\x16\x2b\x00\x75\x85\xee\x62\x46\xef\xd3\x85\xb5\x6b\x60\xbe\xf2\x30\x7a\x8c\x0b\x4b\xa6\xd0\xf9\x64\x42\xe7\x07\x41\x41\xe3\x2c\x5d\xf9\x6d\xe9\x39\x98\x3b\x3b\x5d\x67\xd4\x5c\xed\xf2\xf0\x48\x7b\xbd\x2d\x31\xdd\x3f\x34\xad\x44\x76\x51\x9a\x56\x22\xa7\x95\xc8\x69\x25\xf2\xe1\x56\x22\x1f\x00\x32\x6a\x73\x92\xed\xe1\xc6\x7d\x9f\x49\x2c\x69\x7e\xc8\x31\x4c\x0c\xb4\xf2\x54\x3b\x79\x3b\x9e\x4d\xb4\xd1\x18\x3e\x5f\x9a\x93\xa2\x11\xc3\xda\x27\x0b\xaf\x37\x2e\x5c\x37\xfb\xeb\x9a\xd6\xc3\xac\xc3\xcc\xf8\x1e\x5b\x9d\xac\x22\x64\xb7\xed\x26\xb8\xf3\xb9\x3c\xbb\x1f\xe2\xb0\x22\x77\x43\x6a\x62\x29\x39\x59\xa6\xe6\xe5\xcd\x7b\x83\xc0\x5b\x8e\x93\x64\xac\xeb\xca\x4f\x65\xac\x4a\xbc\x1e\xcd\x82\xfa\x3c\x70\x36\xb6\xb5\xed\x79\xef\xec\x68\x00\xff\x54\xfa\xb5\xe3\xf1\xdb\xe1\xbe\xce\x76\x17\xaf\x57\xb6\x6b\x89\x05\x09\xce\x52\xb9\x01\x2a\x49\xbe\xd9\xf4\xd2\xb8\x7a\xbf\x91\x02\xf3\x22\x8c\x13\xf2\x77\xd8\x8e\x43\x8b\xe1\x54\x6e\x5e\x9d\xc7\x49\x44\x02\x22\xc7\xa4\x79\x81\x85\xb8\x65\x3c\x1c\x93\xe6\x59\xa2\xf8\x1c\x51\x95\x05\xd9\x20\x00\x21\x7e\x60\x21\x58\xa9\x56\xff\xbe\xb6\x5a\x5e\x5b\x3f\x1f\xd6\xd3\x3c\xc4\x4d\xba\x99\xb4\x63\x6e\x7d\x3e\x3d\x57\xd2\x18\x5f\x47\xe8\xc3\x06\x8a\x68\x6c\x7f\x3b\x72\x0f\xe7\xe2\x77\x77\xf1\xd0\x99\xab\xdf\x2e\xfe\xd6\xbb\xcd\x1a\xb9\x90\xd1\xaf\xf2\x38\x3d\xdb\x74\xf8\xeb\xe3\xda\xe8\x2a\x62\xb7\xda\x1b\x07\xa9\xdc\x30\x5e\xbc\x68\xfb\x6b\x9f\x97\xf1\xc6\xb1\xd8\x5c\x29\x1e\x49\x30\xc5\xf7\xde\xad\x91\x42\xf9\xdd\xed\x89\x80\x25\xbe\x37\xd7\xe7\x32\x5c\xe6\x35\xac\xd4\x0c\x2d\xf7\x90\xc4\xe3\xf5\xe3\x2f\x7f\x54\x18\x88\xe3\x61\x47\x85\x64\x7f\xc0\xd7\x3f\x1a\x92\x42\xe9\xc7\x1e\x0d\x95\x76\xa7\x51\xa0\x8f\x02\x1b\x46\x9e\x06\x42\xd1\xf2\x01\x07\x02\xde\xe9\x7d\x1a\x0b\xa7\x32\x16\xcc\xc0\xee\xc4\x90\xd2\x5f\x6f\x98\x54\x5d\xf2\x95\xe1\xa7\x69\x10\x3a\x06\xe1\x65\xb3\x17\x47\x58\x78\xd0\x45\xd6\x5b\xd5\x5f\x25\x1d\x71\x49\xa6\x7a\x64\xda\xd0\x6f\xc7\x3a\x4c\xe3\x09\xc0\x6e\x96\x2c\xa7\xa7\x77\x34\x10\x05\x08\x21\x44\x92\x65\x77\xdf\x20\x5c\xbc\xe7\x97\x3f\xf4\x1a\x45\xd6\xe7\x27\x4a\xde\x74\x27\x66\x11\x7d\x70\xba\xd3\x78\xf9\x1e\x0d\xca\xc8\x39\xde\x7c\xb3\xa6\xe1\xbc\xd7\xc1\x6a\x6f\xb3\x0e\x52\xbe\xe4\x98\x8a\x15\x70\x94\x70\x26\x59\xc0\xa2\xf2\x1c\xfb\xd9\xc5\xf9\xbc\xd5\x92\x9c\xa3\xdf\xe6\x1e\xb3\x0d\x49\xba\x87\x50\x5f\x84\xfe\xe9\xd6\xf8\xbb\xe6\xf0\x7a\xeb\xa6\x65\x3b\x86\x8b\x79\x93\xf5\x59\x20\x6e\xb4\xa7\x44\xf4\x3f\xa5\xfe\x67\x42\x12\xdb\xd3\xe7\xbb\xa5\xa3\x8c\x5c\x2b\x97\xbb\xbb\x7f\x8e\xc5\x6e\xed\x43\x5c\xbf\x74\xc8\x8f\xff\xe6\xd6\xbe\x91\xb6\xf5\x95\xe4\xed\x93\xc4\xa8\x5b\xf9\x76\x4d\x35\xb7\xd8\x8c\xb6\x7d\xaf\x72\xe0\xb6\xbd\x01\x63\x9e\x76\xab\x1a\x32\x76\xe4\x8c\x76\xc2\xad\x6c\xa2\x65\xf7\xcf\xf8\xa7\xda\x2a\xb9\x8c\x3d\x3c\xa3\x9d\x64\x33\xe5\x1a\xb5\x2d\xfb\x86\xa2\x5a\x7f\x19\x5b\x7f\xc6\x3f\xd1\x53\xd3\xe2\x41\x5b\xd3\x4f\xf0\xec\xb0\x42\x73\x43\xd2\x68\x27\xd3\x6a\x6a\x34\xf6\x4e\x1e\x52\x8b\x87\x6c\xcc\xae\x44\xfb\x9e\xa7\x51\x4f\x9d\x55\x03\x81\x8e\x67\xfc\xb4\x69\xf0\x3a\x18\xf2\x40\xd0\xf6\xa8\x34\xe3\xc9\x98\xaf\xf6\xda\x24\xd3\xeb\x60\xb9\x0e\xd3\x1f\xa9\xff\xee\x1f\xfd\x37\x00\x00\xff\xff\x69\x5d\x0a\x6a\x39\x9d\x00\x00")
+
+func v2SchemaJSONBytes() ([]byte, error) {
+	return bindataRead(
+		_v2SchemaJSON,
+		"v2/schema.json",
+	)
+}
+
+func v2SchemaJSON() (*asset, error) {
+	bytes, err := v2SchemaJSONBytes()
+	if err != nil {
+		return nil, err
+	}
+
+	info := bindataFileInfo{name: "v2/schema.json", size: 40249, mode: os.FileMode(420), modTime: time.Unix(1523760397, 0)}
+	a := &asset{bytes: bytes, info: info}
+	return a, nil
+}
+
+// Asset loads and returns the asset for the given name.
+// It returns an error if the asset could not be found or
+// could not be loaded.
+func Asset(name string) ([]byte, error) {
+	cannonicalName := strings.Replace(name, "\\", "/", -1)
+	if f, ok := _bindata[cannonicalName]; ok {
+		a, err := f()
+		if err != nil {
+			return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
+		}
+		return a.bytes, nil
+	}
+	return nil, fmt.Errorf("Asset %s not found", name)
+}
+
+// MustAsset is like Asset but panics when Asset would return an error.
+// It simplifies safe initialization of global variables.
+func MustAsset(name string) []byte {
+	a, err := Asset(name)
+	if err != nil {
+		panic("asset: Asset(" + name + "): " + err.Error())
+	}
+
+	return a
+}
+
+// AssetInfo loads and returns the asset info for the given name.
+// It returns an error if the asset could not be found or
+// could not be loaded.
+func AssetInfo(name string) (os.FileInfo, error) {
+	cannonicalName := strings.Replace(name, "\\", "/", -1)
+	if f, ok := _bindata[cannonicalName]; ok {
+		a, err := f()
+		if err != nil {
+			return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
+		}
+		return a.info, nil
+	}
+	return nil, fmt.Errorf("AssetInfo %s not found", name)
+}
+
+// AssetNames returns the names of the assets.
+func AssetNames() []string {
+	names := make([]string, 0, len(_bindata))
+	for name := range _bindata {
+		names = append(names, name)
+	}
+	return names
+}
+
+// _bindata is a table, holding each asset generator, mapped to its name.
+var _bindata = map[string]func() (*asset, error){
+	"jsonschema-draft-04.json": jsonschemaDraft04JSON,
+	"v2/schema.json":           v2SchemaJSON,
+}
+
+// AssetDir returns the file names below a certain
+// directory embedded in the file by go-bindata.
+// For example if you run go-bindata on data/... and data contains the
+// following hierarchy:
+//     data/
+//       foo.txt
+//       img/
+//         a.png
+//         b.png
+// then AssetDir("data") would return []string{"foo.txt", "img"}
+// AssetDir("data/img") would return []string{"a.png", "b.png"}
+// AssetDir("foo.txt") and AssetDir("notexist") would return an error
+// AssetDir("") will return []string{"data"}.
+func AssetDir(name string) ([]string, error) {
+	node := _bintree
+	if len(name) != 0 {
+		cannonicalName := strings.Replace(name, "\\", "/", -1)
+		pathList := strings.Split(cannonicalName, "/")
+		for _, p := range pathList {
+			node = node.Children[p]
+			if node == nil {
+				return nil, fmt.Errorf("Asset %s not found", name)
+			}
+		}
+	}
+	if node.Func != nil {
+		return nil, fmt.Errorf("Asset %s not found", name)
+	}
+	rv := make([]string, 0, len(node.Children))
+	for childName := range node.Children {
+		rv = append(rv, childName)
+	}
+	return rv, nil
+}
+
+type bintree struct {
+	Func     func() (*asset, error)
+	Children map[string]*bintree
+}
+
+var _bintree = &bintree{nil, map[string]*bintree{
+	"jsonschema-draft-04.json": &bintree{jsonschemaDraft04JSON, map[string]*bintree{}},
+	"v2": &bintree{nil, map[string]*bintree{
+		"schema.json": &bintree{v2SchemaJSON, map[string]*bintree{}},
+	}},
+}}
+
+// RestoreAsset restores an asset under the given directory
+func RestoreAsset(dir, name string) error {
+	data, err := Asset(name)
+	if err != nil {
+		return err
+	}
+	info, err := AssetInfo(name)
+	if err != nil {
+		return err
+	}
+	err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
+	if err != nil {
+		return err
+	}
+	err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
+	if err != nil {
+		return err
+	}
+	err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+// RestoreAssets restores an asset under the given directory recursively
+func RestoreAssets(dir, name string) error {
+	children, err := AssetDir(name)
+	// File
+	if err != nil {
+		return RestoreAsset(dir, name)
+	}
+	// Dir
+	for _, child := range children {
+		err = RestoreAssets(dir, filepath.Join(name, child))
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func _filePath(dir, name string) string {
+	cannonicalName := strings.Replace(name, "\\", "/", -1)
+	return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
+}
diff --git a/go/vendor/github.com/go-openapi/spec/contact_info.go b/go/vendor/github.com/go-openapi/spec/contact_info.go
new file mode 100644
index 0000000..f285970
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/contact_info.go
@@ -0,0 +1,24 @@
+// 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 spec
+
+// ContactInfo contact information for the exposed API.
+//
+// For more information: http://goo.gl/8us55a#contactObject
+type ContactInfo struct {
+	Name  string `json:"name,omitempty"`
+	URL   string `json:"url,omitempty"`
+	Email string `json:"email,omitempty"`
+}
diff --git a/go/vendor/github.com/go-openapi/spec/debug.go b/go/vendor/github.com/go-openapi/spec/debug.go
new file mode 100644
index 0000000..7edb95a
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/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 spec
+
+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
+	specLogger *log.Logger
+)
+
+func init() {
+	debugOptions()
+}
+
+func debugOptions() {
+	specLogger = log.New(os.Stdout, "spec:", 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)
+		specLogger.Printf("%s:%d: %s", filepath.Base(file1), pos1, fmt.Sprintf(msg, args...))
+	}
+}
diff --git a/go/vendor/github.com/go-openapi/spec/expander.go b/go/vendor/github.com/go-openapi/spec/expander.go
new file mode 100644
index 0000000..456a9dd
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/expander.go
@@ -0,0 +1,1227 @@
+// 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 spec
+
+import (
+	"encoding/json"
+	"fmt"
+	"log"
+	"net/url"
+	"os"
+	"path"
+	"path/filepath"
+	"reflect"
+	"strings"
+	"sync"
+
+	"github.com/go-openapi/jsonpointer"
+	"github.com/go-openapi/swag"
+)
+
+// ExpandOptions provides options for expand.
+type ExpandOptions struct {
+	RelativeBase        string
+	SkipSchemas         bool
+	ContinueOnError     bool
+	AbsoluteCircularRef bool
+}
+
+// ResolutionCache a cache for resolving urls
+type ResolutionCache interface {
+	Get(string) (interface{}, bool)
+	Set(string, interface{})
+}
+
+type simpleCache struct {
+	lock  sync.RWMutex
+	store map[string]interface{}
+}
+
+var resCache ResolutionCache
+
+func init() {
+	resCache = initResolutionCache()
+}
+
+// initResolutionCache initializes the URI resolution cache
+func initResolutionCache() ResolutionCache {
+	return &simpleCache{store: map[string]interface{}{
+		"http://swagger.io/v2/schema.json":       MustLoadSwagger20Schema(),
+		"http://json-schema.org/draft-04/schema": MustLoadJSONSchemaDraft04(),
+	}}
+}
+
+// resolverContext allows to share a context during spec processing.
+// At the moment, it just holds the index of circular references found.
+type resolverContext struct {
+	// circulars holds all visited circular references, which allows shortcuts.
+	// NOTE: this is not just a performance improvement: it is required to figure out
+	// circular references which participate several cycles.
+	// This structure is privately instantiated and needs not be locked against
+	// concurrent access, unless we chose to implement a parallel spec walking.
+	circulars map[string]bool
+	basePath  string
+}
+
+func newResolverContext(originalBasePath string) *resolverContext {
+	return &resolverContext{
+		circulars: make(map[string]bool),
+		basePath:  originalBasePath, // keep the root base path in context
+	}
+}
+
+// Get retrieves a cached URI
+func (s *simpleCache) Get(uri string) (interface{}, bool) {
+	debugLog("getting %q from resolution cache", uri)
+	s.lock.RLock()
+	v, ok := s.store[uri]
+	debugLog("got %q from resolution cache: %t", uri, ok)
+
+	s.lock.RUnlock()
+	return v, ok
+}
+
+// Set caches a URI
+func (s *simpleCache) Set(uri string, data interface{}) {
+	s.lock.Lock()
+	s.store[uri] = data
+	s.lock.Unlock()
+}
+
+// ResolveRefWithBase resolves a reference against a context root with preservation of base path
+func ResolveRefWithBase(root interface{}, ref *Ref, opts *ExpandOptions) (*Schema, error) {
+	resolver, err := defaultSchemaLoader(root, opts, nil, nil)
+	if err != nil {
+		return nil, err
+	}
+	specBasePath := ""
+	if opts != nil && opts.RelativeBase != "" {
+		specBasePath, _ = absPath(opts.RelativeBase)
+	}
+
+	result := new(Schema)
+	if err := resolver.Resolve(ref, result, specBasePath); err != nil {
+		return nil, err
+	}
+	return result, nil
+}
+
+// ResolveRef resolves a reference against a context root
+// ref is guaranteed to be in root (no need to go to external files)
+// ResolveRef is ONLY called from the code generation module
+func ResolveRef(root interface{}, ref *Ref) (*Schema, error) {
+	res, _, err := ref.GetPointer().Get(root)
+	if err != nil {
+		panic(err)
+	}
+	switch sch := res.(type) {
+	case Schema:
+		return &sch, nil
+	case *Schema:
+		return sch, nil
+	case map[string]interface{}:
+		b, _ := json.Marshal(sch)
+		newSch := new(Schema)
+		_ = json.Unmarshal(b, newSch)
+		return newSch, nil
+	default:
+		return nil, fmt.Errorf("unknown type for the resolved reference")
+	}
+}
+
+// ResolveParameter resolves a parameter reference against a context root
+func ResolveParameter(root interface{}, ref Ref) (*Parameter, error) {
+	return ResolveParameterWithBase(root, ref, nil)
+}
+
+// ResolveParameterWithBase resolves a parameter reference against a context root and base path
+func ResolveParameterWithBase(root interface{}, ref Ref, opts *ExpandOptions) (*Parameter, error) {
+	resolver, err := defaultSchemaLoader(root, opts, nil, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	result := new(Parameter)
+	if err := resolver.Resolve(&ref, result, ""); err != nil {
+		return nil, err
+	}
+	return result, nil
+}
+
+// ResolveResponse resolves response a reference against a context root
+func ResolveResponse(root interface{}, ref Ref) (*Response, error) {
+	return ResolveResponseWithBase(root, ref, nil)
+}
+
+// ResolveResponseWithBase resolves response a reference against a context root and base path
+func ResolveResponseWithBase(root interface{}, ref Ref, opts *ExpandOptions) (*Response, error) {
+	resolver, err := defaultSchemaLoader(root, opts, nil, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	result := new(Response)
+	if err := resolver.Resolve(&ref, result, ""); err != nil {
+		return nil, err
+	}
+	return result, nil
+}
+
+// ResolveItems resolves header and parameter items reference against a context root and base path
+func ResolveItems(root interface{}, ref Ref, opts *ExpandOptions) (*Items, error) {
+	resolver, err := defaultSchemaLoader(root, opts, nil, nil)
+	if err != nil {
+		return nil, err
+	}
+	basePath := ""
+	if opts.RelativeBase != "" {
+		basePath = opts.RelativeBase
+	}
+	result := new(Items)
+	if err := resolver.Resolve(&ref, result, basePath); err != nil {
+		return nil, err
+	}
+	return result, nil
+}
+
+// ResolvePathItem resolves response a path item against a context root and base path
+func ResolvePathItem(root interface{}, ref Ref, opts *ExpandOptions) (*PathItem, error) {
+	resolver, err := defaultSchemaLoader(root, opts, nil, nil)
+	if err != nil {
+		return nil, err
+	}
+	basePath := ""
+	if opts.RelativeBase != "" {
+		basePath = opts.RelativeBase
+	}
+	result := new(PathItem)
+	if err := resolver.Resolve(&ref, result, basePath); err != nil {
+		return nil, err
+	}
+	return result, nil
+}
+
+type schemaLoader struct {
+	root    interface{}
+	options *ExpandOptions
+	cache   ResolutionCache
+	context *resolverContext
+	loadDoc func(string) (json.RawMessage, error)
+}
+
+var idPtr, _ = jsonpointer.New("/id")
+var refPtr, _ = jsonpointer.New("/$ref")
+
+// PathLoader function to use when loading remote refs
+var PathLoader func(string) (json.RawMessage, error)
+
+func init() {
+	PathLoader = func(path string) (json.RawMessage, error) {
+		data, err := swag.LoadFromFileOrHTTP(path)
+		if err != nil {
+			return nil, err
+		}
+		return json.RawMessage(data), nil
+	}
+}
+
+func defaultSchemaLoader(
+	root interface{},
+	expandOptions *ExpandOptions,
+	cache ResolutionCache,
+	context *resolverContext) (*schemaLoader, error) {
+
+	if cache == nil {
+		cache = resCache
+	}
+	if expandOptions == nil {
+		expandOptions = &ExpandOptions{}
+	}
+	absBase, _ := absPath(expandOptions.RelativeBase)
+	if context == nil {
+		context = newResolverContext(absBase)
+	}
+	return &schemaLoader{
+		root:    root,
+		options: expandOptions,
+		cache:   cache,
+		context: context,
+		loadDoc: func(path string) (json.RawMessage, error) {
+			debugLog("fetching document at %q", path)
+			return PathLoader(path)
+		},
+	}, nil
+}
+
+func idFromNode(node interface{}) (*Ref, error) {
+	if idValue, _, err := idPtr.Get(node); err == nil {
+		if refStr, ok := idValue.(string); ok && refStr != "" {
+			idRef, err := NewRef(refStr)
+			if err != nil {
+				return nil, err
+			}
+			return &idRef, nil
+		}
+	}
+	return nil, nil
+}
+
+func nextRef(startingNode interface{}, startingRef *Ref, ptr *jsonpointer.Pointer) *Ref {
+	if startingRef == nil {
+		return nil
+	}
+
+	if ptr == nil {
+		return startingRef
+	}
+
+	ret := startingRef
+	var idRef *Ref
+	node := startingNode
+
+	for _, tok := range ptr.DecodedTokens() {
+		node, _, _ = jsonpointer.GetForToken(node, tok)
+		if node == nil {
+			break
+		}
+
+		idRef, _ = idFromNode(node)
+		if idRef != nil {
+			nw, err := ret.Inherits(*idRef)
+			if err != nil {
+				break
+			}
+			ret = nw
+		}
+
+		refRef, _, _ := refPtr.Get(node)
+		if refRef != nil {
+			var rf Ref
+			switch value := refRef.(type) {
+			case string:
+				rf, _ = NewRef(value)
+			}
+			nw, err := ret.Inherits(rf)
+			if err != nil {
+				break
+			}
+			nwURL := nw.GetURL()
+			if nwURL.Scheme == "file" || (nwURL.Scheme == "" && nwURL.Host == "") {
+				nwpt := filepath.ToSlash(nwURL.Path)
+				if filepath.IsAbs(nwpt) {
+					_, err := os.Stat(nwpt)
+					if err != nil {
+						nwURL.Path = filepath.Join(".", nwpt)
+					}
+				}
+			}
+
+			ret = nw
+		}
+
+	}
+
+	return ret
+}
+
+// normalize absolute path for cache.
+// on Windows, drive letters should be converted to lower as scheme in net/url.URL
+func normalizeAbsPath(path string) string {
+	u, err := url.Parse(path)
+	if err != nil {
+		debugLog("normalize absolute path failed: %s", err)
+		return path
+	}
+	return u.String()
+}
+
+// base or refPath could be a file path or a URL
+// given a base absolute path and a ref path, return the absolute path of refPath
+// 1) if refPath is absolute, return it
+// 2) if refPath is relative, join it with basePath keeping the scheme, hosts, and ports if exists
+// base could be a directory or a full file path
+func normalizePaths(refPath, base string) string {
+	refURL, _ := url.Parse(refPath)
+	if path.IsAbs(refURL.Path) || filepath.IsAbs(refPath) {
+		// refPath is actually absolute
+		if refURL.Host != "" {
+			return refPath
+		}
+		parts := strings.Split(refPath, "#")
+		result := filepath.FromSlash(parts[0])
+		if len(parts) == 2 {
+			result += "#" + parts[1]
+		}
+		return result
+	}
+
+	// relative refPath
+	baseURL, _ := url.Parse(base)
+	if !strings.HasPrefix(refPath, "#") {
+		// combining paths
+		if baseURL.Host != "" {
+			baseURL.Path = path.Join(path.Dir(baseURL.Path), refURL.Path)
+		} else { // base is a file
+			newBase := fmt.Sprintf("%s#%s", filepath.Join(filepath.Dir(base), filepath.FromSlash(refURL.Path)), refURL.Fragment)
+			return newBase
+		}
+
+	}
+	// copying fragment from ref to base
+	baseURL.Fragment = refURL.Fragment
+	return baseURL.String()
+}
+
+// denormalizePaths returns to simplest notation on file $ref,
+// i.e. strips the absolute path and sets a path relative to the base path.
+//
+// This is currently used when we rewrite ref after a circular ref has been detected
+func denormalizeFileRef(ref *Ref, relativeBase, originalRelativeBase string) *Ref {
+	debugLog("denormalizeFileRef for: %s", ref.String())
+
+	if ref.String() == "" || ref.IsRoot() || ref.HasFragmentOnly {
+		return ref
+	}
+	// strip relativeBase from URI
+	relativeBaseURL, _ := url.Parse(relativeBase)
+	relativeBaseURL.Fragment = ""
+
+	if relativeBaseURL.IsAbs() && strings.HasPrefix(ref.String(), relativeBase) {
+		// this should work for absolute URI (e.g. http://...): we have an exact match, just trim prefix
+		r, _ := NewRef(strings.TrimPrefix(ref.String(), relativeBase))
+		return &r
+	}
+
+	if relativeBaseURL.IsAbs() {
+		// other absolute URL get unchanged (i.e. with a non-empty scheme)
+		return ref
+	}
+
+	// for relative file URIs:
+	originalRelativeBaseURL, _ := url.Parse(originalRelativeBase)
+	originalRelativeBaseURL.Fragment = ""
+	if strings.HasPrefix(ref.String(), originalRelativeBaseURL.String()) {
+		// the resulting ref is in the expanded spec: return a local ref
+		r, _ := NewRef(strings.TrimPrefix(ref.String(), originalRelativeBaseURL.String()))
+		return &r
+	}
+
+	// check if we may set a relative path, considering the original base path for this spec.
+	// Example:
+	//   spec is located at /mypath/spec.json
+	//   my normalized ref points to: /mypath/item.json#/target
+	//   expected result: item.json#/target
+	parts := strings.Split(ref.String(), "#")
+	relativePath, err := filepath.Rel(path.Dir(originalRelativeBaseURL.String()), parts[0])
+	if err != nil {
+		// there is no common ancestor (e.g. different drives on windows)
+		// leaves the ref unchanged
+		return ref
+	}
+	if len(parts) == 2 {
+		relativePath += "#" + parts[1]
+	}
+	r, _ := NewRef(relativePath)
+	return &r
+}
+
+// relativeBase could be an ABSOLUTE file path or an ABSOLUTE URL
+func normalizeFileRef(ref *Ref, relativeBase string) *Ref {
+	// This is important for when the reference is pointing to the root schema
+	if ref.String() == "" {
+		r, _ := NewRef(relativeBase)
+		return &r
+	}
+
+	debugLog("normalizing %s against %s", ref.String(), relativeBase)
+
+	s := normalizePaths(ref.String(), relativeBase)
+	r, _ := NewRef(s)
+	return &r
+}
+
+func (r *schemaLoader) resolveRef(ref *Ref, target interface{}, basePath string) error {
+	tgt := reflect.ValueOf(target)
+	if tgt.Kind() != reflect.Ptr {
+		return fmt.Errorf("resolve ref: target needs to be a pointer")
+	}
+
+	refURL := ref.GetURL()
+	if refURL == nil {
+		return nil
+	}
+
+	var res interface{}
+	var data interface{}
+	var err error
+	// Resolve against the root if it isn't nil, and if ref is pointing at the root, or has a fragment only which means
+	// it is pointing somewhere in the root.
+	root := r.root
+	if (ref.IsRoot() || ref.HasFragmentOnly) && root == nil && basePath != "" {
+		if baseRef, erb := NewRef(basePath); erb == nil {
+			root, _, _, _ = r.load(baseRef.GetURL())
+		}
+	}
+	if (ref.IsRoot() || ref.HasFragmentOnly) && root != nil {
+		data = root
+	} else {
+		baseRef := normalizeFileRef(ref, basePath)
+		debugLog("current ref is: %s", ref.String())
+		debugLog("current ref normalized file: %s", baseRef.String())
+		data, _, _, err = r.load(baseRef.GetURL())
+		if err != nil {
+			return err
+		}
+	}
+
+	res = data
+	if ref.String() != "" {
+		res, _, err = ref.GetPointer().Get(data)
+		if err != nil {
+			return err
+		}
+	}
+	if err := swag.DynamicJSONToStruct(res, target); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (r *schemaLoader) load(refURL *url.URL) (interface{}, url.URL, bool, error) {
+	debugLog("loading schema from url: %s", refURL)
+	toFetch := *refURL
+	toFetch.Fragment = ""
+
+	normalized := normalizeAbsPath(toFetch.String())
+
+	data, fromCache := r.cache.Get(normalized)
+	if !fromCache {
+		b, err := r.loadDoc(normalized)
+		if err != nil {
+			return nil, url.URL{}, false, err
+		}
+
+		if err := json.Unmarshal(b, &data); err != nil {
+			return nil, url.URL{}, false, err
+		}
+		r.cache.Set(normalized, data)
+	}
+
+	return data, toFetch, fromCache, nil
+}
+
+// Resolve resolves a reference against basePath and stores the result in target
+// Resolve is not in charge of following references, it only resolves ref by following its URL
+// if the schema that ref is referring to has more refs in it. Resolve doesn't resolve them
+// if basePath is an empty string, ref is resolved against the root schema stored in the schemaLoader struct
+func (r *schemaLoader) Resolve(ref *Ref, target interface{}, basePath string) error {
+	return r.resolveRef(ref, target, basePath)
+}
+
+// absPath returns the absolute path of a file
+func absPath(fname string) (string, error) {
+	if strings.HasPrefix(fname, "http") {
+		return fname, nil
+	}
+	if filepath.IsAbs(fname) {
+		return fname, nil
+	}
+	wd, err := os.Getwd()
+	return filepath.Join(wd, fname), err
+}
+
+// ExpandSpec expands the references in a swagger spec
+func ExpandSpec(spec *Swagger, options *ExpandOptions) error {
+	resolver, err := defaultSchemaLoader(spec, options, nil, nil)
+	// Just in case this ever returns an error.
+	if shouldStopOnError(err, resolver.options) {
+		return err
+	}
+
+	// getting the base path of the spec to adjust all subsequent reference resolutions
+	specBasePath := ""
+	if options != nil && options.RelativeBase != "" {
+		specBasePath, _ = absPath(options.RelativeBase)
+	}
+
+	if options == nil || !options.SkipSchemas {
+		for key, definition := range spec.Definitions {
+			var def *Schema
+			var err error
+			if def, err = expandSchema(definition, []string{fmt.Sprintf("#/definitions/%s", key)}, resolver, specBasePath); shouldStopOnError(err, resolver.options) {
+				return err
+			}
+			if def != nil {
+				spec.Definitions[key] = *def
+			}
+		}
+	}
+
+	for key, parameter := range spec.Parameters {
+		if err := expandParameter(&parameter, resolver, specBasePath); shouldStopOnError(err, resolver.options) {
+			return err
+		}
+		spec.Parameters[key] = parameter
+	}
+
+	for key, response := range spec.Responses {
+		if err := expandResponse(&response, resolver, specBasePath); shouldStopOnError(err, resolver.options) {
+			return err
+		}
+		spec.Responses[key] = response
+	}
+
+	if spec.Paths != nil {
+		for key, path := range spec.Paths.Paths {
+			if err := expandPathItem(&path, resolver, specBasePath); shouldStopOnError(err, resolver.options) {
+				return err
+			}
+			spec.Paths.Paths[key] = path
+		}
+	}
+
+	return nil
+}
+
+func shouldStopOnError(err error, opts *ExpandOptions) bool {
+	if err != nil && !opts.ContinueOnError {
+		return true
+	}
+
+	if err != nil {
+		log.Println(err)
+	}
+
+	return false
+}
+
+// baseForRoot loads in the cache the root document and produces a fake "root" base path entry
+// for further $ref resolution
+func baseForRoot(root interface{}, cache ResolutionCache) string {
+	// cache the root document to resolve $ref's
+	const rootBase = "root"
+	if root != nil {
+		base, _ := absPath(rootBase)
+		normalizedBase := normalizeAbsPath(base)
+		debugLog("setting root doc in cache at: %s", normalizedBase)
+		if cache == nil {
+			cache = resCache
+		}
+		cache.Set(normalizedBase, root)
+		return rootBase
+	}
+	return ""
+}
+
+// ExpandSchema expands the refs in the schema object with reference to the root object
+// go-openapi/validate uses this function
+// notice that it is impossible to reference a json schema in a different file other than root
+func ExpandSchema(schema *Schema, root interface{}, cache ResolutionCache) error {
+	opts := &ExpandOptions{
+		// when a root is specified, cache the root as an in-memory document for $ref retrieval
+		RelativeBase:    baseForRoot(root, cache),
+		SkipSchemas:     false,
+		ContinueOnError: false,
+		// when no base path is specified, remaining $ref (circular) are rendered with an absolute path
+		AbsoluteCircularRef: true,
+	}
+	return ExpandSchemaWithBasePath(schema, cache, opts)
+}
+
+// ExpandSchemaWithBasePath expands the refs in the schema object, base path configured through expand options
+func ExpandSchemaWithBasePath(schema *Schema, cache ResolutionCache, opts *ExpandOptions) error {
+	if schema == nil {
+		return nil
+	}
+
+	var basePath string
+	if opts.RelativeBase != "" {
+		basePath, _ = absPath(opts.RelativeBase)
+	}
+
+	resolver, err := defaultSchemaLoader(nil, opts, cache, nil)
+	if err != nil {
+		return err
+	}
+
+	refs := []string{""}
+	var s *Schema
+	if s, err = expandSchema(*schema, refs, resolver, basePath); err != nil {
+		return err
+	}
+	*schema = *s
+	return nil
+}
+
+func expandItems(target Schema, parentRefs []string, resolver *schemaLoader, basePath string) (*Schema, error) {
+	if target.Items != nil {
+		if target.Items.Schema != nil {
+			t, err := expandSchema(*target.Items.Schema, parentRefs, resolver, basePath)
+			if err != nil {
+				return nil, err
+			}
+			*target.Items.Schema = *t
+		}
+		for i := range target.Items.Schemas {
+			t, err := expandSchema(target.Items.Schemas[i], parentRefs, resolver, basePath)
+			if err != nil {
+				return nil, err
+			}
+			target.Items.Schemas[i] = *t
+		}
+	}
+	return &target, nil
+}
+
+// basePathFromSchemaID returns a new basePath based on an existing basePath and a schema ID
+func basePathFromSchemaID(oldBasePath, id string) string {
+	u, err := url.Parse(oldBasePath)
+	if err != nil {
+		panic(err)
+	}
+	uid, err := url.Parse(id)
+	if err != nil {
+		panic(err)
+	}
+
+	if path.IsAbs(uid.Path) {
+		return id
+	}
+	u.Path = path.Join(path.Dir(u.Path), uid.Path)
+	return u.String()
+}
+
+// isCircular detects cycles in sequences of $ref.
+// It relies on a private context (which needs not be locked).
+func (r *schemaLoader) isCircular(ref *Ref, basePath string, parentRefs ...string) (foundCycle bool) {
+	normalizedRef := normalizePaths(ref.String(), basePath)
+	if _, ok := r.context.circulars[normalizedRef]; ok {
+		// circular $ref has been already detected in another explored cycle
+		foundCycle = true
+		return
+	}
+	foundCycle = swag.ContainsStringsCI(parentRefs, normalizedRef)
+	if foundCycle {
+		r.context.circulars[normalizedRef] = true
+	}
+	return
+}
+
+func updateBasePath(transitive *schemaLoader, resolver *schemaLoader, basePath string) string {
+	if transitive != resolver {
+		debugLog("got a new resolver")
+		if transitive.options != nil && transitive.options.RelativeBase != "" {
+			basePath, _ = absPath(transitive.options.RelativeBase)
+			debugLog("new basePath = %s", basePath)
+		}
+	}
+
+	return basePath
+}
+
+func expandSchema(target Schema, parentRefs []string, resolver *schemaLoader, basePath string) (*Schema, error) {
+	if target.Ref.String() == "" && target.Ref.IsRoot() {
+		// normalizing is important
+		newRef := normalizeFileRef(&target.Ref, basePath)
+		target.Ref = *newRef
+		return &target, nil
+
+	}
+
+	/* change the base path of resolution when an ID is encountered
+	   otherwise the basePath should inherit the parent's */
+	// important: ID can be relative path
+	if target.ID != "" {
+		debugLog("schema has ID: %s", target.ID)
+		// handling the case when id is a folder
+		// remember that basePath has to be a file
+		refPath := target.ID
+		if strings.HasSuffix(target.ID, "/") {
+			// path.Clean here would not work correctly if basepath is http
+			refPath = fmt.Sprintf("%s%s", refPath, "placeholder.json")
+		}
+		basePath = normalizePaths(refPath, basePath)
+	}
+
+	/* Explain here what this function does */
+	var t *Schema
+	/* if Ref is found, everything else doesn't matter */
+	/* Ref also changes the resolution scope of children expandSchema */
+	if target.Ref.String() != "" {
+		/* Here the resolution scope is changed because a $ref was encountered */
+		normalizedRef := normalizeFileRef(&target.Ref, basePath)
+		normalizedBasePath := normalizedRef.RemoteURI()
+
+		if resolver.isCircular(normalizedRef, basePath, parentRefs...) {
+			// this means there is a cycle in the recursion tree: return the Ref
+			// - circular refs cannot be expanded. We leave them as ref.
+			// - denormalization means that a new local file ref is set relative to the original basePath
+			debugLog("shortcut circular ref: basePath: %s, normalizedPath: %s, normalized ref: %s",
+				basePath, normalizedBasePath, normalizedRef.String())
+			if !resolver.options.AbsoluteCircularRef {
+				target.Ref = *denormalizeFileRef(normalizedRef, normalizedBasePath, resolver.context.basePath)
+			} else {
+				target.Ref = *normalizedRef
+			}
+			return &target, nil
+		}
+
+		debugLog("basePath: %s", basePath)
+		if Debug {
+			b, _ := json.Marshal(target)
+			debugLog("calling Resolve with target: %s", string(b))
+		}
+		if err := resolver.Resolve(&target.Ref, &t, basePath); shouldStopOnError(err, resolver.options) {
+			return nil, err
+		}
+
+		if t != nil {
+			parentRefs = append(parentRefs, normalizedRef.String())
+			var err error
+			transitiveResolver, err := transitiveResolver(basePath, target.Ref, resolver)
+			if shouldStopOnError(err, resolver.options) {
+				return nil, err
+			}
+
+			basePath = updateBasePath(transitiveResolver, resolver, normalizedBasePath)
+
+			return expandSchema(*t, parentRefs, transitiveResolver, basePath)
+		}
+	}
+
+	t, err := expandItems(target, parentRefs, resolver, basePath)
+	if shouldStopOnError(err, resolver.options) {
+		return &target, err
+	}
+	if t != nil {
+		target = *t
+	}
+
+	for i := range target.AllOf {
+		t, err := expandSchema(target.AllOf[i], parentRefs, resolver, basePath)
+		if shouldStopOnError(err, resolver.options) {
+			return &target, err
+		}
+		target.AllOf[i] = *t
+	}
+	for i := range target.AnyOf {
+		t, err := expandSchema(target.AnyOf[i], parentRefs, resolver, basePath)
+		if shouldStopOnError(err, resolver.options) {
+			return &target, err
+		}
+		target.AnyOf[i] = *t
+	}
+	for i := range target.OneOf {
+		t, err := expandSchema(target.OneOf[i], parentRefs, resolver, basePath)
+		if shouldStopOnError(err, resolver.options) {
+			return &target, err
+		}
+		if t != nil {
+			target.OneOf[i] = *t
+		}
+	}
+	if target.Not != nil {
+		t, err := expandSchema(*target.Not, parentRefs, resolver, basePath)
+		if shouldStopOnError(err, resolver.options) {
+			return &target, err
+		}
+		if t != nil {
+			*target.Not = *t
+		}
+	}
+	for k := range target.Properties {
+		t, err := expandSchema(target.Properties[k], parentRefs, resolver, basePath)
+		if shouldStopOnError(err, resolver.options) {
+			return &target, err
+		}
+		if t != nil {
+			target.Properties[k] = *t
+		}
+	}
+	if target.AdditionalProperties != nil && target.AdditionalProperties.Schema != nil {
+		t, err := expandSchema(*target.AdditionalProperties.Schema, parentRefs, resolver, basePath)
+		if shouldStopOnError(err, resolver.options) {
+			return &target, err
+		}
+		if t != nil {
+			*target.AdditionalProperties.Schema = *t
+		}
+	}
+	for k := range target.PatternProperties {
+		t, err := expandSchema(target.PatternProperties[k], parentRefs, resolver, basePath)
+		if shouldStopOnError(err, resolver.options) {
+			return &target, err
+		}
+		if t != nil {
+			target.PatternProperties[k] = *t
+		}
+	}
+	for k := range target.Dependencies {
+		if target.Dependencies[k].Schema != nil {
+			t, err := expandSchema(*target.Dependencies[k].Schema, parentRefs, resolver, basePath)
+			if shouldStopOnError(err, resolver.options) {
+				return &target, err
+			}
+			if t != nil {
+				*target.Dependencies[k].Schema = *t
+			}
+		}
+	}
+	if target.AdditionalItems != nil && target.AdditionalItems.Schema != nil {
+		t, err := expandSchema(*target.AdditionalItems.Schema, parentRefs, resolver, basePath)
+		if shouldStopOnError(err, resolver.options) {
+			return &target, err
+		}
+		if t != nil {
+			*target.AdditionalItems.Schema = *t
+		}
+	}
+	for k := range target.Definitions {
+		t, err := expandSchema(target.Definitions[k], parentRefs, resolver, basePath)
+		if shouldStopOnError(err, resolver.options) {
+			return &target, err
+		}
+		if t != nil {
+			target.Definitions[k] = *t
+		}
+	}
+	return &target, nil
+}
+
+func derefPathItem(pathItem *PathItem, parentRefs []string, resolver *schemaLoader, basePath string) error {
+	curRef := pathItem.Ref.String()
+	if curRef != "" {
+		normalizedRef := normalizeFileRef(&pathItem.Ref, basePath)
+		normalizedBasePath := normalizedRef.RemoteURI()
+
+		if resolver.isCircular(normalizedRef, basePath, parentRefs...) {
+			return nil
+		}
+
+		if err := resolver.Resolve(&pathItem.Ref, pathItem, basePath); shouldStopOnError(err, resolver.options) {
+			return err
+		}
+
+		if pathItem.Ref.String() != "" && pathItem.Ref.String() != curRef && basePath != normalizedBasePath {
+			parentRefs = append(parentRefs, normalizedRef.String())
+			return derefPathItem(pathItem, parentRefs, resolver, normalizedBasePath)
+		}
+	}
+
+	return nil
+}
+
+func expandPathItem(pathItem *PathItem, resolver *schemaLoader, basePath string) error {
+	if pathItem == nil {
+		return nil
+	}
+
+	parentRefs := []string{}
+	if err := derefPathItem(pathItem, parentRefs, resolver, basePath); shouldStopOnError(err, resolver.options) {
+		return err
+	}
+	if pathItem.Ref.String() != "" {
+		var err error
+		resolver, err = transitiveResolver(basePath, pathItem.Ref, resolver)
+		if shouldStopOnError(err, resolver.options) {
+			return err
+		}
+	}
+	pathItem.Ref = Ref{}
+
+	// Currently unused:
+	//parentRefs = parentRefs[0:]
+
+	for idx := range pathItem.Parameters {
+		if err := expandParameter(&(pathItem.Parameters[idx]), resolver, basePath); shouldStopOnError(err, resolver.options) {
+			return err
+		}
+	}
+	if err := expandOperation(pathItem.Get, resolver, basePath); shouldStopOnError(err, resolver.options) {
+		return err
+	}
+	if err := expandOperation(pathItem.Head, resolver, basePath); shouldStopOnError(err, resolver.options) {
+		return err
+	}
+	if err := expandOperation(pathItem.Options, resolver, basePath); shouldStopOnError(err, resolver.options) {
+		return err
+	}
+	if err := expandOperation(pathItem.Put, resolver, basePath); shouldStopOnError(err, resolver.options) {
+		return err
+	}
+	if err := expandOperation(pathItem.Post, resolver, basePath); shouldStopOnError(err, resolver.options) {
+		return err
+	}
+	if err := expandOperation(pathItem.Patch, resolver, basePath); shouldStopOnError(err, resolver.options) {
+		return err
+	}
+	if err := expandOperation(pathItem.Delete, resolver, basePath); shouldStopOnError(err, resolver.options) {
+		return err
+	}
+	return nil
+}
+
+func expandOperation(op *Operation, resolver *schemaLoader, basePath string) error {
+	if op == nil {
+		return nil
+	}
+
+	for i, param := range op.Parameters {
+		if err := expandParameter(&param, resolver, basePath); shouldStopOnError(err, resolver.options) {
+			return err
+		}
+		op.Parameters[i] = param
+	}
+
+	if op.Responses != nil {
+		responses := op.Responses
+		if err := expandResponse(responses.Default, resolver, basePath); shouldStopOnError(err, resolver.options) {
+			return err
+		}
+		for code, response := range responses.StatusCodeResponses {
+			if err := expandResponse(&response, resolver, basePath); shouldStopOnError(err, resolver.options) {
+				return err
+			}
+			responses.StatusCodeResponses[code] = response
+		}
+	}
+	return nil
+}
+
+func transitiveResolver(basePath string, ref Ref, resolver *schemaLoader) (*schemaLoader, error) {
+	if ref.IsRoot() || ref.HasFragmentOnly {
+		return resolver, nil
+	}
+
+	baseRef, _ := NewRef(basePath)
+	currentRef := normalizeFileRef(&ref, basePath)
+	// Set a new root to resolve against
+	if !strings.HasPrefix(currentRef.String(), baseRef.String()) {
+		rootURL := currentRef.GetURL()
+		rootURL.Fragment = ""
+		root, _ := resolver.cache.Get(rootURL.String())
+		var err error
+
+		// shallow copy of resolver options to set a new RelativeBase when
+		// traversing multiple documents
+		newOptions := resolver.options
+		newOptions.RelativeBase = rootURL.String()
+		debugLog("setting new root: %s", newOptions.RelativeBase)
+		resolver, err = defaultSchemaLoader(root, newOptions, resolver.cache, resolver.context)
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	return resolver, nil
+}
+
+// ExpandResponseWithRoot expands a response based on a root document, not a fetchable document
+func ExpandResponseWithRoot(response *Response, root interface{}, cache ResolutionCache) error {
+	opts := &ExpandOptions{
+		RelativeBase:    baseForRoot(root, cache),
+		SkipSchemas:     false,
+		ContinueOnError: false,
+		// when no base path is specified, remaining $ref (circular) are rendered with an absolute path
+		AbsoluteCircularRef: true,
+	}
+	resolver, err := defaultSchemaLoader(root, opts, nil, nil)
+	if err != nil {
+		return err
+	}
+
+	return expandResponse(response, resolver, opts.RelativeBase)
+}
+
+// ExpandResponse expands a response based on a basepath
+// This is the exported version of expandResponse
+// all refs inside response will be resolved relative to basePath
+func ExpandResponse(response *Response, basePath string) error {
+	var specBasePath string
+	if basePath != "" {
+		specBasePath, _ = absPath(basePath)
+	}
+	opts := &ExpandOptions{
+		RelativeBase: specBasePath,
+	}
+	resolver, err := defaultSchemaLoader(nil, opts, nil, nil)
+	if err != nil {
+		return err
+	}
+
+	return expandResponse(response, resolver, opts.RelativeBase)
+}
+
+func derefResponse(response *Response, parentRefs []string, resolver *schemaLoader, basePath string) error {
+	curRef := response.Ref.String()
+	if curRef != "" {
+		/* Here the resolution scope is changed because a $ref was encountered */
+		normalizedRef := normalizeFileRef(&response.Ref, basePath)
+		normalizedBasePath := normalizedRef.RemoteURI()
+
+		if resolver.isCircular(normalizedRef, basePath, parentRefs...) {
+			return nil
+		}
+
+		if err := resolver.Resolve(&response.Ref, response, basePath); shouldStopOnError(err, resolver.options) {
+			return err
+		}
+
+		if response.Ref.String() != "" && response.Ref.String() != curRef && basePath != normalizedBasePath {
+			parentRefs = append(parentRefs, normalizedRef.String())
+			return derefResponse(response, parentRefs, resolver, normalizedBasePath)
+		}
+	}
+
+	return nil
+}
+
+func expandResponse(response *Response, resolver *schemaLoader, basePath string) error {
+	if response == nil {
+		return nil
+	}
+	parentRefs := []string{}
+	if err := derefResponse(response, parentRefs, resolver, basePath); shouldStopOnError(err, resolver.options) {
+		return err
+	}
+	if response.Ref.String() != "" {
+		transitiveResolver, err := transitiveResolver(basePath, response.Ref, resolver)
+		if shouldStopOnError(err, transitiveResolver.options) {
+			return err
+		}
+		basePath = updateBasePath(transitiveResolver, resolver, basePath)
+		resolver = transitiveResolver
+	}
+	if response.Schema != nil && response.Schema.Ref.String() != "" {
+		// schema expanded to a $ref in another root
+		var ern error
+		response.Schema.Ref, ern = NewRef(normalizePaths(response.Schema.Ref.String(), response.Ref.RemoteURI()))
+		if ern != nil {
+			return ern
+		}
+	}
+	response.Ref = Ref{}
+
+	parentRefs = parentRefs[0:]
+	if !resolver.options.SkipSchemas && response.Schema != nil {
+		// parentRefs = append(parentRefs, response.Schema.Ref.String())
+		s, err := expandSchema(*response.Schema, parentRefs, resolver, basePath)
+		if shouldStopOnError(err, resolver.options) {
+			return err
+		}
+		*response.Schema = *s
+	}
+
+	return nil
+}
+
+// ExpandParameterWithRoot expands a parameter based on a root document, not a fetchable document
+func ExpandParameterWithRoot(parameter *Parameter, root interface{}, cache ResolutionCache) error {
+	opts := &ExpandOptions{
+		RelativeBase:    baseForRoot(root, cache),
+		SkipSchemas:     false,
+		ContinueOnError: false,
+		// when no base path is specified, remaining $ref (circular) are rendered with an absolute path
+		AbsoluteCircularRef: true,
+	}
+	resolver, err := defaultSchemaLoader(root, opts, nil, nil)
+	if err != nil {
+		return err
+	}
+
+	return expandParameter(parameter, resolver, opts.RelativeBase)
+}
+
+// ExpandParameter expands a parameter based on a basepath
+// This is the exported version of expandParameter
+// all refs inside parameter will be resolved relative to basePath
+func ExpandParameter(parameter *Parameter, basePath string) error {
+	var specBasePath string
+	if basePath != "" {
+		specBasePath, _ = absPath(basePath)
+	}
+	opts := &ExpandOptions{
+		RelativeBase: specBasePath,
+	}
+	resolver, err := defaultSchemaLoader(nil, opts, nil, nil)
+	if err != nil {
+		return err
+	}
+
+	return expandParameter(parameter, resolver, opts.RelativeBase)
+}
+
+func derefParameter(parameter *Parameter, parentRefs []string, resolver *schemaLoader, basePath string) error {
+	curRef := parameter.Ref.String()
+	if curRef != "" {
+		normalizedRef := normalizeFileRef(&parameter.Ref, basePath)
+		normalizedBasePath := normalizedRef.RemoteURI()
+
+		if resolver.isCircular(normalizedRef, basePath, parentRefs...) {
+			return nil
+		}
+
+		if err := resolver.Resolve(&parameter.Ref, parameter, basePath); shouldStopOnError(err, resolver.options) {
+			return err
+		}
+
+		if parameter.Ref.String() != "" && parameter.Ref.String() != curRef && basePath != normalizedBasePath {
+			parentRefs = append(parentRefs, normalizedRef.String())
+			return derefParameter(parameter, parentRefs, resolver, normalizedBasePath)
+		}
+	}
+
+	return nil
+}
+
+func expandParameter(parameter *Parameter, resolver *schemaLoader, basePath string) error {
+	if parameter == nil {
+		return nil
+	}
+
+	parentRefs := []string{}
+	if err := derefParameter(parameter, parentRefs, resolver, basePath); shouldStopOnError(err, resolver.options) {
+		return err
+	}
+	if parameter.Ref.String() != "" {
+		transitiveResolver, err := transitiveResolver(basePath, parameter.Ref, resolver)
+		if shouldStopOnError(err, transitiveResolver.options) {
+			return err
+		}
+		basePath = updateBasePath(transitiveResolver, resolver, basePath)
+		resolver = transitiveResolver
+	}
+
+	if parameter.Schema != nil && parameter.Schema.Ref.String() != "" {
+		// schema expanded to a $ref in another root
+		var ern error
+		parameter.Schema.Ref, ern = NewRef(normalizePaths(parameter.Schema.Ref.String(), parameter.Ref.RemoteURI()))
+		if ern != nil {
+			return ern
+		}
+	}
+	parameter.Ref = Ref{}
+
+	parentRefs = parentRefs[0:]
+	if !resolver.options.SkipSchemas && parameter.Schema != nil {
+		s, err := expandSchema(*parameter.Schema, parentRefs, resolver, basePath)
+		if shouldStopOnError(err, resolver.options) {
+			return err
+		}
+		*parameter.Schema = *s
+	}
+	return nil
+}
diff --git a/go/vendor/github.com/go-openapi/spec/external_docs.go b/go/vendor/github.com/go-openapi/spec/external_docs.go
new file mode 100644
index 0000000..88add91
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/external_docs.go
@@ -0,0 +1,24 @@
+// 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 spec
+
+// ExternalDocumentation allows referencing an external resource for
+// extended documentation.
+//
+// For more information: http://goo.gl/8us55a#externalDocumentationObject
+type ExternalDocumentation struct {
+	Description string `json:"description,omitempty"`
+	URL         string `json:"url,omitempty"`
+}
diff --git a/go/vendor/github.com/go-openapi/spec/go.mod b/go/vendor/github.com/go-openapi/spec/go.mod
new file mode 100644
index 0000000..5af64c1
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/go.mod
@@ -0,0 +1,16 @@
+module github.com/go-openapi/spec
+
+require (
+	github.com/PuerkitoBio/purell v1.1.0 // indirect
+	github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
+	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/go-openapi/jsonpointer v0.17.0
+	github.com/go-openapi/jsonreference v0.17.0
+	github.com/go-openapi/swag v0.17.0
+	github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	github.com/stretchr/testify v1.2.2
+	golang.org/x/net v0.0.0-20181005035420-146acd28ed58 // indirect
+	golang.org/x/text v0.3.0 // indirect
+	gopkg.in/yaml.v2 v2.2.1
+)
diff --git a/go/vendor/github.com/go-openapi/spec/go.sum b/go/vendor/github.com/go-openapi/spec/go.sum
new file mode 100644
index 0000000..ab6bfb6
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/go.sum
@@ -0,0 +1,22 @@
+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/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/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/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/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/spec/header.go b/go/vendor/github.com/go-openapi/spec/header.go
new file mode 100644
index 0000000..82f77f7
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/header.go
@@ -0,0 +1,193 @@
+// 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 spec
+
+import (
+	"encoding/json"
+	"strings"
+
+	"github.com/go-openapi/jsonpointer"
+	"github.com/go-openapi/swag"
+)
+
+// HeaderProps describes a response header
+type HeaderProps struct {
+	Description string `json:"description,omitempty"`
+}
+
+// Header describes a header for a response of the API
+//
+// For more information: http://goo.gl/8us55a#headerObject
+type Header struct {
+	CommonValidations
+	SimpleSchema
+	VendorExtensible
+	HeaderProps
+}
+
+// ResponseHeader creates a new header instance for use in a response
+func ResponseHeader() *Header {
+	return new(Header)
+}
+
+// WithDescription sets the description on this response, allows for chaining
+func (h *Header) WithDescription(description string) *Header {
+	h.Description = description
+	return h
+}
+
+// Typed a fluent builder method for the type of parameter
+func (h *Header) Typed(tpe, format string) *Header {
+	h.Type = tpe
+	h.Format = format
+	return h
+}
+
+// CollectionOf a fluent builder method for an array item
+func (h *Header) CollectionOf(items *Items, format string) *Header {
+	h.Type = "array"
+	h.Items = items
+	h.CollectionFormat = format
+	return h
+}
+
+// WithDefault sets the default value on this item
+func (h *Header) WithDefault(defaultValue interface{}) *Header {
+	h.Default = defaultValue
+	return h
+}
+
+// WithMaxLength sets a max length value
+func (h *Header) WithMaxLength(max int64) *Header {
+	h.MaxLength = &max
+	return h
+}
+
+// WithMinLength sets a min length value
+func (h *Header) WithMinLength(min int64) *Header {
+	h.MinLength = &min
+	return h
+}
+
+// WithPattern sets a pattern value
+func (h *Header) WithPattern(pattern string) *Header {
+	h.Pattern = pattern
+	return h
+}
+
+// WithMultipleOf sets a multiple of value
+func (h *Header) WithMultipleOf(number float64) *Header {
+	h.MultipleOf = &number
+	return h
+}
+
+// WithMaximum sets a maximum number value
+func (h *Header) WithMaximum(max float64, exclusive bool) *Header {
+	h.Maximum = &max
+	h.ExclusiveMaximum = exclusive
+	return h
+}
+
+// WithMinimum sets a minimum number value
+func (h *Header) WithMinimum(min float64, exclusive bool) *Header {
+	h.Minimum = &min
+	h.ExclusiveMinimum = exclusive
+	return h
+}
+
+// WithEnum sets a the enum values (replace)
+func (h *Header) WithEnum(values ...interface{}) *Header {
+	h.Enum = append([]interface{}{}, values...)
+	return h
+}
+
+// WithMaxItems sets the max items
+func (h *Header) WithMaxItems(size int64) *Header {
+	h.MaxItems = &size
+	return h
+}
+
+// WithMinItems sets the min items
+func (h *Header) WithMinItems(size int64) *Header {
+	h.MinItems = &size
+	return h
+}
+
+// UniqueValues dictates that this array can only have unique items
+func (h *Header) UniqueValues() *Header {
+	h.UniqueItems = true
+	return h
+}
+
+// AllowDuplicates this array can have duplicates
+func (h *Header) AllowDuplicates() *Header {
+	h.UniqueItems = false
+	return h
+}
+
+// MarshalJSON marshal this to JSON
+func (h Header) MarshalJSON() ([]byte, error) {
+	b1, err := json.Marshal(h.CommonValidations)
+	if err != nil {
+		return nil, err
+	}
+	b2, err := json.Marshal(h.SimpleSchema)
+	if err != nil {
+		return nil, err
+	}
+	b3, err := json.Marshal(h.HeaderProps)
+	if err != nil {
+		return nil, err
+	}
+	return swag.ConcatJSON(b1, b2, b3), nil
+}
+
+// UnmarshalJSON unmarshals this header from JSON
+func (h *Header) UnmarshalJSON(data []byte) error {
+	if err := json.Unmarshal(data, &h.CommonValidations); err != nil {
+		return err
+	}
+	if err := json.Unmarshal(data, &h.SimpleSchema); err != nil {
+		return err
+	}
+	if err := json.Unmarshal(data, &h.VendorExtensible); err != nil {
+		return err
+	}
+	return json.Unmarshal(data, &h.HeaderProps)
+}
+
+// JSONLookup look up a value by the json property name
+func (h Header) JSONLookup(token string) (interface{}, error) {
+	if ex, ok := h.Extensions[token]; ok {
+		return &ex, nil
+	}
+
+	r, _, err := jsonpointer.GetForToken(h.CommonValidations, token)
+	if err != nil && !strings.HasPrefix(err.Error(), "object has no field") {
+		return nil, err
+	}
+	if r != nil {
+		return r, nil
+	}
+	r, _, err = jsonpointer.GetForToken(h.SimpleSchema, token)
+	if err != nil && !strings.HasPrefix(err.Error(), "object has no field") {
+		return nil, err
+	}
+	if r != nil {
+		return r, nil
+	}
+	r, _, err = jsonpointer.GetForToken(h.HeaderProps, token)
+	return r, err
+}
diff --git a/go/vendor/github.com/go-openapi/spec/info.go b/go/vendor/github.com/go-openapi/spec/info.go
new file mode 100644
index 0000000..cfb37ec
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/info.go
@@ -0,0 +1,168 @@
+// 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 spec
+
+import (
+	"encoding/json"
+	"strings"
+
+	"github.com/go-openapi/jsonpointer"
+	"github.com/go-openapi/swag"
+)
+
+// Extensions vendor specific extensions
+type Extensions map[string]interface{}
+
+// Add adds a value to these extensions
+func (e Extensions) Add(key string, value interface{}) {
+	realKey := strings.ToLower(key)
+	e[realKey] = value
+}
+
+// GetString gets a string value from the extensions
+func (e Extensions) GetString(key string) (string, bool) {
+	if v, ok := e[strings.ToLower(key)]; ok {
+		str, ok := v.(string)
+		return str, ok
+	}
+	return "", false
+}
+
+// GetBool gets a string value from the extensions
+func (e Extensions) GetBool(key string) (bool, bool) {
+	if v, ok := e[strings.ToLower(key)]; ok {
+		str, ok := v.(bool)
+		return str, ok
+	}
+	return false, false
+}
+
+// GetStringSlice gets a string value from the extensions
+func (e Extensions) GetStringSlice(key string) ([]string, bool) {
+	if v, ok := e[strings.ToLower(key)]; ok {
+		arr, isSlice := v.([]interface{})
+		if !isSlice {
+			return nil, false
+		}
+		var strs []string
+		for _, iface := range arr {
+			str, isString := iface.(string)
+			if !isString {
+				return nil, false
+			}
+			strs = append(strs, str)
+		}
+		return strs, ok
+	}
+	return nil, false
+}
+
+// VendorExtensible composition block.
+type VendorExtensible struct {
+	Extensions Extensions
+}
+
+// AddExtension adds an extension to this extensible object
+func (v *VendorExtensible) AddExtension(key string, value interface{}) {
+	if value == nil {
+		return
+	}
+	if v.Extensions == nil {
+		v.Extensions = make(map[string]interface{})
+	}
+	v.Extensions.Add(key, value)
+}
+
+// MarshalJSON marshals the extensions to json
+func (v VendorExtensible) MarshalJSON() ([]byte, error) {
+	toser := make(map[string]interface{})
+	for k, v := range v.Extensions {
+		lk := strings.ToLower(k)
+		if strings.HasPrefix(lk, "x-") {
+			toser[k] = v
+		}
+	}
+	return json.Marshal(toser)
+}
+
+// UnmarshalJSON for this extensible object
+func (v *VendorExtensible) UnmarshalJSON(data []byte) error {
+	var d map[string]interface{}
+	if err := json.Unmarshal(data, &d); err != nil {
+		return err
+	}
+	for k, vv := range d {
+		lk := strings.ToLower(k)
+		if strings.HasPrefix(lk, "x-") {
+			if v.Extensions == nil {
+				v.Extensions = map[string]interface{}{}
+			}
+			v.Extensions[k] = vv
+		}
+	}
+	return nil
+}
+
+// InfoProps the properties for an info definition
+type InfoProps struct {
+	Description    string       `json:"description,omitempty"`
+	Title          string       `json:"title,omitempty"`
+	TermsOfService string       `json:"termsOfService,omitempty"`
+	Contact        *ContactInfo `json:"contact,omitempty"`
+	License        *License     `json:"license,omitempty"`
+	Version        string       `json:"version,omitempty"`
+}
+
+// Info object provides metadata about the API.
+// The metadata can be used by the clients if needed, and can be presented in the Swagger-UI for convenience.
+//
+// For more information: http://goo.gl/8us55a#infoObject
+type Info struct {
+	VendorExtensible
+	InfoProps
+}
+
+// JSONLookup look up a value by the json property name
+func (i Info) JSONLookup(token string) (interface{}, error) {
+	if ex, ok := i.Extensions[token]; ok {
+		return &ex, nil
+	}
+	r, _, err := jsonpointer.GetForToken(i.InfoProps, token)
+	return r, err
+}
+
+// MarshalJSON marshal this to JSON
+func (i Info) MarshalJSON() ([]byte, error) {
+	b1, err := json.Marshal(i.InfoProps)
+	if err != nil {
+		return nil, err
+	}
+	b2, err := json.Marshal(i.VendorExtensible)
+	if err != nil {
+		return nil, err
+	}
+	return swag.ConcatJSON(b1, b2), nil
+}
+
+// UnmarshalJSON marshal this from JSON
+func (i *Info) UnmarshalJSON(data []byte) error {
+	if err := json.Unmarshal(data, &i.InfoProps); err != nil {
+		return err
+	}
+	if err := json.Unmarshal(data, &i.VendorExtensible); err != nil {
+		return err
+	}
+	return nil
+}
diff --git a/go/vendor/github.com/go-openapi/spec/items.go b/go/vendor/github.com/go-openapi/spec/items.go
new file mode 100644
index 0000000..cf42989
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/items.go
@@ -0,0 +1,233 @@
+// 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 spec
+
+import (
+	"encoding/json"
+	"strings"
+
+	"github.com/go-openapi/jsonpointer"
+	"github.com/go-openapi/swag"
+)
+
+// SimpleSchema describe swagger simple schemas for parameters and headers
+type SimpleSchema struct {
+	Type             string      `json:"type,omitempty"`
+	Format           string      `json:"format,omitempty"`
+	Items            *Items      `json:"items,omitempty"`
+	CollectionFormat string      `json:"collectionFormat,omitempty"`
+	Default          interface{} `json:"default,omitempty"`
+	Example          interface{} `json:"example,omitempty"`
+}
+
+// TypeName return the type (or format) of a simple schema
+func (s *SimpleSchema) TypeName() string {
+	if s.Format != "" {
+		return s.Format
+	}
+	return s.Type
+}
+
+// ItemsTypeName yields the type of items in a simple schema array
+func (s *SimpleSchema) ItemsTypeName() string {
+	if s.Items == nil {
+		return ""
+	}
+	return s.Items.TypeName()
+}
+
+// CommonValidations describe common JSON-schema validations
+type CommonValidations struct {
+	Maximum          *float64      `json:"maximum,omitempty"`
+	ExclusiveMaximum bool          `json:"exclusiveMaximum,omitempty"`
+	Minimum          *float64      `json:"minimum,omitempty"`
+	ExclusiveMinimum bool          `json:"exclusiveMinimum,omitempty"`
+	MaxLength        *int64        `json:"maxLength,omitempty"`
+	MinLength        *int64        `json:"minLength,omitempty"`
+	Pattern          string        `json:"pattern,omitempty"`
+	MaxItems         *int64        `json:"maxItems,omitempty"`
+	MinItems         *int64        `json:"minItems,omitempty"`
+	UniqueItems      bool          `json:"uniqueItems,omitempty"`
+	MultipleOf       *float64      `json:"multipleOf,omitempty"`
+	Enum             []interface{} `json:"enum,omitempty"`
+}
+
+// Items a limited subset of JSON-Schema's items object.
+// It is used by parameter definitions that are not located in "body".
+//
+// For more information: http://goo.gl/8us55a#items-object
+type Items struct {
+	Refable
+	CommonValidations
+	SimpleSchema
+	VendorExtensible
+}
+
+// NewItems creates a new instance of items
+func NewItems() *Items {
+	return &Items{}
+}
+
+// Typed a fluent builder method for the type of item
+func (i *Items) Typed(tpe, format string) *Items {
+	i.Type = tpe
+	i.Format = format
+	return i
+}
+
+// CollectionOf a fluent builder method for an array item
+func (i *Items) CollectionOf(items *Items, format string) *Items {
+	i.Type = "array"
+	i.Items = items
+	i.CollectionFormat = format
+	return i
+}
+
+// WithDefault sets the default value on this item
+func (i *Items) WithDefault(defaultValue interface{}) *Items {
+	i.Default = defaultValue
+	return i
+}
+
+// WithMaxLength sets a max length value
+func (i *Items) WithMaxLength(max int64) *Items {
+	i.MaxLength = &max
+	return i
+}
+
+// WithMinLength sets a min length value
+func (i *Items) WithMinLength(min int64) *Items {
+	i.MinLength = &min
+	return i
+}
+
+// WithPattern sets a pattern value
+func (i *Items) WithPattern(pattern string) *Items {
+	i.Pattern = pattern
+	return i
+}
+
+// WithMultipleOf sets a multiple of value
+func (i *Items) WithMultipleOf(number float64) *Items {
+	i.MultipleOf = &number
+	return i
+}
+
+// WithMaximum sets a maximum number value
+func (i *Items) WithMaximum(max float64, exclusive bool) *Items {
+	i.Maximum = &max
+	i.ExclusiveMaximum = exclusive
+	return i
+}
+
+// WithMinimum sets a minimum number value
+func (i *Items) WithMinimum(min float64, exclusive bool) *Items {
+	i.Minimum = &min
+	i.ExclusiveMinimum = exclusive
+	return i
+}
+
+// WithEnum sets a the enum values (replace)
+func (i *Items) WithEnum(values ...interface{}) *Items {
+	i.Enum = append([]interface{}{}, values...)
+	return i
+}
+
+// WithMaxItems sets the max items
+func (i *Items) WithMaxItems(size int64) *Items {
+	i.MaxItems = &size
+	return i
+}
+
+// WithMinItems sets the min items
+func (i *Items) WithMinItems(size int64) *Items {
+	i.MinItems = &size
+	return i
+}
+
+// UniqueValues dictates that this array can only have unique items
+func (i *Items) UniqueValues() *Items {
+	i.UniqueItems = true
+	return i
+}
+
+// AllowDuplicates this array can have duplicates
+func (i *Items) AllowDuplicates() *Items {
+	i.UniqueItems = false
+	return i
+}
+
+// UnmarshalJSON hydrates this items instance with the data from JSON
+func (i *Items) UnmarshalJSON(data []byte) error {
+	var validations CommonValidations
+	if err := json.Unmarshal(data, &validations); err != nil {
+		return err
+	}
+	var ref Refable
+	if err := json.Unmarshal(data, &ref); err != nil {
+		return err
+	}
+	var simpleSchema SimpleSchema
+	if err := json.Unmarshal(data, &simpleSchema); err != nil {
+		return err
+	}
+	var vendorExtensible VendorExtensible
+	if err := json.Unmarshal(data, &vendorExtensible); err != nil {
+		return err
+	}
+	i.Refable = ref
+	i.CommonValidations = validations
+	i.SimpleSchema = simpleSchema
+	i.VendorExtensible = vendorExtensible
+	return nil
+}
+
+// MarshalJSON converts this items object to JSON
+func (i Items) MarshalJSON() ([]byte, error) {
+	b1, err := json.Marshal(i.CommonValidations)
+	if err != nil {
+		return nil, err
+	}
+	b2, err := json.Marshal(i.SimpleSchema)
+	if err != nil {
+		return nil, err
+	}
+	b3, err := json.Marshal(i.Refable)
+	if err != nil {
+		return nil, err
+	}
+	b4, err := json.Marshal(i.VendorExtensible)
+	if err != nil {
+		return nil, err
+	}
+	return swag.ConcatJSON(b4, b3, b1, b2), nil
+}
+
+// JSONLookup look up a value by the json property name
+func (i Items) JSONLookup(token string) (interface{}, error) {
+	if token == "$ref" {
+		return &i.Ref, nil
+	}
+
+	r, _, err := jsonpointer.GetForToken(i.CommonValidations, token)
+	if err != nil && !strings.HasPrefix(err.Error(), "object has no field") {
+		return nil, err
+	}
+	if r != nil {
+		return r, nil
+	}
+	r, _, err = jsonpointer.GetForToken(i.SimpleSchema, token)
+	return r, err
+}
diff --git a/go/vendor/github.com/go-openapi/spec/license.go b/go/vendor/github.com/go-openapi/spec/license.go
new file mode 100644
index 0000000..f20961b
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/license.go
@@ -0,0 +1,23 @@
+// 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 spec
+
+// License information for the exposed API.
+//
+// For more information: http://goo.gl/8us55a#licenseObject
+type License struct {
+	Name string `json:"name,omitempty"`
+	URL  string `json:"url,omitempty"`
+}
diff --git a/go/vendor/github.com/go-openapi/spec/operation.go b/go/vendor/github.com/go-openapi/spec/operation.go
new file mode 100644
index 0000000..32f7d8f
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/operation.go
@@ -0,0 +1,259 @@
+// 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 spec
+
+import (
+	"encoding/json"
+
+	"github.com/go-openapi/jsonpointer"
+	"github.com/go-openapi/swag"
+)
+
+// OperationProps describes an operation
+type OperationProps struct {
+	Description  string                 `json:"description,omitempty"`
+	Consumes     []string               `json:"consumes,omitempty"`
+	Produces     []string               `json:"produces,omitempty"`
+	Schemes      []string               `json:"schemes,omitempty"` // the scheme, when present must be from [http, https, ws, wss]
+	Tags         []string               `json:"tags,omitempty"`
+	Summary      string                 `json:"summary,omitempty"`
+	ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty"`
+	ID           string                 `json:"operationId,omitempty"`
+	Deprecated   bool                   `json:"deprecated,omitempty"`
+	Security     []map[string][]string  `json:"security,omitempty"` //Special case, see MarshalJSON function
+	Parameters   []Parameter            `json:"parameters,omitempty"`
+	Responses    *Responses             `json:"responses,omitempty"`
+}
+
+// MarshalJSON takes care of serializing operation properties to JSON
+//
+// We use a custom marhaller here to handle a special cases related to
+// the Security field. We need to preserve zero length slice
+// while omitting the field when the value is nil/unset.
+func (op OperationProps) MarshalJSON() ([]byte, error) {
+	type Alias OperationProps
+	if op.Security == nil {
+		return json.Marshal(&struct {
+			Security []map[string][]string `json:"security,omitempty"`
+			*Alias
+		}{
+			Security: op.Security,
+			Alias:    (*Alias)(&op),
+		})
+	}
+	return json.Marshal(&struct {
+		Security []map[string][]string `json:"security"`
+		*Alias
+	}{
+		Security: op.Security,
+		Alias:    (*Alias)(&op),
+	})
+}
+
+// Operation describes a single API operation on a path.
+//
+// For more information: http://goo.gl/8us55a#operationObject
+type Operation struct {
+	VendorExtensible
+	OperationProps
+}
+
+// SuccessResponse gets a success response model
+func (o *Operation) SuccessResponse() (*Response, int, bool) {
+	if o.Responses == nil {
+		return nil, 0, false
+	}
+
+	for k, v := range o.Responses.StatusCodeResponses {
+		if k/100 == 2 {
+			return &v, k, true
+		}
+	}
+
+	return o.Responses.Default, 0, false
+}
+
+// JSONLookup look up a value by the json property name
+func (o Operation) JSONLookup(token string) (interface{}, error) {
+	if ex, ok := o.Extensions[token]; ok {
+		return &ex, nil
+	}
+	r, _, err := jsonpointer.GetForToken(o.OperationProps, token)
+	return r, err
+}
+
+// UnmarshalJSON hydrates this items instance with the data from JSON
+func (o *Operation) UnmarshalJSON(data []byte) error {
+	if err := json.Unmarshal(data, &o.OperationProps); err != nil {
+		return err
+	}
+	if err := json.Unmarshal(data, &o.VendorExtensible); err != nil {
+		return err
+	}
+	return nil
+}
+
+// MarshalJSON converts this items object to JSON
+func (o Operation) MarshalJSON() ([]byte, error) {
+	b1, err := json.Marshal(o.OperationProps)
+	if err != nil {
+		return nil, err
+	}
+	b2, err := json.Marshal(o.VendorExtensible)
+	if err != nil {
+		return nil, err
+	}
+	concated := swag.ConcatJSON(b1, b2)
+	return concated, nil
+}
+
+// NewOperation creates a new operation instance.
+// It expects an ID as parameter but not passing an ID is also valid.
+func NewOperation(id string) *Operation {
+	op := new(Operation)
+	op.ID = id
+	return op
+}
+
+// WithID sets the ID property on this operation, allows for chaining.
+func (o *Operation) WithID(id string) *Operation {
+	o.ID = id
+	return o
+}
+
+// WithDescription sets the description on this operation, allows for chaining
+func (o *Operation) WithDescription(description string) *Operation {
+	o.Description = description
+	return o
+}
+
+// WithSummary sets the summary on this operation, allows for chaining
+func (o *Operation) WithSummary(summary string) *Operation {
+	o.Summary = summary
+	return o
+}
+
+// WithExternalDocs sets/removes the external docs for/from this operation.
+// When you pass empty strings as params the external documents will be removed.
+// When you pass non-empty string as one value then those values will be used on the external docs object.
+// So when you pass a non-empty description, you should also pass the url and vice versa.
+func (o *Operation) WithExternalDocs(description, url string) *Operation {
+	if description == "" && url == "" {
+		o.ExternalDocs = nil
+		return o
+	}
+
+	if o.ExternalDocs == nil {
+		o.ExternalDocs = &ExternalDocumentation{}
+	}
+	o.ExternalDocs.Description = description
+	o.ExternalDocs.URL = url
+	return o
+}
+
+// Deprecate marks the operation as deprecated
+func (o *Operation) Deprecate() *Operation {
+	o.Deprecated = true
+	return o
+}
+
+// Undeprecate marks the operation as not deprected
+func (o *Operation) Undeprecate() *Operation {
+	o.Deprecated = false
+	return o
+}
+
+// WithConsumes adds media types for incoming body values
+func (o *Operation) WithConsumes(mediaTypes ...string) *Operation {
+	o.Consumes = append(o.Consumes, mediaTypes...)
+	return o
+}
+
+// WithProduces adds media types for outgoing body values
+func (o *Operation) WithProduces(mediaTypes ...string) *Operation {
+	o.Produces = append(o.Produces, mediaTypes...)
+	return o
+}
+
+// WithTags adds tags for this operation
+func (o *Operation) WithTags(tags ...string) *Operation {
+	o.Tags = append(o.Tags, tags...)
+	return o
+}
+
+// AddParam adds a parameter to this operation, when a parameter for that location
+// and with that name already exists it will be replaced
+func (o *Operation) AddParam(param *Parameter) *Operation {
+	if param == nil {
+		return o
+	}
+
+	for i, p := range o.Parameters {
+		if p.Name == param.Name && p.In == param.In {
+			params := append(o.Parameters[:i], *param)
+			params = append(params, o.Parameters[i+1:]...)
+			o.Parameters = params
+			return o
+		}
+	}
+
+	o.Parameters = append(o.Parameters, *param)
+	return o
+}
+
+// RemoveParam removes a parameter from the operation
+func (o *Operation) RemoveParam(name, in string) *Operation {
+	for i, p := range o.Parameters {
+		if p.Name == name && p.In == name {
+			o.Parameters = append(o.Parameters[:i], o.Parameters[i+1:]...)
+			return o
+		}
+	}
+	return o
+}
+
+// SecuredWith adds a security scope to this operation.
+func (o *Operation) SecuredWith(name string, scopes ...string) *Operation {
+	o.Security = append(o.Security, map[string][]string{name: scopes})
+	return o
+}
+
+// WithDefaultResponse adds a default response to the operation.
+// Passing a nil value will remove the response
+func (o *Operation) WithDefaultResponse(response *Response) *Operation {
+	return o.RespondsWith(0, response)
+}
+
+// RespondsWith adds a status code response to the operation.
+// When the code is 0 the value of the response will be used as default response value.
+// When the value of the response is nil it will be removed from the operation
+func (o *Operation) RespondsWith(code int, response *Response) *Operation {
+	if o.Responses == nil {
+		o.Responses = new(Responses)
+	}
+	if code == 0 {
+		o.Responses.Default = response
+		return o
+	}
+	if response == nil {
+		delete(o.Responses.StatusCodeResponses, code)
+		return o
+	}
+	if o.Responses.StatusCodeResponses == nil {
+		o.Responses.StatusCodeResponses = make(map[int]Response)
+	}
+	o.Responses.StatusCodeResponses[code] = *response
+	return o
+}
diff --git a/go/vendor/github.com/go-openapi/spec/parameter.go b/go/vendor/github.com/go-openapi/spec/parameter.go
new file mode 100644
index 0000000..cb1a88d
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/parameter.go
@@ -0,0 +1,302 @@
+// 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 spec
+
+import (
+	"encoding/json"
+	"strings"
+
+	"github.com/go-openapi/jsonpointer"
+	"github.com/go-openapi/swag"
+)
+
+// QueryParam creates a query parameter
+func QueryParam(name string) *Parameter {
+	return &Parameter{ParamProps: ParamProps{Name: name, In: "query"}}
+}
+
+// HeaderParam creates a header parameter, this is always required by default
+func HeaderParam(name string) *Parameter {
+	return &Parameter{ParamProps: ParamProps{Name: name, In: "header", Required: true}}
+}
+
+// PathParam creates a path parameter, this is always required
+func PathParam(name string) *Parameter {
+	return &Parameter{ParamProps: ParamProps{Name: name, In: "path", Required: true}}
+}
+
+// BodyParam creates a body parameter
+func BodyParam(name string, schema *Schema) *Parameter {
+	return &Parameter{ParamProps: ParamProps{Name: name, In: "body", Schema: schema}, SimpleSchema: SimpleSchema{Type: "object"}}
+}
+
+// FormDataParam creates a body parameter
+func FormDataParam(name string) *Parameter {
+	return &Parameter{ParamProps: ParamProps{Name: name, In: "formData"}}
+}
+
+// FileParam creates a body parameter
+func FileParam(name string) *Parameter {
+	return &Parameter{ParamProps: ParamProps{Name: name, In: "formData"}, SimpleSchema: SimpleSchema{Type: "file"}}
+}
+
+// SimpleArrayParam creates a param for a simple array (string, int, date etc)
+func SimpleArrayParam(name, tpe, fmt string) *Parameter {
+	return &Parameter{ParamProps: ParamProps{Name: name}, SimpleSchema: SimpleSchema{Type: "array", CollectionFormat: "csv", Items: &Items{SimpleSchema: SimpleSchema{Type: "string", Format: fmt}}}}
+}
+
+// ParamRef creates a parameter that's a json reference
+func ParamRef(uri string) *Parameter {
+	p := new(Parameter)
+	p.Ref = MustCreateRef(uri)
+	return p
+}
+
+// ParamProps describes the specific attributes of an operation parameter
+type ParamProps struct {
+	Description     string  `json:"description,omitempty"`
+	Name            string  `json:"name,omitempty"`
+	In              string  `json:"in,omitempty"`
+	Required        bool    `json:"required,omitempty"`
+	Schema          *Schema `json:"schema,omitempty"`          // when in == "body"
+	AllowEmptyValue bool    `json:"allowEmptyValue,omitempty"` // when in == "query" || "formData"
+}
+
+// Parameter a unique parameter is defined by a combination of a [name](#parameterName) and [location](#parameterIn).
+//
+// There are five possible parameter types.
+// * Path - Used together with [Path Templating](#pathTemplating), where the parameter value is actually part of the operation's URL. This does not include the host or base path of the API. For example, in `/items/{itemId}`, the path parameter is `itemId`.
+// * Query - Parameters that are appended to the URL. For example, in `/items?id=###`, the query parameter is `id`.
+// * Header - Custom headers that are expected as part of the request.
+// * Body - The payload that's appended to the HTTP request. Since there can only be one payload, there can only be *one* body parameter. The name of the body parameter has no effect on the parameter itself and is used for documentation purposes only. Since Form parameters are also in the payload, body and form parameters cannot exist together for the same operation.
+// * Form - Used to describe the payload of an HTTP request when either `application/x-www-form-urlencoded` or `multipart/form-data` are used as the content type of the request (in Swagger's definition, the [`consumes`](#operationConsumes) property of an operation). This is the only parameter type that can be used to send files, thus supporting the `file` type. Since form parameters are sent in the payload, they cannot be declared together with a body parameter for the same operation. Form parameters have a different format based on the content-type used (for further details, consult http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4):
+//   * `application/x-www-form-urlencoded` - Similar to the format of Query parameters but as a payload. For example, `foo=1&bar=swagger` - both `foo` and `bar` are form parameters. This is normally used for simple parameters that are being transferred.
+//   * `multipart/form-data` - each parameter takes a section in the payload with an internal header. For example, for the header `Content-Disposition: form-data; name="submit-name"` the name of the parameter is `submit-name`. This type of form parameters is more commonly used for file transfers.
+//
+// For more information: http://goo.gl/8us55a#parameterObject
+type Parameter struct {
+	Refable
+	CommonValidations
+	SimpleSchema
+	VendorExtensible
+	ParamProps
+}
+
+// JSONLookup look up a value by the json property name
+func (p Parameter) JSONLookup(token string) (interface{}, error) {
+	if ex, ok := p.Extensions[token]; ok {
+		return &ex, nil
+	}
+	if token == "$ref" {
+		return &p.Ref, nil
+	}
+
+	r, _, err := jsonpointer.GetForToken(p.CommonValidations, token)
+	if err != nil && !strings.HasPrefix(err.Error(), "object has no field") {
+		return nil, err
+	}
+	if r != nil {
+		return r, nil
+	}
+	r, _, err = jsonpointer.GetForToken(p.SimpleSchema, token)
+	if err != nil && !strings.HasPrefix(err.Error(), "object has no field") {
+		return nil, err
+	}
+	if r != nil {
+		return r, nil
+	}
+	r, _, err = jsonpointer.GetForToken(p.ParamProps, token)
+	return r, err
+}
+
+// WithDescription a fluent builder method for the description of the parameter
+func (p *Parameter) WithDescription(description string) *Parameter {
+	p.Description = description
+	return p
+}
+
+// Named a fluent builder method to override the name of the parameter
+func (p *Parameter) Named(name string) *Parameter {
+	p.Name = name
+	return p
+}
+
+// WithLocation a fluent builder method to override the location of the parameter
+func (p *Parameter) WithLocation(in string) *Parameter {
+	p.In = in
+	return p
+}
+
+// Typed a fluent builder method for the type of the parameter value
+func (p *Parameter) Typed(tpe, format string) *Parameter {
+	p.Type = tpe
+	p.Format = format
+	return p
+}
+
+// CollectionOf a fluent builder method for an array parameter
+func (p *Parameter) CollectionOf(items *Items, format string) *Parameter {
+	p.Type = "array"
+	p.Items = items
+	p.CollectionFormat = format
+	return p
+}
+
+// WithDefault sets the default value on this parameter
+func (p *Parameter) WithDefault(defaultValue interface{}) *Parameter {
+	p.AsOptional() // with default implies optional
+	p.Default = defaultValue
+	return p
+}
+
+// AllowsEmptyValues flags this parameter as being ok with empty values
+func (p *Parameter) AllowsEmptyValues() *Parameter {
+	p.AllowEmptyValue = true
+	return p
+}
+
+// NoEmptyValues flags this parameter as not liking empty values
+func (p *Parameter) NoEmptyValues() *Parameter {
+	p.AllowEmptyValue = false
+	return p
+}
+
+// AsOptional flags this parameter as optional
+func (p *Parameter) AsOptional() *Parameter {
+	p.Required = false
+	return p
+}
+
+// AsRequired flags this parameter as required
+func (p *Parameter) AsRequired() *Parameter {
+	if p.Default != nil { // with a default required makes no sense
+		return p
+	}
+	p.Required = true
+	return p
+}
+
+// WithMaxLength sets a max length value
+func (p *Parameter) WithMaxLength(max int64) *Parameter {
+	p.MaxLength = &max
+	return p
+}
+
+// WithMinLength sets a min length value
+func (p *Parameter) WithMinLength(min int64) *Parameter {
+	p.MinLength = &min
+	return p
+}
+
+// WithPattern sets a pattern value
+func (p *Parameter) WithPattern(pattern string) *Parameter {
+	p.Pattern = pattern
+	return p
+}
+
+// WithMultipleOf sets a multiple of value
+func (p *Parameter) WithMultipleOf(number float64) *Parameter {
+	p.MultipleOf = &number
+	return p
+}
+
+// WithMaximum sets a maximum number value
+func (p *Parameter) WithMaximum(max float64, exclusive bool) *Parameter {
+	p.Maximum = &max
+	p.ExclusiveMaximum = exclusive
+	return p
+}
+
+// WithMinimum sets a minimum number value
+func (p *Parameter) WithMinimum(min float64, exclusive bool) *Parameter {
+	p.Minimum = &min
+	p.ExclusiveMinimum = exclusive
+	return p
+}
+
+// WithEnum sets a the enum values (replace)
+func (p *Parameter) WithEnum(values ...interface{}) *Parameter {
+	p.Enum = append([]interface{}{}, values...)
+	return p
+}
+
+// WithMaxItems sets the max items
+func (p *Parameter) WithMaxItems(size int64) *Parameter {
+	p.MaxItems = &size
+	return p
+}
+
+// WithMinItems sets the min items
+func (p *Parameter) WithMinItems(size int64) *Parameter {
+	p.MinItems = &size
+	return p
+}
+
+// UniqueValues dictates that this array can only have unique items
+func (p *Parameter) UniqueValues() *Parameter {
+	p.UniqueItems = true
+	return p
+}
+
+// AllowDuplicates this array can have duplicates
+func (p *Parameter) AllowDuplicates() *Parameter {
+	p.UniqueItems = false
+	return p
+}
+
+// UnmarshalJSON hydrates this items instance with the data from JSON
+func (p *Parameter) UnmarshalJSON(data []byte) error {
+	if err := json.Unmarshal(data, &p.CommonValidations); err != nil {
+		return err
+	}
+	if err := json.Unmarshal(data, &p.Refable); err != nil {
+		return err
+	}
+	if err := json.Unmarshal(data, &p.SimpleSchema); err != nil {
+		return err
+	}
+	if err := json.Unmarshal(data, &p.VendorExtensible); err != nil {
+		return err
+	}
+	if err := json.Unmarshal(data, &p.ParamProps); err != nil {
+		return err
+	}
+	return nil
+}
+
+// MarshalJSON converts this items object to JSON
+func (p Parameter) MarshalJSON() ([]byte, error) {
+	b1, err := json.Marshal(p.CommonValidations)
+	if err != nil {
+		return nil, err
+	}
+	b2, err := json.Marshal(p.SimpleSchema)
+	if err != nil {
+		return nil, err
+	}
+	b3, err := json.Marshal(p.Refable)
+	if err != nil {
+		return nil, err
+	}
+	b4, err := json.Marshal(p.VendorExtensible)
+	if err != nil {
+		return nil, err
+	}
+	b5, err := json.Marshal(p.ParamProps)
+	if err != nil {
+		return nil, err
+	}
+	return swag.ConcatJSON(b3, b1, b2, b4, b5), nil
+}
diff --git a/go/vendor/github.com/go-openapi/spec/path_item.go b/go/vendor/github.com/go-openapi/spec/path_item.go
new file mode 100644
index 0000000..a8ae63e
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/path_item.go
@@ -0,0 +1,90 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package spec
+
+import (
+	"encoding/json"
+
+	"github.com/go-openapi/jsonpointer"
+	"github.com/go-openapi/swag"
+)
+
+// PathItemProps the path item specific properties
+type PathItemProps struct {
+	Get        *Operation  `json:"get,omitempty"`
+	Put        *Operation  `json:"put,omitempty"`
+	Post       *Operation  `json:"post,omitempty"`
+	Delete     *Operation  `json:"delete,omitempty"`
+	Options    *Operation  `json:"options,omitempty"`
+	Head       *Operation  `json:"head,omitempty"`
+	Patch      *Operation  `json:"patch,omitempty"`
+	Parameters []Parameter `json:"parameters,omitempty"`
+}
+
+// PathItem describes the operations available on a single path.
+// A Path Item may be empty, due to [ACL constraints](http://goo.gl/8us55a#securityFiltering).
+// The path itself is still exposed to the documentation viewer but they will
+// not know which operations and parameters are available.
+//
+// For more information: http://goo.gl/8us55a#pathItemObject
+type PathItem struct {
+	Refable
+	VendorExtensible
+	PathItemProps
+}
+
+// JSONLookup look up a value by the json property name
+func (p PathItem) JSONLookup(token string) (interface{}, error) {
+	if ex, ok := p.Extensions[token]; ok {
+		return &ex, nil
+	}
+	if token == "$ref" {
+		return &p.Ref, nil
+	}
+	r, _, err := jsonpointer.GetForToken(p.PathItemProps, token)
+	return r, err
+}
+
+// UnmarshalJSON hydrates this items instance with the data from JSON
+func (p *PathItem) UnmarshalJSON(data []byte) error {
+	if err := json.Unmarshal(data, &p.Refable); err != nil {
+		return err
+	}
+	if err := json.Unmarshal(data, &p.VendorExtensible); err != nil {
+		return err
+	}
+	if err := json.Unmarshal(data, &p.PathItemProps); err != nil {
+		return err
+	}
+	return nil
+}
+
+// MarshalJSON converts this items object to JSON
+func (p PathItem) MarshalJSON() ([]byte, error) {
+	b3, err := json.Marshal(p.Refable)
+	if err != nil {
+		return nil, err
+	}
+	b4, err := json.Marshal(p.VendorExtensible)
+	if err != nil {
+		return nil, err
+	}
+	b5, err := json.Marshal(p.PathItemProps)
+	if err != nil {
+		return nil, err
+	}
+	concated := swag.ConcatJSON(b3, b4, b5)
+	return concated, nil
+}
diff --git a/go/vendor/github.com/go-openapi/spec/paths.go b/go/vendor/github.com/go-openapi/spec/paths.go
new file mode 100644
index 0000000..9dc82a2
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/paths.go
@@ -0,0 +1,97 @@
+// 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 spec
+
+import (
+	"encoding/json"
+	"fmt"
+	"strings"
+
+	"github.com/go-openapi/swag"
+)
+
+// Paths holds the relative paths to the individual endpoints.
+// The path is appended to the [`basePath`](http://goo.gl/8us55a#swaggerBasePath) in order
+// to construct the full URL.
+// The Paths may be empty, due to [ACL constraints](http://goo.gl/8us55a#securityFiltering).
+//
+// For more information: http://goo.gl/8us55a#pathsObject
+type Paths struct {
+	VendorExtensible
+	Paths map[string]PathItem `json:"-"` // custom serializer to flatten this, each entry must start with "/"
+}
+
+// JSONLookup look up a value by the json property name
+func (p Paths) JSONLookup(token string) (interface{}, error) {
+	if pi, ok := p.Paths[token]; ok {
+		return &pi, nil
+	}
+	if ex, ok := p.Extensions[token]; ok {
+		return &ex, nil
+	}
+	return nil, fmt.Errorf("object has no field %q", token)
+}
+
+// UnmarshalJSON hydrates this items instance with the data from JSON
+func (p *Paths) UnmarshalJSON(data []byte) error {
+	var res map[string]json.RawMessage
+	if err := json.Unmarshal(data, &res); err != nil {
+		return err
+	}
+	for k, v := range res {
+		if strings.HasPrefix(strings.ToLower(k), "x-") {
+			if p.Extensions == nil {
+				p.Extensions = make(map[string]interface{})
+			}
+			var d interface{}
+			if err := json.Unmarshal(v, &d); err != nil {
+				return err
+			}
+			p.Extensions[k] = d
+		}
+		if strings.HasPrefix(k, "/") {
+			if p.Paths == nil {
+				p.Paths = make(map[string]PathItem)
+			}
+			var pi PathItem
+			if err := json.Unmarshal(v, &pi); err != nil {
+				return err
+			}
+			p.Paths[k] = pi
+		}
+	}
+	return nil
+}
+
+// MarshalJSON converts this items object to JSON
+func (p Paths) MarshalJSON() ([]byte, error) {
+	b1, err := json.Marshal(p.VendorExtensible)
+	if err != nil {
+		return nil, err
+	}
+
+	pths := make(map[string]PathItem)
+	for k, v := range p.Paths {
+		if strings.HasPrefix(k, "/") {
+			pths[k] = v
+		}
+	}
+	b2, err := json.Marshal(pths)
+	if err != nil {
+		return nil, err
+	}
+	concated := swag.ConcatJSON(b1, b2)
+	return concated, nil
+}
diff --git a/go/vendor/github.com/go-openapi/spec/ref.go b/go/vendor/github.com/go-openapi/spec/ref.go
new file mode 100644
index 0000000..1405bfd
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/ref.go
@@ -0,0 +1,167 @@
+// 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 spec
+
+import (
+	"encoding/json"
+	"net/http"
+	"os"
+	"path/filepath"
+
+	"github.com/go-openapi/jsonreference"
+)
+
+// Refable is a struct for things that accept a $ref property
+type Refable struct {
+	Ref Ref
+}
+
+// MarshalJSON marshals the ref to json
+func (r Refable) MarshalJSON() ([]byte, error) {
+	return r.Ref.MarshalJSON()
+}
+
+// UnmarshalJSON unmarshalss the ref from json
+func (r *Refable) UnmarshalJSON(d []byte) error {
+	return json.Unmarshal(d, &r.Ref)
+}
+
+// Ref represents a json reference that is potentially resolved
+type Ref struct {
+	jsonreference.Ref
+}
+
+// RemoteURI gets the remote uri part of the ref
+func (r *Ref) RemoteURI() string {
+	if r.String() == "" {
+		return r.String()
+	}
+
+	u := *r.GetURL()
+	u.Fragment = ""
+	return u.String()
+}
+
+// IsValidURI returns true when the url the ref points to can be found
+func (r *Ref) IsValidURI(basepaths ...string) bool {
+	if r.String() == "" {
+		return true
+	}
+
+	v := r.RemoteURI()
+	if v == "" {
+		return true
+	}
+
+	if r.HasFullURL {
+		rr, err := http.Get(v)
+		if err != nil {
+			return false
+		}
+
+		return rr.StatusCode/100 == 2
+	}
+
+	if !(r.HasFileScheme || r.HasFullFilePath || r.HasURLPathOnly) {
+		return false
+	}
+
+	// check for local file
+	pth := v
+	if r.HasURLPathOnly {
+		base := "."
+		if len(basepaths) > 0 {
+			base = filepath.Dir(filepath.Join(basepaths...))
+		}
+		p, e := filepath.Abs(filepath.ToSlash(filepath.Join(base, pth)))
+		if e != nil {
+			return false
+		}
+		pth = p
+	}
+
+	fi, err := os.Stat(filepath.ToSlash(pth))
+	if err != nil {
+		return false
+	}
+
+	return !fi.IsDir()
+}
+
+// Inherits creates a new reference from a parent and a child
+// If the child cannot inherit from the parent, an error is returned
+func (r *Ref) Inherits(child Ref) (*Ref, error) {
+	ref, err := r.Ref.Inherits(child.Ref)
+	if err != nil {
+		return nil, err
+	}
+	return &Ref{Ref: *ref}, nil
+}
+
+// NewRef creates a new instance of a ref object
+// returns an error when the reference uri is an invalid uri
+func NewRef(refURI string) (Ref, error) {
+	ref, err := jsonreference.New(refURI)
+	if err != nil {
+		return Ref{}, err
+	}
+	return Ref{Ref: ref}, nil
+}
+
+// MustCreateRef creates a ref object but panics when refURI is invalid.
+// Use the NewRef method for a version that returns an error.
+func MustCreateRef(refURI string) Ref {
+	return Ref{Ref: jsonreference.MustCreateRef(refURI)}
+}
+
+// MarshalJSON marshals this ref into a JSON object
+func (r Ref) MarshalJSON() ([]byte, error) {
+	str := r.String()
+	if str == "" {
+		if r.IsRoot() {
+			return []byte(`{"$ref":""}`), nil
+		}
+		return []byte("{}"), nil
+	}
+	v := map[string]interface{}{"$ref": str}
+	return json.Marshal(v)
+}
+
+// UnmarshalJSON unmarshals this ref from a JSON object
+func (r *Ref) UnmarshalJSON(d []byte) error {
+	var v map[string]interface{}
+	if err := json.Unmarshal(d, &v); err != nil {
+		return err
+	}
+	return r.fromMap(v)
+}
+
+func (r *Ref) fromMap(v map[string]interface{}) error {
+	if v == nil {
+		return nil
+	}
+
+	if vv, ok := v["$ref"]; ok {
+		if str, ok := vv.(string); ok {
+			ref, err := jsonreference.New(str)
+			if err != nil {
+				return err
+			}
+			*r = Ref{Ref: ref}
+		}
+	}
+
+	return nil
+}
diff --git a/go/vendor/github.com/go-openapi/spec/response.go b/go/vendor/github.com/go-openapi/spec/response.go
new file mode 100644
index 0000000..586db0d
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/response.go
@@ -0,0 +1,134 @@
+// 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 spec
+
+import (
+	"encoding/json"
+
+	"github.com/go-openapi/jsonpointer"
+	"github.com/go-openapi/swag"
+)
+
+// ResponseProps properties specific to a response
+type ResponseProps struct {
+	Description string                 `json:"description,omitempty"`
+	Schema      *Schema                `json:"schema,omitempty"`
+	Headers     map[string]Header      `json:"headers,omitempty"`
+	Examples    map[string]interface{} `json:"examples,omitempty"`
+}
+
+// Response describes a single response from an API Operation.
+//
+// For more information: http://goo.gl/8us55a#responseObject
+type Response struct {
+	Refable
+	ResponseProps
+	VendorExtensible
+}
+
+// JSONLookup look up a value by the json property name
+func (r Response) JSONLookup(token string) (interface{}, error) {
+	if ex, ok := r.Extensions[token]; ok {
+		return &ex, nil
+	}
+	if token == "$ref" {
+		return &r.Ref, nil
+	}
+	ptr, _, err := jsonpointer.GetForToken(r.ResponseProps, token)
+	return ptr, err
+}
+
+// UnmarshalJSON hydrates this items instance with the data from JSON
+func (r *Response) UnmarshalJSON(data []byte) error {
+	if err := json.Unmarshal(data, &r.ResponseProps); err != nil {
+		return err
+	}
+	if err := json.Unmarshal(data, &r.Refable); err != nil {
+		return err
+	}
+	if err := json.Unmarshal(data, &r.VendorExtensible); err != nil {
+		return err
+	}
+	return nil
+}
+
+// MarshalJSON converts this items object to JSON
+func (r Response) MarshalJSON() ([]byte, error) {
+	b1, err := json.Marshal(r.ResponseProps)
+	if err != nil {
+		return nil, err
+	}
+	b2, err := json.Marshal(r.Refable)
+	if err != nil {
+		return nil, err
+	}
+	b3, err := json.Marshal(r.VendorExtensible)
+	if err != nil {
+		return nil, err
+	}
+	return swag.ConcatJSON(b1, b2, b3), nil
+}
+
+// NewResponse creates a new response instance
+func NewResponse() *Response {
+	return new(Response)
+}
+
+// ResponseRef creates a response as a json reference
+func ResponseRef(url string) *Response {
+	resp := NewResponse()
+	resp.Ref = MustCreateRef(url)
+	return resp
+}
+
+// WithDescription sets the description on this response, allows for chaining
+func (r *Response) WithDescription(description string) *Response {
+	r.Description = description
+	return r
+}
+
+// WithSchema sets the schema on this response, allows for chaining.
+// Passing a nil argument removes the schema from this response
+func (r *Response) WithSchema(schema *Schema) *Response {
+	r.Schema = schema
+	return r
+}
+
+// AddHeader adds a header to this response
+func (r *Response) AddHeader(name string, header *Header) *Response {
+	if header == nil {
+		return r.RemoveHeader(name)
+	}
+	if r.Headers == nil {
+		r.Headers = make(map[string]Header)
+	}
+	r.Headers[name] = *header
+	return r
+}
+
+// RemoveHeader removes a header from this response
+func (r *Response) RemoveHeader(name string) *Response {
+	delete(r.Headers, name)
+	return r
+}
+
+// AddExample adds an example to this response
+func (r *Response) AddExample(mediaType string, example interface{}) *Response {
+	if r.Examples == nil {
+		r.Examples = make(map[string]interface{})
+	}
+	r.Examples[mediaType] = example
+	return r
+}
diff --git a/go/vendor/github.com/go-openapi/spec/responses.go b/go/vendor/github.com/go-openapi/spec/responses.go
new file mode 100644
index 0000000..4efb6f8
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/responses.go
@@ -0,0 +1,127 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package spec
+
+import (
+	"encoding/json"
+	"fmt"
+	"reflect"
+	"strconv"
+
+	"github.com/go-openapi/swag"
+)
+
+// Responses is a container for the expected responses of an operation.
+// The container maps a HTTP response code to the expected response.
+// It is not expected from the documentation to necessarily cover all possible HTTP response codes,
+// since they may not be known in advance. However, it is expected from the documentation to cover
+// a successful operation response and any known errors.
+//
+// The `default` can be used a default response object for all HTTP codes that are not covered
+// individually by the specification.
+//
+// The `Responses Object` MUST contain at least one response code, and it SHOULD be the response
+// for a successful operation call.
+//
+// For more information: http://goo.gl/8us55a#responsesObject
+type Responses struct {
+	VendorExtensible
+	ResponsesProps
+}
+
+// JSONLookup implements an interface to customize json pointer lookup
+func (r Responses) JSONLookup(token string) (interface{}, error) {
+	if token == "default" {
+		return r.Default, nil
+	}
+	if ex, ok := r.Extensions[token]; ok {
+		return &ex, nil
+	}
+	if i, err := strconv.Atoi(token); err == nil {
+		if scr, ok := r.StatusCodeResponses[i]; ok {
+			return scr, nil
+		}
+	}
+	return nil, fmt.Errorf("object has no field %q", token)
+}
+
+// UnmarshalJSON hydrates this items instance with the data from JSON
+func (r *Responses) UnmarshalJSON(data []byte) error {
+	if err := json.Unmarshal(data, &r.ResponsesProps); err != nil {
+		return err
+	}
+	if err := json.Unmarshal(data, &r.VendorExtensible); err != nil {
+		return err
+	}
+	if reflect.DeepEqual(ResponsesProps{}, r.ResponsesProps) {
+		r.ResponsesProps = ResponsesProps{}
+	}
+	return nil
+}
+
+// MarshalJSON converts this items object to JSON
+func (r Responses) MarshalJSON() ([]byte, error) {
+	b1, err := json.Marshal(r.ResponsesProps)
+	if err != nil {
+		return nil, err
+	}
+	b2, err := json.Marshal(r.VendorExtensible)
+	if err != nil {
+		return nil, err
+	}
+	concated := swag.ConcatJSON(b1, b2)
+	return concated, nil
+}
+
+// ResponsesProps describes all responses for an operation.
+// It tells what is the default response and maps all responses with a
+// HTTP status code.
+type ResponsesProps struct {
+	Default             *Response
+	StatusCodeResponses map[int]Response
+}
+
+// MarshalJSON marshals responses as JSON
+func (r ResponsesProps) MarshalJSON() ([]byte, error) {
+	toser := map[string]Response{}
+	if r.Default != nil {
+		toser["default"] = *r.Default
+	}
+	for k, v := range r.StatusCodeResponses {
+		toser[strconv.Itoa(k)] = v
+	}
+	return json.Marshal(toser)
+}
+
+// UnmarshalJSON unmarshals responses from JSON
+func (r *ResponsesProps) UnmarshalJSON(data []byte) error {
+	var res map[string]Response
+	if err := json.Unmarshal(data, &res); err != nil {
+		return nil
+	}
+	if v, ok := res["default"]; ok {
+		r.Default = &v
+		delete(res, "default")
+	}
+	for k, v := range res {
+		if nk, err := strconv.Atoi(k); err == nil {
+			if r.StatusCodeResponses == nil {
+				r.StatusCodeResponses = map[int]Response{}
+			}
+			r.StatusCodeResponses[nk] = v
+		}
+	}
+	return nil
+}
diff --git a/go/vendor/github.com/go-openapi/spec/schema.go b/go/vendor/github.com/go-openapi/spec/schema.go
new file mode 100644
index 0000000..b9481e2
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/schema.go
@@ -0,0 +1,636 @@
+// 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 spec
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/url"
+	"strings"
+
+	"github.com/go-openapi/jsonpointer"
+	"github.com/go-openapi/swag"
+)
+
+// BooleanProperty creates a boolean property
+func BooleanProperty() *Schema {
+	return &Schema{SchemaProps: SchemaProps{Type: []string{"boolean"}}}
+}
+
+// BoolProperty creates a boolean property
+func BoolProperty() *Schema { return BooleanProperty() }
+
+// StringProperty creates a string property
+func StringProperty() *Schema {
+	return &Schema{SchemaProps: SchemaProps{Type: []string{"string"}}}
+}
+
+// CharProperty creates a string property
+func CharProperty() *Schema {
+	return &Schema{SchemaProps: SchemaProps{Type: []string{"string"}}}
+}
+
+// Float64Property creates a float64/double property
+func Float64Property() *Schema {
+	return &Schema{SchemaProps: SchemaProps{Type: []string{"number"}, Format: "double"}}
+}
+
+// Float32Property creates a float32/float property
+func Float32Property() *Schema {
+	return &Schema{SchemaProps: SchemaProps{Type: []string{"number"}, Format: "float"}}
+}
+
+// Int8Property creates an int8 property
+func Int8Property() *Schema {
+	return &Schema{SchemaProps: SchemaProps{Type: []string{"integer"}, Format: "int8"}}
+}
+
+// Int16Property creates an int16 property
+func Int16Property() *Schema {
+	return &Schema{SchemaProps: SchemaProps{Type: []string{"integer"}, Format: "int16"}}
+}
+
+// Int32Property creates an int32 property
+func Int32Property() *Schema {
+	return &Schema{SchemaProps: SchemaProps{Type: []string{"integer"}, Format: "int32"}}
+}
+
+// Int64Property creates an int64 property
+func Int64Property() *Schema {
+	return &Schema{SchemaProps: SchemaProps{Type: []string{"integer"}, Format: "int64"}}
+}
+
+// StrFmtProperty creates a property for the named string format
+func StrFmtProperty(format string) *Schema {
+	return &Schema{SchemaProps: SchemaProps{Type: []string{"string"}, Format: format}}
+}
+
+// DateProperty creates a date property
+func DateProperty() *Schema {
+	return &Schema{SchemaProps: SchemaProps{Type: []string{"string"}, Format: "date"}}
+}
+
+// DateTimeProperty creates a date time property
+func DateTimeProperty() *Schema {
+	return &Schema{SchemaProps: SchemaProps{Type: []string{"string"}, Format: "date-time"}}
+}
+
+// MapProperty creates a map property
+func MapProperty(property *Schema) *Schema {
+	return &Schema{SchemaProps: SchemaProps{Type: []string{"object"}, AdditionalProperties: &SchemaOrBool{Allows: true, Schema: property}}}
+}
+
+// RefProperty creates a ref property
+func RefProperty(name string) *Schema {
+	return &Schema{SchemaProps: SchemaProps{Ref: MustCreateRef(name)}}
+}
+
+// RefSchema creates a ref property
+func RefSchema(name string) *Schema {
+	return &Schema{SchemaProps: SchemaProps{Ref: MustCreateRef(name)}}
+}
+
+// ArrayProperty creates an array property
+func ArrayProperty(items *Schema) *Schema {
+	if items == nil {
+		return &Schema{SchemaProps: SchemaProps{Type: []string{"array"}}}
+	}
+	return &Schema{SchemaProps: SchemaProps{Items: &SchemaOrArray{Schema: items}, Type: []string{"array"}}}
+}
+
+// ComposedSchema creates a schema with allOf
+func ComposedSchema(schemas ...Schema) *Schema {
+	s := new(Schema)
+	s.AllOf = schemas
+	return s
+}
+
+// SchemaURL represents a schema url
+type SchemaURL string
+
+// MarshalJSON marshal this to JSON
+func (r SchemaURL) MarshalJSON() ([]byte, error) {
+	if r == "" {
+		return []byte("{}"), nil
+	}
+	v := map[string]interface{}{"$schema": string(r)}
+	return json.Marshal(v)
+}
+
+// UnmarshalJSON unmarshal this from JSON
+func (r *SchemaURL) UnmarshalJSON(data []byte) error {
+	var v map[string]interface{}
+	if err := json.Unmarshal(data, &v); err != nil {
+		return err
+	}
+	return r.fromMap(v)
+}
+
+func (r *SchemaURL) fromMap(v map[string]interface{}) error {
+	if v == nil {
+		return nil
+	}
+	if vv, ok := v["$schema"]; ok {
+		if str, ok := vv.(string); ok {
+			u, err := url.Parse(str)
+			if err != nil {
+				return err
+			}
+
+			*r = SchemaURL(u.String())
+		}
+	}
+	return nil
+}
+
+// type ExtraSchemaProps map[string]interface{}
+
+// // JSONSchema represents a structure that is a json schema draft 04
+// type JSONSchema struct {
+// 	SchemaProps
+// 	ExtraSchemaProps
+// }
+
+// // MarshalJSON marshal this to JSON
+// func (s JSONSchema) MarshalJSON() ([]byte, error) {
+// 	b1, err := json.Marshal(s.SchemaProps)
+// 	if err != nil {
+// 		return nil, err
+// 	}
+// 	b2, err := s.Ref.MarshalJSON()
+// 	if err != nil {
+// 		return nil, err
+// 	}
+// 	b3, err := s.Schema.MarshalJSON()
+// 	if err != nil {
+// 		return nil, err
+// 	}
+// 	b4, err := json.Marshal(s.ExtraSchemaProps)
+// 	if err != nil {
+// 		return nil, err
+// 	}
+// 	return swag.ConcatJSON(b1, b2, b3, b4), nil
+// }
+
+// // UnmarshalJSON marshal this from JSON
+// func (s *JSONSchema) UnmarshalJSON(data []byte) error {
+// 	var sch JSONSchema
+// 	if err := json.Unmarshal(data, &sch.SchemaProps); err != nil {
+// 		return err
+// 	}
+// 	if err := json.Unmarshal(data, &sch.Ref); err != nil {
+// 		return err
+// 	}
+// 	if err := json.Unmarshal(data, &sch.Schema); err != nil {
+// 		return err
+// 	}
+// 	if err := json.Unmarshal(data, &sch.ExtraSchemaProps); err != nil {
+// 		return err
+// 	}
+// 	*s = sch
+// 	return nil
+// }
+
+// SchemaProps describes a JSON schema (draft 4)
+type SchemaProps struct {
+	ID                   string            `json:"id,omitempty"`
+	Ref                  Ref               `json:"-"`
+	Schema               SchemaURL         `json:"-"`
+	Description          string            `json:"description,omitempty"`
+	Type                 StringOrArray     `json:"type,omitempty"`
+	Format               string            `json:"format,omitempty"`
+	Title                string            `json:"title,omitempty"`
+	Default              interface{}       `json:"default,omitempty"`
+	Maximum              *float64          `json:"maximum,omitempty"`
+	ExclusiveMaximum     bool              `json:"exclusiveMaximum,omitempty"`
+	Minimum              *float64          `json:"minimum,omitempty"`
+	ExclusiveMinimum     bool              `json:"exclusiveMinimum,omitempty"`
+	MaxLength            *int64            `json:"maxLength,omitempty"`
+	MinLength            *int64            `json:"minLength,omitempty"`
+	Pattern              string            `json:"pattern,omitempty"`
+	MaxItems             *int64            `json:"maxItems,omitempty"`
+	MinItems             *int64            `json:"minItems,omitempty"`
+	UniqueItems          bool              `json:"uniqueItems,omitempty"`
+	MultipleOf           *float64          `json:"multipleOf,omitempty"`
+	Enum                 []interface{}     `json:"enum,omitempty"`
+	MaxProperties        *int64            `json:"maxProperties,omitempty"`
+	MinProperties        *int64            `json:"minProperties,omitempty"`
+	Required             []string          `json:"required,omitempty"`
+	Items                *SchemaOrArray    `json:"items,omitempty"`
+	AllOf                []Schema          `json:"allOf,omitempty"`
+	OneOf                []Schema          `json:"oneOf,omitempty"`
+	AnyOf                []Schema          `json:"anyOf,omitempty"`
+	Not                  *Schema           `json:"not,omitempty"`
+	Properties           map[string]Schema `json:"properties,omitempty"`
+	AdditionalProperties *SchemaOrBool     `json:"additionalProperties,omitempty"`
+	PatternProperties    map[string]Schema `json:"patternProperties,omitempty"`
+	Dependencies         Dependencies      `json:"dependencies,omitempty"`
+	AdditionalItems      *SchemaOrBool     `json:"additionalItems,omitempty"`
+	Definitions          Definitions       `json:"definitions,omitempty"`
+}
+
+// SwaggerSchemaProps are additional properties supported by swagger schemas, but not JSON-schema (draft 4)
+type SwaggerSchemaProps struct {
+	Discriminator string                 `json:"discriminator,omitempty"`
+	ReadOnly      bool                   `json:"readOnly,omitempty"`
+	XML           *XMLObject             `json:"xml,omitempty"`
+	ExternalDocs  *ExternalDocumentation `json:"externalDocs,omitempty"`
+	Example       interface{}            `json:"example,omitempty"`
+}
+
+// Schema the schema object allows the definition of input and output data types.
+// These types can be objects, but also primitives and arrays.
+// This object is based on the [JSON Schema Specification Draft 4](http://json-schema.org/)
+// and uses a predefined subset of it.
+// On top of this subset, there are extensions provided by this specification to allow for more complete documentation.
+//
+// For more information: http://goo.gl/8us55a#schemaObject
+type Schema struct {
+	VendorExtensible
+	SchemaProps
+	SwaggerSchemaProps
+	ExtraProps map[string]interface{} `json:"-"`
+}
+
+// JSONLookup implements an interface to customize json pointer lookup
+func (s Schema) JSONLookup(token string) (interface{}, error) {
+	if ex, ok := s.Extensions[token]; ok {
+		return &ex, nil
+	}
+
+	if ex, ok := s.ExtraProps[token]; ok {
+		return &ex, nil
+	}
+
+	r, _, err := jsonpointer.GetForToken(s.SchemaProps, token)
+	if r != nil || (err != nil && !strings.HasPrefix(err.Error(), "object has no field")) {
+		return r, err
+	}
+	r, _, err = jsonpointer.GetForToken(s.SwaggerSchemaProps, token)
+	return r, err
+}
+
+// WithID sets the id for this schema, allows for chaining
+func (s *Schema) WithID(id string) *Schema {
+	s.ID = id
+	return s
+}
+
+// WithTitle sets the title for this schema, allows for chaining
+func (s *Schema) WithTitle(title string) *Schema {
+	s.Title = title
+	return s
+}
+
+// WithDescription sets the description for this schema, allows for chaining
+func (s *Schema) WithDescription(description string) *Schema {
+	s.Description = description
+	return s
+}
+
+// WithProperties sets the properties for this schema
+func (s *Schema) WithProperties(schemas map[string]Schema) *Schema {
+	s.Properties = schemas
+	return s
+}
+
+// SetProperty sets a property on this schema
+func (s *Schema) SetProperty(name string, schema Schema) *Schema {
+	if s.Properties == nil {
+		s.Properties = make(map[string]Schema)
+	}
+	s.Properties[name] = schema
+	return s
+}
+
+// WithAllOf sets the all of property
+func (s *Schema) WithAllOf(schemas ...Schema) *Schema {
+	s.AllOf = schemas
+	return s
+}
+
+// WithMaxProperties sets the max number of properties an object can have
+func (s *Schema) WithMaxProperties(max int64) *Schema {
+	s.MaxProperties = &max
+	return s
+}
+
+// WithMinProperties sets the min number of properties an object must have
+func (s *Schema) WithMinProperties(min int64) *Schema {
+	s.MinProperties = &min
+	return s
+}
+
+// Typed sets the type of this schema for a single value item
+func (s *Schema) Typed(tpe, format string) *Schema {
+	s.Type = []string{tpe}
+	s.Format = format
+	return s
+}
+
+// AddType adds a type with potential format to the types for this schema
+func (s *Schema) AddType(tpe, format string) *Schema {
+	s.Type = append(s.Type, tpe)
+	if format != "" {
+		s.Format = format
+	}
+	return s
+}
+
+// CollectionOf a fluent builder method for an array parameter
+func (s *Schema) CollectionOf(items Schema) *Schema {
+	s.Type = []string{"array"}
+	s.Items = &SchemaOrArray{Schema: &items}
+	return s
+}
+
+// WithDefault sets the default value on this parameter
+func (s *Schema) WithDefault(defaultValue interface{}) *Schema {
+	s.Default = defaultValue
+	return s
+}
+
+// WithRequired flags this parameter as required
+func (s *Schema) WithRequired(items ...string) *Schema {
+	s.Required = items
+	return s
+}
+
+// AddRequired  adds field names to the required properties array
+func (s *Schema) AddRequired(items ...string) *Schema {
+	s.Required = append(s.Required, items...)
+	return s
+}
+
+// WithMaxLength sets a max length value
+func (s *Schema) WithMaxLength(max int64) *Schema {
+	s.MaxLength = &max
+	return s
+}
+
+// WithMinLength sets a min length value
+func (s *Schema) WithMinLength(min int64) *Schema {
+	s.MinLength = &min
+	return s
+}
+
+// WithPattern sets a pattern value
+func (s *Schema) WithPattern(pattern string) *Schema {
+	s.Pattern = pattern
+	return s
+}
+
+// WithMultipleOf sets a multiple of value
+func (s *Schema) WithMultipleOf(number float64) *Schema {
+	s.MultipleOf = &number
+	return s
+}
+
+// WithMaximum sets a maximum number value
+func (s *Schema) WithMaximum(max float64, exclusive bool) *Schema {
+	s.Maximum = &max
+	s.ExclusiveMaximum = exclusive
+	return s
+}
+
+// WithMinimum sets a minimum number value
+func (s *Schema) WithMinimum(min float64, exclusive bool) *Schema {
+	s.Minimum = &min
+	s.ExclusiveMinimum = exclusive
+	return s
+}
+
+// WithEnum sets a the enum values (replace)
+func (s *Schema) WithEnum(values ...interface{}) *Schema {
+	s.Enum = append([]interface{}{}, values...)
+	return s
+}
+
+// WithMaxItems sets the max items
+func (s *Schema) WithMaxItems(size int64) *Schema {
+	s.MaxItems = &size
+	return s
+}
+
+// WithMinItems sets the min items
+func (s *Schema) WithMinItems(size int64) *Schema {
+	s.MinItems = &size
+	return s
+}
+
+// UniqueValues dictates that this array can only have unique items
+func (s *Schema) UniqueValues() *Schema {
+	s.UniqueItems = true
+	return s
+}
+
+// AllowDuplicates this array can have duplicates
+func (s *Schema) AllowDuplicates() *Schema {
+	s.UniqueItems = false
+	return s
+}
+
+// AddToAllOf adds a schema to the allOf property
+func (s *Schema) AddToAllOf(schemas ...Schema) *Schema {
+	s.AllOf = append(s.AllOf, schemas...)
+	return s
+}
+
+// WithDiscriminator sets the name of the discriminator field
+func (s *Schema) WithDiscriminator(discriminator string) *Schema {
+	s.Discriminator = discriminator
+	return s
+}
+
+// AsReadOnly flags this schema as readonly
+func (s *Schema) AsReadOnly() *Schema {
+	s.ReadOnly = true
+	return s
+}
+
+// AsWritable flags this schema as writeable (not read-only)
+func (s *Schema) AsWritable() *Schema {
+	s.ReadOnly = false
+	return s
+}
+
+// WithExample sets the example for this schema
+func (s *Schema) WithExample(example interface{}) *Schema {
+	s.Example = example
+	return s
+}
+
+// WithExternalDocs sets/removes the external docs for/from this schema.
+// When you pass empty strings as params the external documents will be removed.
+// When you pass non-empty string as one value then those values will be used on the external docs object.
+// So when you pass a non-empty description, you should also pass the url and vice versa.
+func (s *Schema) WithExternalDocs(description, url string) *Schema {
+	if description == "" && url == "" {
+		s.ExternalDocs = nil
+		return s
+	}
+
+	if s.ExternalDocs == nil {
+		s.ExternalDocs = &ExternalDocumentation{}
+	}
+	s.ExternalDocs.Description = description
+	s.ExternalDocs.URL = url
+	return s
+}
+
+// WithXMLName sets the xml name for the object
+func (s *Schema) WithXMLName(name string) *Schema {
+	if s.XML == nil {
+		s.XML = new(XMLObject)
+	}
+	s.XML.Name = name
+	return s
+}
+
+// WithXMLNamespace sets the xml namespace for the object
+func (s *Schema) WithXMLNamespace(namespace string) *Schema {
+	if s.XML == nil {
+		s.XML = new(XMLObject)
+	}
+	s.XML.Namespace = namespace
+	return s
+}
+
+// WithXMLPrefix sets the xml prefix for the object
+func (s *Schema) WithXMLPrefix(prefix string) *Schema {
+	if s.XML == nil {
+		s.XML = new(XMLObject)
+	}
+	s.XML.Prefix = prefix
+	return s
+}
+
+// AsXMLAttribute flags this object as xml attribute
+func (s *Schema) AsXMLAttribute() *Schema {
+	if s.XML == nil {
+		s.XML = new(XMLObject)
+	}
+	s.XML.Attribute = true
+	return s
+}
+
+// AsXMLElement flags this object as an xml node
+func (s *Schema) AsXMLElement() *Schema {
+	if s.XML == nil {
+		s.XML = new(XMLObject)
+	}
+	s.XML.Attribute = false
+	return s
+}
+
+// AsWrappedXML flags this object as wrapped, this is mostly useful for array types
+func (s *Schema) AsWrappedXML() *Schema {
+	if s.XML == nil {
+		s.XML = new(XMLObject)
+	}
+	s.XML.Wrapped = true
+	return s
+}
+
+// AsUnwrappedXML flags this object as an xml node
+func (s *Schema) AsUnwrappedXML() *Schema {
+	if s.XML == nil {
+		s.XML = new(XMLObject)
+	}
+	s.XML.Wrapped = false
+	return s
+}
+
+// MarshalJSON marshal this to JSON
+func (s Schema) MarshalJSON() ([]byte, error) {
+	b1, err := json.Marshal(s.SchemaProps)
+	if err != nil {
+		return nil, fmt.Errorf("schema props %v", err)
+	}
+	b2, err := json.Marshal(s.VendorExtensible)
+	if err != nil {
+		return nil, fmt.Errorf("vendor props %v", err)
+	}
+	b3, err := s.Ref.MarshalJSON()
+	if err != nil {
+		return nil, fmt.Errorf("ref prop %v", err)
+	}
+	b4, err := s.Schema.MarshalJSON()
+	if err != nil {
+		return nil, fmt.Errorf("schema prop %v", err)
+	}
+	b5, err := json.Marshal(s.SwaggerSchemaProps)
+	if err != nil {
+		return nil, fmt.Errorf("common validations %v", err)
+	}
+	var b6 []byte
+	if s.ExtraProps != nil {
+		jj, err := json.Marshal(s.ExtraProps)
+		if err != nil {
+			return nil, fmt.Errorf("extra props %v", err)
+		}
+		b6 = jj
+	}
+	return swag.ConcatJSON(b1, b2, b3, b4, b5, b6), nil
+}
+
+// UnmarshalJSON marshal this from JSON
+func (s *Schema) UnmarshalJSON(data []byte) error {
+	props := struct {
+		SchemaProps
+		SwaggerSchemaProps
+	}{}
+	if err := json.Unmarshal(data, &props); err != nil {
+		return err
+	}
+
+	sch := Schema{
+		SchemaProps:        props.SchemaProps,
+		SwaggerSchemaProps: props.SwaggerSchemaProps,
+	}
+
+	var d map[string]interface{}
+	if err := json.Unmarshal(data, &d); err != nil {
+		return err
+	}
+
+	_ = sch.Ref.fromMap(d)
+	_ = sch.Schema.fromMap(d)
+
+	delete(d, "$ref")
+	delete(d, "$schema")
+	for _, pn := range swag.DefaultJSONNameProvider.GetJSONNames(s) {
+		delete(d, pn)
+	}
+
+	for k, vv := range d {
+		lk := strings.ToLower(k)
+		if strings.HasPrefix(lk, "x-") {
+			if sch.Extensions == nil {
+				sch.Extensions = map[string]interface{}{}
+			}
+			sch.Extensions[k] = vv
+			continue
+		}
+		if sch.ExtraProps == nil {
+			sch.ExtraProps = map[string]interface{}{}
+		}
+		sch.ExtraProps[k] = vv
+	}
+
+	*s = sch
+
+	return nil
+}
diff --git a/go/vendor/github.com/go-openapi/spec/security_scheme.go b/go/vendor/github.com/go-openapi/spec/security_scheme.go
new file mode 100644
index 0000000..9f1b454
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/security_scheme.go
@@ -0,0 +1,143 @@
+// 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 spec
+
+import (
+	"encoding/json"
+
+	"github.com/go-openapi/jsonpointer"
+	"github.com/go-openapi/swag"
+)
+
+const (
+	basic       = "basic"
+	apiKey      = "apiKey"
+	oauth2      = "oauth2"
+	implicit    = "implicit"
+	password    = "password"
+	application = "application"
+	accessCode  = "accessCode"
+)
+
+// BasicAuth creates a basic auth security scheme
+func BasicAuth() *SecurityScheme {
+	return &SecurityScheme{SecuritySchemeProps: SecuritySchemeProps{Type: basic}}
+}
+
+// APIKeyAuth creates an api key auth security scheme
+func APIKeyAuth(fieldName, valueSource string) *SecurityScheme {
+	return &SecurityScheme{SecuritySchemeProps: SecuritySchemeProps{Type: apiKey, Name: fieldName, In: valueSource}}
+}
+
+// OAuth2Implicit creates an implicit flow oauth2 security scheme
+func OAuth2Implicit(authorizationURL string) *SecurityScheme {
+	return &SecurityScheme{SecuritySchemeProps: SecuritySchemeProps{
+		Type:             oauth2,
+		Flow:             implicit,
+		AuthorizationURL: authorizationURL,
+	}}
+}
+
+// OAuth2Password creates a password flow oauth2 security scheme
+func OAuth2Password(tokenURL string) *SecurityScheme {
+	return &SecurityScheme{SecuritySchemeProps: SecuritySchemeProps{
+		Type:     oauth2,
+		Flow:     password,
+		TokenURL: tokenURL,
+	}}
+}
+
+// OAuth2Application creates an application flow oauth2 security scheme
+func OAuth2Application(tokenURL string) *SecurityScheme {
+	return &SecurityScheme{SecuritySchemeProps: SecuritySchemeProps{
+		Type:     oauth2,
+		Flow:     application,
+		TokenURL: tokenURL,
+	}}
+}
+
+// OAuth2AccessToken creates an access token flow oauth2 security scheme
+func OAuth2AccessToken(authorizationURL, tokenURL string) *SecurityScheme {
+	return &SecurityScheme{SecuritySchemeProps: SecuritySchemeProps{
+		Type:             oauth2,
+		Flow:             accessCode,
+		AuthorizationURL: authorizationURL,
+		TokenURL:         tokenURL,
+	}}
+}
+
+// SecuritySchemeProps describes a swagger security scheme in the securityDefinitions section
+type SecuritySchemeProps struct {
+	Description      string            `json:"description,omitempty"`
+	Type             string            `json:"type"`
+	Name             string            `json:"name,omitempty"`             // api key
+	In               string            `json:"in,omitempty"`               // api key
+	Flow             string            `json:"flow,omitempty"`             // oauth2
+	AuthorizationURL string            `json:"authorizationUrl,omitempty"` // oauth2
+	TokenURL         string            `json:"tokenUrl,omitempty"`         // oauth2
+	Scopes           map[string]string `json:"scopes,omitempty"`           // oauth2
+}
+
+// AddScope adds a scope to this security scheme
+func (s *SecuritySchemeProps) AddScope(scope, description string) {
+	if s.Scopes == nil {
+		s.Scopes = make(map[string]string)
+	}
+	s.Scopes[scope] = description
+}
+
+// SecurityScheme allows the definition of a security scheme that can be used by the operations.
+// Supported schemes are basic authentication, an API key (either as a header or as a query parameter)
+// and OAuth2's common flows (implicit, password, application and access code).
+//
+// For more information: http://goo.gl/8us55a#securitySchemeObject
+type SecurityScheme struct {
+	VendorExtensible
+	SecuritySchemeProps
+}
+
+// JSONLookup implements an interface to customize json pointer lookup
+func (s SecurityScheme) JSONLookup(token string) (interface{}, error) {
+	if ex, ok := s.Extensions[token]; ok {
+		return &ex, nil
+	}
+
+	r, _, err := jsonpointer.GetForToken(s.SecuritySchemeProps, token)
+	return r, err
+}
+
+// MarshalJSON marshal this to JSON
+func (s SecurityScheme) MarshalJSON() ([]byte, error) {
+	b1, err := json.Marshal(s.SecuritySchemeProps)
+	if err != nil {
+		return nil, err
+	}
+	b2, err := json.Marshal(s.VendorExtensible)
+	if err != nil {
+		return nil, err
+	}
+	return swag.ConcatJSON(b1, b2), nil
+}
+
+// UnmarshalJSON marshal this from JSON
+func (s *SecurityScheme) UnmarshalJSON(data []byte) error {
+	if err := json.Unmarshal(data, &s.SecuritySchemeProps); err != nil {
+		return err
+	}
+	if err := json.Unmarshal(data, &s.VendorExtensible); err != nil {
+		return err
+	}
+	return nil
+}
diff --git a/go/vendor/github.com/go-openapi/spec/spec.go b/go/vendor/github.com/go-openapi/spec/spec.go
new file mode 100644
index 0000000..0bb045b
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/spec.go
@@ -0,0 +1,86 @@
+// 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 spec
+
+import "encoding/json"
+
+//go:generate curl -L --progress -o ./schemas/v2/schema.json http://swagger.io/v2/schema.json
+//go:generate curl -L --progress  -o ./schemas/jsonschema-draft-04.json http://json-schema.org/draft-04/schema
+//go:generate go-bindata -pkg=spec -prefix=./schemas -ignore=.*\.md ./schemas/...
+//go:generate perl -pi -e s,Json,JSON,g bindata.go
+
+const (
+	// SwaggerSchemaURL the url for the swagger 2.0 schema to validate specs
+	SwaggerSchemaURL = "http://swagger.io/v2/schema.json#"
+	// JSONSchemaURL the url for the json schema schema
+	JSONSchemaURL = "http://json-schema.org/draft-04/schema#"
+)
+
+var (
+	jsonSchema    *Schema
+	swaggerSchema *Schema
+)
+
+func init() {
+	jsonSchema = MustLoadJSONSchemaDraft04()
+	swaggerSchema = MustLoadSwagger20Schema()
+}
+
+// MustLoadJSONSchemaDraft04 panics when Swagger20Schema returns an error
+func MustLoadJSONSchemaDraft04() *Schema {
+	d, e := JSONSchemaDraft04()
+	if e != nil {
+		panic(e)
+	}
+	return d
+}
+
+// JSONSchemaDraft04 loads the json schema document for json shema draft04
+func JSONSchemaDraft04() (*Schema, error) {
+	b, err := Asset("jsonschema-draft-04.json")
+	if err != nil {
+		return nil, err
+	}
+
+	schema := new(Schema)
+	if err := json.Unmarshal(b, schema); err != nil {
+		return nil, err
+	}
+	return schema, nil
+}
+
+// MustLoadSwagger20Schema panics when Swagger20Schema returns an error
+func MustLoadSwagger20Schema() *Schema {
+	d, e := Swagger20Schema()
+	if e != nil {
+		panic(e)
+	}
+	return d
+}
+
+// Swagger20Schema loads the swagger 2.0 schema from the embedded assets
+func Swagger20Schema() (*Schema, error) {
+
+	b, err := Asset("v2/schema.json")
+	if err != nil {
+		return nil, err
+	}
+
+	schema := new(Schema)
+	if err := json.Unmarshal(b, schema); err != nil {
+		return nil, err
+	}
+	return schema, nil
+}
diff --git a/go/vendor/github.com/go-openapi/spec/swagger.go b/go/vendor/github.com/go-openapi/spec/swagger.go
new file mode 100644
index 0000000..4586a21
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/swagger.go
@@ -0,0 +1,318 @@
+// 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 spec
+
+import (
+	"encoding/json"
+	"fmt"
+	"strconv"
+
+	"github.com/go-openapi/jsonpointer"
+	"github.com/go-openapi/swag"
+)
+
+// Swagger this is the root document object for the API specification.
+// It combines what previously was the Resource Listing and API Declaration (version 1.2 and earlier) together into one document.
+//
+// For more information: http://goo.gl/8us55a#swagger-object-
+type Swagger struct {
+	VendorExtensible
+	SwaggerProps
+}
+
+// JSONLookup look up a value by the json property name
+func (s Swagger) JSONLookup(token string) (interface{}, error) {
+	if ex, ok := s.Extensions[token]; ok {
+		return &ex, nil
+	}
+	r, _, err := jsonpointer.GetForToken(s.SwaggerProps, token)
+	return r, err
+}
+
+// MarshalJSON marshals this swagger structure to json
+func (s Swagger) MarshalJSON() ([]byte, error) {
+	b1, err := json.Marshal(s.SwaggerProps)
+	if err != nil {
+		return nil, err
+	}
+	b2, err := json.Marshal(s.VendorExtensible)
+	if err != nil {
+		return nil, err
+	}
+	return swag.ConcatJSON(b1, b2), nil
+}
+
+// UnmarshalJSON unmarshals a swagger spec from json
+func (s *Swagger) UnmarshalJSON(data []byte) error {
+	var sw Swagger
+	if err := json.Unmarshal(data, &sw.SwaggerProps); err != nil {
+		return err
+	}
+	if err := json.Unmarshal(data, &sw.VendorExtensible); err != nil {
+		return err
+	}
+	*s = sw
+	return nil
+}
+
+// SwaggerProps captures the top-level properties of an Api specification
+type SwaggerProps struct {
+	ID                  string                 `json:"id,omitempty"`
+	Consumes            []string               `json:"consumes,omitempty"`
+	Produces            []string               `json:"produces,omitempty"`
+	Schemes             []string               `json:"schemes,omitempty"` // the scheme, when present must be from [http, https, ws, wss]
+	Swagger             string                 `json:"swagger,omitempty"`
+	Info                *Info                  `json:"info,omitempty"`
+	Host                string                 `json:"host,omitempty"`
+	BasePath            string                 `json:"basePath,omitempty"` // must start with a leading "/"
+	Paths               *Paths                 `json:"paths"`              // required
+	Definitions         Definitions            `json:"definitions,omitempty"`
+	Parameters          map[string]Parameter   `json:"parameters,omitempty"`
+	Responses           map[string]Response    `json:"responses,omitempty"`
+	SecurityDefinitions SecurityDefinitions    `json:"securityDefinitions,omitempty"`
+	Security            []map[string][]string  `json:"security,omitempty"`
+	Tags                []Tag                  `json:"tags,omitempty"`
+	ExternalDocs        *ExternalDocumentation `json:"externalDocs,omitempty"`
+}
+
+// Dependencies represent a dependencies property
+type Dependencies map[string]SchemaOrStringArray
+
+// SchemaOrBool represents a schema or boolean value, is biased towards true for the boolean property
+type SchemaOrBool struct {
+	Allows bool
+	Schema *Schema
+}
+
+// JSONLookup implements an interface to customize json pointer lookup
+func (s SchemaOrBool) JSONLookup(token string) (interface{}, error) {
+	if token == "allows" {
+		return s.Allows, nil
+	}
+	r, _, err := jsonpointer.GetForToken(s.Schema, token)
+	return r, err
+}
+
+var jsTrue = []byte("true")
+var jsFalse = []byte("false")
+
+// MarshalJSON convert this object to JSON
+func (s SchemaOrBool) MarshalJSON() ([]byte, error) {
+	if s.Schema != nil {
+		return json.Marshal(s.Schema)
+	}
+
+	if s.Schema == nil && !s.Allows {
+		return jsFalse, nil
+	}
+	return jsTrue, nil
+}
+
+// UnmarshalJSON converts this bool or schema object from a JSON structure
+func (s *SchemaOrBool) UnmarshalJSON(data []byte) error {
+	var nw SchemaOrBool
+	if len(data) >= 4 {
+		if data[0] == '{' {
+			var sch Schema
+			if err := json.Unmarshal(data, &sch); err != nil {
+				return err
+			}
+			nw.Schema = &sch
+		}
+		nw.Allows = !(data[0] == 'f' && data[1] == 'a' && data[2] == 'l' && data[3] == 's' && data[4] == 'e')
+	}
+	*s = nw
+	return nil
+}
+
+// SchemaOrStringArray represents a schema or a string array
+type SchemaOrStringArray struct {
+	Schema   *Schema
+	Property []string
+}
+
+// JSONLookup implements an interface to customize json pointer lookup
+func (s SchemaOrStringArray) JSONLookup(token string) (interface{}, error) {
+	r, _, err := jsonpointer.GetForToken(s.Schema, token)
+	return r, err
+}
+
+// MarshalJSON converts this schema object or array into JSON structure
+func (s SchemaOrStringArray) MarshalJSON() ([]byte, error) {
+	if len(s.Property) > 0 {
+		return json.Marshal(s.Property)
+	}
+	if s.Schema != nil {
+		return json.Marshal(s.Schema)
+	}
+	return []byte("null"), nil
+}
+
+// UnmarshalJSON converts this schema object or array from a JSON structure
+func (s *SchemaOrStringArray) UnmarshalJSON(data []byte) error {
+	var first byte
+	if len(data) > 1 {
+		first = data[0]
+	}
+	var nw SchemaOrStringArray
+	if first == '{' {
+		var sch Schema
+		if err := json.Unmarshal(data, &sch); err != nil {
+			return err
+		}
+		nw.Schema = &sch
+	}
+	if first == '[' {
+		if err := json.Unmarshal(data, &nw.Property); err != nil {
+			return err
+		}
+	}
+	*s = nw
+	return nil
+}
+
+// Definitions contains the models explicitly defined in this spec
+// An object to hold data types that can be consumed and produced by operations.
+// These data types can be primitives, arrays or models.
+//
+// For more information: http://goo.gl/8us55a#definitionsObject
+type Definitions map[string]Schema
+
+// SecurityDefinitions a declaration of the security schemes available to be used in the specification.
+// This does not enforce the security schemes on the operations and only serves to provide
+// the relevant details for each scheme.
+//
+// For more information: http://goo.gl/8us55a#securityDefinitionsObject
+type SecurityDefinitions map[string]*SecurityScheme
+
+// StringOrArray represents a value that can either be a string
+// or an array of strings. Mainly here for serialization purposes
+type StringOrArray []string
+
+// Contains returns true when the value is contained in the slice
+func (s StringOrArray) Contains(value string) bool {
+	for _, str := range s {
+		if str == value {
+			return true
+		}
+	}
+	return false
+}
+
+// JSONLookup implements an interface to customize json pointer lookup
+func (s SchemaOrArray) JSONLookup(token string) (interface{}, error) {
+	if _, err := strconv.Atoi(token); err == nil {
+		r, _, err := jsonpointer.GetForToken(s.Schemas, token)
+		return r, err
+	}
+	r, _, err := jsonpointer.GetForToken(s.Schema, token)
+	return r, err
+}
+
+// UnmarshalJSON unmarshals this string or array object from a JSON array or JSON string
+func (s *StringOrArray) UnmarshalJSON(data []byte) error {
+	var first byte
+	if len(data) > 1 {
+		first = data[0]
+	}
+
+	if first == '[' {
+		var parsed []string
+		if err := json.Unmarshal(data, &parsed); err != nil {
+			return err
+		}
+		*s = StringOrArray(parsed)
+		return nil
+	}
+
+	var single interface{}
+	if err := json.Unmarshal(data, &single); err != nil {
+		return err
+	}
+	if single == nil {
+		return nil
+	}
+	switch single.(type) {
+	case string:
+		*s = StringOrArray([]string{single.(string)})
+		return nil
+	default:
+		return fmt.Errorf("only string or array is allowed, not %T", single)
+	}
+}
+
+// MarshalJSON converts this string or array to a JSON array or JSON string
+func (s StringOrArray) MarshalJSON() ([]byte, error) {
+	if len(s) == 1 {
+		return json.Marshal([]string(s)[0])
+	}
+	return json.Marshal([]string(s))
+}
+
+// SchemaOrArray represents a value that can either be a Schema
+// or an array of Schema. Mainly here for serialization purposes
+type SchemaOrArray struct {
+	Schema  *Schema
+	Schemas []Schema
+}
+
+// Len returns the number of schemas in this property
+func (s SchemaOrArray) Len() int {
+	if s.Schema != nil {
+		return 1
+	}
+	return len(s.Schemas)
+}
+
+// ContainsType returns true when one of the schemas is of the specified type
+func (s *SchemaOrArray) ContainsType(name string) bool {
+	if s.Schema != nil {
+		return s.Schema.Type != nil && s.Schema.Type.Contains(name)
+	}
+	return false
+}
+
+// MarshalJSON converts this schema object or array into JSON structure
+func (s SchemaOrArray) MarshalJSON() ([]byte, error) {
+	if len(s.Schemas) > 0 {
+		return json.Marshal(s.Schemas)
+	}
+	return json.Marshal(s.Schema)
+}
+
+// UnmarshalJSON converts this schema object or array from a JSON structure
+func (s *SchemaOrArray) UnmarshalJSON(data []byte) error {
+	var nw SchemaOrArray
+	var first byte
+	if len(data) > 1 {
+		first = data[0]
+	}
+	if first == '{' {
+		var sch Schema
+		if err := json.Unmarshal(data, &sch); err != nil {
+			return err
+		}
+		nw.Schema = &sch
+	}
+	if first == '[' {
+		if err := json.Unmarshal(data, &nw.Schemas); err != nil {
+			return err
+		}
+	}
+	*s = nw
+	return nil
+}
+
+// vim:set ft=go noet sts=2 sw=2 ts=2:
diff --git a/go/vendor/github.com/go-openapi/spec/tag.go b/go/vendor/github.com/go-openapi/spec/tag.go
new file mode 100644
index 0000000..25256c4
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/tag.go
@@ -0,0 +1,74 @@
+// 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 spec
+
+import (
+	"encoding/json"
+
+	"github.com/go-openapi/jsonpointer"
+	"github.com/go-openapi/swag"
+)
+
+// TagProps describe a tag entry in the top level tags section of a swagger spec
+type TagProps struct {
+	Description  string                 `json:"description,omitempty"`
+	Name         string                 `json:"name,omitempty"`
+	ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty"`
+}
+
+// NewTag creates a new tag
+func NewTag(name, description string, externalDocs *ExternalDocumentation) Tag {
+	return Tag{TagProps: TagProps{description, name, externalDocs}}
+}
+
+// Tag allows adding meta data to a single tag that is used by the [Operation Object](http://goo.gl/8us55a#operationObject).
+// It is not mandatory to have a Tag Object per tag used there.
+//
+// For more information: http://goo.gl/8us55a#tagObject
+type Tag struct {
+	VendorExtensible
+	TagProps
+}
+
+// JSONLookup implements an interface to customize json pointer lookup
+func (t Tag) JSONLookup(token string) (interface{}, error) {
+	if ex, ok := t.Extensions[token]; ok {
+		return &ex, nil
+	}
+
+	r, _, err := jsonpointer.GetForToken(t.TagProps, token)
+	return r, err
+}
+
+// MarshalJSON marshal this to JSON
+func (t Tag) MarshalJSON() ([]byte, error) {
+	b1, err := json.Marshal(t.TagProps)
+	if err != nil {
+		return nil, err
+	}
+	b2, err := json.Marshal(t.VendorExtensible)
+	if err != nil {
+		return nil, err
+	}
+	return swag.ConcatJSON(b1, b2), nil
+}
+
+// UnmarshalJSON marshal this from JSON
+func (t *Tag) UnmarshalJSON(data []byte) error {
+	if err := json.Unmarshal(data, &t.TagProps); err != nil {
+		return err
+	}
+	return json.Unmarshal(data, &t.VendorExtensible)
+}
diff --git a/go/vendor/github.com/go-openapi/spec/xml_object.go b/go/vendor/github.com/go-openapi/spec/xml_object.go
new file mode 100644
index 0000000..945a467
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/spec/xml_object.go
@@ -0,0 +1,68 @@
+// 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 spec
+
+// XMLObject a metadata object that allows for more fine-tuned XML model definitions.
+//
+// For more information: http://goo.gl/8us55a#xmlObject
+type XMLObject struct {
+	Name      string `json:"name,omitempty"`
+	Namespace string `json:"namespace,omitempty"`
+	Prefix    string `json:"prefix,omitempty"`
+	Attribute bool   `json:"attribute,omitempty"`
+	Wrapped   bool   `json:"wrapped,omitempty"`
+}
+
+// WithName sets the xml name for the object
+func (x *XMLObject) WithName(name string) *XMLObject {
+	x.Name = name
+	return x
+}
+
+// WithNamespace sets the xml namespace for the object
+func (x *XMLObject) WithNamespace(namespace string) *XMLObject {
+	x.Namespace = namespace
+	return x
+}
+
+// WithPrefix sets the xml prefix for the object
+func (x *XMLObject) WithPrefix(prefix string) *XMLObject {
+	x.Prefix = prefix
+	return x
+}
+
+// AsAttribute flags this object as xml attribute
+func (x *XMLObject) AsAttribute() *XMLObject {
+	x.Attribute = true
+	return x
+}
+
+// AsElement flags this object as an xml node
+func (x *XMLObject) AsElement() *XMLObject {
+	x.Attribute = false
+	return x
+}
+
+// AsWrapped flags this object as wrapped, this is mostly useful for array types
+func (x *XMLObject) AsWrapped() *XMLObject {
+	x.Wrapped = true
+	return x
+}
+
+// AsUnwrapped flags this object as an xml node
+func (x *XMLObject) AsUnwrapped() *XMLObject {
+	x.Wrapped = false
+	return x
+}
diff --git a/go/vendor/github.com/go-openapi/strfmt/.editorconfig b/go/vendor/github.com/go-openapi/strfmt/.editorconfig
new file mode 100644
index 0000000..3152da6
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/strfmt/.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/strfmt/.gitignore b/go/vendor/github.com/go-openapi/strfmt/.gitignore
new file mode 100644
index 0000000..dd91ed6
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/strfmt/.gitignore
@@ -0,0 +1,2 @@
+secrets.yml
+coverage.out
diff --git a/go/vendor/github.com/go-openapi/strfmt/.golangci.yml b/go/vendor/github.com/go-openapi/strfmt/.golangci.yml
new file mode 100644
index 0000000..4029779
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/strfmt/.golangci.yml
@@ -0,0 +1,19 @@
+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
diff --git a/go/vendor/github.com/go-openapi/strfmt/.travis.yml b/go/vendor/github.com/go-openapi/strfmt/.travis.yml
new file mode 100644
index 0000000..613ee97
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/strfmt/.travis.yml
@@ -0,0 +1,20 @@
+after_success:
+- bash <(curl -s https://codecov.io/bash)
+go:
+- '1.9'
+- 1.10.x
+- 1.11.x
+install:
+- go get -u github.com/stretchr/testify/assert
+- go get -u github.com/pborman/uuid
+- go get -u github.com/asaskevich/govalidator
+- go get -u github.com/mailru/easyjson
+- go get -u github.com/go-openapi/errors
+- go get -u github.com/mitchellh/mapstructure
+- go get -u github.com/globalsign/mgo/bson
+language: go
+notifications:
+  slack:
+    secure: zE5AtIYTpYfQPnTzP+EaQPN7JKtfFAGv6PrJqoIZLOXa8B6zGb6+J1JRNNxWi7faWbyJOxa4FSSsuPsKZMycUK6wlLFIdhDxwqeo7Ew8r6rdZKdfUHQggfNS9wO79ARoNYUDHtmnaBUS+eWSM1YqSc4i99QxyyfuURLOeAaA/q14YbdlTlaw3lrZ0qT92ot1FnVGNOx064zuHtFeUf+jAVRMZ6Q3rvqllwIlPszE6rmHGXBt2VoJxRaBetdwd7FgkcYw9FPXKHhadwC7/75ZAdmxIukhxNMw4Tr5NuPcqNcnbYLenDP7B3lssGVIrP4BRSqekS1d/tqvdvnnFWHMwrNCkSnSc065G5+qWTlXKAemIclgiXXqE2furBNLm05MDdG8fn5epS0UNarkjD+zX336RiqwBlOX4KbF+vPyqcO98CsN0lnd+H6loc9reiTHs37orFFpQ+309av9be2GGsHUsRB9ssIyrewmhAccOmkRtr2dVTZJNFQwa5Kph5TNJuTjnZEwG/xUkEX2YSfwShOsb062JWiflV6PJdnl80pc9Tn7D5sO5Bf9DbijGRJwwP+YiiJtwtr+vsvS+n4sM0b5eqm4UoRo+JJO8ffoJtHS7ItuyRbVQCwEPJ4221WLcf5PquEEDdAPwR+K4Gj8qTXqTDdxOiES1xFUKVgmzhI=
+script:
+- ./hack/coverage
diff --git a/go/vendor/github.com/go-openapi/strfmt/CODE_OF_CONDUCT.md b/go/vendor/github.com/go-openapi/strfmt/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..9322b06
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/strfmt/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/strfmt/LICENSE b/go/vendor/github.com/go-openapi/strfmt/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/strfmt/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/strfmt/README.md b/go/vendor/github.com/go-openapi/strfmt/README.md
new file mode 100644
index 0000000..55f8804
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/strfmt/README.md
@@ -0,0 +1,71 @@
+# Strfmt [![Build Status](https://travis-ci.org/go-openapi/strfmt.svg?branch=master)](https://travis-ci.org/go-openapi/strfmt) [![codecov](https://codecov.io/gh/go-openapi/strfmt/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/strfmt) [![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/strfmt/master/LICENSE)
+[![GoDoc](https://godoc.org/github.com/go-openapi/strfmt?status.svg)](http://godoc.org/github.com/go-openapi/strfmt)
+[![GolangCI](https://golangci.com/badges/github.com/go-openapi/strfmt.svg)](https://golangci.com)
+[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/strfmt)](https://goreportcard.com/report/github.com/go-openapi/strfmt)
+
+This package exposes a registry of data types to support string formats in the go-openapi toolkit.
+
+strfmt represents a well known string format such as credit card or email. The go toolkit for OpenAPI specifications knows how to deal with those.
+
+## Supported data formats
+go-openapi/strfmt follows the swagger 2.0 specification with the following formats 
+defined [here](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types).
+
+It also provides convenient extensions to go-openapi users.
+
+- [x] JSON-schema draft 4 formats
+  - date-time
+  - email
+  - hostname
+  - ipv4
+  - ipv6
+  - uri
+- [x] swagger 2.0 format extensions
+  - binary
+  - byte (e.g. base64 encoded string)
+  - date (e.g. "1970-01-01")
+  - password
+- [x] go-openapi custom format extensions
+  - bsonobjectid (BSON objectID)
+  - creditcard
+  - duration (e.g. "3 weeks", "1ms")
+  - hexcolor (e.g. "#FFFFFF")
+  - isbn, isbn10, isbn13
+  - mac (e.g "01:02:03:04:05:06")
+  - rgbcolor (e.g. "rgb(100,100,100)")
+  - ssn
+  - uuid, uuid3, uuid4, uuid5
+
+> NOTE: as the name stands for, this package is intended to support string formatting only. 
+> It does not provide validation for numerical values with swagger format extension for JSON types "number" or  
+> "integer" (e.g. float, double, int32...).
+
+## Format types 
+Types defined in strfmt expose marshaling and validation capabilities.
+
+List of defined types:
+- Base64
+- CreditCard
+- Date
+- DateTime
+- Duration
+- Email
+- HexColor
+- Hostname
+- IPv4
+- IPv6
+- ISBN
+- ISBN10
+- ISBN13
+- MAC
+- ObjectId
+- Password
+- RGBColor
+- SSN
+- URI
+- UUID
+- UUID3
+- UUID4
+- UUID5
diff --git a/go/vendor/github.com/go-openapi/strfmt/bson.go b/go/vendor/github.com/go-openapi/strfmt/bson.go
new file mode 100644
index 0000000..be8ae2d
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/strfmt/bson.go
@@ -0,0 +1,127 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package strfmt
+
+import (
+	"database/sql/driver"
+	"errors"
+	"fmt"
+
+	"github.com/globalsign/mgo/bson"
+	"github.com/mailru/easyjson/jlexer"
+	"github.com/mailru/easyjson/jwriter"
+)
+
+func init() {
+	var id ObjectId
+	// register this format in the default registry
+	Default.Add("bsonobjectid", &id, IsBSONObjectID)
+}
+
+// IsBSONObjectID returns true when the string is a valid BSON.ObjectId
+func IsBSONObjectID(str string) bool {
+	return bson.IsObjectIdHex(str)
+}
+
+// ObjectId represents a BSON object ID (alias to github.com/globalsign/mgo/bson.ObjectId)
+//
+// swagger:strfmt bsonobjectid
+type ObjectId bson.ObjectId
+
+// NewObjectId creates a ObjectId from a Hex String
+func NewObjectId(hex string) ObjectId {
+	return ObjectId(bson.ObjectIdHex(hex))
+}
+
+// MarshalText turns this instance into text
+func (id *ObjectId) MarshalText() ([]byte, error) {
+	return []byte(bson.ObjectId(*id).Hex()), nil
+}
+
+// UnmarshalText hydrates this instance from text
+func (id *ObjectId) UnmarshalText(data []byte) error { // validation is performed later on
+	*id = ObjectId(bson.ObjectIdHex(string(data)))
+	return nil
+}
+
+// Scan read a value from a database driver
+func (id *ObjectId) Scan(raw interface{}) error {
+	var data []byte
+	switch v := raw.(type) {
+	case []byte:
+		data = v
+	case string:
+		data = []byte(v)
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.URI from: %#v", v)
+	}
+
+	return id.UnmarshalText(data)
+}
+
+// Value converts a value to a database driver value
+func (id *ObjectId) Value() (driver.Value, error) {
+	return driver.Value(string(*id)), nil
+}
+
+func (id *ObjectId) String() string {
+	return string(*id)
+}
+
+// MarshalJSON returns the ObjectId as JSON
+func (id *ObjectId) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	id.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the ObjectId to a easyjson.Writer
+func (id *ObjectId) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(bson.ObjectId(*id).Hex())
+}
+
+// UnmarshalJSON sets the ObjectId from JSON
+func (id *ObjectId) UnmarshalJSON(data []byte) error {
+	l := jlexer.Lexer{Data: data}
+	id.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the ObjectId from a easyjson.Lexer
+func (id *ObjectId) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		*id = NewObjectId(data)
+	}
+}
+
+// GetBSON returns the hex representation of the ObjectId as a bson.M{} map.
+func (id *ObjectId) GetBSON() (interface{}, error) {
+	return bson.M{"data": bson.ObjectId(*id).Hex()}, nil
+}
+
+// SetBSON sets the ObjectId from raw bson data
+func (id *ObjectId) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(string); ok {
+		*id = NewObjectId(data)
+		return nil
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as ObjectId")
+}
diff --git a/go/vendor/github.com/go-openapi/strfmt/date.go b/go/vendor/github.com/go-openapi/strfmt/date.go
new file mode 100644
index 0000000..ccdba44
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/strfmt/date.go
@@ -0,0 +1,150 @@
+// 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 strfmt
+
+import (
+	"database/sql/driver"
+	"errors"
+	"fmt"
+	"time"
+
+	"github.com/globalsign/mgo/bson"
+	"github.com/mailru/easyjson/jlexer"
+	"github.com/mailru/easyjson/jwriter"
+)
+
+func init() {
+	d := Date{}
+	// register this format in the default registry
+	Default.Add("date", &d, IsDate)
+}
+
+// IsDate returns true when the string is a valid date
+func IsDate(str string) bool {
+	_, err := time.Parse(RFC3339FullDate, str)
+	return err == nil
+}
+
+const (
+	// RFC3339FullDate represents a full-date as specified by RFC3339
+	// See: http://goo.gl/xXOvVd
+	RFC3339FullDate = "2006-01-02"
+)
+
+// Date represents a date from the API
+//
+// swagger:strfmt date
+type Date time.Time
+
+// String converts this date into a string
+func (d Date) String() string {
+	return time.Time(d).Format(RFC3339FullDate)
+}
+
+// UnmarshalText parses a text representation into a date type
+func (d *Date) UnmarshalText(text []byte) error {
+	if len(text) == 0 {
+		return nil
+	}
+	dd, err := time.Parse(RFC3339FullDate, string(text))
+	if err != nil {
+		return err
+	}
+	*d = Date(dd)
+	return nil
+}
+
+// MarshalText serializes this date type to string
+func (d Date) MarshalText() ([]byte, error) {
+	return []byte(d.String()), nil
+}
+
+// Scan scans a Date value from database driver type.
+func (d *Date) Scan(raw interface{}) error {
+	switch v := raw.(type) {
+	case []byte:
+		return d.UnmarshalText(v)
+	case string:
+		return d.UnmarshalText([]byte(v))
+	case time.Time:
+		*d = Date(v)
+		return nil
+	case nil:
+		*d = Date{}
+		return nil
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.Date from: %#v", v)
+	}
+}
+
+// Value converts Date to a primitive value ready to written to a database.
+func (d Date) Value() (driver.Value, error) {
+	return driver.Value(d.String()), nil
+}
+
+// MarshalJSON returns the Date as JSON
+func (d Date) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	d.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the Date to a easyjson.Writer
+func (d Date) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(time.Time(d).Format(RFC3339FullDate))
+}
+
+// UnmarshalJSON sets the Date from JSON
+func (d *Date) UnmarshalJSON(data []byte) error {
+	if string(data) == jsonNull {
+		return nil
+	}
+	l := jlexer.Lexer{Data: data}
+	d.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the Date from a easyjson.Lexer
+func (d *Date) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		tt, err := time.Parse(RFC3339FullDate, data)
+		if err != nil {
+			in.AddError(err)
+			return
+		}
+		*d = Date(tt)
+	}
+}
+
+// GetBSON returns the Date as a bson.M{} map.
+func (d *Date) GetBSON() (interface{}, error) {
+	return bson.M{"data": d.String()}, nil
+}
+
+// SetBSON sets the Date from raw bson data
+func (d *Date) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(string); ok {
+		rd, err := time.Parse(RFC3339FullDate, data)
+		*d = Date(rd)
+		return err
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as Date")
+}
diff --git a/go/vendor/github.com/go-openapi/strfmt/default.go b/go/vendor/github.com/go-openapi/strfmt/default.go
new file mode 100644
index 0000000..13235ec
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/strfmt/default.go
@@ -0,0 +1,1853 @@
+// 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 strfmt
+
+import (
+	"database/sql/driver"
+	"encoding/base64"
+	"errors"
+	"fmt"
+	"net/mail"
+	"regexp"
+	"strings"
+
+	"github.com/asaskevich/govalidator"
+	"github.com/globalsign/mgo/bson"
+	"github.com/mailru/easyjson/jlexer"
+	"github.com/mailru/easyjson/jwriter"
+)
+
+const (
+	// HostnamePattern http://json-schema.org/latest/json-schema-validation.html#anchor114
+	//  A string instance is valid against this attribute if it is a valid
+	//  representation for an Internet host name, as defined by RFC 1034, section 3.1 [RFC1034].
+	//  http://tools.ietf.org/html/rfc1034#section-3.5
+	//  <digit> ::= any one of the ten digits 0 through 9
+	//  var digit = /[0-9]/;
+	//  <letter> ::= any one of the 52 alphabetic characters A through Z in upper case and a through z in lower case
+	//  var letter = /[a-zA-Z]/;
+	//  <let-dig> ::= <letter> | <digit>
+	//  var letDig = /[0-9a-zA-Z]/;
+	//  <let-dig-hyp> ::= <let-dig> | "-"
+	//  var letDigHyp = /[-0-9a-zA-Z]/;
+	//  <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
+	//  var ldhStr = /[-0-9a-zA-Z]+/;
+	//  <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
+	//  var label = /[a-zA-Z](([-0-9a-zA-Z]+)?[0-9a-zA-Z])?/;
+	//  <subdomain> ::= <label> | <subdomain> "." <label>
+	//  var subdomain = /^[a-zA-Z](([-0-9a-zA-Z]+)?[0-9a-zA-Z])?(\.[a-zA-Z](([-0-9a-zA-Z]+)?[0-9a-zA-Z])?)*$/;
+	//  <domain> ::= <subdomain> | " "
+	HostnamePattern = `^[a-zA-Z](([-0-9a-zA-Z]+)?[0-9a-zA-Z])?(\.[a-zA-Z](([-0-9a-zA-Z]+)?[0-9a-zA-Z])?)*$`
+	// UUIDPattern Regex for UUID that allows uppercase
+	UUIDPattern = `(?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$`
+	// UUID3Pattern Regex for UUID3 that allows uppercase
+	UUID3Pattern = `(?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?3[0-9a-f]{3}-?[0-9a-f]{4}-?[0-9a-f]{12}$`
+	// UUID4Pattern Regex for UUID4 that allows uppercase
+	UUID4Pattern = `(?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$`
+	// UUID5Pattern Regex for UUID5 that allows uppercase
+	UUID5Pattern = `(?i)^[0-9a-f]{8}-?[0-9a-f]{4}-?5[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12}$`
+	// json null type
+	jsonNull = "null"
+)
+
+var (
+	rxHostname = regexp.MustCompile(HostnamePattern)
+	rxUUID     = regexp.MustCompile(UUIDPattern)
+	rxUUID3    = regexp.MustCompile(UUID3Pattern)
+	rxUUID4    = regexp.MustCompile(UUID4Pattern)
+	rxUUID5    = regexp.MustCompile(UUID5Pattern)
+)
+
+// IsHostname returns true when the string is a valid hostname
+func IsHostname(str string) bool {
+	if !rxHostname.MatchString(str) {
+		return false
+	}
+
+	// the sum of all label octets and label lengths is limited to 255.
+	if len(str) > 255 {
+		return false
+	}
+
+	// Each node has a label, which is zero to 63 octets in length
+	parts := strings.Split(str, ".")
+	valid := true
+	for _, p := range parts {
+		if len(p) > 63 {
+			valid = false
+		}
+	}
+	return valid
+}
+
+// IsUUID returns true is the string matches a UUID, upper case is allowed
+func IsUUID(str string) bool {
+	return rxUUID.MatchString(str)
+}
+
+// IsUUID3 returns true is the string matches a UUID, upper case is allowed
+func IsUUID3(str string) bool {
+	return rxUUID3.MatchString(str)
+}
+
+// IsUUID4 returns true is the string matches a UUID, upper case is allowed
+func IsUUID4(str string) bool {
+	return rxUUID4.MatchString(str)
+}
+
+// IsUUID5 returns true is the string matches a UUID, upper case is allowed
+func IsUUID5(str string) bool {
+	return rxUUID5.MatchString(str)
+}
+
+// Validates an email address.
+func IsEmail(str string) bool {
+	addr, e := mail.ParseAddress(str)
+	return e == nil && addr.Address != ""
+}
+
+func init() {
+	// register formats in the default registry:
+	//   - byte
+	//   - creditcard
+	//   - email
+	//   - hexcolor
+	//   - hostname
+	//   - ipv4
+	//   - ipv6
+	//   - isbn
+	//   - isbn10
+	//   - isbn13
+	//   - mac
+	//   - password
+	//   - rgbcolor
+	//   - ssn
+	//   - uri
+	//   - uuid
+	//   - uuid3
+	//   - uuid4
+	//   - uuid5
+	u := URI("")
+	Default.Add("uri", &u, govalidator.IsRequestURI)
+
+	eml := Email("")
+	Default.Add("email", &eml, IsEmail)
+
+	hn := Hostname("")
+	Default.Add("hostname", &hn, IsHostname)
+
+	ip4 := IPv4("")
+	Default.Add("ipv4", &ip4, govalidator.IsIPv4)
+
+	ip6 := IPv6("")
+	Default.Add("ipv6", &ip6, govalidator.IsIPv6)
+
+	mac := MAC("")
+	Default.Add("mac", &mac, govalidator.IsMAC)
+
+	uid := UUID("")
+	Default.Add("uuid", &uid, IsUUID)
+
+	uid3 := UUID3("")
+	Default.Add("uuid3", &uid3, IsUUID3)
+
+	uid4 := UUID4("")
+	Default.Add("uuid4", &uid4, IsUUID4)
+
+	uid5 := UUID5("")
+	Default.Add("uuid5", &uid5, IsUUID5)
+
+	isbn := ISBN("")
+	Default.Add("isbn", &isbn, func(str string) bool { return govalidator.IsISBN10(str) || govalidator.IsISBN13(str) })
+
+	isbn10 := ISBN10("")
+	Default.Add("isbn10", &isbn10, govalidator.IsISBN10)
+
+	isbn13 := ISBN13("")
+	Default.Add("isbn13", &isbn13, govalidator.IsISBN13)
+
+	cc := CreditCard("")
+	Default.Add("creditcard", &cc, govalidator.IsCreditCard)
+
+	ssn := SSN("")
+	Default.Add("ssn", &ssn, govalidator.IsSSN)
+
+	hc := HexColor("")
+	Default.Add("hexcolor", &hc, govalidator.IsHexcolor)
+
+	rc := RGBColor("")
+	Default.Add("rgbcolor", &rc, govalidator.IsRGBcolor)
+
+	b64 := Base64([]byte(nil))
+	Default.Add("byte", &b64, govalidator.IsBase64)
+
+	pw := Password("")
+	Default.Add("password", &pw, func(_ string) bool { return true })
+}
+
+/* unused:
+var formatCheckers = map[string]Validator{
+	"byte": govalidator.IsBase64,
+}
+*/
+
+// Base64 represents a base64 encoded string
+//
+// swagger:strfmt byte
+type Base64 []byte
+
+// MarshalText turns this instance into text
+func (b Base64) MarshalText() ([]byte, error) {
+	enc := base64.URLEncoding
+	src := []byte(b)
+	buf := make([]byte, enc.EncodedLen(len(src)))
+	enc.Encode(buf, src)
+	return buf, nil
+}
+
+// UnmarshalText hydrates this instance from text
+func (b *Base64) UnmarshalText(data []byte) error { // validation is performed later on
+	enc := base64.URLEncoding
+	dbuf := make([]byte, enc.DecodedLen(len(data)))
+
+	n, err := enc.Decode(dbuf, data)
+	if err != nil {
+		return err
+	}
+
+	*b = dbuf[:n]
+	return nil
+}
+
+// Scan read a value from a database driver
+func (b *Base64) Scan(raw interface{}) error {
+	switch v := raw.(type) {
+	case []byte:
+		*b = Base64(string(v))
+	case string:
+		*b = Base64(v)
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.Base64 from: %#v", v)
+	}
+
+	return nil
+}
+
+// Value converts a value to a database driver value
+func (b Base64) Value() (driver.Value, error) {
+	return driver.Value(string(b)), nil
+}
+
+func (b Base64) String() string {
+	return string(b)
+}
+
+// MarshalJSON returns the Base64 as JSON
+func (b Base64) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	b.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the Base64 to a easyjson.Writer
+func (b Base64) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(base64.StdEncoding.EncodeToString([]byte(b)))
+}
+
+// UnmarshalJSON sets the Base64 from JSON
+func (b *Base64) UnmarshalJSON(data []byte) error {
+	l := jlexer.Lexer{Data: data}
+	b.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the Base64 from a easyjson.Lexer
+func (b *Base64) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		enc := base64.StdEncoding
+		dbuf := make([]byte, enc.DecodedLen(len(data)))
+
+		n, err := enc.Decode(dbuf, []byte(data))
+		if err != nil {
+			in.AddError(err)
+			return
+		}
+
+		*b = dbuf[:n]
+	}
+}
+
+// GetBSON returns the Base64 as a bson.M{} map.
+func (b *Base64) GetBSON() (interface{}, error) {
+	return bson.M{"data": string(*b)}, nil
+}
+
+// SetBSON sets the Base64 from raw bson data
+func (b *Base64) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(string); ok {
+		*b = Base64(data)
+		return nil
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as Base64")
+}
+
+// URI represents the uri string format as specified by the json schema spec
+//
+// swagger:strfmt uri
+type URI string
+
+// MarshalText turns this instance into text
+func (u URI) MarshalText() ([]byte, error) {
+	return []byte(string(u)), nil
+}
+
+// UnmarshalText hydrates this instance from text
+func (u *URI) UnmarshalText(data []byte) error { // validation is performed later on
+	*u = URI(string(data))
+	return nil
+}
+
+// Scan read a value from a database driver
+func (u *URI) Scan(raw interface{}) error {
+	switch v := raw.(type) {
+	case []byte:
+		*u = URI(string(v))
+	case string:
+		*u = URI(v)
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.URI from: %#v", v)
+	}
+
+	return nil
+}
+
+// Value converts a value to a database driver value
+func (u URI) Value() (driver.Value, error) {
+	return driver.Value(string(u)), nil
+}
+
+func (u URI) String() string {
+	return string(u)
+}
+
+// MarshalJSON returns the URI as JSON
+func (u URI) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	u.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the URI to a easyjson.Writer
+func (u URI) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(string(u))
+}
+
+// UnmarshalJSON sets the URI from JSON
+func (u *URI) UnmarshalJSON(data []byte) error {
+	l := jlexer.Lexer{Data: data}
+	u.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the URI from a easyjson.Lexer
+func (u *URI) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		*u = URI(data)
+	}
+}
+
+// GetBSON returns the URI as a bson.M{} map.
+func (u *URI) GetBSON() (interface{}, error) {
+	return bson.M{"data": string(*u)}, nil
+}
+
+// SetBSON sets the URI from raw bson data
+func (u *URI) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(string); ok {
+		*u = URI(data)
+		return nil
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as URI")
+}
+
+// Email represents the email string format as specified by the json schema spec
+//
+// swagger:strfmt email
+type Email string
+
+// MarshalText turns this instance into text
+func (e Email) MarshalText() ([]byte, error) {
+	return []byte(string(e)), nil
+}
+
+// UnmarshalText hydrates this instance from text
+func (e *Email) UnmarshalText(data []byte) error { // validation is performed later on
+	*e = Email(string(data))
+	return nil
+}
+
+// Scan read a value from a database driver
+func (e *Email) Scan(raw interface{}) error {
+	switch v := raw.(type) {
+	case []byte:
+		*e = Email(string(v))
+	case string:
+		*e = Email(v)
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.Email from: %#v", v)
+	}
+
+	return nil
+}
+
+// Value converts a value to a database driver value
+func (e Email) Value() (driver.Value, error) {
+	return driver.Value(string(e)), nil
+}
+
+func (e Email) String() string {
+	return string(e)
+}
+
+// MarshalJSON returns the Email as JSON
+func (e Email) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	e.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the Email to a easyjson.Writer
+func (e Email) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(string(e))
+}
+
+// UnmarshalJSON sets the Email from JSON
+func (e *Email) UnmarshalJSON(data []byte) error {
+	l := jlexer.Lexer{Data: data}
+	e.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the Email from a easyjson.Lexer
+func (e *Email) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		*e = Email(data)
+	}
+}
+
+// GetBSON returns the Email as a bson.M{} map.
+func (e *Email) GetBSON() (interface{}, error) {
+	return bson.M{"data": string(*e)}, nil
+}
+
+// SetBSON sets the Email from raw bson data
+func (e *Email) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(string); ok {
+		*e = Email(data)
+		return nil
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as Email")
+}
+
+// Hostname represents the hostname string format as specified by the json schema spec
+//
+// swagger:strfmt hostname
+type Hostname string
+
+// MarshalText turns this instance into text
+func (h Hostname) MarshalText() ([]byte, error) {
+	return []byte(string(h)), nil
+}
+
+// UnmarshalText hydrates this instance from text
+func (h *Hostname) UnmarshalText(data []byte) error { // validation is performed later on
+	*h = Hostname(string(data))
+	return nil
+}
+
+// Scan read a value from a database driver
+func (h *Hostname) Scan(raw interface{}) error {
+	switch v := raw.(type) {
+	case []byte:
+		*h = Hostname(string(v))
+	case string:
+		*h = Hostname(v)
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.Hostname from: %#v", v)
+	}
+
+	return nil
+}
+
+// Value converts a value to a database driver value
+func (h Hostname) Value() (driver.Value, error) {
+	return driver.Value(string(h)), nil
+}
+
+func (h Hostname) String() string {
+	return string(h)
+}
+
+// MarshalJSON returns the Hostname as JSON
+func (h Hostname) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	h.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the Hostname to a easyjson.Writer
+func (h Hostname) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(string(h))
+}
+
+// UnmarshalJSON sets the Hostname from JSON
+func (h *Hostname) UnmarshalJSON(data []byte) error {
+	l := jlexer.Lexer{Data: data}
+	h.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the Hostname from a easyjson.Lexer
+func (h *Hostname) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		*h = Hostname(data)
+	}
+}
+
+// GetBSON returns the Hostname as a bson.M{} map.
+func (h *Hostname) GetBSON() (interface{}, error) {
+	return bson.M{"data": string(*h)}, nil
+}
+
+// SetBSON sets the Hostname from raw bson data
+func (h *Hostname) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(string); ok {
+		*h = Hostname(data)
+		return nil
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as Hostname")
+}
+
+// IPv4 represents an IP v4 address
+//
+// swagger:strfmt ipv4
+type IPv4 string
+
+// MarshalText turns this instance into text
+func (u IPv4) MarshalText() ([]byte, error) {
+	return []byte(string(u)), nil
+}
+
+// UnmarshalText hydrates this instance from text
+func (u *IPv4) UnmarshalText(data []byte) error { // validation is performed later on
+	*u = IPv4(string(data))
+	return nil
+}
+
+// Scan read a value from a database driver
+func (u *IPv4) Scan(raw interface{}) error {
+	switch v := raw.(type) {
+	case []byte:
+		*u = IPv4(string(v))
+	case string:
+		*u = IPv4(v)
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.IPv4 from: %#v", v)
+	}
+
+	return nil
+}
+
+// Value converts a value to a database driver value
+func (u IPv4) Value() (driver.Value, error) {
+	return driver.Value(string(u)), nil
+}
+
+func (u IPv4) String() string {
+	return string(u)
+}
+
+// MarshalJSON returns the IPv4 as JSON
+func (u IPv4) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	u.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the IPv4 to a easyjson.Writer
+func (u IPv4) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(string(u))
+}
+
+// UnmarshalJSON sets the IPv4 from JSON
+func (u *IPv4) UnmarshalJSON(data []byte) error {
+	l := jlexer.Lexer{Data: data}
+	u.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the IPv4 from a easyjson.Lexer
+func (u *IPv4) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		*u = IPv4(data)
+	}
+}
+
+// GetBSON returns the IPv4 as a bson.M{} map.
+func (u *IPv4) GetBSON() (interface{}, error) {
+	return bson.M{"data": string(*u)}, nil
+}
+
+// SetBSON sets the IPv4 from raw bson data
+func (u *IPv4) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(string); ok {
+		*u = IPv4(data)
+		return nil
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as IPv4")
+}
+
+// IPv6 represents an IP v6 address
+//
+// swagger:strfmt ipv6
+type IPv6 string
+
+// MarshalText turns this instance into text
+func (u IPv6) MarshalText() ([]byte, error) {
+	return []byte(string(u)), nil
+}
+
+// UnmarshalText hydrates this instance from text
+func (u *IPv6) UnmarshalText(data []byte) error { // validation is performed later on
+	*u = IPv6(string(data))
+	return nil
+}
+
+// Scan read a value from a database driver
+func (u *IPv6) Scan(raw interface{}) error {
+	switch v := raw.(type) {
+	case []byte:
+		*u = IPv6(string(v))
+	case string:
+		*u = IPv6(v)
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.IPv6 from: %#v", v)
+	}
+
+	return nil
+}
+
+// Value converts a value to a database driver value
+func (u IPv6) Value() (driver.Value, error) {
+	return driver.Value(string(u)), nil
+}
+
+func (u IPv6) String() string {
+	return string(u)
+}
+
+// MarshalJSON returns the IPv6 as JSON
+func (u IPv6) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	u.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the IPv6 to a easyjson.Writer
+func (u IPv6) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(string(u))
+}
+
+// UnmarshalJSON sets the IPv6 from JSON
+func (u *IPv6) UnmarshalJSON(data []byte) error {
+	l := jlexer.Lexer{Data: data}
+	u.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the IPv6 from a easyjson.Lexer
+func (u *IPv6) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		*u = IPv6(data)
+	}
+}
+
+// GetBSON returns the IPv6 as a bson.M{} map.
+func (u *IPv6) GetBSON() (interface{}, error) {
+	return bson.M{"data": string(*u)}, nil
+}
+
+// SetBSON sets the IPv6 from raw bson data
+func (u *IPv6) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(string); ok {
+		*u = IPv6(data)
+		return nil
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as IPv6")
+}
+
+// MAC represents a 48 bit MAC address
+//
+// swagger:strfmt mac
+type MAC string
+
+// MarshalText turns this instance into text
+func (u MAC) MarshalText() ([]byte, error) {
+	return []byte(string(u)), nil
+}
+
+// UnmarshalText hydrates this instance from text
+func (u *MAC) UnmarshalText(data []byte) error { // validation is performed later on
+	*u = MAC(string(data))
+	return nil
+}
+
+// Scan read a value from a database driver
+func (u *MAC) Scan(raw interface{}) error {
+	switch v := raw.(type) {
+	case []byte:
+		*u = MAC(string(v))
+	case string:
+		*u = MAC(v)
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.IPv4 from: %#v", v)
+	}
+
+	return nil
+}
+
+// Value converts a value to a database driver value
+func (u MAC) Value() (driver.Value, error) {
+	return driver.Value(string(u)), nil
+}
+
+func (u MAC) String() string {
+	return string(u)
+}
+
+// MarshalJSON returns the MAC as JSON
+func (u MAC) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	u.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the MAC to a easyjson.Writer
+func (u MAC) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(string(u))
+}
+
+// UnmarshalJSON sets the MAC from JSON
+func (u *MAC) UnmarshalJSON(data []byte) error {
+	l := jlexer.Lexer{Data: data}
+	u.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the MAC from a easyjson.Lexer
+func (u *MAC) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		*u = MAC(data)
+	}
+}
+
+// GetBSON returns the MAC as a bson.M{} map.
+func (u *MAC) GetBSON() (interface{}, error) {
+	return bson.M{"data": string(*u)}, nil
+}
+
+// SetBSON sets the MAC from raw bson data
+func (u *MAC) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(string); ok {
+		*u = MAC(data)
+		return nil
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as MAC")
+}
+
+// UUID represents a uuid string format
+//
+// swagger:strfmt uuid
+type UUID string
+
+// MarshalText turns this instance into text
+func (u UUID) MarshalText() ([]byte, error) {
+	return []byte(string(u)), nil
+}
+
+// UnmarshalText hydrates this instance from text
+func (u *UUID) UnmarshalText(data []byte) error { // validation is performed later on
+	*u = UUID(string(data))
+	return nil
+}
+
+// Scan read a value from a database driver
+func (u *UUID) Scan(raw interface{}) error {
+	switch v := raw.(type) {
+	case []byte:
+		*u = UUID(string(v))
+	case string:
+		*u = UUID(v)
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.UUID from: %#v", v)
+	}
+
+	return nil
+}
+
+// Value converts a value to a database driver value
+func (u UUID) Value() (driver.Value, error) {
+	return driver.Value(string(u)), nil
+}
+
+func (u UUID) String() string {
+	return string(u)
+}
+
+// MarshalJSON returns the UUID as JSON
+func (u UUID) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	u.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the UUID to a easyjson.Writer
+func (u UUID) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(string(u))
+}
+
+// UnmarshalJSON sets the UUID from JSON
+func (u *UUID) UnmarshalJSON(data []byte) error {
+	if string(data) == jsonNull {
+		return nil
+	}
+	l := jlexer.Lexer{Data: data}
+	u.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the UUID from a easyjson.Lexer
+func (u *UUID) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		*u = UUID(data)
+	}
+}
+
+// GetBSON returns the UUID as a bson.M{} map.
+func (u *UUID) GetBSON() (interface{}, error) {
+	return bson.M{"data": string(*u)}, nil
+}
+
+// SetBSON sets the UUID from raw bson data
+func (u *UUID) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(string); ok {
+		*u = UUID(data)
+		return nil
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as UUID")
+}
+
+// UUID3 represents a uuid3 string format
+//
+// swagger:strfmt uuid3
+type UUID3 string
+
+// MarshalText turns this instance into text
+func (u UUID3) MarshalText() ([]byte, error) {
+	return []byte(string(u)), nil
+}
+
+// UnmarshalText hydrates this instance from text
+func (u *UUID3) UnmarshalText(data []byte) error { // validation is performed later on
+	*u = UUID3(string(data))
+	return nil
+}
+
+// Scan read a value from a database driver
+func (u *UUID3) Scan(raw interface{}) error {
+	switch v := raw.(type) {
+	case []byte:
+		*u = UUID3(string(v))
+	case string:
+		*u = UUID3(v)
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.UUID3 from: %#v", v)
+	}
+
+	return nil
+}
+
+// Value converts a value to a database driver value
+func (u UUID3) Value() (driver.Value, error) {
+	return driver.Value(string(u)), nil
+}
+
+func (u UUID3) String() string {
+	return string(u)
+}
+
+// MarshalJSON returns the UUID3 as JSON
+func (u UUID3) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	u.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the UUID3 to a easyjson.Writer
+func (u UUID3) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(string(u))
+}
+
+// UnmarshalJSON sets the UUID3 from JSON
+func (u *UUID3) UnmarshalJSON(data []byte) error {
+	if string(data) == jsonNull {
+		return nil
+	}
+	l := jlexer.Lexer{Data: data}
+	u.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the UUID3 from a easyjson.Lexer
+func (u *UUID3) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		*u = UUID3(data)
+	}
+}
+
+// GetBSON returns the UUID3 as a bson.M{} map.
+func (u *UUID3) GetBSON() (interface{}, error) {
+	return bson.M{"data": string(*u)}, nil
+}
+
+// SetBSON sets the UUID3 from raw bson data
+func (u *UUID3) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(string); ok {
+		*u = UUID3(data)
+		return nil
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as UUID3")
+}
+
+// UUID4 represents a uuid4 string format
+//
+// swagger:strfmt uuid4
+type UUID4 string
+
+// MarshalText turns this instance into text
+func (u UUID4) MarshalText() ([]byte, error) {
+	return []byte(string(u)), nil
+}
+
+// UnmarshalText hydrates this instance from text
+func (u *UUID4) UnmarshalText(data []byte) error { // validation is performed later on
+	*u = UUID4(string(data))
+	return nil
+}
+
+// Scan read a value from a database driver
+func (u *UUID4) Scan(raw interface{}) error {
+	switch v := raw.(type) {
+	case []byte:
+		*u = UUID4(string(v))
+	case string:
+		*u = UUID4(v)
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.UUID4 from: %#v", v)
+	}
+
+	return nil
+}
+
+// Value converts a value to a database driver value
+func (u UUID4) Value() (driver.Value, error) {
+	return driver.Value(string(u)), nil
+}
+
+func (u UUID4) String() string {
+	return string(u)
+}
+
+// MarshalJSON returns the UUID4 as JSON
+func (u UUID4) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	u.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the UUID4 to a easyjson.Writer
+func (u UUID4) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(string(u))
+}
+
+// UnmarshalJSON sets the UUID4 from JSON
+func (u *UUID4) UnmarshalJSON(data []byte) error {
+	if string(data) == jsonNull {
+		return nil
+	}
+	l := jlexer.Lexer{Data: data}
+	u.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the UUID4 from a easyjson.Lexer
+func (u *UUID4) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		*u = UUID4(data)
+	}
+}
+
+// GetBSON returns the UUID4 as a bson.M{} map.
+func (u *UUID4) GetBSON() (interface{}, error) {
+	return bson.M{"data": string(*u)}, nil
+}
+
+// SetBSON sets the UUID4 from raw bson data
+func (u *UUID4) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(string); ok {
+		*u = UUID4(data)
+		return nil
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as UUID4")
+}
+
+// UUID5 represents a uuid5 string format
+//
+// swagger:strfmt uuid5
+type UUID5 string
+
+// MarshalText turns this instance into text
+func (u UUID5) MarshalText() ([]byte, error) {
+	return []byte(string(u)), nil
+}
+
+// UnmarshalText hydrates this instance from text
+func (u *UUID5) UnmarshalText(data []byte) error { // validation is performed later on
+	*u = UUID5(string(data))
+	return nil
+}
+
+// Scan read a value from a database driver
+func (u *UUID5) Scan(raw interface{}) error {
+	switch v := raw.(type) {
+	case []byte:
+		*u = UUID5(string(v))
+	case string:
+		*u = UUID5(v)
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.UUID5 from: %#v", v)
+	}
+
+	return nil
+}
+
+// Value converts a value to a database driver value
+func (u UUID5) Value() (driver.Value, error) {
+	return driver.Value(string(u)), nil
+}
+
+func (u UUID5) String() string {
+	return string(u)
+}
+
+// MarshalJSON returns the UUID5 as JSON
+func (u UUID5) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	u.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the UUID5 to a easyjson.Writer
+func (u UUID5) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(string(u))
+}
+
+// UnmarshalJSON sets the UUID5 from JSON
+func (u *UUID5) UnmarshalJSON(data []byte) error {
+	if string(data) == jsonNull {
+		return nil
+	}
+	l := jlexer.Lexer{Data: data}
+	u.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the UUID5 from a easyjson.Lexer
+func (u *UUID5) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		*u = UUID5(data)
+	}
+}
+
+// GetBSON returns the UUID5 as a bson.M{} map.
+func (u *UUID5) GetBSON() (interface{}, error) {
+	return bson.M{"data": string(*u)}, nil
+}
+
+// SetBSON sets the UUID5 from raw bson data
+func (u *UUID5) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(string); ok {
+		*u = UUID5(data)
+		return nil
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as UUID5")
+}
+
+// ISBN represents an isbn string format
+//
+// swagger:strfmt isbn
+type ISBN string
+
+// MarshalText turns this instance into text
+func (u ISBN) MarshalText() ([]byte, error) {
+	return []byte(string(u)), nil
+}
+
+// UnmarshalText hydrates this instance from text
+func (u *ISBN) UnmarshalText(data []byte) error { // validation is performed later on
+	*u = ISBN(string(data))
+	return nil
+}
+
+// Scan read a value from a database driver
+func (u *ISBN) Scan(raw interface{}) error {
+	switch v := raw.(type) {
+	case []byte:
+		*u = ISBN(string(v))
+	case string:
+		*u = ISBN(v)
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.ISBN from: %#v", v)
+	}
+
+	return nil
+}
+
+// Value converts a value to a database driver value
+func (u ISBN) Value() (driver.Value, error) {
+	return driver.Value(string(u)), nil
+}
+
+func (u ISBN) String() string {
+	return string(u)
+}
+
+// MarshalJSON returns the ISBN as JSON
+func (u ISBN) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	u.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the ISBN to a easyjson.Writer
+func (u ISBN) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(string(u))
+}
+
+// UnmarshalJSON sets the ISBN from JSON
+func (u *ISBN) UnmarshalJSON(data []byte) error {
+	l := jlexer.Lexer{Data: data}
+	u.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the ISBN from a easyjson.Lexer
+func (u *ISBN) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		*u = ISBN(data)
+	}
+}
+
+// GetBSON returns the ISBN as a bson.M{} map.
+func (u *ISBN) GetBSON() (interface{}, error) {
+	return bson.M{"data": string(*u)}, nil
+}
+
+// SetBSON sets the ISBN from raw bson data
+func (u *ISBN) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(string); ok {
+		*u = ISBN(data)
+		return nil
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as ISBN")
+}
+
+// ISBN10 represents an isbn 10 string format
+//
+// swagger:strfmt isbn10
+type ISBN10 string
+
+// MarshalText turns this instance into text
+func (u ISBN10) MarshalText() ([]byte, error) {
+	return []byte(string(u)), nil
+}
+
+// UnmarshalText hydrates this instance from text
+func (u *ISBN10) UnmarshalText(data []byte) error { // validation is performed later on
+	*u = ISBN10(string(data))
+	return nil
+}
+
+// Scan read a value from a database driver
+func (u *ISBN10) Scan(raw interface{}) error {
+	switch v := raw.(type) {
+	case []byte:
+		*u = ISBN10(string(v))
+	case string:
+		*u = ISBN10(v)
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.ISBN10 from: %#v", v)
+	}
+
+	return nil
+}
+
+// Value converts a value to a database driver value
+func (u ISBN10) Value() (driver.Value, error) {
+	return driver.Value(string(u)), nil
+}
+
+func (u ISBN10) String() string {
+	return string(u)
+}
+
+// MarshalJSON returns the ISBN10 as JSON
+func (u ISBN10) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	u.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the ISBN10 to a easyjson.Writer
+func (u ISBN10) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(string(u))
+}
+
+// UnmarshalJSON sets the ISBN10 from JSON
+func (u *ISBN10) UnmarshalJSON(data []byte) error {
+	l := jlexer.Lexer{Data: data}
+	u.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the ISBN10 from a easyjson.Lexer
+func (u *ISBN10) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		*u = ISBN10(data)
+	}
+}
+
+// GetBSON returns the ISBN10 as a bson.M{} map.
+func (u *ISBN10) GetBSON() (interface{}, error) {
+	return bson.M{"data": string(*u)}, nil
+}
+
+// SetBSON sets the ISBN10 from raw bson data
+func (u *ISBN10) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(string); ok {
+		*u = ISBN10(data)
+		return nil
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as ISBN10")
+}
+
+// ISBN13 represents an isbn 13 string format
+//
+// swagger:strfmt isbn13
+type ISBN13 string
+
+// MarshalText turns this instance into text
+func (u ISBN13) MarshalText() ([]byte, error) {
+	return []byte(string(u)), nil
+}
+
+// UnmarshalText hydrates this instance from text
+func (u *ISBN13) UnmarshalText(data []byte) error { // validation is performed later on
+	*u = ISBN13(string(data))
+	return nil
+}
+
+// Scan read a value from a database driver
+func (u *ISBN13) Scan(raw interface{}) error {
+	switch v := raw.(type) {
+	case []byte:
+		*u = ISBN13(string(v))
+	case string:
+		*u = ISBN13(v)
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.ISBN13 from: %#v", v)
+	}
+
+	return nil
+}
+
+// Value converts a value to a database driver value
+func (u ISBN13) Value() (driver.Value, error) {
+	return driver.Value(string(u)), nil
+}
+
+func (u ISBN13) String() string {
+	return string(u)
+}
+
+// MarshalJSON returns the ISBN13 as JSON
+func (u ISBN13) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	u.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the ISBN13 to a easyjson.Writer
+func (u ISBN13) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(string(u))
+}
+
+// UnmarshalJSON sets the ISBN13 from JSON
+func (u *ISBN13) UnmarshalJSON(data []byte) error {
+	l := jlexer.Lexer{Data: data}
+	u.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the ISBN13 from a easyjson.Lexer
+func (u *ISBN13) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		*u = ISBN13(data)
+	}
+}
+
+// GetBSON returns the ISBN13 as a bson.M{} map.
+func (u *ISBN13) GetBSON() (interface{}, error) {
+	return bson.M{"data": string(*u)}, nil
+}
+
+// SetBSON sets the ISBN13 from raw bson data
+func (u *ISBN13) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(string); ok {
+		*u = ISBN13(data)
+		return nil
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as ISBN13")
+}
+
+// CreditCard represents a credit card string format
+//
+// swagger:strfmt creditcard
+type CreditCard string
+
+// MarshalText turns this instance into text
+func (u CreditCard) MarshalText() ([]byte, error) {
+	return []byte(string(u)), nil
+}
+
+// UnmarshalText hydrates this instance from text
+func (u *CreditCard) UnmarshalText(data []byte) error { // validation is performed later on
+	*u = CreditCard(string(data))
+	return nil
+}
+
+// Scan read a value from a database driver
+func (u *CreditCard) Scan(raw interface{}) error {
+	switch v := raw.(type) {
+	case []byte:
+		*u = CreditCard(string(v))
+	case string:
+		*u = CreditCard(v)
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.CreditCard from: %#v", v)
+	}
+
+	return nil
+}
+
+// Value converts a value to a database driver value
+func (u CreditCard) Value() (driver.Value, error) {
+	return driver.Value(string(u)), nil
+}
+
+func (u CreditCard) String() string {
+	return string(u)
+}
+
+// MarshalJSON returns the CreditCard as JSON
+func (u CreditCard) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	u.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the CreditCard to a easyjson.Writer
+func (u CreditCard) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(string(u))
+}
+
+// UnmarshalJSON sets the CreditCard from JSON
+func (u *CreditCard) UnmarshalJSON(data []byte) error {
+	l := jlexer.Lexer{Data: data}
+	u.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the CreditCard from a easyjson.Lexer
+func (u *CreditCard) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		*u = CreditCard(data)
+	}
+}
+
+// GetBSON returns the CreditCard as a bson.M{} map.
+func (u *CreditCard) GetBSON() (interface{}, error) {
+	return bson.M{"data": string(*u)}, nil
+}
+
+// SetBSON sets the CreditCard from raw bson data
+func (u *CreditCard) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(string); ok {
+		*u = CreditCard(data)
+		return nil
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as CreditCard")
+}
+
+// SSN represents a social security string format
+//
+// swagger:strfmt ssn
+type SSN string
+
+// MarshalText turns this instance into text
+func (u SSN) MarshalText() ([]byte, error) {
+	return []byte(string(u)), nil
+}
+
+// UnmarshalText hydrates this instance from text
+func (u *SSN) UnmarshalText(data []byte) error { // validation is performed later on
+	*u = SSN(string(data))
+	return nil
+}
+
+// Scan read a value from a database driver
+func (u *SSN) Scan(raw interface{}) error {
+	switch v := raw.(type) {
+	case []byte:
+		*u = SSN(string(v))
+	case string:
+		*u = SSN(v)
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.SSN from: %#v", v)
+	}
+
+	return nil
+}
+
+// Value converts a value to a database driver value
+func (u SSN) Value() (driver.Value, error) {
+	return driver.Value(string(u)), nil
+}
+
+func (u SSN) String() string {
+	return string(u)
+}
+
+// MarshalJSON returns the SSN as JSON
+func (u SSN) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	u.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the SSN to a easyjson.Writer
+func (u SSN) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(string(u))
+}
+
+// UnmarshalJSON sets the SSN from JSON
+func (u *SSN) UnmarshalJSON(data []byte) error {
+	l := jlexer.Lexer{Data: data}
+	u.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the SSN from a easyjson.Lexer
+func (u *SSN) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		*u = SSN(data)
+	}
+}
+
+// GetBSON returns the SSN as a bson.M{} map.
+func (u *SSN) GetBSON() (interface{}, error) {
+	return bson.M{"data": string(*u)}, nil
+}
+
+// SetBSON sets the SSN from raw bson data
+func (u *SSN) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(string); ok {
+		*u = SSN(data)
+		return nil
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as SSN")
+}
+
+// HexColor represents a hex color string format
+//
+// swagger:strfmt hexcolor
+type HexColor string
+
+// MarshalText turns this instance into text
+func (h HexColor) MarshalText() ([]byte, error) {
+	return []byte(string(h)), nil
+}
+
+// UnmarshalText hydrates this instance from text
+func (h *HexColor) UnmarshalText(data []byte) error { // validation is performed later on
+	*h = HexColor(string(data))
+	return nil
+}
+
+// Scan read a value from a database driver
+func (h *HexColor) Scan(raw interface{}) error {
+	switch v := raw.(type) {
+	case []byte:
+		*h = HexColor(string(v))
+	case string:
+		*h = HexColor(v)
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.HexColor from: %#v", v)
+	}
+
+	return nil
+}
+
+// Value converts a value to a database driver value
+func (h HexColor) Value() (driver.Value, error) {
+	return driver.Value(string(h)), nil
+}
+
+func (h HexColor) String() string {
+	return string(h)
+}
+
+// MarshalJSON returns the HexColor as JSON
+func (h HexColor) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	h.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the HexColor to a easyjson.Writer
+func (h HexColor) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(string(h))
+}
+
+// UnmarshalJSON sets the HexColor from JSON
+func (h *HexColor) UnmarshalJSON(data []byte) error {
+	l := jlexer.Lexer{Data: data}
+	h.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the HexColor from a easyjson.Lexer
+func (h *HexColor) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		*h = HexColor(data)
+	}
+}
+
+// GetBSON returns the HexColor as a bson.M{} map.
+func (h *HexColor) GetBSON() (interface{}, error) {
+	return bson.M{"data": string(*h)}, nil
+}
+
+// SetBSON sets the HexColor from raw bson data
+func (h *HexColor) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(string); ok {
+		*h = HexColor(data)
+		return nil
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as HexColor")
+}
+
+// RGBColor represents a RGB color string format
+//
+// swagger:strfmt rgbcolor
+type RGBColor string
+
+// MarshalText turns this instance into text
+func (r RGBColor) MarshalText() ([]byte, error) {
+	return []byte(string(r)), nil
+}
+
+// UnmarshalText hydrates this instance from text
+func (r *RGBColor) UnmarshalText(data []byte) error { // validation is performed later on
+	*r = RGBColor(string(data))
+	return nil
+}
+
+// Scan read a value from a database driver
+func (r *RGBColor) Scan(raw interface{}) error {
+	switch v := raw.(type) {
+	case []byte:
+		*r = RGBColor(string(v))
+	case string:
+		*r = RGBColor(v)
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.RGBColor from: %#v", v)
+	}
+
+	return nil
+}
+
+// Value converts a value to a database driver value
+func (r RGBColor) Value() (driver.Value, error) {
+	return driver.Value(string(r)), nil
+}
+
+func (r RGBColor) String() string {
+	return string(r)
+}
+
+// MarshalJSON returns the RGBColor as JSON
+func (r RGBColor) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	r.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the RGBColor to a easyjson.Writer
+func (r RGBColor) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(string(r))
+}
+
+// UnmarshalJSON sets the RGBColor from JSON
+func (r *RGBColor) UnmarshalJSON(data []byte) error {
+	l := jlexer.Lexer{Data: data}
+	r.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the RGBColor from a easyjson.Lexer
+func (r *RGBColor) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		*r = RGBColor(data)
+	}
+}
+
+// GetBSON returns the RGBColor as a bson.M{} map.
+func (r *RGBColor) GetBSON() (interface{}, error) {
+	return bson.M{"data": string(*r)}, nil
+}
+
+// SetBSON sets the RGBColor from raw bson data
+func (r *RGBColor) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(string); ok {
+		*r = RGBColor(data)
+		return nil
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as RGBColor")
+}
+
+// Password represents a password.
+// This has no validations and is mainly used as a marker for UI components.
+//
+// swagger:strfmt password
+type Password string
+
+// MarshalText turns this instance into text
+func (r Password) MarshalText() ([]byte, error) {
+	return []byte(string(r)), nil
+}
+
+// UnmarshalText hydrates this instance from text
+func (r *Password) UnmarshalText(data []byte) error { // validation is performed later on
+	*r = Password(string(data))
+	return nil
+}
+
+// Scan read a value from a database driver
+func (r *Password) Scan(raw interface{}) error {
+	switch v := raw.(type) {
+	case []byte:
+		*r = Password(string(v))
+	case string:
+		*r = Password(v)
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.Password from: %#v", v)
+	}
+
+	return nil
+}
+
+// Value converts a value to a database driver value
+func (r Password) Value() (driver.Value, error) {
+	return driver.Value(string(r)), nil
+}
+
+func (r Password) String() string {
+	return string(r)
+}
+
+// MarshalJSON returns the Password as JSON
+func (r Password) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	r.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the Password to a easyjson.Writer
+func (r Password) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(string(r))
+}
+
+// UnmarshalJSON sets the Password from JSON
+func (r *Password) UnmarshalJSON(data []byte) error {
+	l := jlexer.Lexer{Data: data}
+	r.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the Password from a easyjson.Lexer
+func (r *Password) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		*r = Password(data)
+	}
+}
+
+// GetBSON returns the Password as a bson.M{} map.
+func (r *Password) GetBSON() (interface{}, error) {
+	return bson.M{"data": string(*r)}, nil
+}
+
+// SetBSON sets the Password from raw bson data
+func (r *Password) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(string); ok {
+		*r = Password(data)
+		return nil
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as Password")
+}
diff --git a/go/vendor/github.com/go-openapi/strfmt/doc.go b/go/vendor/github.com/go-openapi/strfmt/doc.go
new file mode 100644
index 0000000..41aebe6
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/strfmt/doc.go
@@ -0,0 +1,18 @@
+// 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 strfmt contains custom string formats
+//
+// TODO: add info on how to define and register a custom format
+package strfmt
diff --git a/go/vendor/github.com/go-openapi/strfmt/duration.go b/go/vendor/github.com/go-openapi/strfmt/duration.go
new file mode 100644
index 0000000..28df8e4
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/strfmt/duration.go
@@ -0,0 +1,203 @@
+// 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 strfmt
+
+import (
+	"database/sql/driver"
+	"errors"
+	"fmt"
+	"regexp"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/globalsign/mgo/bson"
+	"github.com/mailru/easyjson/jlexer"
+	"github.com/mailru/easyjson/jwriter"
+)
+
+func init() {
+	d := Duration(0)
+	// register this format in the default registry
+	Default.Add("duration", &d, IsDuration)
+}
+
+var (
+	timeUnits = [][]string{
+		{"ns", "nano"},
+		{"us", "µs", "micro"},
+		{"ms", "milli"},
+		{"s", "sec"},
+		{"m", "min"},
+		{"h", "hr", "hour"},
+		{"d", "day"},
+		{"w", "wk", "week"},
+	}
+
+	timeMultiplier = map[string]time.Duration{
+		"ns": time.Nanosecond,
+		"us": time.Microsecond,
+		"ms": time.Millisecond,
+		"s":  time.Second,
+		"m":  time.Minute,
+		"h":  time.Hour,
+		"d":  24 * time.Hour,
+		"w":  7 * 24 * time.Hour,
+	}
+
+	durationMatcher = regexp.MustCompile(`((\d+)\s*([A-Za-zµ]+))`)
+)
+
+// IsDuration returns true if the provided string is a valid duration
+func IsDuration(str string) bool {
+	_, err := ParseDuration(str)
+	return err == nil
+}
+
+// Duration represents a duration
+//
+// Duration stores a period of time as a nanosecond count, with the largest
+// repesentable duration being approximately 290 years.
+//
+// swagger:strfmt duration
+type Duration time.Duration
+
+// MarshalText turns this instance into text
+func (d Duration) MarshalText() ([]byte, error) {
+	return []byte(time.Duration(d).String()), nil
+}
+
+// UnmarshalText hydrates this instance from text
+func (d *Duration) UnmarshalText(data []byte) error { // validation is performed later on
+	dd, err := ParseDuration(string(data))
+	if err != nil {
+		return err
+	}
+	*d = Duration(dd)
+	return nil
+}
+
+// ParseDuration parses a duration from a string, compatible with scala duration syntax
+func ParseDuration(cand string) (time.Duration, error) {
+	if dur, err := time.ParseDuration(cand); err == nil {
+		return dur, nil
+	}
+
+	var dur time.Duration
+	ok := false
+	for _, match := range durationMatcher.FindAllStringSubmatch(cand, -1) {
+
+		factor, err := strconv.Atoi(match[2]) // converts string to int
+		if err != nil {
+			return 0, err
+		}
+		unit := strings.ToLower(strings.TrimSpace(match[3]))
+
+		for _, variants := range timeUnits {
+			last := len(variants) - 1
+			multiplier := timeMultiplier[variants[0]]
+
+			for i, variant := range variants {
+				if (last == i && strings.HasPrefix(unit, variant)) || strings.EqualFold(variant, unit) {
+					ok = true
+					dur += (time.Duration(factor) * multiplier)
+				}
+			}
+		}
+	}
+
+	if ok {
+		return dur, nil
+	}
+	return 0, fmt.Errorf("Unable to parse %s as duration", cand)
+}
+
+// Scan reads a Duration value from database driver type.
+func (d *Duration) Scan(raw interface{}) error {
+	switch v := raw.(type) {
+	// TODO: case []byte: // ?
+	case int64:
+		*d = Duration(v)
+	case float64:
+		*d = Duration(int64(v))
+	case nil:
+		*d = Duration(0)
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.Duration from: %#v", v)
+	}
+
+	return nil
+}
+
+// Value converts Duration to a primitive value ready to be written to a database.
+func (d Duration) Value() (driver.Value, error) {
+	return driver.Value(int64(d)), nil
+}
+
+// String converts this duration to a string
+func (d Duration) String() string {
+	return time.Duration(d).String()
+}
+
+// MarshalJSON returns the Duration as JSON
+func (d Duration) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	d.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the Duration to a easyjson.Writer
+func (d Duration) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(time.Duration(d).String())
+}
+
+// UnmarshalJSON sets the Duration from JSON
+func (d *Duration) UnmarshalJSON(data []byte) error {
+	l := jlexer.Lexer{Data: data}
+	d.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the Duration from a easyjson.Lexer
+func (d *Duration) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		tt, err := ParseDuration(data)
+		if err != nil {
+			in.AddError(err)
+			return
+		}
+		*d = Duration(tt)
+	}
+}
+
+// GetBSON returns the Duration a bson.M{} map.
+func (d *Duration) GetBSON() (interface{}, error) {
+	return bson.M{"data": int64(*d)}, nil
+}
+
+// SetBSON sets the Duration from raw bson data
+func (d *Duration) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(int64); ok {
+		*d = Duration(data)
+		return nil
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as Duration")
+}
diff --git a/go/vendor/github.com/go-openapi/strfmt/format.go b/go/vendor/github.com/go-openapi/strfmt/format.go
new file mode 100644
index 0000000..8afccbd
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/strfmt/format.go
@@ -0,0 +1,307 @@
+// 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 strfmt
+
+import (
+	"encoding"
+	"reflect"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/go-openapi/errors"
+	"github.com/mitchellh/mapstructure"
+)
+
+// Default is the default formats registry
+var Default = NewSeededFormats(nil, nil)
+
+// Validator represents a validator for a string format.
+type Validator func(string) bool
+
+// Format represents a string format.
+//
+// All implementations of Format provide a string representation and text
+// marshaling/unmarshaling interface to be used by encoders (e.g. encoding/json).
+type Format interface {
+	String() string
+	encoding.TextMarshaler
+	encoding.TextUnmarshaler
+}
+
+// Registry is a registry of string formats, with a validation method.
+type Registry interface {
+	Add(string, Format, Validator) bool
+	DelByName(string) bool
+	GetType(string) (reflect.Type, bool)
+	ContainsName(string) bool
+	Validates(string, string) bool
+	Parse(string, string) (interface{}, error)
+	MapStructureHookFunc() mapstructure.DecodeHookFunc
+}
+
+type knownFormat struct {
+	Name      string
+	OrigName  string
+	Type      reflect.Type
+	Validator Validator
+}
+
+// NameNormalizer is a function that normalizes a format name.
+type NameNormalizer func(string) string
+
+// DefaultNameNormalizer removes all dashes
+func DefaultNameNormalizer(name string) string {
+	return strings.Replace(name, "-", "", -1)
+}
+
+type defaultFormats struct {
+	sync.Mutex
+	data          []knownFormat
+	normalizeName NameNormalizer
+}
+
+// NewFormats creates a new formats registry seeded with the values from the default
+func NewFormats() Registry {
+	return NewSeededFormats(Default.(*defaultFormats).data, nil)
+}
+
+// NewSeededFormats creates a new formats registry
+func NewSeededFormats(seeds []knownFormat, normalizer NameNormalizer) Registry {
+	if normalizer == nil {
+		normalizer = DefaultNameNormalizer
+	}
+	// copy here, don't modify original
+	d := append([]knownFormat(nil), seeds...)
+	return &defaultFormats{
+		data:          d,
+		normalizeName: normalizer,
+	}
+}
+
+// MapStructureHookFunc is a decode hook function for mapstructure
+func (f *defaultFormats) MapStructureHookFunc() mapstructure.DecodeHookFunc {
+	return func(from reflect.Type, to reflect.Type, data interface{}) (interface{}, error) {
+		if from.Kind() != reflect.String {
+			return data, nil
+		}
+		for _, v := range f.data {
+			tpe, _ := f.GetType(v.Name)
+			if to == tpe {
+				switch v.Name {
+				case "date":
+					d, err := time.Parse(RFC3339FullDate, data.(string))
+					if err != nil {
+						return nil, err
+					}
+					return Date(d), nil
+				case "datetime":
+					return ParseDateTime(data.(string))
+				case "duration":
+					dur, err := ParseDuration(data.(string))
+					if err != nil {
+						return nil, err
+					}
+					return Duration(dur), nil
+				case "uri":
+					return URI(data.(string)), nil
+				case "email":
+					return Email(data.(string)), nil
+				case "uuid":
+					return UUID(data.(string)), nil
+				case "uuid3":
+					return UUID3(data.(string)), nil
+				case "uuid4":
+					return UUID4(data.(string)), nil
+				case "uuid5":
+					return UUID5(data.(string)), nil
+				case "hostname":
+					return Hostname(data.(string)), nil
+				case "ipv4":
+					return IPv4(data.(string)), nil
+				case "ipv6":
+					return IPv6(data.(string)), nil
+				case "mac":
+					return MAC(data.(string)), nil
+				case "isbn":
+					return ISBN(data.(string)), nil
+				case "isbn10":
+					return ISBN10(data.(string)), nil
+				case "isbn13":
+					return ISBN13(data.(string)), nil
+				case "creditcard":
+					return CreditCard(data.(string)), nil
+				case "ssn":
+					return SSN(data.(string)), nil
+				case "hexcolor":
+					return HexColor(data.(string)), nil
+				case "rgbcolor":
+					return RGBColor(data.(string)), nil
+				case "byte":
+					return Base64(data.(string)), nil
+				case "password":
+					return Password(data.(string)), nil
+				default:
+					return nil, errors.InvalidTypeName(v.Name)
+				}
+			}
+		}
+		return data, nil
+	}
+}
+
+// Add adds a new format, return true if this was a new item instead of a replacement
+func (f *defaultFormats) Add(name string, strfmt Format, validator Validator) bool {
+	f.Lock()
+	defer f.Unlock()
+
+	nme := f.normalizeName(name)
+
+	tpe := reflect.TypeOf(strfmt)
+	if tpe.Kind() == reflect.Ptr {
+		tpe = tpe.Elem()
+	}
+
+	for i := range f.data {
+		v := &f.data[i]
+		if v.Name == nme {
+			v.Type = tpe
+			v.Validator = validator
+			return false
+		}
+	}
+
+	// turns out it's new after all
+	f.data = append(f.data, knownFormat{Name: nme, OrigName: name, Type: tpe, Validator: validator})
+	return true
+}
+
+// GetType gets the type for the specified name
+func (f *defaultFormats) GetType(name string) (reflect.Type, bool) {
+	f.Lock()
+	defer f.Unlock()
+	nme := f.normalizeName(name)
+	for _, v := range f.data {
+		if v.Name == nme {
+			return v.Type, true
+		}
+	}
+	return nil, false
+}
+
+// DelByName removes the format by the specified name, returns true when an item was actually removed
+func (f *defaultFormats) DelByName(name string) bool {
+	f.Lock()
+	defer f.Unlock()
+
+	nme := f.normalizeName(name)
+
+	for i, v := range f.data {
+		if v.Name == nme {
+			f.data[i] = knownFormat{} // release
+			f.data = append(f.data[:i], f.data[i+1:]...)
+			return true
+		}
+	}
+	return false
+}
+
+// DelByType removes the specified format, returns true when an item was actually removed
+func (f *defaultFormats) DelByFormat(strfmt Format) bool {
+	f.Lock()
+	defer f.Unlock()
+
+	tpe := reflect.TypeOf(strfmt)
+	if tpe.Kind() == reflect.Ptr {
+		tpe = tpe.Elem()
+	}
+
+	for i, v := range f.data {
+		if v.Type == tpe {
+			f.data[i] = knownFormat{} // release
+			f.data = append(f.data[:i], f.data[i+1:]...)
+			return true
+		}
+	}
+	return false
+}
+
+// ContainsName returns true if this registry contains the specified name
+func (f *defaultFormats) ContainsName(name string) bool {
+	f.Lock()
+	defer f.Unlock()
+	nme := f.normalizeName(name)
+	for _, v := range f.data {
+		if v.Name == nme {
+			return true
+		}
+	}
+	return false
+}
+
+// ContainsFormat returns true if this registry contains the specified format
+func (f *defaultFormats) ContainsFormat(strfmt Format) bool {
+	f.Lock()
+	defer f.Unlock()
+	tpe := reflect.TypeOf(strfmt)
+	if tpe.Kind() == reflect.Ptr {
+		tpe = tpe.Elem()
+	}
+
+	for _, v := range f.data {
+		if v.Type == tpe {
+			return true
+		}
+	}
+	return false
+}
+
+// Validates passed data against format.
+//
+// Note that the format name is automatically normalized, e.g. one may
+// use "date-time" to use the "datetime" format validator.
+func (f *defaultFormats) Validates(name, data string) bool {
+	f.Lock()
+	defer f.Unlock()
+	nme := f.normalizeName(name)
+	for _, v := range f.data {
+		if v.Name == nme {
+			return v.Validator(data)
+		}
+	}
+	return false
+}
+
+// Parse a string into the appropriate format representation type.
+//
+// E.g. parsing a string a "date" will return a Date type.
+func (f *defaultFormats) Parse(name, data string) (interface{}, error) {
+	f.Lock()
+	defer f.Unlock()
+	nme := f.normalizeName(name)
+	for _, v := range f.data {
+		if v.Name == nme {
+			nw := reflect.New(v.Type).Interface()
+			if dec, ok := nw.(encoding.TextUnmarshaler); ok {
+				if err := dec.UnmarshalText([]byte(data)); err != nil {
+					return nil, err
+				}
+				return nw, nil
+			}
+			return nil, errors.InvalidTypeName(name)
+		}
+	}
+	return nil, errors.InvalidTypeName(name)
+}
diff --git a/go/vendor/github.com/go-openapi/strfmt/go.mod b/go/vendor/github.com/go-openapi/strfmt/go.mod
new file mode 100644
index 0000000..19c0939
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/strfmt/go.mod
@@ -0,0 +1,13 @@
+module github.com/go-openapi/strfmt
+
+require (
+	github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf
+	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb
+	github.com/go-openapi/errors v0.17.0
+	github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329
+	github.com/mitchellh/mapstructure v1.1.2
+	github.com/pborman/uuid v1.2.0
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	github.com/stretchr/testify v1.2.2
+)
diff --git a/go/vendor/github.com/go-openapi/strfmt/go.sum b/go/vendor/github.com/go-openapi/strfmt/go.sum
new file mode 100644
index 0000000..77349a2
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/strfmt/go.sum
@@ -0,0 +1,19 @@
+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/errors v0.17.0 h1:47T+LqPrQUxFXQnB22aLBfsTRFSqWp5y4OiFgQm+/Lw=
+github.com/go-openapi/errors v0.17.0/go.mod h1:La0D2x9HoXenv7MDEiAv6vWoe84CXFo0PQRk/jdQlww=
+github.com/google/uuid v1.0.0 h1:b4Gk+7WdP/d3HZH8EJsZpvV7EtDOgaZLtnaNGIu1adA=
+github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+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/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
+github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
+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=
diff --git a/go/vendor/github.com/go-openapi/strfmt/time.go b/go/vendor/github.com/go-openapi/strfmt/time.go
new file mode 100644
index 0000000..987deab
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/strfmt/time.go
@@ -0,0 +1,195 @@
+// 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 strfmt
+
+import (
+	"database/sql/driver"
+	"errors"
+	"fmt"
+	"regexp"
+	"strings"
+	"time"
+
+	"github.com/globalsign/mgo/bson"
+	"github.com/mailru/easyjson/jlexer"
+	"github.com/mailru/easyjson/jwriter"
+)
+
+func init() {
+	dt := DateTime{}
+	Default.Add("datetime", &dt, IsDateTime)
+}
+
+// IsDateTime returns true when the string is a valid date-time
+func IsDateTime(str string) bool {
+	if len(str) < 4 {
+		return false
+	}
+	s := strings.Split(strings.ToLower(str), "t")
+	if len(s) < 2 || !IsDate(s[0]) {
+		return false
+	}
+
+	matches := rxDateTime.FindAllStringSubmatch(s[1], -1)
+	if len(matches) == 0 || len(matches[0]) == 0 {
+		return false
+	}
+	m := matches[0]
+	res := m[1] <= "23" && m[2] <= "59" && m[3] <= "59"
+	return res
+}
+
+const (
+	// RFC3339Millis represents a ISO8601 format to millis instead of to nanos
+	RFC3339Millis = "2006-01-02T15:04:05.000Z07:00"
+	// RFC3339Micro represents a ISO8601 format to micro instead of to nano
+	RFC3339Micro = "2006-01-02T15:04:05.000000Z07:00"
+	// DateTimePattern pattern to match for the date-time format from http://tools.ietf.org/html/rfc3339#section-5.6
+	DateTimePattern = `^([0-9]{2}):([0-9]{2}):([0-9]{2})(.[0-9]+)?(z|([+-][0-9]{2}:[0-9]{2}))$`
+)
+
+var (
+	dateTimeFormats = []string{RFC3339Micro, RFC3339Millis, time.RFC3339, time.RFC3339Nano}
+	rxDateTime      = regexp.MustCompile(DateTimePattern)
+	// MarshalFormat sets the time resolution format used for marshaling time (set to milliseconds)
+	MarshalFormat = RFC3339Millis
+)
+
+// ParseDateTime parses a string that represents an ISO8601 time or a unix epoch
+func ParseDateTime(data string) (DateTime, error) {
+	if data == "" {
+		return NewDateTime(), nil
+	}
+	var lastError error
+	for _, layout := range dateTimeFormats {
+		dd, err := time.Parse(layout, data)
+		if err != nil {
+			lastError = err
+			continue
+		}
+		lastError = nil
+		return DateTime(dd), nil
+	}
+	return DateTime{}, lastError
+}
+
+// DateTime is a time but it serializes to ISO8601 format with millis
+// It knows how to read 3 different variations of a RFC3339 date time.
+// Most APIs we encounter want either millisecond or second precision times.
+// This just tries to make it worry-free.
+//
+// swagger:strfmt date-time
+type DateTime time.Time
+
+// NewDateTime is a representation of zero value for DateTime type
+func NewDateTime() DateTime {
+	return DateTime(time.Unix(0, 0).UTC())
+}
+
+// String converts this time to a string
+func (t DateTime) String() string {
+	return time.Time(t).Format(MarshalFormat)
+}
+
+// MarshalText implements the text marshaller interface
+func (t DateTime) MarshalText() ([]byte, error) {
+	return []byte(t.String()), nil
+}
+
+// UnmarshalText implements the text unmarshaller interface
+func (t *DateTime) UnmarshalText(text []byte) error {
+	tt, err := ParseDateTime(string(text))
+	if err != nil {
+		return err
+	}
+	*t = tt
+	return nil
+}
+
+// Scan scans a DateTime value from database driver type.
+func (t *DateTime) Scan(raw interface{}) error {
+	// TODO: case int64: and case float64: ?
+	switch v := raw.(type) {
+	case []byte:
+		return t.UnmarshalText(v)
+	case string:
+		return t.UnmarshalText([]byte(v))
+	case time.Time:
+		*t = DateTime(v)
+	case nil:
+		*t = DateTime{}
+	default:
+		return fmt.Errorf("cannot sql.Scan() strfmt.DateTime from: %#v", v)
+	}
+
+	return nil
+}
+
+// Value converts DateTime to a primitive value ready to written to a database.
+func (t DateTime) Value() (driver.Value, error) {
+	return driver.Value(t.String()), nil
+}
+
+// MarshalJSON returns the DateTime as JSON
+func (t DateTime) MarshalJSON() ([]byte, error) {
+	var w jwriter.Writer
+	t.MarshalEasyJSON(&w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON writes the DateTime to a easyjson.Writer
+func (t DateTime) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(time.Time(t).Format(MarshalFormat))
+}
+
+// UnmarshalJSON sets the DateTime from JSON
+func (t *DateTime) UnmarshalJSON(data []byte) error {
+	l := jlexer.Lexer{Data: data}
+	t.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON sets the DateTime from a easyjson.Lexer
+func (t *DateTime) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if data := in.String(); in.Ok() {
+		tt, err := ParseDateTime(data)
+		if err != nil {
+			in.AddError(err)
+			return
+		}
+		*t = tt
+	}
+}
+
+// GetBSON returns the DateTime as a bson.M{} map.
+func (t *DateTime) GetBSON() (interface{}, error) {
+	return bson.M{"data": t.String()}, nil
+}
+
+// SetBSON sets the DateTime from raw bson data
+func (t *DateTime) SetBSON(raw bson.Raw) error {
+	var m bson.M
+	if err := raw.Unmarshal(&m); err != nil {
+		return err
+	}
+
+	if data, ok := m["data"].(string); ok {
+		var err error
+		*t, err = ParseDateTime(data)
+		return err
+	}
+
+	return errors.New("couldn't unmarshal bson raw value as Duration")
+}
diff --git a/go/vendor/github.com/go-openapi/swag/.editorconfig b/go/vendor/github.com/go-openapi/swag/.editorconfig
new file mode 100644
index 0000000..3152da6
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/swag/.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/swag/.gitignore b/go/vendor/github.com/go-openapi/swag/.gitignore
new file mode 100644
index 0000000..5862205
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/swag/.gitignore
@@ -0,0 +1,3 @@
+secrets.yml
+vendor
+Godeps
diff --git a/go/vendor/github.com/go-openapi/swag/.golangci.yml b/go/vendor/github.com/go-openapi/swag/.golangci.yml
new file mode 100644
index 0000000..6b237e4
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/swag/.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: 3
+    min-occurrences: 2
+
+linters:
+  enable-all: true
+  disable:
+    - maligned
+    - lll
diff --git a/go/vendor/github.com/go-openapi/swag/.travis.yml b/go/vendor/github.com/go-openapi/swag/.travis.yml
new file mode 100644
index 0000000..bd3a2e5
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/swag/.travis.yml
@@ -0,0 +1,16 @@
+after_success:
+- bash <(curl -s https://codecov.io/bash)
+go:
+- '1.9'
+- 1.10.x
+- 1.11.x
+install:
+- go get -u github.com/stretchr/testify
+- go get -u github.com/mailru/easyjson
+- go get -u gopkg.in/yaml.v2
+language: go
+notifications:
+  slack:
+    secure: QUWvCkBBK09GF7YtEvHHVt70JOkdlNBG0nIKu/5qc4/nW5HP8I2w0SEf/XR2je0eED1Qe3L/AfMCWwrEj+IUZc3l4v+ju8X8R3Lomhme0Eb0jd1MTMCuPcBT47YCj0M7RON7vXtbFfm1hFJ/jLe5+9FXz0hpXsR24PJc5ZIi/ogNwkaPqG4BmndzecpSh0vc2FJPZUD9LT0I09REY/vXR0oQAalLkW0asGD5taHZTUZq/kBpsNxaAFrLM23i4mUcf33M5fjLpvx5LRICrX/57XpBrDh2TooBU6Qj3CgoY0uPRYUmSNxbVx1czNzl2JtEpb5yjoxfVPQeg0BvQM00G8LJINISR+ohrjhkZmAqchDupAX+yFrxTtORa78CtnIL6z/aTNlgwwVD8kvL/1pFA/JWYmKDmz93mV/+6wubGzNSQCstzjkFA4/iZEKewKUoRIAi/fxyscP6L/rCpmY/4llZZvrnyTqVbt6URWpopUpH4rwYqreXAtJxJsfBJIeSmUIiDIOMGkCTvyTEW3fWGmGoqWtSHLoaWDyAIGb7azb+KvfpWtEcoPFWfSWU+LGee0A/YsUhBl7ADB9A0CJEuR8q4BPpKpfLwPKSiKSAXL7zDkyjExyhtgqbSl2jS+rKIHOZNL8JkCcTP2MKMVd563C5rC5FMKqu3S9m2b6380E=
+script:
+- go test -v -race -cover -coverprofile=coverage.txt -covermode=atomic ./...
diff --git a/go/vendor/github.com/go-openapi/swag/CODE_OF_CONDUCT.md b/go/vendor/github.com/go-openapi/swag/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..9322b06
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/swag/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/swag/LICENSE b/go/vendor/github.com/go-openapi/swag/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/swag/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/swag/README.md b/go/vendor/github.com/go-openapi/swag/README.md
new file mode 100644
index 0000000..459a3e1
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/swag/README.md
@@ -0,0 +1,23 @@
+# Swag [![Build Status](https://travis-ci.org/go-openapi/swag.svg?branch=master)](https://travis-ci.org/go-openapi/swag) [![codecov](https://codecov.io/gh/go-openapi/swag/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/swag) [![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/swag/master/LICENSE)
+[![GoDoc](https://godoc.org/github.com/go-openapi/swag?status.svg)](http://godoc.org/github.com/go-openapi/swag)
+[![GolangCI](https://golangci.com/badges/github.com/go-openapi/swag.svg)](https://golangci.com)
+[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/swag)](https://goreportcard.com/report/github.com/go-openapi/swag)
+
+Contains a bunch of helper functions for go-openapi and go-swagger projects.
+
+You may also use it standalone for your projects.
+
+* convert between value and pointers for builtin types
+* convert from string to builtin types (wraps strconv)
+* fast json concatenation
+* search in path
+* load from file or http
+* name mangling
+
+
+This repo has only few dependencies outside of the standard library:
+
+* JSON utilities depend on github.com/mailru/easyjson
+* YAML utilities depend on gopkg.in/yaml.v2
diff --git a/go/vendor/github.com/go-openapi/swag/convert.go b/go/vendor/github.com/go-openapi/swag/convert.go
new file mode 100644
index 0000000..4e446ff
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/swag/convert.go
@@ -0,0 +1,207 @@
+// 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 swag
+
+import (
+	"math"
+	"strconv"
+	"strings"
+)
+
+// same as ECMA Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER
+const (
+	maxJSONFloat         = float64(1<<53 - 1)  // 9007199254740991.0 	 	 2^53 - 1
+	minJSONFloat         = -float64(1<<53 - 1) //-9007199254740991.0	-2^53 - 1
+	epsilon      float64 = 1e-9
+)
+
+// IsFloat64AJSONInteger allow for integers [-2^53, 2^53-1] inclusive
+func IsFloat64AJSONInteger(f float64) bool {
+	if math.IsNaN(f) || math.IsInf(f, 0) || f < minJSONFloat || f > maxJSONFloat {
+		return false
+	}
+	fa := math.Abs(f)
+	g := float64(uint64(f))
+	ga := math.Abs(g)
+
+	diff := math.Abs(f - g)
+
+	// more info: https://floating-point-gui.de/errors/comparison/#look-out-for-edge-cases
+	if f == g { // best case
+		return true
+	} else if f == float64(int64(f)) || f == float64(uint64(f)) { // optimistic case
+		return true
+	} else if f == 0 || g == 0 || diff < math.SmallestNonzeroFloat64 { // very close to 0 values
+		return diff < (epsilon * math.SmallestNonzeroFloat64)
+	}
+	// check the relative error
+	return diff/math.Min(fa+ga, math.MaxFloat64) < epsilon
+}
+
+var evaluatesAsTrue map[string]struct{}
+
+func init() {
+	evaluatesAsTrue = map[string]struct{}{
+		"true":     {},
+		"1":        {},
+		"yes":      {},
+		"ok":       {},
+		"y":        {},
+		"on":       {},
+		"selected": {},
+		"checked":  {},
+		"t":        {},
+		"enabled":  {},
+	}
+}
+
+// ConvertBool turn a string into a boolean
+func ConvertBool(str string) (bool, error) {
+	_, ok := evaluatesAsTrue[strings.ToLower(str)]
+	return ok, nil
+}
+
+// ConvertFloat32 turn a string into a float32
+func ConvertFloat32(str string) (float32, error) {
+	f, err := strconv.ParseFloat(str, 32)
+	if err != nil {
+		return 0, err
+	}
+	return float32(f), nil
+}
+
+// ConvertFloat64 turn a string into a float64
+func ConvertFloat64(str string) (float64, error) {
+	return strconv.ParseFloat(str, 64)
+}
+
+// ConvertInt8 turn a string into int8 boolean
+func ConvertInt8(str string) (int8, error) {
+	i, err := strconv.ParseInt(str, 10, 8)
+	if err != nil {
+		return 0, err
+	}
+	return int8(i), nil
+}
+
+// ConvertInt16 turn a string into a int16
+func ConvertInt16(str string) (int16, error) {
+	i, err := strconv.ParseInt(str, 10, 16)
+	if err != nil {
+		return 0, err
+	}
+	return int16(i), nil
+}
+
+// ConvertInt32 turn a string into a int32
+func ConvertInt32(str string) (int32, error) {
+	i, err := strconv.ParseInt(str, 10, 32)
+	if err != nil {
+		return 0, err
+	}
+	return int32(i), nil
+}
+
+// ConvertInt64 turn a string into a int64
+func ConvertInt64(str string) (int64, error) {
+	return strconv.ParseInt(str, 10, 64)
+}
+
+// ConvertUint8 turn a string into a uint8
+func ConvertUint8(str string) (uint8, error) {
+	i, err := strconv.ParseUint(str, 10, 8)
+	if err != nil {
+		return 0, err
+	}
+	return uint8(i), nil
+}
+
+// ConvertUint16 turn a string into a uint16
+func ConvertUint16(str string) (uint16, error) {
+	i, err := strconv.ParseUint(str, 10, 16)
+	if err != nil {
+		return 0, err
+	}
+	return uint16(i), nil
+}
+
+// ConvertUint32 turn a string into a uint32
+func ConvertUint32(str string) (uint32, error) {
+	i, err := strconv.ParseUint(str, 10, 32)
+	if err != nil {
+		return 0, err
+	}
+	return uint32(i), nil
+}
+
+// ConvertUint64 turn a string into a uint64
+func ConvertUint64(str string) (uint64, error) {
+	return strconv.ParseUint(str, 10, 64)
+}
+
+// FormatBool turns a boolean into a string
+func FormatBool(value bool) string {
+	return strconv.FormatBool(value)
+}
+
+// FormatFloat32 turns a float32 into a string
+func FormatFloat32(value float32) string {
+	return strconv.FormatFloat(float64(value), 'f', -1, 32)
+}
+
+// FormatFloat64 turns a float64 into a string
+func FormatFloat64(value float64) string {
+	return strconv.FormatFloat(value, 'f', -1, 64)
+}
+
+// FormatInt8 turns an int8 into a string
+func FormatInt8(value int8) string {
+	return strconv.FormatInt(int64(value), 10)
+}
+
+// FormatInt16 turns an int16 into a string
+func FormatInt16(value int16) string {
+	return strconv.FormatInt(int64(value), 10)
+}
+
+// FormatInt32 turns an int32 into a string
+func FormatInt32(value int32) string {
+	return strconv.Itoa(int(value))
+}
+
+// FormatInt64 turns an int64 into a string
+func FormatInt64(value int64) string {
+	return strconv.FormatInt(value, 10)
+}
+
+// FormatUint8 turns an uint8 into a string
+func FormatUint8(value uint8) string {
+	return strconv.FormatUint(uint64(value), 10)
+}
+
+// FormatUint16 turns an uint16 into a string
+func FormatUint16(value uint16) string {
+	return strconv.FormatUint(uint64(value), 10)
+}
+
+// FormatUint32 turns an uint32 into a string
+func FormatUint32(value uint32) string {
+	return strconv.FormatUint(uint64(value), 10)
+}
+
+// FormatUint64 turns an uint64 into a string
+func FormatUint64(value uint64) string {
+	return strconv.FormatUint(value, 10)
+}
diff --git a/go/vendor/github.com/go-openapi/swag/convert_types.go b/go/vendor/github.com/go-openapi/swag/convert_types.go
new file mode 100644
index 0000000..c95e4e7
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/swag/convert_types.go
@@ -0,0 +1,595 @@
+package swag
+
+import "time"
+
+// This file was taken from the aws go sdk
+
+// String returns a pointer to of the string value passed in.
+func String(v string) *string {
+	return &v
+}
+
+// StringValue returns the value of the string pointer passed in or
+// "" if the pointer is nil.
+func StringValue(v *string) string {
+	if v != nil {
+		return *v
+	}
+	return ""
+}
+
+// StringSlice converts a slice of string values into a slice of
+// string pointers
+func StringSlice(src []string) []*string {
+	dst := make([]*string, len(src))
+	for i := 0; i < len(src); i++ {
+		dst[i] = &(src[i])
+	}
+	return dst
+}
+
+// StringValueSlice converts a slice of string pointers into a slice of
+// string values
+func StringValueSlice(src []*string) []string {
+	dst := make([]string, len(src))
+	for i := 0; i < len(src); i++ {
+		if src[i] != nil {
+			dst[i] = *(src[i])
+		}
+	}
+	return dst
+}
+
+// StringMap converts a string map of string values into a string
+// map of string pointers
+func StringMap(src map[string]string) map[string]*string {
+	dst := make(map[string]*string)
+	for k, val := range src {
+		v := val
+		dst[k] = &v
+	}
+	return dst
+}
+
+// StringValueMap converts a string map of string pointers into a string
+// map of string values
+func StringValueMap(src map[string]*string) map[string]string {
+	dst := make(map[string]string)
+	for k, val := range src {
+		if val != nil {
+			dst[k] = *val
+		}
+	}
+	return dst
+}
+
+// Bool returns a pointer to of the bool value passed in.
+func Bool(v bool) *bool {
+	return &v
+}
+
+// BoolValue returns the value of the bool pointer passed in or
+// false if the pointer is nil.
+func BoolValue(v *bool) bool {
+	if v != nil {
+		return *v
+	}
+	return false
+}
+
+// BoolSlice converts a slice of bool values into a slice of
+// bool pointers
+func BoolSlice(src []bool) []*bool {
+	dst := make([]*bool, len(src))
+	for i := 0; i < len(src); i++ {
+		dst[i] = &(src[i])
+	}
+	return dst
+}
+
+// BoolValueSlice converts a slice of bool pointers into a slice of
+// bool values
+func BoolValueSlice(src []*bool) []bool {
+	dst := make([]bool, len(src))
+	for i := 0; i < len(src); i++ {
+		if src[i] != nil {
+			dst[i] = *(src[i])
+		}
+	}
+	return dst
+}
+
+// BoolMap converts a string map of bool values into a string
+// map of bool pointers
+func BoolMap(src map[string]bool) map[string]*bool {
+	dst := make(map[string]*bool)
+	for k, val := range src {
+		v := val
+		dst[k] = &v
+	}
+	return dst
+}
+
+// BoolValueMap converts a string map of bool pointers into a string
+// map of bool values
+func BoolValueMap(src map[string]*bool) map[string]bool {
+	dst := make(map[string]bool)
+	for k, val := range src {
+		if val != nil {
+			dst[k] = *val
+		}
+	}
+	return dst
+}
+
+// Int returns a pointer to of the int value passed in.
+func Int(v int) *int {
+	return &v
+}
+
+// IntValue returns the value of the int pointer passed in or
+// 0 if the pointer is nil.
+func IntValue(v *int) int {
+	if v != nil {
+		return *v
+	}
+	return 0
+}
+
+// IntSlice converts a slice of int values into a slice of
+// int pointers
+func IntSlice(src []int) []*int {
+	dst := make([]*int, len(src))
+	for i := 0; i < len(src); i++ {
+		dst[i] = &(src[i])
+	}
+	return dst
+}
+
+// IntValueSlice converts a slice of int pointers into a slice of
+// int values
+func IntValueSlice(src []*int) []int {
+	dst := make([]int, len(src))
+	for i := 0; i < len(src); i++ {
+		if src[i] != nil {
+			dst[i] = *(src[i])
+		}
+	}
+	return dst
+}
+
+// IntMap converts a string map of int values into a string
+// map of int pointers
+func IntMap(src map[string]int) map[string]*int {
+	dst := make(map[string]*int)
+	for k, val := range src {
+		v := val
+		dst[k] = &v
+	}
+	return dst
+}
+
+// IntValueMap converts a string map of int pointers into a string
+// map of int values
+func IntValueMap(src map[string]*int) map[string]int {
+	dst := make(map[string]int)
+	for k, val := range src {
+		if val != nil {
+			dst[k] = *val
+		}
+	}
+	return dst
+}
+
+// Int32 returns a pointer to of the int64 value passed in.
+func Int32(v int32) *int32 {
+	return &v
+}
+
+// Int32Value returns the value of the int64 pointer passed in or
+// 0 if the pointer is nil.
+func Int32Value(v *int32) int32 {
+	if v != nil {
+		return *v
+	}
+	return 0
+}
+
+// Int32Slice converts a slice of int64 values into a slice of
+// int32 pointers
+func Int32Slice(src []int32) []*int32 {
+	dst := make([]*int32, len(src))
+	for i := 0; i < len(src); i++ {
+		dst[i] = &(src[i])
+	}
+	return dst
+}
+
+// Int32ValueSlice converts a slice of int32 pointers into a slice of
+// int32 values
+func Int32ValueSlice(src []*int32) []int32 {
+	dst := make([]int32, len(src))
+	for i := 0; i < len(src); i++ {
+		if src[i] != nil {
+			dst[i] = *(src[i])
+		}
+	}
+	return dst
+}
+
+// Int32Map converts a string map of int32 values into a string
+// map of int32 pointers
+func Int32Map(src map[string]int32) map[string]*int32 {
+	dst := make(map[string]*int32)
+	for k, val := range src {
+		v := val
+		dst[k] = &v
+	}
+	return dst
+}
+
+// Int32ValueMap converts a string map of int32 pointers into a string
+// map of int32 values
+func Int32ValueMap(src map[string]*int32) map[string]int32 {
+	dst := make(map[string]int32)
+	for k, val := range src {
+		if val != nil {
+			dst[k] = *val
+		}
+	}
+	return dst
+}
+
+// Int64 returns a pointer to of the int64 value passed in.
+func Int64(v int64) *int64 {
+	return &v
+}
+
+// Int64Value returns the value of the int64 pointer passed in or
+// 0 if the pointer is nil.
+func Int64Value(v *int64) int64 {
+	if v != nil {
+		return *v
+	}
+	return 0
+}
+
+// Int64Slice converts a slice of int64 values into a slice of
+// int64 pointers
+func Int64Slice(src []int64) []*int64 {
+	dst := make([]*int64, len(src))
+	for i := 0; i < len(src); i++ {
+		dst[i] = &(src[i])
+	}
+	return dst
+}
+
+// Int64ValueSlice converts a slice of int64 pointers into a slice of
+// int64 values
+func Int64ValueSlice(src []*int64) []int64 {
+	dst := make([]int64, len(src))
+	for i := 0; i < len(src); i++ {
+		if src[i] != nil {
+			dst[i] = *(src[i])
+		}
+	}
+	return dst
+}
+
+// Int64Map converts a string map of int64 values into a string
+// map of int64 pointers
+func Int64Map(src map[string]int64) map[string]*int64 {
+	dst := make(map[string]*int64)
+	for k, val := range src {
+		v := val
+		dst[k] = &v
+	}
+	return dst
+}
+
+// Int64ValueMap converts a string map of int64 pointers into a string
+// map of int64 values
+func Int64ValueMap(src map[string]*int64) map[string]int64 {
+	dst := make(map[string]int64)
+	for k, val := range src {
+		if val != nil {
+			dst[k] = *val
+		}
+	}
+	return dst
+}
+
+// Uint returns a pouinter to of the uint value passed in.
+func Uint(v uint) *uint {
+	return &v
+}
+
+// UintValue returns the value of the uint pouinter passed in or
+// 0 if the pouinter is nil.
+func UintValue(v *uint) uint {
+	if v != nil {
+		return *v
+	}
+	return 0
+}
+
+// UintSlice converts a slice of uint values uinto a slice of
+// uint pouinters
+func UintSlice(src []uint) []*uint {
+	dst := make([]*uint, len(src))
+	for i := 0; i < len(src); i++ {
+		dst[i] = &(src[i])
+	}
+	return dst
+}
+
+// UintValueSlice converts a slice of uint pouinters uinto a slice of
+// uint values
+func UintValueSlice(src []*uint) []uint {
+	dst := make([]uint, len(src))
+	for i := 0; i < len(src); i++ {
+		if src[i] != nil {
+			dst[i] = *(src[i])
+		}
+	}
+	return dst
+}
+
+// UintMap converts a string map of uint values uinto a string
+// map of uint pouinters
+func UintMap(src map[string]uint) map[string]*uint {
+	dst := make(map[string]*uint)
+	for k, val := range src {
+		v := val
+		dst[k] = &v
+	}
+	return dst
+}
+
+// UintValueMap converts a string map of uint pouinters uinto a string
+// map of uint values
+func UintValueMap(src map[string]*uint) map[string]uint {
+	dst := make(map[string]uint)
+	for k, val := range src {
+		if val != nil {
+			dst[k] = *val
+		}
+	}
+	return dst
+}
+
+// Uint32 returns a pouinter to of the uint64 value passed in.
+func Uint32(v uint32) *uint32 {
+	return &v
+}
+
+// Uint32Value returns the value of the uint64 pouinter passed in or
+// 0 if the pouinter is nil.
+func Uint32Value(v *uint32) uint32 {
+	if v != nil {
+		return *v
+	}
+	return 0
+}
+
+// Uint32Slice converts a slice of uint64 values uinto a slice of
+// uint32 pouinters
+func Uint32Slice(src []uint32) []*uint32 {
+	dst := make([]*uint32, len(src))
+	for i := 0; i < len(src); i++ {
+		dst[i] = &(src[i])
+	}
+	return dst
+}
+
+// Uint32ValueSlice converts a slice of uint32 pouinters uinto a slice of
+// uint32 values
+func Uint32ValueSlice(src []*uint32) []uint32 {
+	dst := make([]uint32, len(src))
+	for i := 0; i < len(src); i++ {
+		if src[i] != nil {
+			dst[i] = *(src[i])
+		}
+	}
+	return dst
+}
+
+// Uint32Map converts a string map of uint32 values uinto a string
+// map of uint32 pouinters
+func Uint32Map(src map[string]uint32) map[string]*uint32 {
+	dst := make(map[string]*uint32)
+	for k, val := range src {
+		v := val
+		dst[k] = &v
+	}
+	return dst
+}
+
+// Uint32ValueMap converts a string map of uint32 pouinters uinto a string
+// map of uint32 values
+func Uint32ValueMap(src map[string]*uint32) map[string]uint32 {
+	dst := make(map[string]uint32)
+	for k, val := range src {
+		if val != nil {
+			dst[k] = *val
+		}
+	}
+	return dst
+}
+
+// Uint64 returns a pouinter to of the uint64 value passed in.
+func Uint64(v uint64) *uint64 {
+	return &v
+}
+
+// Uint64Value returns the value of the uint64 pouinter passed in or
+// 0 if the pouinter is nil.
+func Uint64Value(v *uint64) uint64 {
+	if v != nil {
+		return *v
+	}
+	return 0
+}
+
+// Uint64Slice converts a slice of uint64 values uinto a slice of
+// uint64 pouinters
+func Uint64Slice(src []uint64) []*uint64 {
+	dst := make([]*uint64, len(src))
+	for i := 0; i < len(src); i++ {
+		dst[i] = &(src[i])
+	}
+	return dst
+}
+
+// Uint64ValueSlice converts a slice of uint64 pouinters uinto a slice of
+// uint64 values
+func Uint64ValueSlice(src []*uint64) []uint64 {
+	dst := make([]uint64, len(src))
+	for i := 0; i < len(src); i++ {
+		if src[i] != nil {
+			dst[i] = *(src[i])
+		}
+	}
+	return dst
+}
+
+// Uint64Map converts a string map of uint64 values uinto a string
+// map of uint64 pouinters
+func Uint64Map(src map[string]uint64) map[string]*uint64 {
+	dst := make(map[string]*uint64)
+	for k, val := range src {
+		v := val
+		dst[k] = &v
+	}
+	return dst
+}
+
+// Uint64ValueMap converts a string map of uint64 pouinters uinto a string
+// map of uint64 values
+func Uint64ValueMap(src map[string]*uint64) map[string]uint64 {
+	dst := make(map[string]uint64)
+	for k, val := range src {
+		if val != nil {
+			dst[k] = *val
+		}
+	}
+	return dst
+}
+
+// Float64 returns a pointer to of the float64 value passed in.
+func Float64(v float64) *float64 {
+	return &v
+}
+
+// Float64Value returns the value of the float64 pointer passed in or
+// 0 if the pointer is nil.
+func Float64Value(v *float64) float64 {
+	if v != nil {
+		return *v
+	}
+	return 0
+}
+
+// Float64Slice converts a slice of float64 values into a slice of
+// float64 pointers
+func Float64Slice(src []float64) []*float64 {
+	dst := make([]*float64, len(src))
+	for i := 0; i < len(src); i++ {
+		dst[i] = &(src[i])
+	}
+	return dst
+}
+
+// Float64ValueSlice converts a slice of float64 pointers into a slice of
+// float64 values
+func Float64ValueSlice(src []*float64) []float64 {
+	dst := make([]float64, len(src))
+	for i := 0; i < len(src); i++ {
+		if src[i] != nil {
+			dst[i] = *(src[i])
+		}
+	}
+	return dst
+}
+
+// Float64Map converts a string map of float64 values into a string
+// map of float64 pointers
+func Float64Map(src map[string]float64) map[string]*float64 {
+	dst := make(map[string]*float64)
+	for k, val := range src {
+		v := val
+		dst[k] = &v
+	}
+	return dst
+}
+
+// Float64ValueMap converts a string map of float64 pointers into a string
+// map of float64 values
+func Float64ValueMap(src map[string]*float64) map[string]float64 {
+	dst := make(map[string]float64)
+	for k, val := range src {
+		if val != nil {
+			dst[k] = *val
+		}
+	}
+	return dst
+}
+
+// Time returns a pointer to of the time.Time value passed in.
+func Time(v time.Time) *time.Time {
+	return &v
+}
+
+// TimeValue returns the value of the time.Time pointer passed in or
+// time.Time{} if the pointer is nil.
+func TimeValue(v *time.Time) time.Time {
+	if v != nil {
+		return *v
+	}
+	return time.Time{}
+}
+
+// TimeSlice converts a slice of time.Time values into a slice of
+// time.Time pointers
+func TimeSlice(src []time.Time) []*time.Time {
+	dst := make([]*time.Time, len(src))
+	for i := 0; i < len(src); i++ {
+		dst[i] = &(src[i])
+	}
+	return dst
+}
+
+// TimeValueSlice converts a slice of time.Time pointers into a slice of
+// time.Time values
+func TimeValueSlice(src []*time.Time) []time.Time {
+	dst := make([]time.Time, len(src))
+	for i := 0; i < len(src); i++ {
+		if src[i] != nil {
+			dst[i] = *(src[i])
+		}
+	}
+	return dst
+}
+
+// TimeMap converts a string map of time.Time values into a string
+// map of time.Time pointers
+func TimeMap(src map[string]time.Time) map[string]*time.Time {
+	dst := make(map[string]*time.Time)
+	for k, val := range src {
+		v := val
+		dst[k] = &v
+	}
+	return dst
+}
+
+// TimeValueMap converts a string map of time.Time pointers into a string
+// map of time.Time values
+func TimeValueMap(src map[string]*time.Time) map[string]time.Time {
+	dst := make(map[string]time.Time)
+	for k, val := range src {
+		if val != nil {
+			dst[k] = *val
+		}
+	}
+	return dst
+}
diff --git a/go/vendor/github.com/go-openapi/swag/doc.go b/go/vendor/github.com/go-openapi/swag/doc.go
new file mode 100644
index 0000000..e01e1a0
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/swag/doc.go
@@ -0,0 +1,33 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/*
+Package swag contains a bunch of helper functions for go-openapi and go-swagger projects.
+
+You may also use it standalone for your projects.
+
+  * convert between value and pointers for builtin types
+  * convert from string to builtin types (wraps strconv)
+  * fast json concatenation
+  * search in path
+  * load from file or http
+  * name mangling
+
+
+This repo has only few dependencies outside of the standard library:
+
+  * JSON utilities depend on github.com/mailru/easyjson
+  * YAML utilities depend on gopkg.in/yaml.v2
+*/
+package swag
diff --git a/go/vendor/github.com/go-openapi/swag/go.mod b/go/vendor/github.com/go-openapi/swag/go.mod
new file mode 100644
index 0000000..9eb936a
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/swag/go.mod
@@ -0,0 +1,9 @@
+module github.com/go-openapi/swag
+
+require (
+	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	github.com/stretchr/testify v1.2.2
+	gopkg.in/yaml.v2 v2.2.1
+)
diff --git a/go/vendor/github.com/go-openapi/swag/go.sum b/go/vendor/github.com/go-openapi/swag/go.sum
new file mode 100644
index 0000000..d6e717b
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/swag/go.sum
@@ -0,0 +1,9 @@
+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/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/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=
+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/swag/json.go b/go/vendor/github.com/go-openapi/swag/json.go
new file mode 100644
index 0000000..33da5e4
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/swag/json.go
@@ -0,0 +1,311 @@
+// 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 swag
+
+import (
+	"bytes"
+	"encoding/json"
+	"log"
+	"reflect"
+	"strings"
+	"sync"
+
+	"github.com/mailru/easyjson/jlexer"
+	"github.com/mailru/easyjson/jwriter"
+)
+
+// nullJSON represents a JSON object with null type
+var nullJSON = []byte("null")
+
+// DefaultJSONNameProvider the default cache for types
+var DefaultJSONNameProvider = NewNameProvider()
+
+const comma = byte(',')
+
+var closers map[byte]byte
+
+func init() {
+	closers = map[byte]byte{
+		'{': '}',
+		'[': ']',
+	}
+}
+
+type ejMarshaler interface {
+	MarshalEasyJSON(w *jwriter.Writer)
+}
+
+type ejUnmarshaler interface {
+	UnmarshalEasyJSON(w *jlexer.Lexer)
+}
+
+// WriteJSON writes json data, prefers finding an appropriate interface to short-circuit the marshaller
+// so it takes the fastest option available.
+func WriteJSON(data interface{}) ([]byte, error) {
+	if d, ok := data.(ejMarshaler); ok {
+		jw := new(jwriter.Writer)
+		d.MarshalEasyJSON(jw)
+		return jw.BuildBytes()
+	}
+	if d, ok := data.(json.Marshaler); ok {
+		return d.MarshalJSON()
+	}
+	return json.Marshal(data)
+}
+
+// ReadJSON reads json data, prefers finding an appropriate interface to short-circuit the unmarshaller
+// so it takes the fastes option available
+func ReadJSON(data []byte, value interface{}) error {
+	if d, ok := value.(ejUnmarshaler); ok {
+		jl := &jlexer.Lexer{Data: data}
+		d.UnmarshalEasyJSON(jl)
+		return jl.Error()
+	}
+	if d, ok := value.(json.Unmarshaler); ok {
+		return d.UnmarshalJSON(data)
+	}
+	return json.Unmarshal(data, value)
+}
+
+// DynamicJSONToStruct converts an untyped json structure into a struct
+func DynamicJSONToStruct(data interface{}, target interface{}) error {
+	// TODO: convert straight to a json typed map  (mergo + iterate?)
+	b, err := WriteJSON(data)
+	if err != nil {
+		return err
+	}
+	return ReadJSON(b, target)
+}
+
+// ConcatJSON concatenates multiple json objects efficiently
+func ConcatJSON(blobs ...[]byte) []byte {
+	if len(blobs) == 0 {
+		return nil
+	}
+
+	last := len(blobs) - 1
+	for blobs[last] == nil || bytes.Equal(blobs[last], nullJSON) {
+		// strips trailing null objects
+		last = last - 1
+		if last < 0 {
+			// there was nothing but "null"s or nil...
+			return nil
+		}
+	}
+	if last == 0 {
+		return blobs[0]
+	}
+
+	var opening, closing byte
+	var idx, a int
+	buf := bytes.NewBuffer(nil)
+
+	for i, b := range blobs[:last+1] {
+		if b == nil || bytes.Equal(b, nullJSON) {
+			// a null object is in the list: skip it
+			continue
+		}
+		if len(b) > 0 && opening == 0 { // is this an array or an object?
+			opening, closing = b[0], closers[b[0]]
+		}
+
+		if opening != '{' && opening != '[' {
+			continue // don't know how to concatenate non container objects
+		}
+
+		if len(b) < 3 { // yep empty but also the last one, so closing this thing
+			if i == last && a > 0 {
+				if err := buf.WriteByte(closing); err != nil {
+					log.Println(err)
+				}
+			}
+			continue
+		}
+
+		idx = 0
+		if a > 0 { // we need to join with a comma for everything beyond the first non-empty item
+			if err := buf.WriteByte(comma); err != nil {
+				log.Println(err)
+			}
+			idx = 1 // this is not the first or the last so we want to drop the leading bracket
+		}
+
+		if i != last { // not the last one, strip brackets
+			if _, err := buf.Write(b[idx : len(b)-1]); err != nil {
+				log.Println(err)
+			}
+		} else { // last one, strip only the leading bracket
+			if _, err := buf.Write(b[idx:]); err != nil {
+				log.Println(err)
+			}
+		}
+		a++
+	}
+	// somehow it ended up being empty, so provide a default value
+	if buf.Len() == 0 {
+		if err := buf.WriteByte(opening); err != nil {
+			log.Println(err)
+		}
+		if err := buf.WriteByte(closing); err != nil {
+			log.Println(err)
+		}
+	}
+	return buf.Bytes()
+}
+
+// ToDynamicJSON turns an object into a properly JSON typed structure
+func ToDynamicJSON(data interface{}) interface{} {
+	// TODO: convert straight to a json typed map (mergo + iterate?)
+	b, err := json.Marshal(data)
+	if err != nil {
+		log.Println(err)
+	}
+	var res interface{}
+	if err := json.Unmarshal(b, &res); err != nil {
+		log.Println(err)
+	}
+	return res
+}
+
+// FromDynamicJSON turns an object into a properly JSON typed structure
+func FromDynamicJSON(data, target interface{}) error {
+	b, err := json.Marshal(data)
+	if err != nil {
+		log.Println(err)
+	}
+	return json.Unmarshal(b, target)
+}
+
+// NameProvider represents an object capabale of translating from go property names
+// to json property names
+// This type is thread-safe.
+type NameProvider struct {
+	lock  *sync.Mutex
+	index map[reflect.Type]nameIndex
+}
+
+type nameIndex struct {
+	jsonNames map[string]string
+	goNames   map[string]string
+}
+
+// NewNameProvider creates a new name provider
+func NewNameProvider() *NameProvider {
+	return &NameProvider{
+		lock:  &sync.Mutex{},
+		index: make(map[reflect.Type]nameIndex),
+	}
+}
+
+func buildnameIndex(tpe reflect.Type, idx, reverseIdx map[string]string) {
+	for i := 0; i < tpe.NumField(); i++ {
+		targetDes := tpe.Field(i)
+
+		if targetDes.PkgPath != "" { // unexported
+			continue
+		}
+
+		if targetDes.Anonymous { // walk embedded structures tree down first
+			buildnameIndex(targetDes.Type, idx, reverseIdx)
+			continue
+		}
+
+		if tag := targetDes.Tag.Get("json"); tag != "" {
+
+			parts := strings.Split(tag, ",")
+			if len(parts) == 0 {
+				continue
+			}
+
+			nm := parts[0]
+			if nm == "-" {
+				continue
+			}
+			if nm == "" { // empty string means we want to use the Go name
+				nm = targetDes.Name
+			}
+
+			idx[nm] = targetDes.Name
+			reverseIdx[targetDes.Name] = nm
+		}
+	}
+}
+
+func newNameIndex(tpe reflect.Type) nameIndex {
+	var idx = make(map[string]string, tpe.NumField())
+	var reverseIdx = make(map[string]string, tpe.NumField())
+
+	buildnameIndex(tpe, idx, reverseIdx)
+	return nameIndex{jsonNames: idx, goNames: reverseIdx}
+}
+
+// GetJSONNames gets all the json property names for a type
+func (n *NameProvider) GetJSONNames(subject interface{}) []string {
+	n.lock.Lock()
+	defer n.lock.Unlock()
+	tpe := reflect.Indirect(reflect.ValueOf(subject)).Type()
+	names, ok := n.index[tpe]
+	if !ok {
+		names = n.makeNameIndex(tpe)
+	}
+
+	res := make([]string, 0, len(names.jsonNames))
+	for k := range names.jsonNames {
+		res = append(res, k)
+	}
+	return res
+}
+
+// GetJSONName gets the json name for a go property name
+func (n *NameProvider) GetJSONName(subject interface{}, name string) (string, bool) {
+	tpe := reflect.Indirect(reflect.ValueOf(subject)).Type()
+	return n.GetJSONNameForType(tpe, name)
+}
+
+// GetJSONNameForType gets the json name for a go property name on a given type
+func (n *NameProvider) GetJSONNameForType(tpe reflect.Type, name string) (string, bool) {
+	n.lock.Lock()
+	defer n.lock.Unlock()
+	names, ok := n.index[tpe]
+	if !ok {
+		names = n.makeNameIndex(tpe)
+	}
+	nme, ok := names.goNames[name]
+	return nme, ok
+}
+
+func (n *NameProvider) makeNameIndex(tpe reflect.Type) nameIndex {
+	names := newNameIndex(tpe)
+	n.index[tpe] = names
+	return names
+}
+
+// GetGoName gets the go name for a json property name
+func (n *NameProvider) GetGoName(subject interface{}, name string) (string, bool) {
+	tpe := reflect.Indirect(reflect.ValueOf(subject)).Type()
+	return n.GetGoNameForType(tpe, name)
+}
+
+// GetGoNameForType gets the go name for a given type for a json property name
+func (n *NameProvider) GetGoNameForType(tpe reflect.Type, name string) (string, bool) {
+	n.lock.Lock()
+	defer n.lock.Unlock()
+	names, ok := n.index[tpe]
+	if !ok {
+		names = n.makeNameIndex(tpe)
+	}
+	nme, ok := names.jsonNames[name]
+	return nme, ok
+}
diff --git a/go/vendor/github.com/go-openapi/swag/loading.go b/go/vendor/github.com/go-openapi/swag/loading.go
new file mode 100644
index 0000000..70f4fb3
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/swag/loading.go
@@ -0,0 +1,80 @@
+// 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 swag
+
+import (
+	"fmt"
+	"io/ioutil"
+	"log"
+	"net/http"
+	"path/filepath"
+	"strings"
+	"time"
+)
+
+// LoadHTTPTimeout the default timeout for load requests
+var LoadHTTPTimeout = 30 * time.Second
+
+// LoadFromFileOrHTTP loads the bytes from a file or a remote http server based on the path passed in
+func LoadFromFileOrHTTP(path string) ([]byte, error) {
+	return LoadStrategy(path, ioutil.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(path)
+}
+
+// LoadFromFileOrHTTPWithTimeout loads the bytes from a file or a remote http server based on the path passed in
+// timeout arg allows for per request overriding of the request timeout
+func LoadFromFileOrHTTPWithTimeout(path string, timeout time.Duration) ([]byte, error) {
+	return LoadStrategy(path, ioutil.ReadFile, loadHTTPBytes(timeout))(path)
+}
+
+// LoadStrategy returns a loader function for a given path or uri
+func LoadStrategy(path string, local, remote func(string) ([]byte, error)) func(string) ([]byte, error) {
+	if strings.HasPrefix(path, "http") {
+		return remote
+	}
+	return func(pth string) ([]byte, error) {
+		upth, err := pathUnescape(pth)
+		if err != nil {
+			return nil, err
+		}
+		return local(filepath.FromSlash(upth))
+	}
+}
+
+func loadHTTPBytes(timeout time.Duration) func(path string) ([]byte, error) {
+	return func(path string) ([]byte, error) {
+		client := &http.Client{Timeout: timeout}
+		req, err := http.NewRequest("GET", path, nil)
+		if err != nil {
+			return nil, err
+		}
+		resp, err := client.Do(req)
+		defer func() {
+			if resp != nil {
+				if e := resp.Body.Close(); e != nil {
+					log.Println(e)
+				}
+			}
+		}()
+		if err != nil {
+			return nil, err
+		}
+
+		if resp.StatusCode != http.StatusOK {
+			return nil, fmt.Errorf("could not access document at %q [%s] ", path, resp.Status)
+		}
+
+		return ioutil.ReadAll(resp.Body)
+	}
+}
diff --git a/go/vendor/github.com/go-openapi/swag/net.go b/go/vendor/github.com/go-openapi/swag/net.go
new file mode 100644
index 0000000..8323fa3
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/swag/net.go
@@ -0,0 +1,24 @@
+package swag
+
+import (
+	"net"
+	"strconv"
+)
+
+// SplitHostPort splits a network address into a host and a port.
+// The port is -1 when there is no port to be found
+func SplitHostPort(addr string) (host string, port int, err error) {
+	h, p, err := net.SplitHostPort(addr)
+	if err != nil {
+		return "", -1, err
+	}
+	if p == "" {
+		return "", -1, &net.AddrError{Err: "missing port in address", Addr: addr}
+	}
+
+	pi, err := strconv.Atoi(p)
+	if err != nil {
+		return "", -1, err
+	}
+	return h, pi, nil
+}
diff --git a/go/vendor/github.com/go-openapi/swag/path.go b/go/vendor/github.com/go-openapi/swag/path.go
new file mode 100644
index 0000000..941bd01
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/swag/path.go
@@ -0,0 +1,59 @@
+// 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 swag
+
+import (
+	"os"
+	"path/filepath"
+	"runtime"
+	"strings"
+)
+
+const (
+	// GOPATHKey represents the env key for gopath
+	GOPATHKey = "GOPATH"
+)
+
+// FindInSearchPath finds a package in a provided lists of paths
+func FindInSearchPath(searchPath, pkg string) string {
+	pathsList := filepath.SplitList(searchPath)
+	for _, path := range pathsList {
+		if evaluatedPath, err := filepath.EvalSymlinks(filepath.Join(path, "src", pkg)); err == nil {
+			if _, err := os.Stat(evaluatedPath); err == nil {
+				return evaluatedPath
+			}
+		}
+	}
+	return ""
+}
+
+// FindInGoSearchPath finds a package in the $GOPATH:$GOROOT
+func FindInGoSearchPath(pkg string) string {
+	return FindInSearchPath(FullGoSearchPath(), pkg)
+}
+
+// FullGoSearchPath gets the search paths for finding packages
+func FullGoSearchPath() string {
+	allPaths := os.Getenv(GOPATHKey)
+	if allPaths == "" {
+		allPaths = filepath.Join(os.Getenv("HOME"), "go")
+	}
+	if allPaths != "" {
+		allPaths = strings.Join([]string{allPaths, runtime.GOROOT()}, ":")
+	} else {
+		allPaths = runtime.GOROOT()
+	}
+	return allPaths
+}
diff --git a/go/vendor/github.com/go-openapi/swag/post_go18.go b/go/vendor/github.com/go-openapi/swag/post_go18.go
new file mode 100644
index 0000000..ef48086
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/swag/post_go18.go
@@ -0,0 +1,9 @@
+// +build go1.8
+
+package swag
+
+import "net/url"
+
+func pathUnescape(path string) (string, error) {
+	return url.PathUnescape(path)
+}
diff --git a/go/vendor/github.com/go-openapi/swag/post_go19.go b/go/vendor/github.com/go-openapi/swag/post_go19.go
new file mode 100644
index 0000000..567680c
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/swag/post_go19.go
@@ -0,0 +1,53 @@
+// +build go1.9
+
+package swag
+
+import (
+	"sort"
+	"sync"
+)
+
+// indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms.
+// Since go1.9, this may be implemented with sync.Map.
+type indexOfInitialisms struct {
+	sortMutex *sync.Mutex
+	index     *sync.Map
+}
+
+func newIndexOfInitialisms() *indexOfInitialisms {
+	return &indexOfInitialisms{
+		sortMutex: new(sync.Mutex),
+		index:     new(sync.Map),
+	}
+}
+
+func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms {
+	m.sortMutex.Lock()
+	defer m.sortMutex.Unlock()
+	for k, v := range initial {
+		m.index.Store(k, v)
+	}
+	return m
+}
+
+func (m *indexOfInitialisms) isInitialism(key string) bool {
+	_, ok := m.index.Load(key)
+	return ok
+}
+
+func (m *indexOfInitialisms) add(key string) *indexOfInitialisms {
+	m.index.Store(key, true)
+	return m
+}
+
+func (m *indexOfInitialisms) sorted() (result []string) {
+	m.sortMutex.Lock()
+	defer m.sortMutex.Unlock()
+	m.index.Range(func(key, value interface{}) bool {
+		k := key.(string)
+		result = append(result, k)
+		return true
+	})
+	sort.Sort(sort.Reverse(byLength(result)))
+	return
+}
diff --git a/go/vendor/github.com/go-openapi/swag/pre_go18.go b/go/vendor/github.com/go-openapi/swag/pre_go18.go
new file mode 100644
index 0000000..860bb2b
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/swag/pre_go18.go
@@ -0,0 +1,9 @@
+// +build !go1.8
+
+package swag
+
+import "net/url"
+
+func pathUnescape(path string) (string, error) {
+	return url.QueryUnescape(path)
+}
diff --git a/go/vendor/github.com/go-openapi/swag/pre_go19.go b/go/vendor/github.com/go-openapi/swag/pre_go19.go
new file mode 100644
index 0000000..72c48ae
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/swag/pre_go19.go
@@ -0,0 +1,55 @@
+// +build !go1.9
+
+package swag
+
+import (
+	"sort"
+	"sync"
+)
+
+// indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms.
+// Before go1.9, this may be implemented with a mutex on the map.
+type indexOfInitialisms struct {
+	getMutex *sync.Mutex
+	index    map[string]bool
+}
+
+func newIndexOfInitialisms() *indexOfInitialisms {
+	return &indexOfInitialisms{
+		getMutex: new(sync.Mutex),
+		index:    make(map[string]bool, 50),
+	}
+}
+
+func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms {
+	m.getMutex.Lock()
+	defer m.getMutex.Unlock()
+	for k, v := range initial {
+		m.index[k] = v
+	}
+	return m
+}
+
+func (m *indexOfInitialisms) isInitialism(key string) bool {
+	m.getMutex.Lock()
+	defer m.getMutex.Unlock()
+	_, ok := m.index[key]
+	return ok
+}
+
+func (m *indexOfInitialisms) add(key string) *indexOfInitialisms {
+	m.getMutex.Lock()
+	defer m.getMutex.Unlock()
+	m.index[key] = true
+	return m
+}
+
+func (m *indexOfInitialisms) sorted() (result []string) {
+	m.getMutex.Lock()
+	defer m.getMutex.Unlock()
+	for k := range m.index {
+		result = append(result, k)
+	}
+	sort.Sort(sort.Reverse(byLength(result)))
+	return
+}
diff --git a/go/vendor/github.com/go-openapi/swag/util.go b/go/vendor/github.com/go-openapi/swag/util.go
new file mode 100644
index 0000000..e659968
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/swag/util.go
@@ -0,0 +1,405 @@
+// 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 swag
+
+import (
+	"math"
+	"reflect"
+	"regexp"
+	"strings"
+	"sync"
+	"unicode"
+)
+
+// commonInitialisms are common acronyms that are kept as whole uppercased words.
+var commonInitialisms *indexOfInitialisms
+
+// initialisms is a slice of sorted initialisms
+var initialisms []string
+
+var once sync.Once
+
+var isInitialism func(string) bool
+
+func init() {
+	// Taken from https://github.com/golang/lint/blob/3390df4df2787994aea98de825b964ac7944b817/lint.go#L732-L769
+	var configuredInitialisms = map[string]bool{
+		"ACL":   true,
+		"API":   true,
+		"ASCII": true,
+		"CPU":   true,
+		"CSS":   true,
+		"DNS":   true,
+		"EOF":   true,
+		"GUID":  true,
+		"HTML":  true,
+		"HTTPS": true,
+		"HTTP":  true,
+		"ID":    true,
+		"IP":    true,
+		"JSON":  true,
+		"LHS":   true,
+		"OAI":   true,
+		"QPS":   true,
+		"RAM":   true,
+		"RHS":   true,
+		"RPC":   true,
+		"SLA":   true,
+		"SMTP":  true,
+		"SQL":   true,
+		"SSH":   true,
+		"TCP":   true,
+		"TLS":   true,
+		"TTL":   true,
+		"UDP":   true,
+		"UI":    true,
+		"UID":   true,
+		"UUID":  true,
+		"URI":   true,
+		"URL":   true,
+		"UTF8":  true,
+		"VM":    true,
+		"XML":   true,
+		"XMPP":  true,
+		"XSRF":  true,
+		"XSS":   true,
+	}
+
+	// a thread-safe index of initialisms
+	commonInitialisms = newIndexOfInitialisms().load(configuredInitialisms)
+
+	// a test function
+	isInitialism = commonInitialisms.isInitialism
+}
+
+func ensureSorted() {
+	initialisms = commonInitialisms.sorted()
+}
+
+const (
+	//collectionFormatComma = "csv"
+	collectionFormatSpace = "ssv"
+	collectionFormatTab   = "tsv"
+	collectionFormatPipe  = "pipes"
+	collectionFormatMulti = "multi"
+)
+
+// JoinByFormat joins a string array by a known format (e.g. swagger's collectionFormat attribute):
+//		ssv: space separated value
+//		tsv: tab separated value
+//		pipes: pipe (|) separated value
+//		csv: comma separated value (default)
+func JoinByFormat(data []string, format string) []string {
+	if len(data) == 0 {
+		return data
+	}
+	var sep string
+	switch format {
+	case collectionFormatSpace:
+		sep = " "
+	case collectionFormatTab:
+		sep = "\t"
+	case collectionFormatPipe:
+		sep = "|"
+	case collectionFormatMulti:
+		return data
+	default:
+		sep = ","
+	}
+	return []string{strings.Join(data, sep)}
+}
+
+// SplitByFormat splits a string by a known format:
+//		ssv: space separated value
+//		tsv: tab separated value
+//		pipes: pipe (|) separated value
+//		csv: comma separated value (default)
+//
+func SplitByFormat(data, format string) []string {
+	if data == "" {
+		return nil
+	}
+	var sep string
+	switch format {
+	case collectionFormatSpace:
+		sep = " "
+	case collectionFormatTab:
+		sep = "\t"
+	case collectionFormatPipe:
+		sep = "|"
+	case collectionFormatMulti:
+		return nil
+	default:
+		sep = ","
+	}
+	var result []string
+	for _, s := range strings.Split(data, sep) {
+		if ts := strings.TrimSpace(s); ts != "" {
+			result = append(result, ts)
+		}
+	}
+	return result
+}
+
+type byLength []string
+
+func (s byLength) Len() int {
+	return len(s)
+}
+func (s byLength) Swap(i, j int) {
+	s[i], s[j] = s[j], s[i]
+}
+func (s byLength) Less(i, j int) bool {
+	return len(s[i]) < len(s[j])
+}
+
+// Prepares strings by splitting by caps, spaces, dashes, and underscore
+func split(str string) []string {
+	repl := strings.NewReplacer(
+		"@", "At ",
+		"&", "And ",
+		"|", "Pipe ",
+		"$", "Dollar ",
+		"!", "Bang ",
+		"-", " ",
+		"_", " ",
+	)
+
+	rex1 := regexp.MustCompile(`(\p{Lu})`)
+	rex2 := regexp.MustCompile(`(\pL|\pM|\pN|\p{Pc})+`)
+
+	str = trim(str)
+
+	// Convert dash and underscore to spaces
+	str = repl.Replace(str)
+
+	// Split when uppercase is found (needed for Snake)
+	str = rex1.ReplaceAllString(str, " $1")
+
+	// check if consecutive single char things make up an initialism
+	once.Do(ensureSorted)
+	for _, k := range initialisms {
+		str = strings.Replace(str, rex1.ReplaceAllString(k, " $1"), " "+k, -1)
+	}
+	// Get the final list of words
+	//words = rex2.FindAllString(str, -1)
+	return rex2.FindAllString(str, -1)
+}
+
+// Removes leading whitespaces
+func trim(str string) string {
+	return strings.Trim(str, " ")
+}
+
+// Shortcut to strings.ToUpper()
+func upper(str string) string {
+	return strings.ToUpper(trim(str))
+}
+
+// Shortcut to strings.ToLower()
+func lower(str string) string {
+	return strings.ToLower(trim(str))
+}
+
+// Camelize an uppercased word
+func Camelize(word string) (camelized string) {
+	for pos, ru := range word {
+		if pos > 0 {
+			camelized += string(unicode.ToLower(ru))
+		} else {
+			camelized += string(unicode.ToUpper(ru))
+		}
+	}
+	return
+}
+
+// ToFileName lowercases and underscores a go type name
+func ToFileName(name string) string {
+	in := split(name)
+	out := make([]string, 0, len(in))
+
+	for _, w := range in {
+		out = append(out, lower(w))
+	}
+
+	return strings.Join(out, "_")
+}
+
+// ToCommandName lowercases and underscores a go type name
+func ToCommandName(name string) string {
+	in := split(name)
+	out := make([]string, 0, len(in))
+
+	for _, w := range in {
+		out = append(out, lower(w))
+	}
+	return strings.Join(out, "-")
+}
+
+// ToHumanNameLower represents a code name as a human series of words
+func ToHumanNameLower(name string) string {
+	in := split(name)
+	out := make([]string, 0, len(in))
+
+	for _, w := range in {
+		if !isInitialism(upper(w)) {
+			out = append(out, lower(w))
+		} else {
+			out = append(out, w)
+		}
+	}
+	return strings.Join(out, " ")
+}
+
+// ToHumanNameTitle represents a code name as a human series of words with the first letters titleized
+func ToHumanNameTitle(name string) string {
+	in := split(name)
+	out := make([]string, 0, len(in))
+
+	for _, w := range in {
+		uw := upper(w)
+		if !isInitialism(uw) {
+			out = append(out, upper(w[:1])+lower(w[1:]))
+		} else {
+			out = append(out, w)
+		}
+	}
+	return strings.Join(out, " ")
+}
+
+// ToJSONName camelcases a name which can be underscored or pascal cased
+func ToJSONName(name string) string {
+	in := split(name)
+	out := make([]string, 0, len(in))
+
+	for i, w := range in {
+		if i == 0 {
+			out = append(out, lower(w))
+			continue
+		}
+		out = append(out, upper(w[:1])+lower(w[1:]))
+	}
+	return strings.Join(out, "")
+}
+
+// ToVarName camelcases a name which can be underscored or pascal cased
+func ToVarName(name string) string {
+	res := ToGoName(name)
+	if isInitialism(res) {
+		return lower(res)
+	}
+	if len(res) <= 1 {
+		return lower(res)
+	}
+	return lower(res[:1]) + res[1:]
+}
+
+// ToGoName translates a swagger name which can be underscored or camel cased to a name that golint likes
+func ToGoName(name string) string {
+	in := split(name)
+	out := make([]string, 0, len(in))
+
+	for _, w := range in {
+		uw := upper(w)
+		mod := int(math.Min(float64(len(uw)), 2))
+		if !isInitialism(uw) && !isInitialism(uw[:len(uw)-mod]) {
+			uw = upper(w[:1]) + lower(w[1:])
+		}
+		out = append(out, uw)
+	}
+
+	result := strings.Join(out, "")
+	if len(result) > 0 {
+		ud := upper(result[:1])
+		ru := []rune(ud)
+		if unicode.IsUpper(ru[0]) {
+			result = ud + result[1:]
+		} else {
+			result = "X" + ud + result[1:]
+		}
+	}
+	return result
+}
+
+// ContainsStrings searches a slice of strings for a case-sensitive match
+func ContainsStrings(coll []string, item string) bool {
+	for _, a := range coll {
+		if a == item {
+			return true
+		}
+	}
+	return false
+}
+
+// ContainsStringsCI searches a slice of strings for a case-insensitive match
+func ContainsStringsCI(coll []string, item string) bool {
+	for _, a := range coll {
+		if strings.EqualFold(a, item) {
+			return true
+		}
+	}
+	return false
+}
+
+type zeroable interface {
+	IsZero() bool
+}
+
+// IsZero returns true when the value passed into the function is a zero value.
+// This allows for safer checking of interface values.
+func IsZero(data interface{}) bool {
+	// check for things that have an IsZero method instead
+	if vv, ok := data.(zeroable); ok {
+		return vv.IsZero()
+	}
+	// continue with slightly more complex reflection
+	v := reflect.ValueOf(data)
+	switch v.Kind() {
+	case reflect.String:
+		return v.Len() == 0
+	case reflect.Bool:
+		return !v.Bool()
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return v.Int() == 0
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return v.Uint() == 0
+	case reflect.Float32, reflect.Float64:
+		return v.Float() == 0
+	case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
+		return v.IsNil()
+	case reflect.Struct, reflect.Array:
+		return reflect.DeepEqual(data, reflect.Zero(v.Type()).Interface())
+	case reflect.Invalid:
+		return true
+	}
+	return false
+}
+
+// AddInitialisms add additional initialisms
+func AddInitialisms(words ...string) {
+	for _, word := range words {
+		//commonInitialisms[upper(word)] = true
+		commonInitialisms.add(upper(word))
+	}
+	// sort again
+	initialisms = commonInitialisms.sorted()
+}
+
+// CommandLineOptionsGroup represents a group of user-defined command line options
+type CommandLineOptionsGroup struct {
+	ShortDescription string
+	LongDescription  string
+	Options          interface{}
+}
diff --git a/go/vendor/github.com/go-openapi/swag/yaml.go b/go/vendor/github.com/go-openapi/swag/yaml.go
new file mode 100644
index 0000000..f458c81
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/swag/yaml.go
@@ -0,0 +1,228 @@
+// 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 swag
+
+import (
+	"encoding/json"
+	"fmt"
+	"path/filepath"
+	"strconv"
+
+	"github.com/mailru/easyjson/jlexer"
+	"github.com/mailru/easyjson/jwriter"
+
+	yaml "gopkg.in/yaml.v2"
+)
+
+// YAMLMatcher matches yaml
+func YAMLMatcher(path string) bool {
+	ext := filepath.Ext(path)
+	return ext == ".yaml" || ext == ".yml"
+}
+
+// YAMLToJSON converts YAML unmarshaled data into json compatible data
+func YAMLToJSON(data interface{}) (json.RawMessage, error) {
+	jm, err := transformData(data)
+	if err != nil {
+		return nil, err
+	}
+	b, err := WriteJSON(jm)
+	return json.RawMessage(b), err
+}
+
+// BytesToYAMLDoc converts a byte slice into a YAML document
+func BytesToYAMLDoc(data []byte) (interface{}, error) {
+	var canary map[interface{}]interface{} // validate this is an object and not a different type
+	if err := yaml.Unmarshal(data, &canary); err != nil {
+		return nil, err
+	}
+
+	var document yaml.MapSlice // preserve order that is present in the document
+	if err := yaml.Unmarshal(data, &document); err != nil {
+		return nil, err
+	}
+	return document, nil
+}
+
+// JSONMapSlice represent a JSON object, with the order of keys maintained
+type JSONMapSlice []JSONMapItem
+
+// MarshalJSON renders a JSONMapSlice as JSON
+func (s JSONMapSlice) MarshalJSON() ([]byte, error) {
+	w := &jwriter.Writer{Flags: jwriter.NilMapAsEmpty | jwriter.NilSliceAsEmpty}
+	s.MarshalEasyJSON(w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON renders a JSONMapSlice as JSON, using easyJSON
+func (s JSONMapSlice) MarshalEasyJSON(w *jwriter.Writer) {
+	w.RawByte('{')
+
+	ln := len(s)
+	last := ln - 1
+	for i := 0; i < ln; i++ {
+		s[i].MarshalEasyJSON(w)
+		if i != last { // last item
+			w.RawByte(',')
+		}
+	}
+
+	w.RawByte('}')
+}
+
+// UnmarshalJSON makes a JSONMapSlice from JSON
+func (s *JSONMapSlice) UnmarshalJSON(data []byte) error {
+	l := jlexer.Lexer{Data: data}
+	s.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON makes a JSONMapSlice from JSON, using easyJSON
+func (s *JSONMapSlice) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	if in.IsNull() {
+		in.Skip()
+		return
+	}
+
+	var result JSONMapSlice
+	in.Delim('{')
+	for !in.IsDelim('}') {
+		var mi JSONMapItem
+		mi.UnmarshalEasyJSON(in)
+		result = append(result, mi)
+	}
+	*s = result
+}
+
+// JSONMapItem represents the value of a key in a JSON object held by JSONMapSlice
+type JSONMapItem struct {
+	Key   string
+	Value interface{}
+}
+
+// MarshalJSON renders a JSONMapItem as JSON
+func (s JSONMapItem) MarshalJSON() ([]byte, error) {
+	w := &jwriter.Writer{Flags: jwriter.NilMapAsEmpty | jwriter.NilSliceAsEmpty}
+	s.MarshalEasyJSON(w)
+	return w.BuildBytes()
+}
+
+// MarshalEasyJSON renders a JSONMapItem as JSON, using easyJSON
+func (s JSONMapItem) MarshalEasyJSON(w *jwriter.Writer) {
+	w.String(s.Key)
+	w.RawByte(':')
+	w.Raw(WriteJSON(s.Value))
+}
+
+// UnmarshalJSON makes a JSONMapItem from JSON
+func (s *JSONMapItem) UnmarshalJSON(data []byte) error {
+	l := jlexer.Lexer{Data: data}
+	s.UnmarshalEasyJSON(&l)
+	return l.Error()
+}
+
+// UnmarshalEasyJSON makes a JSONMapItem from JSON, using easyJSON
+func (s *JSONMapItem) UnmarshalEasyJSON(in *jlexer.Lexer) {
+	key := in.UnsafeString()
+	in.WantColon()
+	value := in.Interface()
+	in.WantComma()
+	s.Key = key
+	s.Value = value
+}
+
+func transformData(input interface{}) (out interface{}, err error) {
+	switch in := input.(type) {
+	case yaml.MapSlice:
+
+		o := make(JSONMapSlice, len(in))
+		for i, mi := range in {
+			var nmi JSONMapItem
+			switch k := mi.Key.(type) {
+			case string:
+				nmi.Key = k
+			case int:
+				nmi.Key = strconv.Itoa(k)
+			default:
+				return nil, fmt.Errorf("types don't match expect map key string or int got: %T", mi.Key)
+			}
+
+			v, ert := transformData(mi.Value)
+			if ert != nil {
+				return nil, ert
+			}
+			nmi.Value = v
+			o[i] = nmi
+		}
+		return o, nil
+	case map[interface{}]interface{}:
+		o := make(JSONMapSlice, 0, len(in))
+		for ke, va := range in {
+			var nmi JSONMapItem
+			switch k := ke.(type) {
+			case string:
+				nmi.Key = k
+			case int:
+				nmi.Key = strconv.Itoa(k)
+			default:
+				return nil, fmt.Errorf("types don't match expect map key string or int got: %T", ke)
+			}
+
+			v, ert := transformData(va)
+			if ert != nil {
+				return nil, ert
+			}
+			nmi.Value = v
+			o = append(o, nmi)
+		}
+		return o, nil
+	case []interface{}:
+		len1 := len(in)
+		o := make([]interface{}, len1)
+		for i := 0; i < len1; i++ {
+			o[i], err = transformData(in[i])
+			if err != nil {
+				return nil, err
+			}
+		}
+		return o, nil
+	}
+	return input, nil
+}
+
+// YAMLDoc loads a yaml document from either http or a file and converts it to json
+func YAMLDoc(path string) (json.RawMessage, error) {
+	yamlDoc, err := YAMLData(path)
+	if err != nil {
+		return nil, err
+	}
+
+	data, err := YAMLToJSON(yamlDoc)
+	if err != nil {
+		return nil, err
+	}
+
+	return data, nil
+}
+
+// YAMLData loads a yaml document from either http or a file
+func YAMLData(path string) (interface{}, error) {
+	data, err := LoadFromFileOrHTTP(path)
+	if err != nil {
+		return nil, err
+	}
+
+	return BytesToYAMLDoc(data)
+}
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
+}