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
}
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.
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" {
		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)
}