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
+}
