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