Repository: deepmap/oapi-codegen
Pull request #852 (2022-11-11 23:52:44)

fix(oapi-codegen): command line parsing compatibility
Improve command line compatibility between old and new style configs so existing user setups work as expected where possible.

This restores -generate and -templates flags from deprecated states as the new configuration format doesn't provide the needed functionality with out them. It makes all but -alias-types work with new config files.

The -alias-types doesn't do anything in either config mode any more.

For -generate the use case is one configuration and multiple output files for different generation types, which we use extensively.

For -templates having to have go .tmpl inside a .yaml config file works for simple snippets but for large templates its not practical, hence the direction option is required.


Patch:
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
new file mode 100644
index 0000000..6757ff9
--- /dev/null
+++ b/.github/workflows/lint.yml
@@ -0,0 +1,20 @@
+name: Lint project
+on: [push, pull_request]
+jobs:
+  build:
+    name: Build
+    runs-on: ubuntu-latest
+    steps:
+      - name: Check out source code
+        uses: actions/checkout@v3
+
+      - name: Set up Go
+        uses: actions/setup-go@v3
+        with:
+          go-version-file: 'go.mod'
+
+      - name: golangci-lint
+        uses: golangci/golangci-lint-action@v3
+        with:
+          # Make sure this matches the version we've got in our `Makefile`
+          version: v1.50.1
diff --git a/.gitignore b/.gitignore
index f0b76c0..74762c2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
 .idea
 .DS_Store
-.vscode/
\ No newline at end of file
+.vscode/
+bin/
diff --git a/Makefile b/Makefile
index 146075b..f767556 100644
--- a/Makefile
+++ b/Makefile
@@ -1,3 +1,6 @@
+GOBASE=$(shell pwd)
+GOBIN=$(GOBASE)/bin
+
 help:
 	@echo "This is a helper makefile for oapi-codegen"
 	@echo "Targets:"
@@ -6,6 +9,15 @@ help:
 	@echo "    gin_example  generate gin example server code"
 	@echo "    tidy         tidy go mod"
 
+$(GOBIN)/golangci-lint:
+	curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GOBIN) v1.50.1
+
+.PHONY: tools
+tools: $(GOBIN)/golangci-lint
+
+lint: tools
+	$(GOBIN)/golangci-lint run ./...
+
 generate:
 	go generate ./...
 
diff --git a/README.md b/README.md
index 295edf3..f51aa46 100644
--- a/README.md
+++ b/README.md
@@ -40,7 +40,7 @@ into objects which match the OpenAPI 3.0 definition. The code generator in this
 directory does a lot of that for you. You would run it like so:
 
     go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@latest
-    oapi-codegen petstore-expanded.yaml > petstore.gen.go
+    oapi-codegen -package petstore petstore-expanded.yaml > petstore.gen.go
 
 Let's go through that `petstore.gen.go` file to show you everything which was
 generated.
@@ -632,6 +632,35 @@ which help you to use the various OpenAPI 3 Authentication mechanism.
   }
   ```
 
+- `x-enum-varnames`: supplies other enum names for the corresponding values. (alias: `x-enumNames`)
+
+    ```yaml
+    components:
+      schemas:
+        Object:
+          properties:
+            category:
+              type: integer
+              enum: [0, 1, 2]
+              x-enum-varnames:
+                - notice
+                - warning
+                - urgent
+    ```
+
+    After code generation you will get this result:
+
+    ```go
+    // Defines values for ObjectCategory.
+    const (
+    	Notice  ObjectCategory = 0
+    	Urgent  ObjectCategory = 2
+    	Warning ObjectCategory = 1
+    )
+
+    // ObjectCategory defines model for Object.Category.
+    type ObjectCategory int
+    ```
 
 ## Using `oapi-codegen`
 
diff --git a/cmd/oapi-codegen/oapi-codegen.go b/cmd/oapi-codegen/oapi-codegen.go
index 957b90f..eb213e4 100644
--- a/cmd/oapi-codegen/oapi-codegen.go
+++ b/cmd/oapi-codegen/oapi-codegen.go
@@ -17,9 +17,10 @@ import (
 	"flag"
 	"fmt"
 	"os"
+	"os/exec"
 	"path"
+	"path/filepath"
 	"runtime/debug"
-	"strings"
 
 	"gopkg.in/yaml.v2"
 
@@ -40,13 +41,13 @@ var (
 	flagPrintVersion   bool
 	flagPackageName    string
 	flagPrintUsage     bool
+	flagGenerate       string
+	flagTemplatesDir   string
 
-	// The options below are deprecated, and they will be removed in a future
+	// Deprecated: The options below will be removed in a future
 	// release. Please use the new config file format.
-	flagGenerate           string
 	flagIncludeTags        string
 	flagExcludeTags        string
-	flagTemplatesDir       string
 	flagImportMapping      string
 	flagExcludeSchemas     string
 	flagResponseTypeSuffix string
@@ -162,10 +163,8 @@ func main() {
 		// config style. It should work correctly if we go down the old path,
 		// even if we have a simple config file readable as both types.
 		deprecatedFlagNames := map[string]bool{
-			"generate":             true,
 			"include-tags":         true,
 			"exclude-tags":         true,
-			"templates":            true,
 			"import-mapping":       true,
 			"exclude-schemas":      true,
 			"response-type-suffix": true,
@@ -214,9 +213,8 @@ func main() {
 				OutputFile: flagOutputFile,
 			}
 		}
-		var err error
-		opts, err = updateConfigFromFlags(opts)
-		if err != nil {
+
+		if err := updateConfigFromFlags(&opts); err != nil {
 			errExit("error processing flags: %v\n", err)
 		}
 	} else {
@@ -238,6 +236,10 @@ func main() {
 	// fields.
 	opts.Configuration = opts.UpdateDefaults()
 
+	if err := detectPackageName(&opts); err != nil {
+		errExit("%s\n", err)
+	}
+
 	// Now, ensure that the config options are valid.
 	if err := opts.Validate(); err != nil {
 		errExit("configuration error: %v\n", err)
@@ -309,52 +311,91 @@ func loadTemplateOverrides(templatesDir string) (map[string]string, error) {
 	return templates, nil
 }
 
+// detectPackageName detects and sets PackageName if not already set.
+func detectPackageName(cfg *configuration) error {
+	if cfg.PackageName != "" {
+		return nil
+	}
+
+	if cfg.OutputFile != "" {
+		// Determine from the package name of the output file.
+		dir := filepath.Dir(cfg.PackageName)
+		cmd := exec.Command("go", "list", "-f", "{{.Name}}", dir)
+		out, err := cmd.CombinedOutput()
+		if err != nil {
+			outStr := string(out)
+			switch {
+			case strings.Contains(outStr, "expected 'package', found 'EOF'"):
+				// Redirecting the output to current directory which hasn't
+				// written anything yet, ignore.
+			case strings.HasPrefix(outStr, "no Go files in"):
+				// No go files yet, ignore.
+			default:
+				// Unexpected failure report.
+				return fmt.Errorf("detect package name for %q output: %q: %w", dir, string(out), err)
+			}
+		} else {
+			cfg.PackageName = string(out)
+			return nil
+		}
+	}
+
+	// Fallback to determining from the spec file name.
+	parts := strings.Split(filepath.Base(flag.Arg(0)), ".")
+	cfg.PackageName = codegen.LowercaseFirstCharacter(codegen.ToCamelCase(parts[0]))
+
+	return nil
+}
+
 // updateConfigFromFlags updates a loaded configuration from flags. Flags
-// override anything in the file. We generate errors for command line options
-// associated with the old style configuration
-func updateConfigFromFlags(cfg configuration) (configuration, error) {
+// override anything in the file. We generate errors for any unsupported
+// command line flags.
+func updateConfigFromFlags(cfg *configuration) error {
 	if flagPackageName != "" {
 		cfg.PackageName = flagPackageName
 	}
 
-	var unsupportedFlags []string
-
 	if flagGenerate != "types,client,server,spec" {
-		unsupportedFlags = append(unsupportedFlags, "--generate")
+		// Override generation and output options from generate command line flag.
+		if err := generationTargets(&cfg.Configuration, util.ParseCommandLineList(flagGenerate)); err != nil {
+			return err
+		}
 	}
 	if flagIncludeTags != "" {
-		unsupportedFlags = append(unsupportedFlags, "--include-tags")
+		cfg.OutputOptions.IncludeTags = util.ParseCommandLineList(flagIncludeTags)
 	}
 	if flagExcludeTags != "" {
-		unsupportedFlags = append(unsupportedFlags, "--exclude-tags")
+		cfg.OutputOptions.ExcludeTags = util.ParseCommandLineList(flagExcludeTags)
 	}
 	if flagTemplatesDir != "" {
-		unsupportedFlags = append(unsupportedFlags, "--templates")
+		templates, err := loadTemplateOverrides(flagTemplatesDir)
+		if err != nil {
+			return fmt.Errorf("load templates from %q: %w", flagTemplatesDir, err)
+		}
+		cfg.OutputOptions.UserTemplates = templates
 	}
 	if flagImportMapping != "" {
-		unsupportedFlags = append(unsupportedFlags, "--import-mapping")
+		var err error
+		cfg.ImportMapping, err = util.ParseCommandlineMap(flagImportMapping)
+		if err != nil {
+			return err
+		}
 	}
 	if flagExcludeSchemas != "" {
-		unsupportedFlags = append(unsupportedFlags, "--exclude-schemas")
+		cfg.OutputOptions.ExcludeSchemas = util.ParseCommandLineList(flagExcludeSchemas)
 	}
 	if flagResponseTypeSuffix != "" {
-		unsupportedFlags = append(unsupportedFlags, "--response-type-suffix")
+		cfg.OutputOptions.ResponseTypeSuffix = flagResponseTypeSuffix
 	}
 	if flagAliasTypes {
-		unsupportedFlags = append(unsupportedFlags, "--alias-types")
-	}
-
-	if len(unsupportedFlags) > 0 {
-		return configuration{}, fmt.Errorf("flags %s aren't supported in "+
-			"new config style, please use --old-config-style or update your configuration ",
-			strings.Join(unsupportedFlags, ", "))
+		return fmt.Errorf("--alias-types isn't supported any more")
 	}
 
 	if cfg.OutputFile == "" {
 		cfg.OutputFile = flagOutputFile
 	}
 
-	return cfg, nil
+	return nil
 }
 
 // updateOldConfigFromFlags parses the flags and the config file. Anything which is
@@ -392,6 +433,40 @@ func updateOldConfigFromFlags(cfg oldConfiguration) oldConfiguration {
 	return cfg
 }
 
+// generationTargets sets cfg options based on the generation targets.
+func generationTargets(cfg *codegen.Configuration, targets []string) error {
+	opts := codegen.GenerateOptions{} // Blank to start with.
+	for _, opt := range targets {
+		switch opt {
+		case "chi-server", "chi":
+			opts.ChiServer = true
+		case "server", "echo-server", "echo":
+			opts.EchoServer = true
+		case "gin", "gin-server":
+			opts.GinServer = true
+		case "gorilla", "gorilla-server":
+			opts.GorillaServer = true
+		case "strict-server":
+			opts.Strict = true
+		case "client":
+			opts.Client = true
+		case "types", "models":
+			opts.Models = true
+		case "spec", "embedded-spec":
+			opts.EmbeddedSpec = true
+		case "skip-fmt":
+			cfg.OutputOptions.SkipFmt = true
+		case "skip-prune":
+			cfg.OutputOptions.SkipPrune = true
+		default:
+			return fmt.Errorf("unknown generate option %q", opt)
+		}
+	}
+	cfg.Generate = opts
+
+	return nil
+}
+
 func newConfigFromOldConfig(c oldConfiguration) configuration {
 	// Take flags into account.
 	cfg := updateOldConfigFromFlags(c)
@@ -403,33 +478,10 @@ func newConfigFromOldConfig(c oldConfiguration) configuration {
 	}
 	opts.OutputOptions.ResponseTypeSuffix = flagResponseTypeSuffix
 
-	for _, g := range cfg.GenerateTargets {
-		switch g {
-		case "client":
-			opts.Generate.Client = true
-		case "chi-server":
-			opts.Generate.ChiServer = true
-		case "server":
-			opts.Generate.EchoServer = true
-		case "gin":
-			opts.Generate.GinServer = true
-		case "gorilla":
-			opts.Generate.GorillaServer = true
-		case "strict-server":
-			opts.Generate.Strict = true
-		case "types":
-			opts.Generate.Models = true
-		case "spec":
-			opts.Generate.EmbeddedSpec = true
-		case "skip-fmt":
-			opts.OutputOptions.SkipFmt = true
-		case "skip-prune":
-			opts.OutputOptions.SkipPrune = true
-		default:
-			fmt.Printf("unknown generate option %s\n", g)
-			flag.PrintDefaults()
-			os.Exit(1)
-		}
+	if err := generationTargets(&opts, cfg.GenerateTargets); err != nil {
+		fmt.Println(err)
+		flag.PrintDefaults()
+		os.Exit(1)
 	}
 
 	opts.OutputOptions.IncludeTags = cfg.IncludeTags
diff --git a/examples/petstore-expanded/gin/api/petstore-server.gen.go b/examples/petstore-expanded/gin/api/petstore-server.gen.go
index 8dabdd9..3b0368d 100644
--- a/examples/petstore-expanded/gin/api/petstore-server.gen.go
+++ b/examples/petstore-expanded/gin/api/petstore-server.gen.go
@@ -69,6 +69,9 @@ func (siw *ServerInterfaceWrapper) FindPets(c *gin.Context) {
 
 	for _, middleware := range siw.HandlerMiddlewares {
 		middleware(c)
+		if c.IsAborted() {
+			return
+		}
 	}
 
 	siw.Handler.FindPets(c, params)
@@ -79,6 +82,9 @@ func (siw *ServerInterfaceWrapper) AddPet(c *gin.Context) {
 
 	for _, middleware := range siw.HandlerMiddlewares {
 		middleware(c)
+		if c.IsAborted() {
+			return
+		}
 	}
 
 	siw.Handler.AddPet(c)
@@ -100,6 +106,9 @@ func (siw *ServerInterfaceWrapper) DeletePet(c *gin.Context) {
 
 	for _, middleware := range siw.HandlerMiddlewares {
 		middleware(c)
+		if c.IsAborted() {
+			return
+		}
 	}
 
 	siw.Handler.DeletePet(c, id)
@@ -121,6 +130,9 @@ func (siw *ServerInterfaceWrapper) FindPetByID(c *gin.Context) {
 
 	for _, middleware := range siw.HandlerMiddlewares {
 		middleware(c)
+		if c.IsAborted() {
+			return
+		}
 	}
 
 	siw.Handler.FindPetByID(c, id)
@@ -134,15 +146,13 @@ type GinServerOptions struct {
 }
 
 // RegisterHandlers creates http.Handler with routing matching OpenAPI spec.
-func RegisterHandlers(router *gin.Engine, si ServerInterface) *gin.Engine {
-	return RegisterHandlersWithOptions(router, si, GinServerOptions{})
+func RegisterHandlers(router gin.IRouter, si ServerInterface) {
+	RegisterHandlersWithOptions(router, si, GinServerOptions{})
 }
 
 // RegisterHandlersWithOptions creates http.Handler with additional options
-func RegisterHandlersWithOptions(router *gin.Engine, si ServerInterface, options GinServerOptions) *gin.Engine {
-
+func RegisterHandlersWithOptions(router gin.IRouter, si ServerInterface, options GinServerOptions) {
 	errorHandler := options.ErrorHandler
-
 	if errorHandler == nil {
 		errorHandler = func(c *gin.Context, err error, statusCode int) {
 			c.JSON(statusCode, gin.H{"msg": err.Error()})
@@ -156,14 +166,9 @@ func RegisterHandlersWithOptions(router *gin.Engine, si ServerInterface, options
 	}
 
 	router.GET(options.BaseURL+"/pets", wrapper.FindPets)
-
 	router.POST(options.BaseURL+"/pets", wrapper.AddPet)
-
 	router.DELETE(options.BaseURL+"/pets/:id", wrapper.DeletePet)
-
 	router.GET(options.BaseURL+"/pets/:id", wrapper.FindPetByID)
-
-	return router
 }
 
 // Base64 encoded, gzipped, json marshaled Swagger object
diff --git a/examples/petstore-expanded/gin/petstore.go b/examples/petstore-expanded/gin/petstore.go
index 2eae15b..a5b40a2 100644
--- a/examples/petstore-expanded/gin/petstore.go
+++ b/examples/petstore-expanded/gin/petstore.go
@@ -11,9 +11,10 @@ import (
 	"net/http"
 	"os"
 
+	"github.com/gin-gonic/gin"
+
 	"github.com/deepmap/oapi-codegen/examples/petstore-expanded/gin/api"
 	middleware "github.com/deepmap/oapi-codegen/pkg/gin-middleware"
-	"github.com/gin-gonic/gin"
 )
 
 func NewGinPetServer(petStore *api.PetStore, port int) *http.Server {
@@ -35,7 +36,7 @@ func NewGinPetServer(petStore *api.PetStore, port int) *http.Server {
 	r.Use(middleware.OapiRequestValidator(swagger))
 
 	// We now register our petStore above as the handler for the interface
-	r = api.RegisterHandlers(r, petStore)
+	api.RegisterHandlers(r, petStore)
 
 	s := &http.Server{
 		Handler: r,
diff --git a/examples/petstore-expanded/gorilla/api/cfg.yaml b/examples/petstore-expanded/gorilla/api/cfg.yaml
index 7f1a2d7..8ead7a6 100644
--- a/examples/petstore-expanded/gorilla/api/cfg.yaml
+++ b/examples/petstore-expanded/gorilla/api/cfg.yaml
@@ -4,3 +4,5 @@ generate:
   models: true
   embedded-spec: true
 output: petstore.gen.go
+compatibility:
+  apply-gorilla-middleware-first-to-last: true
diff --git a/examples/petstore-expanded/gorilla/api/petstore.gen.go b/examples/petstore-expanded/gorilla/api/petstore.gen.go
index deac982..b55ecd0 100644
--- a/examples/petstore-expanded/gorilla/api/petstore.gen.go
+++ b/examples/petstore-expanded/gorilla/api/petstore.gen.go
@@ -114,8 +114,8 @@ func (siw *ServerInterfaceWrapper) FindPets(w http.ResponseWriter, r *http.Reque
 		siw.Handler.FindPets(w, r, params)
 	}
 
-	for _, middleware := range siw.HandlerMiddlewares {
-		handler = middleware(handler)
+	for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- {
+		handler = siw.HandlerMiddlewares[i](handler)
 	}
 
 	handler(w, r.WithContext(ctx))
@@ -129,8 +129,8 @@ func (siw *ServerInterfaceWrapper) AddPet(w http.ResponseWriter, r *http.Request
 		siw.Handler.AddPet(w, r)
 	}
 
-	for _, middleware := range siw.HandlerMiddlewares {
-		handler = middleware(handler)
+	for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- {
+		handler = siw.HandlerMiddlewares[i](handler)
 	}
 
 	handler(w, r.WithContext(ctx))
@@ -155,8 +155,8 @@ func (siw *ServerInterfaceWrapper) DeletePet(w http.ResponseWriter, r *http.Requ
 		siw.Handler.DeletePet(w, r, id)
 	}
 
-	for _, middleware := range siw.HandlerMiddlewares {
-		handler = middleware(handler)
+	for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- {
+		handler = siw.HandlerMiddlewares[i](handler)
 	}
 
 	handler(w, r.WithContext(ctx))
@@ -181,8 +181,8 @@ func (siw *ServerInterfaceWrapper) FindPetByID(w http.ResponseWriter, r *http.Re
 		siw.Handler.FindPetByID(w, r, id)
 	}
 
-	for _, middleware := range siw.HandlerMiddlewares {
-		handler = middleware(handler)
+	for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- {
+		handler = siw.HandlerMiddlewares[i](handler)
 	}
 
 	handler(w, r.WithContext(ctx))
diff --git a/go.mod b/go.mod
index 9dcd51f..e3364ea 100644
--- a/go.mod
+++ b/go.mod
@@ -2,34 +2,38 @@ module github.com/deepmap/oapi-codegen
 
 require (
 	github.com/apapsch/go-jsonmerge/v2 v2.0.0
-	github.com/getkin/kin-openapi v0.107.0
-	github.com/gin-gonic/gin v1.8.1
-	github.com/go-chi/chi/v5 v5.0.7
+	github.com/getkin/kin-openapi v0.114.0
+	github.com/gin-gonic/gin v1.9.0
+	github.com/go-chi/chi/v5 v5.0.8
 	github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219
 	github.com/google/uuid v1.3.0
 	github.com/gorilla/mux v1.8.0
-	github.com/labstack/echo/v4 v4.9.1
+	github.com/labstack/echo/v4 v4.10.2
 	github.com/lestrrat-go/jwx v1.2.25
-	github.com/matryer/moq v0.2.7
-	github.com/stretchr/testify v1.8.1
-	golang.org/x/tools v0.2.0
+	github.com/matryer/moq v0.3.1
+	github.com/stretchr/testify v1.8.2
+	golang.org/x/text v0.8.0
+	golang.org/x/tools v0.7.0
 	gopkg.in/yaml.v2 v2.4.0
 )
 
 require (
+	github.com/bytedance/sonic v1.8.0 // indirect
+	github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
 	github.com/gin-contrib/sse v0.1.0 // indirect
 	github.com/go-openapi/jsonpointer v0.19.5 // indirect
 	github.com/go-openapi/swag v0.21.1 // indirect
-	github.com/go-playground/locales v0.14.0 // indirect
-	github.com/go-playground/universal-translator v0.18.0 // indirect
-	github.com/go-playground/validator/v10 v10.11.1 // indirect
-	github.com/goccy/go-json v0.9.11 // indirect
+	github.com/go-playground/locales v0.14.1 // indirect
+	github.com/go-playground/universal-translator v0.18.1 // indirect
+	github.com/go-playground/validator/v10 v10.11.2 // indirect
+	github.com/goccy/go-json v0.10.0 // indirect
 	github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
 	github.com/invopop/yaml v0.1.0 // indirect
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
+	github.com/klauspost/cpuid/v2 v2.0.9 // indirect
 	github.com/labstack/gommon v0.4.0 // indirect
 	github.com/leodido/go-urn v1.2.1 // indirect
 	github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect
@@ -39,23 +43,25 @@ require (
 	github.com/lestrrat-go/option v1.0.0 // indirect
 	github.com/mailru/easyjson v0.7.7 // indirect
 	github.com/mattn/go-colorable v0.1.13 // indirect
-	github.com/mattn/go-isatty v0.0.16 // indirect
+	github.com/mattn/go-isatty v0.0.17 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
 	github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
-	github.com/pelletier/go-toml/v2 v2.0.5 // indirect
+	github.com/pelletier/go-toml/v2 v2.0.6 // indirect
+	github.com/perimeterx/marshmallow v1.1.4 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/stretchr/objx v0.5.0 // indirect
-	github.com/ugorji/go/codec v1.2.7 // indirect
+	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
+	github.com/ugorji/go/codec v1.2.9 // indirect
 	github.com/valyala/bytebufferpool v1.0.0 // indirect
 	github.com/valyala/fasttemplate v1.2.2 // indirect
-	golang.org/x/crypto v0.1.0 // indirect
-	golang.org/x/mod v0.6.0 // indirect
-	golang.org/x/net v0.1.0 // indirect
-	golang.org/x/sys v0.1.0 // indirect
-	golang.org/x/text v0.4.0 // indirect
-	golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect
+	golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
+	golang.org/x/crypto v0.6.0 // indirect
+	golang.org/x/mod v0.9.0 // indirect
+	golang.org/x/net v0.8.0 // indirect
+	golang.org/x/sys v0.6.0 // indirect
+	golang.org/x/time v0.3.0 // indirect
 	golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect
 	google.golang.org/protobuf v1.28.1 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
diff --git a/go.sum b/go.sum
index c8c1e6b..5e5310b 100644
--- a/go.sum
+++ b/go.sum
@@ -2,6 +2,12 @@ github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMz
 github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ=
 github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk=
 github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
+github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
+github.com/bytedance/sonic v1.8.0 h1:ea0Xadu+sHlu7x5O3gKhRpQ1IKiMrSiHttPF0ybECuA=
+github.com/bytedance/sonic v1.8.0/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
+github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
+github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
+github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -10,30 +16,31 @@ github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn
 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d/go.mod h1:tmAIfUFEirG/Y8jhZ9M+h36obRZAk/1fcSpXwAVlfqE=
 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc=
 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs=
-github.com/getkin/kin-openapi v0.107.0 h1:bxhL6QArW7BXQj8NjXfIJQy680NsMKd25nwhvpCXchg=
-github.com/getkin/kin-openapi v0.107.0/go.mod h1:9Dhr+FasATJZjS4iOLvB0hkaxgYdulrNYm2e9epLWOo=
+github.com/getkin/kin-openapi v0.114.0 h1:ar7QiJpDdlR+zSyPjrLf8mNnpoFP/lI90XcywMCFNe8=
+github.com/getkin/kin-openapi v0.114.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc=
 github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
 github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
-github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=
-github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
-github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8=
-github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
+github.com/gin-gonic/gin v1.9.0 h1:OjyFBKICoexlu99ctXNR2gg+c5pKrKMuyjgARg9qeY8=
+github.com/gin-gonic/gin v1.9.0/go.mod h1:W1Me9+hsUSyj3CePGrd1/QrKJMSJ1Tu/0hFEH89961k=
+github.com/go-chi/chi/v5 v5.0.8 h1:lD+NLqFcAi1ovnVZpsnObHGW4xb4J8lNmoYVfECH1Y0=
+github.com/go-chi/chi/v5 v5.0.8/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
 github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
 github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
 github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
 github.com/go-openapi/swag v0.21.1 h1:wm0rhTb5z7qpJRHBdPOMuY4QjVUMbF6/kwoYeRAOrKU=
 github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
-github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
-github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
-github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
-github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
-github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
-github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
-github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ=
-github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
+github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
+github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
+github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
+github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
+github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
+github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU=
+github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s=
+github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
+github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
 github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
-github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk=
-github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA=
+github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
 github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
@@ -53,16 +60,16 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF
 github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
 github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
 github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE=
+github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
+github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
-github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
 github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
-github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
-github.com/labstack/echo/v4 v4.9.1 h1:GliPYSpzGKlyOhqIbG8nmHBo3i1saKWFOgh41AN3b+Y=
-github.com/labstack/echo/v4 v4.9.1/go.mod h1:Pop5HLc+xoc4qhTZ1ip6C0RtP7Z+4VzRLWZZFKqbbjo=
+github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M=
+github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k=
 github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
 github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
 github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
@@ -84,14 +91,15 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN
 github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
 github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
-github.com/matryer/moq v0.2.7 h1:RtpiPUM8L7ZSCbSwK+QcZH/E9tgqAkFjKQxsRs25b4w=
-github.com/matryer/moq v0.2.7/go.mod h1:kITsx543GOENm48TUAQyJ9+SAvFSr7iGQXPoth/VUBk=
+github.com/matryer/moq v0.3.1 h1:kLDiBJoGcusWS2BixGyTkF224aSCD8nLY24tj/NcTCs=
+github.com/matryer/moq v0.3.1/go.mod h1:RJ75ZZZD71hejp39j4crZLsEDszGk6iH4v4YsWFKH4s=
 github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
 github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
 github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
 github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
-github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
 github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
+github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -100,16 +108,15 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
-github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg=
-github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas=
-github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
+github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
+github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
+github.com/perimeterx/marshmallow v1.1.4 h1:pZLDH9RjlLGGorbXhcaQLhfuV0pFMNfPO55FuFkxqLw=
+github.com/perimeterx/marshmallow v1.1.4/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
 github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
-github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
 github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
@@ -121,64 +128,50 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
 github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
+github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
+github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
 github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
-github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
 github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
+github.com/ugorji/go/codec v1.2.9 h1:rmenucSohSTiyL09Y+l2OCk+FrMxGMzho2+tjr5ticU=
+github.com/ugorji/go/codec v1.2.9/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
 github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
 github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
 github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
-github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU=
+golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
 golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
-golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
-golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
-golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I=
-golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
+golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
+golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
+golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
-golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
+golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
+golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
-golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
-golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/time v0.0.0-20220411224347-583f2d630306 h1:+gHMid33q6pen7kv9xvT+JRinntgeXO2AeZVd0AWD3w=
-golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
+golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
+golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
-golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
-golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
+golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U=
 golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
@@ -188,8 +181,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
-gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
@@ -199,3 +190,4 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C
 gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
diff --git a/pkg/chi-middleware/oapi_validate.go b/pkg/chi-middleware/oapi_validate.go
index 8c37a79..c09c2f1 100644
--- a/pkg/chi-middleware/oapi_validate.go
+++ b/pkg/chi-middleware/oapi_validate.go
@@ -7,6 +7,7 @@ import (
 	"context"
 	"errors"
 	"fmt"
+	"log"
 	"net/http"
 	"strings"
 
@@ -27,6 +28,8 @@ type Options struct {
 	Options           openapi3filter.Options
 	ErrorHandler      ErrorHandler
 	MultiErrorHandler MultiErrorHandler
+	// SilenceServersWarning allows silencing a warning for https://github.com/deepmap/oapi-codegen/issues/882 that reports when an OpenAPI spec has `spec.Servers != nil`
+	SilenceServersWarning bool
 }
 
 // OapiRequestValidator Creates middleware to validate request by swagger spec.
@@ -38,6 +41,10 @@ func OapiRequestValidator(swagger *openapi3.T) func(next http.Handler) http.Hand
 // OapiRequestValidatorWithOptions Creates middleware to validate request by swagger spec.
 // This middleware is good for net/http either since go-chi is 100% compatible with net/http.
 func OapiRequestValidatorWithOptions(swagger *openapi3.T, options *Options) func(next http.Handler) http.Handler {
+	if swagger.Servers != nil && (options == nil || options.SilenceServersWarning) {
+		log.Println("WARN: OapiRequestValidatorWithOptions called with an OpenAPI spec that has `Servers` set. This may lead to an HTTP 400 with `no matching operation was found` when sending a valid request, as the validator performs `Host` header validation. If you're expecting `Host` header validation, you can silence this warning by setting `Options.SilenceServersWarning = true`. See https://github.com/deepmap/oapi-codegen/issues/882 for more information.")
+	}
+
 	router, err := gorillamux.NewRouter(swagger)
 	if err != nil {
 		panic(err)
diff --git a/pkg/codegen/codegen.go b/pkg/codegen/codegen.go
index 5086691..956d589 100644
--- a/pkg/codegen/codegen.go
+++ b/pkg/codegen/codegen.go
@@ -201,9 +201,12 @@ func Generate(spec *openapi3.T, opts Configuration) (string, error) {
 
 	var strictServerOut string
 	if opts.Generate.Strict {
-		responses, err := GenerateResponseDefinitions("", spec.Components.Responses)
-		if err != nil {
-			return "", fmt.Errorf("error generation response definitions for schema: %w", err)
+		var responses []ResponseDefinition
+		if spec.Components != nil {
+			responses, err = GenerateResponseDefinitions("", spec.Components.Responses)
+			if err != nil {
+				return "", fmt.Errorf("error generation response definitions for schema: %w", err)
+			}
 		}
 		strictServerResponses, err := GenerateStrictResponses(t, responses)
 		if err != nil {
@@ -339,28 +342,31 @@ func Generate(spec *openapi3.T, opts Configuration) (string, error) {
 }
 
 func GenerateTypeDefinitions(t *template.Template, swagger *openapi3.T, ops []OperationDefinition, excludeSchemas []string) (string, error) {
-	schemaTypes, err := GenerateTypesForSchemas(t, swagger.Components.Schemas, excludeSchemas)
-	if err != nil {
-		return "", fmt.Errorf("error generating Go types for component schemas: %w", err)
-	}
+	var allTypes []TypeDefinition
+	if swagger.Components != nil {
+		schemaTypes, err := GenerateTypesForSchemas(t, swagger.Components.Schemas, excludeSchemas)
+		if err != nil {
+			return "", fmt.Errorf("error generating Go types for component schemas: %w", err)
+		}
 
-	paramTypes, err := GenerateTypesForParameters(t, swagger.Components.Parameters)
-	if err != nil {
-		return "", fmt.Errorf("error generating Go types for component parameters: %w", err)
-	}
-	allTypes := append(schemaTypes, paramTypes...)
+		paramTypes, err := GenerateTypesForParameters(t, swagger.Components.Parameters)
+		if err != nil {
+			return "", fmt.Errorf("error generating Go types for component parameters: %w", err)
+		}
+		allTypes = append(schemaTypes, paramTypes...)
 
-	responseTypes, err := GenerateTypesForResponses(t, swagger.Components.Responses)
-	if err != nil {
-		return "", fmt.Errorf("error generating Go types for component responses: %w", err)
-	}
-	allTypes = append(allTypes, responseTypes...)
+		responseTypes, err := GenerateTypesForResponses(t, swagger.Components.Responses)
+		if err != nil {
+			return "", fmt.Errorf("error generating Go types for component responses: %w", err)
+		}
+		allTypes = append(allTypes, responseTypes...)
 
-	bodyTypes, err := GenerateTypesForRequestBodies(t, swagger.Components.RequestBodies)
-	if err != nil {
-		return "", fmt.Errorf("error generating Go types for component request bodies: %w", err)
+		bodyTypes, err := GenerateTypesForRequestBodies(t, swagger.Components.RequestBodies)
+		if err != nil {
+			return "", fmt.Errorf("error generating Go types for component request bodies: %w", err)
+		}
+		allTypes = append(allTypes, bodyTypes...)
 	}
-	allTypes = append(allTypes, bodyTypes...)
 
 	// Go through all operations, and add their types to allTypes, so that we can
 	// scan all of them for enums. Operation definitions are handled differently
@@ -396,7 +402,12 @@ func GenerateTypeDefinitions(t *template.Template, swagger *openapi3.T, ops []Op
 		return "", fmt.Errorf("error generating union boilerplate: %w", err)
 	}
 
-	typeDefinitions := strings.Join([]string{enumsOut, typesOut, operationsOut, allOfBoilerplate, unionBoilerplate}, "")
+	unionAndAdditionalBoilerplate, err := GenerateUnionAndAdditionalProopertiesBoilerplate(t, allTypes)
+	if err != nil {
+		return "", fmt.Errorf("error generating boilerplate for union types with additionalProperties: %w", err)
+	}
+
+	typeDefinitions := strings.Join([]string{enumsOut, typesOut, operationsOut, allOfBoilerplate, unionBoilerplate, unionAndAdditionalBoilerplate}, "")
 	return typeDefinitions, nil
 }
 
@@ -778,6 +789,26 @@ func GenerateUnionBoilerplate(t *template.Template, typeDefs []TypeDefinition) (
 	return GenerateTemplates([]string{"union.tmpl"}, t, context)
 }
 
+func GenerateUnionAndAdditionalProopertiesBoilerplate(t *template.Template, typeDefs []TypeDefinition) (string, error) {
+	var filteredTypes []TypeDefinition
+	for _, t := range typeDefs {
+		if len(t.Schema.UnionElements) != 0 && t.Schema.HasAdditionalProperties {
+			filteredTypes = append(filteredTypes, t)
+		}
+	}
+
+	if len(filteredTypes) == 0 {
+		return "", nil
+	}
+	context := struct {
+		Types []TypeDefinition
+	}{
+		Types: filteredTypes,
+	}
+
+	return GenerateTemplates([]string{"union-and-additional-properties.tmpl"}, t, context)
+}
+
 // SanitizeCode runs sanitizers across the generated Go code to ensure the
 // generated code will be able to compile.
 func SanitizeCode(goCode string) string {
@@ -868,6 +899,10 @@ func OperationImports(ops []OperationDefinition) (map[string]goImport, error) {
 
 func GetTypeDefinitionsImports(swagger *openapi3.T, excludeSchemas []string) (map[string]goImport, error) {
 	res := map[string]goImport{}
+	if swagger.Components == nil {
+		return res, nil
+	}
+
 	schemaImports, err := GetSchemaImports(swagger.Components.Schemas, excludeSchemas)
 	if err != nil {
 		return nil, err
diff --git a/pkg/codegen/configuration.go b/pkg/codegen/configuration.go
index 1400c3c..afa4fc5 100644
--- a/pkg/codegen/configuration.go
+++ b/pkg/codegen/configuration.go
@@ -69,6 +69,11 @@ type CompatibilityOptions struct {
 	// This resolves the behavior such that middlewares are chained in the order they are invoked.
 	// Please see https://github.com/deepmap/oapi-codegen/issues/786
 	ApplyChiMiddlewareFirstToLast bool `yaml:"apply-chi-middleware-first-to-last,omitempty"`
+	// Our generated code for gorilla/mux has historically inverted the order in which gorilla/mux middleware is
+	// applied such that the last invoked middleware ends up executing first in the middlewares chain
+	// This resolves the behavior such that middlewares are chained in the order they are invoked.
+	// Please see https://github.com/deepmap/oapi-codegen/issues/841
+	ApplyGorillaMiddlewareFirstToLast bool `yaml:"apply-gorilla-middleware-first-to-last,omitempty"`
 }
 
 // OutputOptions are used to modify the output code in some way.
diff --git a/pkg/codegen/extension.go b/pkg/codegen/extension.go
index 69c4621..ca4c3b6 100644
--- a/pkg/codegen/extension.go
+++ b/pkg/codegen/extension.go
@@ -1,7 +1,6 @@
 package codegen
 
 import (
-	"encoding/json"
 	"fmt"
 )
 
@@ -13,22 +12,20 @@ const (
 	// extGoName is used to override a field name
 	extGoName = "x-go-name"
 	// extGoTypeName is used to override a generated typename for something.
-	extGoTypeName       = "x-go-type-name"
-	extPropGoJsonIgnore = "x-go-json-ignore"
-	extPropOmitEmpty    = "x-omitempty"
-	extPropExtraTags    = "x-oapi-codegen-extra-tags"
+	extGoTypeName        = "x-go-type-name"
+	extPropGoJsonIgnore  = "x-go-json-ignore"
+	extPropOmitEmpty     = "x-omitempty"
+	extPropExtraTags     = "x-oapi-codegen-extra-tags"
+	extEnumVarNames      = "x-enum-varnames"
+	extEnumNames         = "x-enumNames"
+	extDeprecationReason = "x-deprecated-reason"
 )
 
 func extString(extPropValue interface{}) (string, error) {
-	raw, ok := extPropValue.(json.RawMessage)
+	str, ok := extPropValue.(string)
 	if !ok {
 		return "", fmt.Errorf("failed to convert type: %T", extPropValue)
 	}
-	var str string
-	if err := json.Unmarshal(raw, &str); err != nil {
-		return "", fmt.Errorf("failed to unmarshal json: %w", err)
-	}
-
 	return str, nil
 }
 func extTypeName(extPropValue interface{}) (string, error) {
@@ -40,41 +37,53 @@ func extParseGoFieldName(extPropValue interface{}) (string, error) {
 }
 
 func extParseOmitEmpty(extPropValue interface{}) (bool, error) {
-	raw, ok := extPropValue.(json.RawMessage)
+	omitEmpty, ok := extPropValue.(bool)
 	if !ok {
 		return false, fmt.Errorf("failed to convert type: %T", extPropValue)
 	}
-
-	var omitEmpty bool
-	if err := json.Unmarshal(raw, &omitEmpty); err != nil {
-		return false, fmt.Errorf("failed to unmarshal json: %w", err)
-	}
-
 	return omitEmpty, nil
 }
 
 func extExtraTags(extPropValue interface{}) (map[string]string, error) {
-	raw, ok := extPropValue.(json.RawMessage)
+	tagsI, ok := extPropValue.(map[string]interface{})
 	if !ok {
 		return nil, fmt.Errorf("failed to convert type: %T", extPropValue)
 	}
-	var tags map[string]string
-	if err := json.Unmarshal(raw, &tags); err != nil {
-		return nil, fmt.Errorf("failed to unmarshal json: %w", err)
+	tags := make(map[string]string, len(tagsI))
+	for k, v := range tagsI {
+		vs, ok := v.(string)
+		if !ok {
+			return nil, fmt.Errorf("failed to convert type: %T", v)
+		}
+		tags[k] = vs
 	}
 	return tags, nil
 }
 
 func extParseGoJsonIgnore(extPropValue interface{}) (bool, error) {
-	raw, ok := extPropValue.(json.RawMessage)
+	goJsonIgnore, ok := extPropValue.(bool)
 	if !ok {
 		return false, fmt.Errorf("failed to convert type: %T", extPropValue)
 	}
+	return goJsonIgnore, nil
+}
 
-	var goJsonIgnore bool
-	if err := json.Unmarshal(raw, &goJsonIgnore); err != nil {
-		return false, fmt.Errorf("failed to unmarshal json: %w", err)
+func extParseEnumVarNames(extPropValue interface{}) ([]string, error) {
+	namesI, ok := extPropValue.([]interface{})
+	if !ok {
+		return nil, fmt.Errorf("failed to convert type: %T", extPropValue)
+	}
+	names := make([]string, len(namesI))
+	for i, v := range namesI {
+		vs, ok := v.(string)
+		if !ok {
+			return nil, fmt.Errorf("failed to convert type: %T", v)
+		}
+		names[i] = vs
 	}
+	return names, nil
+}
 
-	return goJsonIgnore, nil
+func extParseDeprecationReason(extPropValue interface{}) (string, error) {
+	return extString(extPropValue)
 }
diff --git a/pkg/codegen/merge_schemas.go b/pkg/codegen/merge_schemas.go
index 610f0d2..84256b1 100644
--- a/pkg/codegen/merge_schemas.go
+++ b/pkg/codegen/merge_schemas.go
@@ -37,7 +37,7 @@ func mergeSchemas(allOf []*openapi3.SchemaRef, path []string) (Schema, error) {
 		if err != nil {
 			return Schema{}, err
 		}
-		schema, err = mergeOpenapiSchemas(schema, oneOfSchema)
+		schema, err = mergeOpenapiSchemas(schema, oneOfSchema, true)
 		if err != nil {
 			return Schema{}, fmt.Errorf("error merging schemas for AllOf: %w", err)
 		}
@@ -53,10 +53,10 @@ func valueWithPropagatedRef(ref *openapi3.SchemaRef) (openapi3.Schema, error) {
 	}
 
 	pathParts := strings.Split(ref.Ref, "#")
-	if len(pathParts) != 2 {
+	if len(pathParts) < 1 || len(pathParts) > 2 {
 		return openapi3.Schema{}, fmt.Errorf("unsupported reference: %s", ref.Ref)
 	}
-	remoteComponent, _ := pathParts[0], pathParts[1]
+	remoteComponent := pathParts[0]
 
 	// remote ref
 	schema := *ref.Value
@@ -74,7 +74,7 @@ func mergeAllOf(allOf []*openapi3.SchemaRef) (openapi3.Schema, error) {
 	var schema openapi3.Schema
 	for _, schemaRef := range allOf {
 		var err error
-		schema, err = mergeOpenapiSchemas(schema, *schemaRef.Value)
+		schema, err = mergeOpenapiSchemas(schema, *schemaRef.Value, true)
 		if err != nil {
 			return openapi3.Schema{}, fmt.Errorf("error merging schemas for AllOf: %w", err)
 		}
@@ -84,7 +84,7 @@ func mergeAllOf(allOf []*openapi3.SchemaRef) (openapi3.Schema, error) {
 
 // mergeOpenapiSchemas merges two openAPI schemas and returns the schema
 // all of whose fields are composed.
-func mergeOpenapiSchemas(s1, s2 openapi3.Schema) (openapi3.Schema, error) {
+func mergeOpenapiSchemas(s1, s2 openapi3.Schema, allOf bool) (openapi3.Schema, error) {
 	var result openapi3.Schema
 	if s1.Extensions != nil || s2.Extensions != nil {
 		result.Extensions = make(map[string]interface{})
@@ -212,15 +212,15 @@ func mergeOpenapiSchemas(s1, s2 openapi3.Schema) (openapi3.Schema, error) {
 	if SchemaHasAdditionalProperties(&s1) && SchemaHasAdditionalProperties(&s2) {
 		return openapi3.Schema{}, errors.New("merging two schemas with additional properties, this is unhandled")
 	}
-	if s1.AdditionalProperties != nil {
-		result.AdditionalProperties = s1.AdditionalProperties
+	if s1.AdditionalProperties.Schema != nil {
+		result.AdditionalProperties.Schema = s1.AdditionalProperties.Schema
 	}
-	if s2.AdditionalProperties != nil {
-		result.AdditionalProperties = s2.AdditionalProperties
+	if s2.AdditionalProperties.Schema != nil {
+		result.AdditionalProperties.Schema = s2.AdditionalProperties.Schema
 	}
 
-	// Unhandled for now
-	if s1.Discriminator != nil || s2.Discriminator != nil {
+	// Allow discriminators for allOf merges, but disallow for one/anyOfs.
+	if !allOf && (s1.Discriminator != nil || s2.Discriminator != nil) {
 		return openapi3.Schema{}, errors.New("merging two schemas with discriminators is not supported")
 	}
 
diff --git a/pkg/codegen/operations.go b/pkg/codegen/operations.go
index 314e894..28b991f 100644
--- a/pkg/codegen/operations.go
+++ b/pkg/codegen/operations.go
@@ -126,8 +126,8 @@ func (pd ParameterDefinition) GoVariableName() string {
 
 func (pd ParameterDefinition) GoName() string {
 	goName := pd.ParamName
-	if _, ok := pd.Spec.ExtensionProps.Extensions[extGoName]; ok {
-		if extGoFieldName, err := extParseGoFieldName(pd.Spec.ExtensionProps.Extensions[extGoName]); err == nil {
+	if _, ok := pd.Spec.Extensions[extGoName]; ok {
+		if extGoFieldName, err := extParseGoFieldName(pd.Spec.Extensions[extGoName]); err == nil {
 			goName = extGoFieldName
 		}
 	}
@@ -663,6 +663,17 @@ func GenerateBodyDefinitions(operationID string, bodyOrRef *openapi3.RequestBody
 		// type under #/components, we'll define a type for it, so
 		// that we have an easy to use type for marshaling.
 		if bodySchema.RefType == "" {
+			if contentType == "application/x-www-form-urlencoded" {
+				// Apply the appropriate structure tag if the request
+				// schema was defined under the operations' section.
+				for i := range bodySchema.Properties {
+					bodySchema.Properties[i].NeedsFormTag = true
+				}
+
+				// Regenerate the Golang struct adding the new form tag.
+				bodySchema.GoType = GenStructFromSchema(bodySchema)
+			}
+
 			td := TypeDefinition{
 				TypeName: bodyTypeName,
 				Schema:   bodySchema,
@@ -825,12 +836,12 @@ func GenerateParamsTypes(op OperationDefinition) []TypeDefinition {
 			})
 		}
 		prop := Property{
-			Description:    param.Spec.Description,
-			JsonFieldName:  param.ParamName,
-			Required:       param.Required,
-			Schema:         pSchema,
-			NeedsFormTag:   param.Style() == "form",
-			ExtensionProps: &param.Spec.ExtensionProps,
+			Description:   param.Spec.Description,
+			JsonFieldName: param.ParamName,
+			Required:      param.Required,
+			Schema:        pSchema,
+			NeedsFormTag:  param.Style() == "form",
+			Extensions:    param.Spec.Extensions,
 		}
 		s.Properties = append(s.Properties, prop)
 	}
diff --git a/pkg/codegen/prune.go b/pkg/codegen/prune.go
index b9f05f5..9dc4fd8 100644
--- a/pkg/codegen/prune.go
+++ b/pkg/codegen/prune.go
@@ -28,14 +28,14 @@ func walkSwagger(swagger *openapi3.T, doFn func(RefWrapper) (bool, error)) error
 
 	for _, p := range swagger.Paths {
 		for _, param := range p.Parameters {
-			walkParameterRef(param, doFn)
+			_ = walkParameterRef(param, doFn)
 		}
 		for _, op := range p.Operations() {
-			walkOperation(op, doFn)
+			_ = walkOperation(op, doFn)
 		}
 	}
 
-	walkComponents(&swagger.Components, doFn)
+	_ = walkComponents(swagger.Components, doFn)
 
 	return nil
 }
@@ -53,11 +53,11 @@ func walkOperation(op *openapi3.Operation, doFn func(RefWrapper) (bool, error))
 	_ = walkRequestBodyRef(op.RequestBody, doFn)
 
 	for _, response := range op.Responses {
-		walkResponseRef(response, doFn)
+		_ = walkResponseRef(response, doFn)
 	}
 
 	for _, callback := range op.Callbacks {
-		walkCallbackRef(callback, doFn)
+		_ = walkCallbackRef(callback, doFn)
 	}
 
 	return nil
@@ -126,25 +126,25 @@ func walkSchemaRef(ref *openapi3.SchemaRef, doFn func(RefWrapper) (bool, error))
 	}
 
 	for _, ref := range ref.Value.OneOf {
-		walkSchemaRef(ref, doFn)
+		_ = walkSchemaRef(ref, doFn)
 	}
 
 	for _, ref := range ref.Value.AnyOf {
-		walkSchemaRef(ref, doFn)
+		_ = walkSchemaRef(ref, doFn)
 	}
 
 	for _, ref := range ref.Value.AllOf {
-		walkSchemaRef(ref, doFn)
+		_ = walkSchemaRef(ref, doFn)
 	}
 
-	walkSchemaRef(ref.Value.Not, doFn)
-	walkSchemaRef(ref.Value.Items, doFn)
+	_ = walkSchemaRef(ref.Value.Not, doFn)
+	_ = walkSchemaRef(ref.Value.Items, doFn)
 
 	for _, ref := range ref.Value.Properties {
-		walkSchemaRef(ref, doFn)
+		_ = walkSchemaRef(ref, doFn)
 	}
 
-	walkSchemaRef(ref.Value.AdditionalProperties, doFn)
+	_ = walkSchemaRef(ref.Value.AdditionalProperties.Schema, doFn)
 
 	return nil
 }
@@ -166,20 +166,20 @@ func walkParameterRef(ref *openapi3.ParameterRef, doFn func(RefWrapper) (bool, e
 		return nil
 	}
 
-	walkSchemaRef(ref.Value.Schema, doFn)
+	_ = walkSchemaRef(ref.Value.Schema, doFn)
 
 	for _, example := range ref.Value.Examples {
-		walkExampleRef(example, doFn)
+		_ = walkExampleRef(example, doFn)
 	}
 
 	for _, mediaType := range ref.Value.Content {
 		if mediaType == nil {
 			continue
 		}
-		walkSchemaRef(mediaType.Schema, doFn)
+		_ = walkSchemaRef(mediaType.Schema, doFn)
 
 		for _, example := range mediaType.Examples {
-			walkExampleRef(example, doFn)
+			_ = walkExampleRef(example, doFn)
 		}
 	}
 
@@ -207,10 +207,10 @@ func walkRequestBodyRef(ref *openapi3.RequestBodyRef, doFn func(RefWrapper) (boo
 		if mediaType == nil {
 			continue
 		}
-		walkSchemaRef(mediaType.Schema, doFn)
+		_ = walkSchemaRef(mediaType.Schema, doFn)
 
 		for _, example := range mediaType.Examples {
-			walkExampleRef(example, doFn)
+			_ = walkExampleRef(example, doFn)
 		}
 	}
 
@@ -235,22 +235,22 @@ func walkResponseRef(ref *openapi3.ResponseRef, doFn func(RefWrapper) (bool, err
 	}
 
 	for _, header := range ref.Value.Headers {
-		walkHeaderRef(header, doFn)
+		_ = walkHeaderRef(header, doFn)
 	}
 
 	for _, mediaType := range ref.Value.Content {
 		if mediaType == nil {
 			continue
 		}
-		walkSchemaRef(mediaType.Schema, doFn)
+		_ = walkSchemaRef(mediaType.Schema, doFn)
 
 		for _, example := range mediaType.Examples {
-			walkExampleRef(example, doFn)
+			_ = walkExampleRef(example, doFn)
 		}
 	}
 
 	for _, link := range ref.Value.Links {
-		walkLinkRef(link, doFn)
+		_ = walkLinkRef(link, doFn)
 	}
 
 	return nil
@@ -275,17 +275,17 @@ func walkCallbackRef(ref *openapi3.CallbackRef, doFn func(RefWrapper) (bool, err
 
 	for _, pathItem := range *ref.Value {
 		for _, parameter := range pathItem.Parameters {
-			walkParameterRef(parameter, doFn)
+			_ = walkParameterRef(parameter, doFn)
 		}
-		walkOperation(pathItem.Connect, doFn)
-		walkOperation(pathItem.Delete, doFn)
-		walkOperation(pathItem.Get, doFn)
-		walkOperation(pathItem.Head, doFn)
-		walkOperation(pathItem.Options, doFn)
-		walkOperation(pathItem.Patch, doFn)
-		walkOperation(pathItem.Post, doFn)
-		walkOperation(pathItem.Put, doFn)
-		walkOperation(pathItem.Trace, doFn)
+		_ = walkOperation(pathItem.Connect, doFn)
+		_ = walkOperation(pathItem.Delete, doFn)
+		_ = walkOperation(pathItem.Get, doFn)
+		_ = walkOperation(pathItem.Head, doFn)
+		_ = walkOperation(pathItem.Options, doFn)
+		_ = walkOperation(pathItem.Patch, doFn)
+		_ = walkOperation(pathItem.Post, doFn)
+		_ = walkOperation(pathItem.Put, doFn)
+		_ = walkOperation(pathItem.Trace, doFn)
 	}
 
 	return nil
@@ -308,7 +308,7 @@ func walkHeaderRef(ref *openapi3.HeaderRef, doFn func(RefWrapper) (bool, error))
 		return nil
 	}
 
-	walkSchemaRef(ref.Value.Schema, doFn)
+	_ = walkSchemaRef(ref.Value.Schema, doFn)
 
 	return nil
 }
@@ -380,7 +380,7 @@ func walkExampleRef(ref *openapi3.ExampleRef, doFn func(RefWrapper) (bool, error
 func findComponentRefs(swagger *openapi3.T) []string {
 	refs := []string{}
 
-	walkSwagger(swagger, func(ref RefWrapper) (bool, error) {
+	_ = walkSwagger(swagger, func(ref RefWrapper) (bool, error) {
 		if ref.Ref != "" {
 			refs = append(refs, ref.Ref)
 			return false, nil
@@ -392,6 +392,10 @@ func findComponentRefs(swagger *openapi3.T) []string {
 }
 
 func removeOrphanedComponents(swagger *openapi3.T, refs []string) int {
+	if swagger.Components == nil {
+		return 0
+	}
+
 	countRemoved := 0
 
 	for key := range swagger.Components.Schemas {
diff --git a/pkg/codegen/schema.go b/pkg/codegen/schema.go
index bbba3fc..457e102 100644
--- a/pkg/codegen/schema.go
+++ b/pkg/codegen/schema.go
@@ -59,7 +59,7 @@ func (s *Schema) AddProperty(p Property) error {
 	// Scan all existing properties for a conflict
 	for _, e := range s.Properties {
 		if e.JsonFieldName == p.JsonFieldName && !PropertiesEqual(e, p) {
-			return errors.New(fmt.Sprintf("property '%s' already exists with a different type", e.JsonFieldName))
+			return fmt.Errorf("property '%s' already exists with a different type", e.JsonFieldName)
 		}
 	}
 	s.Properties = append(s.Properties, p)
@@ -76,15 +76,16 @@ func (s Schema) GetAdditionalTypeDefs() []TypeDefinition {
 }
 
 type Property struct {
-	Description    string
-	JsonFieldName  string
-	Schema         Schema
-	Required       bool
-	Nullable       bool
-	ReadOnly       bool
-	WriteOnly      bool
-	NeedsFormTag   bool
-	ExtensionProps *openapi3.ExtensionProps
+	Description   string
+	JsonFieldName string
+	Schema        Schema
+	Required      bool
+	Nullable      bool
+	ReadOnly      bool
+	WriteOnly     bool
+	NeedsFormTag  bool
+	Extensions    map[string]interface{}
+	Deprecated    bool
 }
 
 func (p Property) GoFieldName() string {
@@ -309,8 +310,8 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) {
 
 			// If additional properties are defined, we will override the default
 			// above with the specific definition.
-			if schema.AdditionalProperties != nil {
-				additionalSchema, err := GenerateGoSchema(schema.AdditionalProperties, path)
+			if schema.AdditionalProperties.Schema != nil {
+				additionalSchema, err := GenerateGoSchema(schema.AdditionalProperties.Schema, path)
 				if err != nil {
 					return Schema{}, fmt.Errorf("error generating type for additional properties: %w", err)
 				}
@@ -380,14 +381,15 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) {
 					description = p.Value.Description
 				}
 				prop := Property{
-					JsonFieldName:  pName,
-					Schema:         pSchema,
-					Required:       required,
-					Description:    description,
-					Nullable:       p.Value.Nullable,
-					ReadOnly:       p.Value.ReadOnly,
-					WriteOnly:      p.Value.WriteOnly,
-					ExtensionProps: &p.Value.ExtensionProps,
+					JsonFieldName: pName,
+					Schema:        pSchema,
+					Required:      required,
+					Description:   description,
+					Nullable:      p.Value.Nullable,
+					ReadOnly:      p.Value.ReadOnly,
+					WriteOnly:     p.Value.WriteOnly,
+					Extensions:    p.Value.Extensions,
+					Deprecated:    p.Value.Deprecated,
 				}
 				outSchema.Properties = append(outSchema.Properties, prop)
 			}
@@ -421,7 +423,17 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) {
 			enumValues[i] = fmt.Sprintf("%v", enumValue)
 		}
 
-		sanitizedValues := SanitizeEnumNames(enumValues)
+		enumNames := enumValues
+		for _, key := range []string{extEnumVarNames, extEnumNames} {
+			if _, ok := schema.Extensions[key]; ok {
+				if extEnumNames, err := extParseEnumVarNames(schema.Extensions[key]); err == nil {
+					enumNames = extEnumNames
+					break
+				}
+			}
+		}
+
+		sanitizedValues := SanitizeEnumNames(enumNames, enumValues)
 		outSchema.EnumValues = make(map[string]string, len(sanitizedValues))
 
 		for k, v := range sanitizedValues {
@@ -596,8 +608,8 @@ func GenFieldsFromProperties(props []Property) []string {
 		field := ""
 
 		goFieldName := p.GoFieldName()
-		if _, ok := p.ExtensionProps.Extensions[extGoName]; ok {
-			if extGoFieldName, err := extParseGoFieldName(p.ExtensionProps.Extensions[extGoName]); err == nil {
+		if _, ok := p.Extensions[extGoName]; ok {
+			if extGoFieldName, err := extParseGoFieldName(p.Extensions[extGoName]); err == nil {
 				goFieldName = extGoFieldName
 			}
 		}
@@ -612,12 +624,24 @@ func GenFieldsFromProperties(props []Property) []string {
 			field += fmt.Sprintf("%s\n", StringWithTypeNameToGoComment(p.Description, p.GoFieldName()))
 		}
 
+		if p.Deprecated {
+			// This comment has to be on its own line for godoc & IDEs to pick up
+			var deprecationReason string
+			if _, ok := p.Extensions[extDeprecationReason]; ok {
+				if extOmitEmpty, err := extParseDeprecationReason(p.Extensions[extDeprecationReason]); err == nil {
+					deprecationReason = extOmitEmpty
+				}
+			}
+
+			field += fmt.Sprintf("%s\n", DeprecationComment(deprecationReason))
+		}
+
 		field += fmt.Sprintf("    %s %s", goFieldName, p.GoTypeDef())
 
 		// Support x-omitempty
 		overrideOmitEmpty := true
-		if _, ok := p.ExtensionProps.Extensions[extPropOmitEmpty]; ok {
-			if extOmitEmpty, err := extParseOmitEmpty(p.ExtensionProps.Extensions[extPropOmitEmpty]); err == nil {
+		if _, ok := p.Extensions[extPropOmitEmpty]; ok {
+			if extOmitEmpty, err := extParseOmitEmpty(p.Extensions[extPropOmitEmpty]); err == nil {
 				overrideOmitEmpty = extOmitEmpty
 			}
 		}
@@ -637,14 +661,14 @@ func GenFieldsFromProperties(props []Property) []string {
 		}
 
 		// Support x-go-json-ignore
-		if _, ok := p.ExtensionProps.Extensions[extPropGoJsonIgnore]; ok {
-			if goJsonIgnore, err := extParseGoJsonIgnore(p.ExtensionProps.Extensions[extPropGoJsonIgnore]); err == nil && goJsonIgnore {
+		if _, ok := p.Extensions[extPropGoJsonIgnore]; ok {
+			if goJsonIgnore, err := extParseGoJsonIgnore(p.Extensions[extPropGoJsonIgnore]); err == nil && goJsonIgnore {
 				fieldTags["json"] = "-"
 			}
 		}
 
 		// Support x-oapi-codegen-extra-tags
-		if extension, ok := p.ExtensionProps.Extensions[extPropExtraTags]; ok {
+		if extension, ok := p.Extensions[extPropExtraTags]; ok {
 			if tags, err := extExtraTags(extension); err == nil {
 				keys := SortedStringKeys(tags)
 				for _, k := range keys {
@@ -750,15 +774,30 @@ func generateUnion(outSchema *Schema, elements openapi3.SchemaRefs, discriminato
 		}
 
 		if discriminator != nil {
+			if len(discriminator.Mapping) != 0 && element.Ref == "" {
+				return errors.New("ambiguous discriminator.mapping: please replace inlined object with $ref")
+			}
+
+			// Explicit mapping.
+			var mapped bool
 			for k, v := range discriminator.Mapping {
 				if v == element.Ref {
 					outSchema.Discriminator.Mapping[k] = elementSchema.GoType
+					mapped = true
 					break
 				}
 			}
+			// Implicit mapping.
+			if !mapped {
+				outSchema.Discriminator.Mapping[RefPathToObjName(element.Ref)] = elementSchema.GoType
+			}
 		}
 		outSchema.UnionElements = append(outSchema.UnionElements, UnionElement(elementSchema.GoType))
 	}
 
+	if (outSchema.Discriminator != nil) && len(outSchema.Discriminator.Mapping) != len(elements) {
+		return errors.New("discriminator: not all schemas were mapped")
+	}
+
 	return nil
 }
diff --git a/pkg/codegen/template_helpers.go b/pkg/codegen/template_helpers.go
index 7ef57f3..16671fb 100644
--- a/pkg/codegen/template_helpers.go
+++ b/pkg/codegen/template_helpers.go
@@ -22,11 +22,13 @@ import (
 
 	"github.com/deepmap/oapi-codegen/pkg/util"
 	"github.com/labstack/echo/v4"
+	"golang.org/x/text/cases"
+	"golang.org/x/text/language"
 )
 
 const (
 	// These allow the case statements to be sorted later:
-	prefixMostSpecific, prefixLessSpecific, prefixLeastSpecific = "3", "6", "9"
+	prefixLeastSpecific = "9"
 
 	defaultClientTypeName = "Client"
 )
@@ -37,6 +39,8 @@ var (
 	contentTypesXML  = []string{echo.MIMEApplicationXML, echo.MIMETextXML, "application/problems+xml"}
 
 	responseTypeSuffix = "Response"
+
+	titleCaser = cases.Title(language.English)
 )
 
 // This function takes an array of Parameter definition, and generates a valid
@@ -259,7 +263,11 @@ func getConditionOfResponseName(statusCodeVar, responseName string) string {
 
 // This outputs a string array
 func toStringArray(sarr []string) string {
-	return `[]string{"` + strings.Join(sarr, `","`) + `"}`
+	s := strings.Join(sarr, `","`)
+	if len(s) > 0 {
+		s = `"` + s + `"`
+	}
+	return `[]string{` + s + `}`
 }
 
 func stripNewLines(s string) string {
@@ -288,7 +296,7 @@ var TemplateFunctions = template.FuncMap{
 	"getResponseTypeDefinitions": getResponseTypeDefinitions,
 	"toStringArray":              toStringArray,
 	"lower":                      strings.ToLower,
-	"title":                      strings.Title,
+	"title":                      titleCaser.String,
 	"stripNewLines":              stripNewLines,
 	"sanitizeGoIdentity":         SanitizeGoIdentity,
 	"toGoComment":                StringWithTypeNameToGoComment,
diff --git a/pkg/codegen/templates/additional-properties.tmpl b/pkg/codegen/templates/additional-properties.tmpl
index 8a37647..c83cc10 100644
--- a/pkg/codegen/templates/additional-properties.tmpl
+++ b/pkg/codegen/templates/additional-properties.tmpl
@@ -17,6 +17,7 @@ func (a *{{.TypeName}}) Set(fieldName string, value {{$addType}}) {
     a.AdditionalProperties[fieldName] = value
 }
 
+{{if eq 0 (len .Schema.UnionElements) -}}
 // Override default JSON handling for {{.TypeName}} to handle AdditionalProperties
 func (a *{{.TypeName}}) UnmarshalJSON(b []byte) error {
     object := make(map[string]json.RawMessage)
@@ -68,3 +69,4 @@ func (a {{.TypeName}}) MarshalJSON() ([]byte, error) {
 	return json.Marshal(object)
 }
 {{end}}
+{{end}}
\ No newline at end of file
diff --git a/pkg/codegen/templates/chi/chi-middleware.tmpl b/pkg/codegen/templates/chi/chi-middleware.tmpl
index bb4e8f7..e99bbeb 100644
--- a/pkg/codegen/templates/chi/chi-middleware.tmpl
+++ b/pkg/codegen/templates/chi/chi-middleware.tmpl
@@ -40,7 +40,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ
   {{end}}
 
 {{range .SecurityDefinitions}}
-  ctx = context.WithValue(ctx, {{.ProviderName | ucFirst}}Scopes, {{toStringArray .Scopes}})
+  ctx = context.WithValue(ctx, {{.ProviderName | sanitizeGoIdentity | ucFirst}}Scopes, {{toStringArray .Scopes}})
 {{end}}
 
   {{if .RequiresParamObject}}
diff --git a/pkg/codegen/templates/constants.tmpl b/pkg/codegen/templates/constants.tmpl
index a3a0859..8fad876 100644
--- a/pkg/codegen/templates/constants.tmpl
+++ b/pkg/codegen/templates/constants.tmpl
@@ -1,7 +1,7 @@
 {{- if gt (len .SecuritySchemeProviderNames) 0 }}
 const (
 {{range $ProviderName := .SecuritySchemeProviderNames}}
-    {{- $ProviderName | ucFirst}}Scopes = "{{$ProviderName}}.Scopes"
+    {{- $ProviderName | sanitizeGoIdentity | ucFirst}}Scopes = "{{$ProviderName}}.Scopes"
 {{end}}
 )
 {{end}}
diff --git a/pkg/codegen/templates/gin/gin-register.tmpl b/pkg/codegen/templates/gin/gin-register.tmpl
index 188cbb8..8f03722 100644
--- a/pkg/codegen/templates/gin/gin-register.tmpl
+++ b/pkg/codegen/templates/gin/gin-register.tmpl
@@ -6,15 +6,14 @@ type GinServerOptions struct {
 }
 
 // RegisterHandlers creates http.Handler with routing matching OpenAPI spec.
-func RegisterHandlers(router *gin.Engine, si ServerInterface) *gin.Engine {
-  return RegisterHandlersWithOptions(router, si, GinServerOptions{})
+func RegisterHandlers(router gin.IRouter, si ServerInterface) {
+  RegisterHandlersWithOptions(router, si, GinServerOptions{})
 }
 
 // RegisterHandlersWithOptions creates http.Handler with additional options
-func RegisterHandlersWithOptions(router *gin.Engine, si ServerInterface, options GinServerOptions) *gin.Engine {
-    {{if .}}
+func RegisterHandlersWithOptions(router gin.IRouter, si ServerInterface, options GinServerOptions) {
+    {{- if . -}}
     errorHandler := options.ErrorHandler
-
     if errorHandler == nil {
         errorHandler = func(c *gin.Context, err error, statusCode int) {
             c.JSON(statusCode, gin.H{"msg": err.Error()})
@@ -27,8 +26,8 @@ func RegisterHandlersWithOptions(router *gin.Engine, si ServerInterface, options
         ErrorHandler: errorHandler,
     }
     {{end}}
-    {{range .}}
+
+    {{range . -}}
     router.{{.Method }}(options.BaseURL+"{{.Path | swaggerUriToGinUri }}", wrapper.{{.OperationId}})
-    {{end}}
-    return router
+    {{end -}}
 }
diff --git a/pkg/codegen/templates/gin/gin-wrappers.tmpl b/pkg/codegen/templates/gin/gin-wrappers.tmpl
index 3c11bcd..c34a522 100644
--- a/pkg/codegen/templates/gin/gin-wrappers.tmpl
+++ b/pkg/codegen/templates/gin/gin-wrappers.tmpl
@@ -40,7 +40,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *gin.Context) {
   {{end}}
 
 {{range .SecurityDefinitions}}
-  c.Set({{.ProviderName | ucFirst}}Scopes, {{toStringArray .Scopes}})
+  c.Set({{.ProviderName | sanitizeGoIdentity | ucFirst}}Scopes, {{toStringArray .Scopes}})
 {{end}}
 
   {{if .RequiresParamObject}}
@@ -62,16 +62,15 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *gin.Context) {
           var value {{.TypeDef}}
           err = json.Unmarshal([]byte(paramValue), &value)
           if err != nil {
-            siw.ErrorHandler(c, fmt.Errorf("Error unmarshalling parameter '{{.ParamName}}' as JSON: %s", err), http.StatusBadRequest) {
+            siw.ErrorHandler(c, fmt.Errorf("Error unmarshalling parameter '{{.ParamName}}' as JSON: %s", err), http.StatusBadRequest)
             return
           }
 
           params.{{.GoName}} = {{if not .Required}}&{{end}}value
         {{end}}
         }{{if .Required}} else {
-           if !siw.ErrorHandler(c, fmt.Errorf("Query argument {{.ParamName}} is required, but not found: %s", err), http.StatusBadRequest) {
-             return
-           }
+           siw.ErrorHandler(c, fmt.Errorf("Query argument {{.ParamName}} is required, but not found: %s", err), http.StatusBadRequest)
+           return
         }{{end}}
       {{end}}
 
@@ -127,18 +126,19 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *gin.Context) {
     {{end}}
 
     {{range .CookieParams}}
-      var cookie *http.Cookie
+      {
+      var cookie string
 
       if cookie, err = c.Cookie("{{.ParamName}}"); err == nil {
 
       {{- if .IsPassThrough}}
-        params.{{.GoName}} = {{if not .Required}}&{{end}}cookie.Value
+        params.{{.GoName}} = {{if not .Required}}&{{end}}cookie
       {{end}}
 
       {{- if .IsJson}}
         var value {{.TypeDef}}
         var decoded string
-        decoded, err := url.QueryUnescape(cookie.Value)
+        decoded, err := url.QueryUnescape(cookie)
         if err != nil {
             siw.ErrorHandler(c, fmt.Errorf("Error unescaping cookie parameter '{{.ParamName}}'"), http.StatusBadRequest)
             return
@@ -155,7 +155,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *gin.Context) {
 
       {{- if .IsStyled}}
         var value {{.TypeDef}}
-        err = runtime.BindStyledParameter("simple",{{.Explode}}, "{{.ParamName}}", cookie.Value, &value)
+        err = runtime.BindStyledParameter("simple",{{.Explode}}, "{{.ParamName}}", cookie, &value)
         if err != nil {
             siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter {{.ParamName}}: %s", err), http.StatusBadRequest)
             return
@@ -170,11 +170,15 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *gin.Context) {
         return
       }
       {{- end}}
+      }
     {{end}}
   {{end}}
 
   for _, middleware := range siw.HandlerMiddlewares {
     middleware(c)
+    if c.IsAborted() {
+      return
+    }
   }
 
   siw.Handler.{{.OperationId}}(c{{genParamNames .PathParams}}{{if .RequiresParamObject}}, params{{end}})
diff --git a/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl b/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl
index a72713b..1360891 100644
--- a/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl
+++ b/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl
@@ -40,7 +40,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ
   {{end}}
 
 {{range .SecurityDefinitions}}
-  ctx = context.WithValue(ctx, {{.ProviderName | ucFirst}}Scopes, {{toStringArray .Scopes}})
+  ctx = context.WithValue(ctx, {{.ProviderName | sanitizeGoIdentity | ucFirst}}Scopes, {{toStringArray .Scopes}})
 {{end}}
 
   {{if .RequiresParamObject}}
@@ -177,9 +177,15 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ
     siw.Handler.{{.OperationId}}(w, r{{genParamNames .PathParams}}{{if .RequiresParamObject}}, params{{end}})
 }
 
+  {{if opts.Compatibility.ApplyGorillaMiddlewareFirstToLast}}
+  for i := len(siw.HandlerMiddlewares) -1; i >= 0; i-- {
+    handler = siw.HandlerMiddlewares[i](handler)
+  }
+  {{else}}
   for _, middleware := range siw.HandlerMiddlewares {
     handler = middleware(handler)
   }
+  {{end}}
 
   handler(w, r.WithContext(ctx))
 }
@@ -253,4 +259,3 @@ type TooManyValuesForParamError struct {
 func (e *TooManyValuesForParamError) Error() string {
     return fmt.Sprintf("Expected one value for %s, got %d", e.ParamName, e.Count)
 }
-
diff --git a/pkg/codegen/templates/strict/strict-echo.tmpl b/pkg/codegen/templates/strict/strict-echo.tmpl
index c858c09..4bd6aec 100644
--- a/pkg/codegen/templates/strict/strict-echo.tmpl
+++ b/pkg/codegen/templates/strict/strict-echo.tmpl
@@ -18,8 +18,7 @@ type strictHandler struct {
         var request {{$opid | ucFirst}}RequestObject
 
         {{range .PathParams -}}
-            {{$varName := .GoVariableName -}}
-            request.{{$varName | ucFirst}} = {{$varName}}
+            request.{{.GoName}} = {{.GoVariableName}}
         {{end -}}
 
         {{if .RequiresParamObject -}}
diff --git a/pkg/codegen/templates/strict/strict-gin.tmpl b/pkg/codegen/templates/strict/strict-gin.tmpl
index 8097e28..9622fb2 100644
--- a/pkg/codegen/templates/strict/strict-gin.tmpl
+++ b/pkg/codegen/templates/strict/strict-gin.tmpl
@@ -18,8 +18,7 @@ type strictHandler struct {
         var request {{$opid | ucFirst}}RequestObject
 
         {{range .PathParams -}}
-            {{$varName := .GoVariableName -}}
-            request.{{$varName | ucFirst}} = {{$varName}}
+            request.{{.GoName}} = {{.GoVariableName}}
         {{end -}}
 
         {{if .RequiresParamObject -}}
diff --git a/pkg/codegen/templates/strict/strict-http.tmpl b/pkg/codegen/templates/strict/strict-http.tmpl
index b1d2e9d..d04503d 100644
--- a/pkg/codegen/templates/strict/strict-http.tmpl
+++ b/pkg/codegen/templates/strict/strict-http.tmpl
@@ -35,8 +35,7 @@ type strictHandler struct {
         var request {{$opid | ucFirst}}RequestObject
 
         {{range .PathParams -}}
-            {{$varName := .GoVariableName -}}
-            request.{{$varName | ucFirst}} = {{$varName}}
+            request.{{.GoName}} = {{.GoVariableName}}
         {{end -}}
 
         {{if .RequiresParamObject -}}
diff --git a/pkg/codegen/templates/union-and-additional-properties.tmpl b/pkg/codegen/templates/union-and-additional-properties.tmpl
new file mode 100644
index 0000000..79b4c67
--- /dev/null
+++ b/pkg/codegen/templates/union-and-additional-properties.tmpl
@@ -0,0 +1,72 @@
+{{range .Types}}
+
+{{$addType := .Schema.AdditionalPropertiesType.TypeDecl}}
+{{$typeName := .TypeName -}}
+{{$discriminator := .Schema.Discriminator}}
+{{$properties := .Schema.Properties -}}
+
+// Override default JSON handling for {{.TypeName}} to handle AdditionalProperties and union
+func (a *{{.TypeName}}) UnmarshalJSON(b []byte) error {
+    err := a.union.UnmarshalJSON(b)
+    if err != nil {
+        return err
+    }
+    object := make(map[string]json.RawMessage)
+	err = json.Unmarshal(b, &object)
+	if err != nil {
+		return err
+	}
+{{range .Schema.Properties}}
+    if raw, found := object["{{.JsonFieldName}}"]; found {
+        err = json.Unmarshal(raw, &a.{{.GoFieldName}})
+        if err != nil {
+            return fmt.Errorf("error reading '{{.JsonFieldName}}': %w", err)
+        }
+        delete(object, "{{.JsonFieldName}}")
+    }
+{{end}}
+    if len(object) != 0 {
+        a.AdditionalProperties = make(map[string]{{$addType}})
+        for fieldName, fieldBuf := range object {
+            var fieldVal {{$addType}}
+            err := json.Unmarshal(fieldBuf, &fieldVal)
+            if err != nil {
+                return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err)
+            }
+            a.AdditionalProperties[fieldName] = fieldVal
+        }
+    }
+	return nil
+}
+
+// Override default JSON handling for {{.TypeName}} to handle AdditionalProperties and union
+func (a {{.TypeName}}) MarshalJSON() ([]byte, error) {
+    var err error
+    b, err := a.union.MarshalJSON()
+    if err != nil {
+        return nil, err
+    }
+    object := make(map[string]json.RawMessage)
+    if a.union != nil {
+        err = json.Unmarshal(b, &object)
+        if err != nil {
+            return nil, err
+        }
+    }
+{{range .Schema.Properties}}
+{{if not .Required}}if a.{{.GoFieldName}} != nil { {{end}}
+    object["{{.JsonFieldName}}"], err = json.Marshal(a.{{.GoFieldName}})
+    if err != nil {
+        return nil, fmt.Errorf("error marshaling '{{.JsonFieldName}}': %w", err)
+    }
+{{if not .Required}} }{{end}}
+{{end}}
+    for fieldName, field := range a.AdditionalProperties {
+		object[fieldName], err = json.Marshal(field)
+		if err != nil {
+			return nil, fmt.Errorf("error marshaling '%s': %w", fieldName, err)
+		}
+	}
+	return json.Marshal(object)
+}
+{{end}}
diff --git a/pkg/codegen/templates/union.tmpl b/pkg/codegen/templates/union.tmpl
index b758a82..8bb34a2 100644
--- a/pkg/codegen/templates/union.tmpl
+++ b/pkg/codegen/templates/union.tmpl
@@ -53,7 +53,7 @@
               return err
             }
 
-            merged, err := runtime.JsonMerge(b, t.union)
+            merged, err := runtime.JsonMerge(t.union, b)
             t.union = merged
             return err
         }
@@ -86,6 +86,8 @@
         {{end}}
     {{end}}
 
+    {{if not .Schema.HasAdditionalProperties}}
+
     func (t {{.TypeName}}) MarshalJSON() ([]byte, error) {
         b, err := t.union.MarshalJSON()
         {{if ne 0 (len .Schema.Properties) -}}
@@ -134,4 +136,5 @@
         {{end -}}
         return err
     }
+    {{end}}
 {{end}}
diff --git a/pkg/codegen/utils.go b/pkg/codegen/utils.go
index 4339858..c386cd3 100644
--- a/pkg/codegen/utils.go
+++ b/pkg/codegen/utils.go
@@ -14,7 +14,6 @@
 package codegen
 
 import (
-	"encoding/json"
 	"fmt"
 	"go/token"
 	"net/url"
@@ -34,7 +33,7 @@ var (
 )
 
 func init() {
-	pathParamRE = regexp.MustCompile("{[.;?]?([^{}*]+)\\*?}")
+	pathParamRE = regexp.MustCompile(`{[.;?]?([^{}*]+)\*?}`)
 
 	predeclaredIdentifiers := []string{
 		// Types
@@ -291,6 +290,23 @@ func StringInArray(str string, array []string) bool {
 	return false
 }
 
+// RefPathToObjName returns the name of referenced object without changes.
+//
+//	#/components/schemas/Foo -> Foo
+//	#/components/parameters/Bar -> Bar
+//	#/components/responses/baz_baz -> baz_baz
+//	document.json#/Foo -> Foo
+//	http://deepmap.com/schemas/document.json#/objObj -> objObj
+//
+// Does not check refPath correctness.
+func RefPathToObjName(refPath string) string {
+	parts := strings.Split(refPath, "/")
+	if len(parts) > 0 {
+		return parts[len(parts)-1]
+	}
+	return ""
+}
+
 // RefPathToGoType takes a $ref value and converts it to a Go typename.
 // #/components/schemas/Foo -> Foo
 // #/components/parameters/Bar -> Bar
@@ -554,13 +570,17 @@ func SanitizeGoIdentity(str string) string {
 
 // SanitizeEnumNames fixes illegal chars in the enum names
 // and removes duplicates
-func SanitizeEnumNames(enumNames []string) map[string]string {
-	dupCheck := make(map[string]int, len(enumNames))
-	deDup := make([]string, 0, len(enumNames))
-
-	for _, n := range enumNames {
+func SanitizeEnumNames(enumNames, enumValues []string) map[string]string {
+	dupCheck := make(map[string]int, len(enumValues))
+	deDup := make([][]string, 0, len(enumValues))
+
+	for i, v := range enumValues {
+		n := v
+		if i < len(enumNames) {
+			n = enumNames[i]
+		}
 		if _, dup := dupCheck[n]; !dup {
-			deDup = append(deDup, n)
+			deDup = append(deDup, []string{n, v})
 		}
 		dupCheck[n] = 0
 	}
@@ -568,13 +588,14 @@ func SanitizeEnumNames(enumNames []string) map[string]string {
 	dupCheck = make(map[string]int, len(deDup))
 	sanitizedDeDup := make(map[string]string, len(deDup))
 
-	for _, n := range deDup {
+	for _, p := range deDup {
+		n, v := p[0], p[1]
 		sanitized := SanitizeGoIdentity(SchemaNameToTypeName(n))
 
 		if _, dup := dupCheck[sanitized]; !dup {
-			sanitizedDeDup[sanitized] = n
+			sanitizedDeDup[sanitized] = v
 		} else {
-			sanitizedDeDup[sanitized+strconv.Itoa(dupCheck[sanitized])] = n
+			sanitizedDeDup[sanitized+strconv.Itoa(dupCheck[sanitized])] = v
 		}
 		dupCheck[sanitized]++
 	}
@@ -641,11 +662,11 @@ func SchemaNameToTypeName(name string) string {
 // you must specify an additionalProperties type
 // If additionalProperties it true/false, this field will be non-nil.
 func SchemaHasAdditionalProperties(schema *openapi3.Schema) bool {
-	if schema.AdditionalPropertiesAllowed != nil && *schema.AdditionalPropertiesAllowed {
+	if schema.AdditionalProperties.Has != nil && *schema.AdditionalProperties.Has {
 		return true
 	}
 
-	if schema.AdditionalProperties != nil {
+	if schema.AdditionalProperties.Schema != nil {
 		return true
 	}
 	return false
@@ -673,6 +694,15 @@ func StringWithTypeNameToGoComment(in, typeName string) string {
 	return stringToGoCommentWithPrefix(in, typeName)
 }
 
+func DeprecationComment(reason string) string {
+	var content = "Deprecated:" // The colon is required at the end even without reason
+	if reason != "" {
+		content += fmt.Sprintf(" %s", reason)
+	}
+
+	return stringToGoCommentWithPrefix(content, "")
+}
+
 func stringToGoCommentWithPrefix(in, prefix string) string {
 	if len(in) == 0 || len(strings.TrimSpace(in)) == 0 { // ignore empty comment
 		return ""
@@ -835,15 +865,30 @@ func ParseGoImportExtension(v *openapi3.SchemaRef) (*goImport, error) {
 
 	goTypeImportExt := v.Value.Extensions[extPropGoImport]
 
-	if raw, ok := goTypeImportExt.(json.RawMessage); ok {
-		gi := goImport{}
-		if err := json.Unmarshal(raw, &gi); err != nil {
-			return nil, err
+	importI, ok := goTypeImportExt.(map[string]interface{})
+	if !ok {
+		return nil, fmt.Errorf("failed to convert type: %T", goTypeImportExt)
+	}
+
+	gi := goImport{}
+	// replicate the case-insensitive field mapping json.Unmarshal would do
+	for k, v := range importI {
+		if strings.EqualFold(k, "name") {
+			if vs, ok := v.(string); ok {
+				gi.Name = vs
+			} else {
+				return nil, fmt.Errorf("failed to convert type: %T", v)
+			}
+		} else if strings.EqualFold(k, "path") {
+			if vs, ok := v.(string); ok {
+				gi.Path = vs
+			} else {
+				return nil, fmt.Errorf("failed to convert type: %T", v)
+			}
 		}
-		return &gi, nil
 	}
 
-	return nil, nil
+	return &gi, nil
 }
 
 func MergeImports(dst, src map[string]goImport) {
diff --git a/pkg/gin-middleware/oapi_validate.go b/pkg/gin-middleware/oapi_validate.go
index e2097b6..3406134 100644
--- a/pkg/gin-middleware/oapi_validate.go
+++ b/pkg/gin-middleware/oapi_validate.go
@@ -18,6 +18,7 @@ import (
 	"context"
 	"errors"
 	"fmt"
+	"log"
 	"net/http"
 	"os"
 	"strings"
@@ -70,10 +71,16 @@ type Options struct {
 	ParamDecoder      openapi3filter.ContentParameterDecoder
 	UserData          interface{}
 	MultiErrorHandler MultiErrorHandler
+	// SilenceServersWarning allows silencing a warning for https://github.com/deepmap/oapi-codegen/issues/882 that reports when an OpenAPI spec has `spec.Servers != nil`
+	SilenceServersWarning bool
 }
 
 // OapiRequestValidatorWithOptions creates a validator from a swagger object, with validation options
 func OapiRequestValidatorWithOptions(swagger *openapi3.T, options *Options) gin.HandlerFunc {
+	if swagger.Servers != nil && (options == nil || options.SilenceServersWarning) {
+		log.Println("WARN: OapiRequestValidatorWithOptions called with an OpenAPI spec that has `Servers` set. This may lead to an HTTP 400 with `no matching operation was found` when sending a valid request, as the validator performs `Host` header validation. If you're expecting `Host` header validation, you can silence this warning by setting `Options.SilenceServersWarning = true`. See https://github.com/deepmap/oapi-codegen/issues/882 for more information.")
+	}
+
 	router, err := gorillamux.NewRouter(swagger)
 	if err != nil {
 		panic(err)
@@ -122,12 +129,12 @@ func ValidateRequestFromContext(c *gin.Context, router routers.Router, options *
 
 	// Pass the gin context into the request validator, so that any callbacks
 	// which it invokes make it available.
-	requestContext := context.WithValue(context.Background(), GinContextKey, c)
+	requestContext := context.WithValue(context.Background(), GinContextKey, c) //nolint:staticcheck
 
 	if options != nil {
 		validationInput.Options = &options.Options
 		validationInput.ParamDecoder = options.ParamDecoder
-		requestContext = context.WithValue(requestContext, UserDataKey, options.UserData)
+		requestContext = context.WithValue(requestContext, UserDataKey, options.UserData) //nolint:staticcheck
 	}
 
 	err = openapi3filter.ValidateRequest(requestContext, validationInput)
diff --git a/pkg/middleware/oapi_validate.go b/pkg/middleware/oapi_validate.go
index 6a48a49..0318d29 100644
--- a/pkg/middleware/oapi_validate.go
+++ b/pkg/middleware/oapi_validate.go
@@ -18,6 +18,7 @@ import (
 	"context"
 	"errors"
 	"fmt"
+	"log"
 	"net/http"
 	"os"
 	"strings"
@@ -73,10 +74,16 @@ type Options struct {
 	UserData          interface{}
 	Skipper           echomiddleware.Skipper
 	MultiErrorHandler MultiErrorHandler
+	// SilenceServersWarning allows silencing a warning for https://github.com/deepmap/oapi-codegen/issues/882 that reports when an OpenAPI spec has `spec.Servers != nil`
+	SilenceServersWarning bool
 }
 
 // OapiRequestValidatorWithOptions creates a validator from a swagger object, with validation options
 func OapiRequestValidatorWithOptions(swagger *openapi3.T, options *Options) echo.MiddlewareFunc {
+	if swagger.Servers != nil && (options == nil || options.SilenceServersWarning) {
+		log.Println("WARN: OapiRequestValidatorWithOptions called with an OpenAPI spec that has `Servers` set. This may lead to an HTTP 400 with `no matching operation was found` when sending a valid request, as the validator performs `Host` header validation. If you're expecting `Host` header validation, you can silence this warning by setting `Options.SilenceServersWarning = true`. See https://github.com/deepmap/oapi-codegen/issues/882 for more information.")
+	}
+
 	router, err := gorillamux.NewRouter(swagger)
 	if err != nil {
 		panic(err)
@@ -130,12 +137,12 @@ func ValidateRequestFromContext(ctx echo.Context, router routers.Router, options
 
 	// Pass the Echo context into the request validator, so that any callbacks
 	// which it invokes make it available.
-	requestContext := context.WithValue(context.Background(), EchoContextKey, ctx)
+	requestContext := context.WithValue(context.Background(), EchoContextKey, ctx) //nolint:staticcheck
 
 	if options != nil {
 		validationInput.Options = &options.Options
 		validationInput.ParamDecoder = options.ParamDecoder
-		requestContext = context.WithValue(requestContext, UserDataKey, options.UserData)
+		requestContext = context.WithValue(requestContext, UserDataKey, options.UserData) //nolint:staticcheck
 	}
 
 	err = openapi3filter.ValidateRequest(requestContext, validationInput)
diff --git a/pkg/runtime/bindform.go b/pkg/runtime/bindform.go
index b502f55..4f4fb76 100644
--- a/pkg/runtime/bindform.go
+++ b/pkg/runtime/bindform.go
@@ -99,7 +99,7 @@ func MarshalForm(ptr interface{}, encodings map[string]RequestBodyEncoding) (url
 		tag = strings.Split(tag, ",")[0] // extract the name of the tag
 		if encoding, ok := encodings[tag]; ok && encoding.ContentType != "" {
 			if strings.HasPrefix(encoding.ContentType, jsonContentType) {
-				if data, err := json.Marshal(field); err != nil {
+				if data, err := json.Marshal(field); err != nil { //nolint:staticcheck
 					return nil, err
 				} else {
 					result[tag] = append(result[tag], string(data))
@@ -131,7 +131,7 @@ func bindFormImpl(v reflect.Value, form map[string][]string, files map[string][]
 	case reflect.Slice:
 		if files := append(files[name], files[name+"[]"]...); len(files) != 0 {
 			if _, ok := v.Interface().([]types.File); ok {
-				result := make([]types.File, len(files), len(files))
+				result := make([]types.File, len(files))
 				for i, file := range files {
 					result[i].InitFromMultipart(file)
 				}
diff --git a/pkg/runtime/deepobject.go b/pkg/runtime/deepobject.go
index 54fc163..87e9dd9 100644
--- a/pkg/runtime/deepobject.go
+++ b/pkg/runtime/deepobject.go
@@ -242,9 +242,10 @@ func assignPathValues(dst interface{}, pathValues fieldOrValue) error {
 			tm, err = time.Parse(time.RFC3339Nano, pathValues.value)
 			if err != nil {
 				// Fall back to parsing it as a date.
-				tm, err = time.Parse(types.DateFormat, pathValues.value)
+				// TODO: why is this marked as an ineffassign?
+				tm, err = time.Parse(types.DateFormat, pathValues.value) //nolint:ineffassign,staticcheck
 				if err != nil {
-					return fmt.Errorf("error parsing tim as RFC3339 or 2006-01-02 time: %s", err)
+					return fmt.Errorf("error parsing '%s' as RFC3339 or 2006-01-02 time: %s", pathValues.value, err)
 				}
 				return fmt.Errorf("invalid date format: %w", err)
 			}
diff --git a/pkg/runtime/styleparam.go b/pkg/runtime/styleparam.go
index 8f7e129..06b2e25 100644
--- a/pkg/runtime/styleparam.go
+++ b/pkg/runtime/styleparam.go
@@ -27,6 +27,7 @@ import (
 	"time"
 
 	"github.com/deepmap/oapi-codegen/pkg/types"
+	"github.com/google/uuid"
 )
 
 // Parameter escaping works differently based on where a header is found
@@ -428,6 +429,10 @@ func primitiveToString(value interface{}) (string, error) {
 	case reflect.Struct:
 		// If input has Marshaler, such as object has Additional Property or AnyOf,
 		// We use this Marshaler and convert into interface{} before styling.
+		if v, ok := value.(uuid.UUID); ok {
+			output = v.String()
+			break
+		}
 		if m, ok := value.(json.Marshaler); ok {
 			buf, err := m.MarshalJSON()
 			if err != nil {


Test patch:
diff --git a/internal/test/all_of/doc.go b/internal/test/all_of/doc.go
index 0740268..0388e17 100644
--- a/internal/test/all_of/doc.go
+++ b/internal/test/all_of/doc.go
@@ -1,4 +1,4 @@
-package all_of
+package allof
 
 //go:generate go run github.com/deepmap/oapi-codegen/cmd/oapi-codegen --config=config1.yaml openapi.yaml
 //go:generate go run github.com/deepmap/oapi-codegen/cmd/oapi-codegen --config=config2.yaml openapi.yaml
diff --git a/internal/test/any_of/param/param.gen.go b/internal/test/any_of/param/param.gen.go
index 7de9459..07dd59b 100644
--- a/internal/test/any_of/param/param.gen.go
+++ b/internal/test/any_of/param/param.gen.go
@@ -70,7 +70,7 @@ func (t *Test) MergeTest0(v Test0) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -96,7 +96,7 @@ func (t *Test) MergeTest1(v Test1) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -132,7 +132,7 @@ func (t *Test2) MergeTest20(v Test20) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -158,7 +158,7 @@ func (t *Test2) MergeTest21(v Test21) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
diff --git a/internal/test/components/components.gen.go b/internal/test/components/components.gen.go
index d7e23d3..eb60975 100644
--- a/internal/test/components/components.gen.go
+++ b/internal/test/components/components.gen.go
@@ -170,7 +170,7 @@ type ObjectWithJsonField struct {
 	Value2 json.RawMessage `json:"value2,omitempty"`
 }
 
-// OneOfObject1 oneOf with references and no disciminator
+// OneOfObject1 oneOf with references and no discriminator
 type OneOfObject1 struct {
 	union json.RawMessage
 }
@@ -217,6 +217,13 @@ type OneOfObject120 = string
 // OneOfObject121 defines model for .
 type OneOfObject121 = float32
 
+// OneOfObject13 oneOf with fixed discriminator and other fields allowed
+type OneOfObject13 struct {
+	Type                 string                 `json:"type"`
+	AdditionalProperties map[string]interface{} `json:"-"`
+	union                json.RawMessage
+}
+
 // OneOfObject2 oneOf with inline elements
 type OneOfObject2 struct {
 	union json.RawMessage
@@ -249,7 +256,7 @@ type OneOfObject4 struct {
 	union         json.RawMessage
 }
 
-// OneOfObject5 oneOf with disciminator but no mapping
+// OneOfObject5 oneOf with discriminator but no mapping
 type OneOfObject5 struct {
 	union json.RawMessage
 }
@@ -259,6 +266,16 @@ type OneOfObject6 struct {
 	union json.RawMessage
 }
 
+// OneOfObject61 oneOf with discriminator and partial mapping
+type OneOfObject61 struct {
+	union json.RawMessage
+}
+
+// OneOfObject62 oneOf with snake_case discriminator and partial snake_case mapping
+type OneOfObject62 struct {
+	union json.RawMessage
+}
+
 // OneOfObject7 array of oneOf
 type OneOfObject7 = []OneOfObject7_Item
 
@@ -330,6 +347,12 @@ type SchemaObject struct {
 	WriteOnlyRequiredProp *int    `json:"writeOnlyRequiredProp,omitempty"`
 }
 
+// OneOfVariant51 defines model for one_of_variant51.
+type OneOfVariant51 struct {
+	Discriminator string `json:"discriminator"`
+	Id            int    `json:"id"`
+}
+
 // EnumParam1 defines model for EnumParam1.
 type EnumParam1 string
 
@@ -772,6 +795,23 @@ func (a AdditionalPropertiesObject4_Inner) MarshalJSON() ([]byte, error) {
 	return json.Marshal(object)
 }
 
+// Getter for additional properties for OneOfObject13. Returns the specified
+// element and whether it was found
+func (a OneOfObject13) Get(fieldName string) (value interface{}, found bool) {
+	if a.AdditionalProperties != nil {
+		value, found = a.AdditionalProperties[fieldName]
+	}
+	return
+}
+
+// Setter for additional properties for OneOfObject13
+func (a *OneOfObject13) Set(fieldName string, value interface{}) {
+	if a.AdditionalProperties == nil {
+		a.AdditionalProperties = make(map[string]interface{})
+	}
+	a.AdditionalProperties[fieldName] = value
+}
+
 // AsOneOfVariant4 returns the union data inside the AnyOfObject1 as a OneOfVariant4
 func (t AnyOfObject1) AsOneOfVariant4() (OneOfVariant4, error) {
 	var body OneOfVariant4
@@ -793,7 +833,7 @@ func (t *AnyOfObject1) MergeOneOfVariant4(v OneOfVariant4) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -819,7 +859,7 @@ func (t *AnyOfObject1) MergeOneOfVariant5(v OneOfVariant5) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -855,7 +895,7 @@ func (t *OneOfObject1) MergeOneOfVariant1(v OneOfVariant1) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -881,7 +921,7 @@ func (t *OneOfObject1) MergeOneOfVariant2(v OneOfVariant2) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -907,7 +947,7 @@ func (t *OneOfObject1) MergeOneOfVariant3(v OneOfVariant3) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -943,7 +983,7 @@ func (t *OneOfObject10) MergeOneOfObject100(v OneOfObject100) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -969,7 +1009,7 @@ func (t *OneOfObject10) MergeOneOfObject101(v OneOfObject101) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1067,7 +1107,7 @@ func (t *OneOfObject11_AdditionalProperties) MergeOneOfObject110(v OneOfObject11
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1093,7 +1133,7 @@ func (t *OneOfObject11_AdditionalProperties) MergeOneOfObject111(v OneOfObject11
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1119,7 +1159,7 @@ func (t *OneOfObject11_AdditionalProperties) MergeOneOfObject112(v OneOfObject11
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1155,7 +1195,7 @@ func (t *OneOfObject12) MergeOneOfObject120(v OneOfObject120) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1181,7 +1221,7 @@ func (t *OneOfObject12) MergeOneOfObject121(v OneOfObject121) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1207,7 +1247,7 @@ func (t *OneOfObject12) MergeOneOfVariant3(v OneOfVariant3) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1233,7 +1273,7 @@ func (t *OneOfObject12) MergeOneOfVariant4(v OneOfVariant4) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1248,6 +1288,89 @@ func (t *OneOfObject12) UnmarshalJSON(b []byte) error {
 	return err
 }
 
+// AsOneOfVariant1 returns the union data inside the OneOfObject13 as a OneOfVariant1
+func (t OneOfObject13) AsOneOfVariant1() (OneOfVariant1, error) {
+	var body OneOfVariant1
+	err := json.Unmarshal(t.union, &body)
+	return body, err
+}
+
+// FromOneOfVariant1 overwrites any union data inside the OneOfObject13 as the provided OneOfVariant1
+func (t *OneOfObject13) FromOneOfVariant1(v OneOfVariant1) error {
+	t.Type = "v1"
+
+	b, err := json.Marshal(v)
+	t.union = b
+	return err
+}
+
+// MergeOneOfVariant1 performs a merge with any union data inside the OneOfObject13, using the provided OneOfVariant1
+func (t *OneOfObject13) MergeOneOfVariant1(v OneOfVariant1) error {
+	t.Type = "v1"
+
+	b, err := json.Marshal(v)
+	if err != nil {
+		return err
+	}
+
+	merged, err := runtime.JsonMerge(t.union, b)
+	t.union = merged
+	return err
+}
+
+// AsOneOfVariant6 returns the union data inside the OneOfObject13 as a OneOfVariant6
+func (t OneOfObject13) AsOneOfVariant6() (OneOfVariant6, error) {
+	var body OneOfVariant6
+	err := json.Unmarshal(t.union, &body)
+	return body, err
+}
+
+// FromOneOfVariant6 overwrites any union data inside the OneOfObject13 as the provided OneOfVariant6
+func (t *OneOfObject13) FromOneOfVariant6(v OneOfVariant6) error {
+	t.Type = "v6"
+
+	b, err := json.Marshal(v)
+	t.union = b
+	return err
+}
+
+// MergeOneOfVariant6 performs a merge with any union data inside the OneOfObject13, using the provided OneOfVariant6
+func (t *OneOfObject13) MergeOneOfVariant6(v OneOfVariant6) error {
+	t.Type = "v6"
+
+	b, err := json.Marshal(v)
+	if err != nil {
+		return err
+	}
+
+	merged, err := runtime.JsonMerge(t.union, b)
+	t.union = merged
+	return err
+}
+
+func (t OneOfObject13) Discriminator() (string, error) {
+	var discriminator struct {
+		Discriminator string `json:"type"`
+	}
+	err := json.Unmarshal(t.union, &discriminator)
+	return discriminator.Discriminator, err
+}
+
+func (t OneOfObject13) ValueByDiscriminator() (interface{}, error) {
+	discriminator, err := t.Discriminator()
+	if err != nil {
+		return nil, err
+	}
+	switch discriminator {
+	case "v1":
+		return t.AsOneOfVariant1()
+	case "v6":
+		return t.AsOneOfVariant6()
+	default:
+		return nil, errors.New("unknown discriminator value: " + discriminator)
+	}
+}
+
 // AsOneOfObject20 returns the union data inside the OneOfObject2 as a OneOfObject20
 func (t OneOfObject2) AsOneOfObject20() (OneOfObject20, error) {
 	var body OneOfObject20
@@ -1269,7 +1392,7 @@ func (t *OneOfObject2) MergeOneOfObject20(v OneOfObject20) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1295,7 +1418,7 @@ func (t *OneOfObject2) MergeOneOfObject21(v OneOfObject21) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1321,7 +1444,7 @@ func (t *OneOfObject2) MergeOneOfObject22(v OneOfObject22) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1357,7 +1480,7 @@ func (t *OneOfObject3_Union) MergeOneOfVariant1(v OneOfVariant1) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1383,7 +1506,7 @@ func (t *OneOfObject3_Union) MergeOneOfVariant2(v OneOfVariant2) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1409,7 +1532,7 @@ func (t *OneOfObject3_Union) MergeOneOfVariant3(v OneOfVariant3) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1445,7 +1568,7 @@ func (t *OneOfObject4) MergeOneOfVariant1(v OneOfVariant1) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1471,7 +1594,7 @@ func (t *OneOfObject4) MergeOneOfVariant2(v OneOfVariant2) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1497,7 +1620,7 @@ func (t *OneOfObject4) MergeOneOfVariant3(v OneOfVariant3) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1555,6 +1678,7 @@ func (t OneOfObject5) AsOneOfVariant4() (OneOfVariant4, error) {
 
 // FromOneOfVariant4 overwrites any union data inside the OneOfObject5 as the provided OneOfVariant4
 func (t *OneOfObject5) FromOneOfVariant4(v OneOfVariant4) error {
+	v.Discriminator = "OneOfVariant4"
 	b, err := json.Marshal(v)
 	t.union = b
 	return err
@@ -1562,12 +1686,13 @@ func (t *OneOfObject5) FromOneOfVariant4(v OneOfVariant4) error {
 
 // MergeOneOfVariant4 performs a merge with any union data inside the OneOfObject5, using the provided OneOfVariant4
 func (t *OneOfObject5) MergeOneOfVariant4(v OneOfVariant4) error {
+	v.Discriminator = "OneOfVariant4"
 	b, err := json.Marshal(v)
 	if err != nil {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1581,6 +1706,7 @@ func (t OneOfObject5) AsOneOfVariant5() (OneOfVariant5, error) {
 
 // FromOneOfVariant5 overwrites any union data inside the OneOfObject5 as the provided OneOfVariant5
 func (t *OneOfObject5) FromOneOfVariant5(v OneOfVariant5) error {
+	v.Discriminator = "OneOfVariant5"
 	b, err := json.Marshal(v)
 	t.union = b
 	return err
@@ -1588,12 +1714,13 @@ func (t *OneOfObject5) FromOneOfVariant5(v OneOfVariant5) error {
 
 // MergeOneOfVariant5 performs a merge with any union data inside the OneOfObject5, using the provided OneOfVariant5
 func (t *OneOfObject5) MergeOneOfVariant5(v OneOfVariant5) error {
+	v.Discriminator = "OneOfVariant5"
 	b, err := json.Marshal(v)
 	if err != nil {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1606,6 +1733,21 @@ func (t OneOfObject5) Discriminator() (string, error) {
 	return discriminator.Discriminator, err
 }
 
+func (t OneOfObject5) ValueByDiscriminator() (interface{}, error) {
+	discriminator, err := t.Discriminator()
+	if err != nil {
+		return nil, err
+	}
+	switch discriminator {
+	case "OneOfVariant4":
+		return t.AsOneOfVariant4()
+	case "OneOfVariant5":
+		return t.AsOneOfVariant5()
+	default:
+		return nil, errors.New("unknown discriminator value: " + discriminator)
+	}
+}
+
 func (t OneOfObject5) MarshalJSON() ([]byte, error) {
 	b, err := t.union.MarshalJSON()
 	return b, err
@@ -1639,7 +1781,7 @@ func (t *OneOfObject6) MergeOneOfVariant4(v OneOfVariant4) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1667,7 +1809,7 @@ func (t *OneOfObject6) MergeOneOfVariant5(v OneOfVariant5) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1705,6 +1847,184 @@ func (t *OneOfObject6) UnmarshalJSON(b []byte) error {
 	return err
 }
 
+// AsOneOfVariant4 returns the union data inside the OneOfObject61 as a OneOfVariant4
+func (t OneOfObject61) AsOneOfVariant4() (OneOfVariant4, error) {
+	var body OneOfVariant4
+	err := json.Unmarshal(t.union, &body)
+	return body, err
+}
+
+// FromOneOfVariant4 overwrites any union data inside the OneOfObject61 as the provided OneOfVariant4
+func (t *OneOfObject61) FromOneOfVariant4(v OneOfVariant4) error {
+	v.Discriminator = "v4"
+	b, err := json.Marshal(v)
+	t.union = b
+	return err
+}
+
+// MergeOneOfVariant4 performs a merge with any union data inside the OneOfObject61, using the provided OneOfVariant4
+func (t *OneOfObject61) MergeOneOfVariant4(v OneOfVariant4) error {
+	v.Discriminator = "v4"
+	b, err := json.Marshal(v)
+	if err != nil {
+		return err
+	}
+
+	merged, err := runtime.JsonMerge(b, t.union)
+	t.union = merged
+	return err
+}
+
+// AsOneOfVariant5 returns the union data inside the OneOfObject61 as a OneOfVariant5
+func (t OneOfObject61) AsOneOfVariant5() (OneOfVariant5, error) {
+	var body OneOfVariant5
+	err := json.Unmarshal(t.union, &body)
+	return body, err
+}
+
+// FromOneOfVariant5 overwrites any union data inside the OneOfObject61 as the provided OneOfVariant5
+func (t *OneOfObject61) FromOneOfVariant5(v OneOfVariant5) error {
+	v.Discriminator = "OneOfVariant5"
+	b, err := json.Marshal(v)
+	t.union = b
+	return err
+}
+
+// MergeOneOfVariant5 performs a merge with any union data inside the OneOfObject61, using the provided OneOfVariant5
+func (t *OneOfObject61) MergeOneOfVariant5(v OneOfVariant5) error {
+	v.Discriminator = "OneOfVariant5"
+	b, err := json.Marshal(v)
+	if err != nil {
+		return err
+	}
+
+	merged, err := runtime.JsonMerge(b, t.union)
+	t.union = merged
+	return err
+}
+
+func (t OneOfObject61) Discriminator() (string, error) {
+	var discriminator struct {
+		Discriminator string `json:"discriminator"`
+	}
+	err := json.Unmarshal(t.union, &discriminator)
+	return discriminator.Discriminator, err
+}
+
+func (t OneOfObject61) ValueByDiscriminator() (interface{}, error) {
+	discriminator, err := t.Discriminator()
+	if err != nil {
+		return nil, err
+	}
+	switch discriminator {
+	case "OneOfVariant5":
+		return t.AsOneOfVariant5()
+	case "v4":
+		return t.AsOneOfVariant4()
+	default:
+		return nil, errors.New("unknown discriminator value: " + discriminator)
+	}
+}
+
+func (t OneOfObject61) MarshalJSON() ([]byte, error) {
+	b, err := t.union.MarshalJSON()
+	return b, err
+}
+
+func (t *OneOfObject61) UnmarshalJSON(b []byte) error {
+	err := t.union.UnmarshalJSON(b)
+	return err
+}
+
+// AsOneOfVariant4 returns the union data inside the OneOfObject62 as a OneOfVariant4
+func (t OneOfObject62) AsOneOfVariant4() (OneOfVariant4, error) {
+	var body OneOfVariant4
+	err := json.Unmarshal(t.union, &body)
+	return body, err
+}
+
+// FromOneOfVariant4 overwrites any union data inside the OneOfObject62 as the provided OneOfVariant4
+func (t *OneOfObject62) FromOneOfVariant4(v OneOfVariant4) error {
+	v.Discriminator = "variant_four"
+	b, err := json.Marshal(v)
+	t.union = b
+	return err
+}
+
+// MergeOneOfVariant4 performs a merge with any union data inside the OneOfObject62, using the provided OneOfVariant4
+func (t *OneOfObject62) MergeOneOfVariant4(v OneOfVariant4) error {
+	v.Discriminator = "variant_four"
+	b, err := json.Marshal(v)
+	if err != nil {
+		return err
+	}
+
+	merged, err := runtime.JsonMerge(b, t.union)
+	t.union = merged
+	return err
+}
+
+// AsOneOfVariant51 returns the union data inside the OneOfObject62 as a OneOfVariant51
+func (t OneOfObject62) AsOneOfVariant51() (OneOfVariant51, error) {
+	var body OneOfVariant51
+	err := json.Unmarshal(t.union, &body)
+	return body, err
+}
+
+// FromOneOfVariant51 overwrites any union data inside the OneOfObject62 as the provided OneOfVariant51
+func (t *OneOfObject62) FromOneOfVariant51(v OneOfVariant51) error {
+	v.Discriminator = "one_of_variant51"
+	b, err := json.Marshal(v)
+	t.union = b
+	return err
+}
+
+// MergeOneOfVariant51 performs a merge with any union data inside the OneOfObject62, using the provided OneOfVariant51
+func (t *OneOfObject62) MergeOneOfVariant51(v OneOfVariant51) error {
+	v.Discriminator = "one_of_variant51"
+	b, err := json.Marshal(v)
+	if err != nil {
+		return err
+	}
+
+	merged, err := runtime.JsonMerge(b, t.union)
+	t.union = merged
+	return err
+}
+
+func (t OneOfObject62) Discriminator() (string, error) {
+	var discriminator struct {
+		Discriminator string `json:"discriminator"`
+	}
+	err := json.Unmarshal(t.union, &discriminator)
+	return discriminator.Discriminator, err
+}
+
+func (t OneOfObject62) ValueByDiscriminator() (interface{}, error) {
+	discriminator, err := t.Discriminator()
+	if err != nil {
+		return nil, err
+	}
+	switch discriminator {
+	case "one_of_variant51":
+		return t.AsOneOfVariant51()
+	case "variant_four":
+		return t.AsOneOfVariant4()
+	default:
+		return nil, errors.New("unknown discriminator value: " + discriminator)
+	}
+}
+
+func (t OneOfObject62) MarshalJSON() ([]byte, error) {
+	b, err := t.union.MarshalJSON()
+	return b, err
+}
+
+func (t *OneOfObject62) UnmarshalJSON(b []byte) error {
+	err := t.union.UnmarshalJSON(b)
+	return err
+}
+
 // AsOneOfVariant1 returns the union data inside the OneOfObject7_Item as a OneOfVariant1
 func (t OneOfObject7_Item) AsOneOfVariant1() (OneOfVariant1, error) {
 	var body OneOfVariant1
@@ -1726,7 +2046,7 @@ func (t *OneOfObject7_Item) MergeOneOfVariant1(v OneOfVariant1) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1752,7 +2072,7 @@ func (t *OneOfObject7_Item) MergeOneOfVariant2(v OneOfVariant2) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1788,7 +2108,7 @@ func (t *OneOfObject8) MergeOneOfVariant1(v OneOfVariant1) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1814,7 +2134,7 @@ func (t *OneOfObject8) MergeOneOfVariant2(v OneOfVariant2) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1888,7 +2208,7 @@ func (t *OneOfObject9) MergeOneOfVariant1(v OneOfVariant1) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1918,7 +2238,7 @@ func (t *OneOfObject9) MergeOneOfVariant6(v OneOfVariant6) error {
 		return err
 	}
 
-	merged, err := runtime.JsonMerge(b, t.union)
+	merged, err := runtime.JsonMerge(t.union, b)
 	t.union = merged
 	return err
 }
@@ -1988,3 +2308,66 @@ func (t *OneOfObject9) UnmarshalJSON(b []byte) error {
 
 	return err
 }
+
+// Override default JSON handling for OneOfObject13 to handle AdditionalProperties and union
+func (a *OneOfObject13) UnmarshalJSON(b []byte) error {
+	err := a.union.UnmarshalJSON(b)
+	if err != nil {
+		return err
+	}
+	object := make(map[string]json.RawMessage)
+	err = json.Unmarshal(b, &object)
+	if err != nil {
+		return err
+	}
+
+	if raw, found := object["type"]; found {
+		err = json.Unmarshal(raw, &a.Type)
+		if err != nil {
+			return fmt.Errorf("error reading 'type': %w", err)
+		}
+		delete(object, "type")
+	}
+
+	if len(object) != 0 {
+		a.AdditionalProperties = make(map[string]interface{})
+		for fieldName, fieldBuf := range object {
+			var fieldVal interface{}
+			err := json.Unmarshal(fieldBuf, &fieldVal)
+			if err != nil {
+				return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err)
+			}
+			a.AdditionalProperties[fieldName] = fieldVal
+		}
+	}
+	return nil
+}
+
+// Override default JSON handling for OneOfObject13 to handle AdditionalProperties and union
+func (a OneOfObject13) MarshalJSON() ([]byte, error) {
+	var err error
+	b, err := a.union.MarshalJSON()
+	if err != nil {
+		return nil, err
+	}
+	object := make(map[string]json.RawMessage)
+	if a.union != nil {
+		err = json.Unmarshal(b, &object)
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	object["type"], err = json.Marshal(a.Type)
+	if err != nil {
+		return nil, fmt.Errorf("error marshaling 'type': %w", err)
+	}
+
+	for fieldName, field := range a.AdditionalProperties {
+		object[fieldName], err = json.Marshal(field)
+		if err != nil {
+			return nil, fmt.Errorf("error marshaling '%s': %w", fieldName, err)
+		}
+	}
+	return json.Marshal(object)
+}
diff --git a/internal/test/components/components.yaml b/internal/test/components/components.yaml
index 79e3857..24fdf77 100644
--- a/internal/test/components/components.yaml
+++ b/internal/test/components/components.yaml
@@ -208,7 +208,7 @@ components:
         additionalProperties:
           $ref: '#/components/schemas/SchemaObject'
     OneOfObject1:
-      description: oneOf with references and no disciminator
+      description: oneOf with references and no discriminator
       oneOf:
         - $ref: '#/components/schemas/OneOfVariant1'
         - $ref: '#/components/schemas/OneOfVariant2'
@@ -244,7 +244,7 @@ components:
         - $ref: '#/components/schemas/OneOfVariant2'
         - $ref: '#/components/schemas/OneOfVariant3'
     OneOfObject5:
-      description: oneOf with disciminator but no mapping
+      description: oneOf with discriminator but no mapping
       oneOf:
         - $ref: '#/components/schemas/OneOfVariant4'
         - $ref: '#/components/schemas/OneOfVariant5'
@@ -260,6 +260,24 @@ components:
         mapping:
           v4: '#/components/schemas/OneOfVariant4'
           v5: '#/components/schemas/OneOfVariant5'
+    OneOfObject61:
+      description: oneOf with discriminator and partial mapping
+      oneOf:
+        - $ref: '#/components/schemas/OneOfVariant4'
+        - $ref: '#/components/schemas/OneOfVariant5'
+      discriminator:
+        propertyName: discriminator
+        mapping:
+          v4: '#/components/schemas/OneOfVariant4'
+    OneOfObject62:
+      description: oneOf with snake_case discriminator and partial snake_case mapping
+      oneOf:
+        - $ref: '#/components/schemas/OneOfVariant4'
+        - $ref: '#/components/schemas/one_of_variant51'
+      discriminator:
+        propertyName: discriminator
+        mapping:
+          variant_four: '#/components/schemas/OneOfVariant4'
     OneOfObject7:
       description: array of oneOf
       type: array
@@ -325,6 +343,23 @@ components:
         - oneOf:
             - $ref: '#/components/schemas/OneOfVariant3'
             - $ref: '#/components/schemas/OneOfVariant4'
+    OneOfObject13:
+      description: oneOf with fixed discriminator and other fields allowed
+      type: object
+      properties:
+        type:
+          type: string
+      oneOf:
+        - $ref: '#/components/schemas/OneOfVariant1'
+        - $ref: '#/components/schemas/OneOfVariant6'
+      discriminator:
+        propertyName: type
+        mapping:
+          v1: '#/components/schemas/OneOfVariant1'
+          v6: '#/components/schemas/OneOfVariant6'
+      required:
+        - type
+      additionalProperties: true
     AnyOfObject1:
       description: simple anyOf case
       anyOf:
@@ -363,6 +398,16 @@ components:
       required:
         - discriminator
         - id
+    one_of_variant51:
+      type: object
+      properties:
+        discriminator:
+          type: string
+        id:
+          type: integer
+      required:
+        - discriminator
+        - id
     OneOfVariant6:
       type: object
       properties:
diff --git a/internal/test/components/components_test.go b/internal/test/components/components_test.go
index a6fbbfd..7810ea2 100644
--- a/internal/test/components/components_test.go
+++ b/internal/test/components/components_test.go
@@ -5,18 +5,12 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func assertJsonEqual(t *testing.T, j1 []byte, j2 []byte) {
-	var v1, v2 interface{}
-
-	err := json.Unmarshal(j1, &v1)
-	assert.NoError(t, err)
-
-	err = json.Unmarshal(j2, &v2)
-	assert.NoError(t, err)
-
-	assert.EqualValues(t, v1, v2)
+	t.Helper()
+	assert.JSONEq(t, string(j1), string(j2))
 }
 
 func TestRawJSON(t *testing.T) {
@@ -87,7 +81,7 @@ func TestOneOf(t *testing.T) {
 	assert.NoError(t, err)
 	v2, err := dst.AsOneOfVariant2()
 	assert.NoError(t, err)
-	assert.Equal(t, OneOfVariant2([]int{1, 2, 3}), v2)
+	assert.Equal(t, []int{1, 2, 3}, v2)
 
 	err = json.Unmarshal([]byte(variant3), &dst)
 	assert.NoError(t, err)
@@ -151,6 +145,117 @@ func TestOneOfWithDiscriminator(t *testing.T) {
 	assertJsonEqual(t, []byte(variant5), marshaled)
 }
 
+func TestOneOfWithDiscriminator_PartialMapping(t *testing.T) {
+	const variant4 = `{"discriminator": "v4", "name": "123"}`
+	const variant5 = `{"discriminator": "OneOfVariant5", "id": 321}`
+	var dst OneOfObject61
+
+	err := json.Unmarshal([]byte(variant4), &dst)
+	assert.NoError(t, err)
+	discriminator, err := dst.Discriminator()
+	require.NoError(t, err)
+	assert.Equal(t, "v4", discriminator)
+	v4, err := dst.ValueByDiscriminator()
+	require.NoError(t, err)
+	assert.Equal(t, OneOfVariant4{Discriminator: "v4", Name: "123"}, v4)
+
+	err = json.Unmarshal([]byte(variant5), &dst)
+	require.NoError(t, err)
+	discriminator, err = dst.Discriminator()
+	require.NoError(t, err)
+	assert.Equal(t, "OneOfVariant5", discriminator)
+	v5, err := dst.ValueByDiscriminator()
+	require.NoError(t, err)
+	assert.Equal(t, OneOfVariant5{Discriminator: "OneOfVariant5", Id: 321}, v5)
+
+	// discriminator value will be filled by the generated code
+	err = dst.FromOneOfVariant4(OneOfVariant4{Name: "123"})
+	require.NoError(t, err)
+	marshaled, err := json.Marshal(dst)
+	require.NoError(t, err)
+	assertJsonEqual(t, []byte(variant4), marshaled)
+
+	err = dst.FromOneOfVariant5(OneOfVariant5{Id: 321})
+	require.NoError(t, err)
+	marshaled, err = json.Marshal(dst)
+	require.NoError(t, err)
+	assertJsonEqual(t, []byte(variant5), marshaled)
+}
+
+func TestOneOfWithDiscriminator_SchemaNameUsed(t *testing.T) {
+	const variant4 = `{"discriminator": "variant_four", "name": "789"}`
+	const variant51 = `{"discriminator": "one_of_variant51", "id": 987}`
+	var dst OneOfObject62
+
+	err := json.Unmarshal([]byte(variant4), &dst)
+	assert.NoError(t, err)
+	discriminator, err := dst.Discriminator()
+	require.NoError(t, err)
+	assert.Equal(t, "variant_four", discriminator)
+	v4, err := dst.ValueByDiscriminator()
+	require.NoError(t, err)
+	assert.Equal(t, OneOfVariant4{Discriminator: "variant_four", Name: "789"}, v4)
+
+	err = json.Unmarshal([]byte(variant51), &dst)
+	require.NoError(t, err)
+	discriminator, err = dst.Discriminator()
+	require.NoError(t, err)
+	assert.Equal(t, "one_of_variant51", discriminator)
+	v5, err := dst.ValueByDiscriminator()
+	require.NoError(t, err)
+	assert.Equal(t, OneOfVariant51{Discriminator: "one_of_variant51", Id: 987}, v5)
+
+	// discriminator value will be filled by the generated code
+	err = dst.FromOneOfVariant4(OneOfVariant4{Name: "789"})
+	require.NoError(t, err)
+	marshaled, err := json.Marshal(dst)
+	require.NoError(t, err)
+	assertJsonEqual(t, []byte(variant4), marshaled)
+
+	err = dst.FromOneOfVariant51(OneOfVariant51{Id: 987})
+	require.NoError(t, err)
+	marshaled, err = json.Marshal(dst)
+	require.NoError(t, err)
+	assertJsonEqual(t, []byte(variant51), marshaled)
+}
+
+func TestOneOfWithDiscriminator_FullImplicitMapping(t *testing.T) {
+	const variant4 = `{"discriminator": "OneOfVariant4", "name": "456"}`
+	const variant5 = `{"discriminator": "OneOfVariant5", "id": 654}`
+	var dst OneOfObject5
+
+	err := json.Unmarshal([]byte(variant4), &dst)
+	assert.NoError(t, err)
+	discriminator, err := dst.Discriminator()
+	require.NoError(t, err)
+	assert.Equal(t, "OneOfVariant4", discriminator)
+	v4, err := dst.ValueByDiscriminator()
+	require.NoError(t, err)
+	assert.Equal(t, OneOfVariant4{Discriminator: "OneOfVariant4", Name: "456"}, v4)
+
+	err = json.Unmarshal([]byte(variant5), &dst)
+	require.NoError(t, err)
+	discriminator, err = dst.Discriminator()
+	require.NoError(t, err)
+	assert.Equal(t, "OneOfVariant5", discriminator)
+	v5, err := dst.ValueByDiscriminator()
+	require.NoError(t, err)
+	assert.Equal(t, OneOfVariant5{Discriminator: "OneOfVariant5", Id: 654}, v5)
+
+	// discriminator value will be filled by the generated code
+	err = dst.FromOneOfVariant4(OneOfVariant4{Name: "456"})
+	require.NoError(t, err)
+	marshaled, err := json.Marshal(dst)
+	require.NoError(t, err)
+	assertJsonEqual(t, []byte(variant4), marshaled)
+
+	err = dst.FromOneOfVariant5(OneOfVariant5{Id: 654})
+	require.NoError(t, err)
+	marshaled, err = json.Marshal(dst)
+	require.NoError(t, err)
+	assertJsonEqual(t, []byte(variant5), marshaled)
+}
+
 func TestOneOfWithFixedProperties(t *testing.T) {
 	const variant1 = "{\"type\": \"v1\", \"name\": \"123\"}"
 	const variant6 = "{\"type\": \"v6\", \"values\": [1, 2, 3]}"
@@ -203,6 +308,34 @@ func TestAnyOf(t *testing.T) {
 	assert.Equal(t, OneOfVariant5{Discriminator: "all", Id: 456}, v5)
 }
 
+func TestOneOfWithAdditional(t *testing.T) {
+	x := OneOfObject13{
+		AdditionalProperties: map[string]interface{}{"x": "y"},
+	}
+	err := x.MergeOneOfVariant1(OneOfVariant1{Name: "test-name"})
+	require.NoError(t, err)
+	b, err := json.Marshal(x)
+	require.NoError(t, err)
+	assert.JSONEq(t, `{"x":"y", "name":"test-name", "type":"v1"}`, string(b))
+	var y OneOfObject13
+	err = json.Unmarshal(b, &y)
+	require.NoError(t, err)
+	assert.Equal(t, x.Type, y.Type)
+	xVariant, err := x.AsOneOfVariant1()
+	require.NoError(t, err)
+	yVariant, err := y.AsOneOfVariant1()
+	require.NoError(t, err)
+	assert.Equal(t, xVariant, yVariant)
+	xAdditional, ok := x.Get("x")
+	assert.True(t, ok)
+	yAdditional, ok := y.Get("x")
+	assert.True(t, ok)
+	assert.Equal(t, xAdditional, yAdditional)
+	b, err = json.Marshal(y)
+	require.NoError(t, err)
+	assert.JSONEq(t, `{"x":"y", "name":"test-name", "type":"v1"}`, string(b))
+}
+
 func TestMarshalWhenNoUnionValueSet(t *testing.T) {
 	const expected = `{}`
 
diff --git a/internal/test/externalref/imports_test.go b/internal/test/externalref/imports_test.go
index c3e326f..607def3 100644
--- a/internal/test/externalref/imports_test.go
+++ b/internal/test/externalref/imports_test.go
@@ -3,8 +3,8 @@ package externalref
 import (
 	"testing"
 
-	"github.com/deepmap/oapi-codegen/internal/test/externalref/packageA"
-	"github.com/deepmap/oapi-codegen/internal/test/externalref/packageB"
+	packageA "github.com/deepmap/oapi-codegen/internal/test/externalref/packageA"
+	packageB "github.com/deepmap/oapi-codegen/internal/test/externalref/packageB"
 	"github.com/stretchr/testify/require"
 )
 
diff --git a/internal/test/externalref/packageA/config.yaml b/internal/test/externalref/packageA/config.yaml
index cbd23be..03240de 100644
--- a/internal/test/externalref/packageA/config.yaml
+++ b/internal/test/externalref/packageA/config.yaml
@@ -1,4 +1,4 @@
-package: packageA
+package: packagea
 generate:
   models: true
   embedded-spec: true
diff --git a/internal/test/externalref/packageA/doc.go b/internal/test/externalref/packageA/doc.go
index 5054abe..8a7bb68 100644
--- a/internal/test/externalref/packageA/doc.go
+++ b/internal/test/externalref/packageA/doc.go
@@ -1,3 +1,3 @@
-package packageA
+package packagea
 
 //go:generate go run github.com/deepmap/oapi-codegen/cmd/oapi-codegen --config=config.yaml spec.yaml
diff --git a/internal/test/externalref/packageA/externalref.gen.go b/internal/test/externalref/packageA/externalref.gen.go
index 01505b1..1a4d648 100644
--- a/internal/test/externalref/packageA/externalref.gen.go
+++ b/internal/test/externalref/packageA/externalref.gen.go
@@ -1,7 +1,7 @@
-// Package packageA provides primitives to interact with the openapi HTTP API.
+// Package packagea provides primitives to interact with the openapi HTTP API.
 //
 // Code generated by github.com/deepmap/oapi-codegen version (devel) DO NOT EDIT.
-package packageA
+package packagea
 
 import (
 	"bytes"
diff --git a/internal/test/externalref/packageB/config.yaml b/internal/test/externalref/packageB/config.yaml
index 72752cd..748a188 100644
--- a/internal/test/externalref/packageB/config.yaml
+++ b/internal/test/externalref/packageB/config.yaml
@@ -1,4 +1,4 @@
-package: packageB
+package: packageb
 generate:
   models: true
   embedded-spec: true
diff --git a/internal/test/externalref/packageB/doc.go b/internal/test/externalref/packageB/doc.go
index fdee47d..73641da 100644
--- a/internal/test/externalref/packageB/doc.go
+++ b/internal/test/externalref/packageB/doc.go
@@ -1,3 +1,3 @@
-package packageB
+package packageb
 
 //go:generate go run github.com/deepmap/oapi-codegen/cmd/oapi-codegen --config=config.yaml spec.yaml
diff --git a/internal/test/externalref/packageB/externalref.gen.go b/internal/test/externalref/packageB/externalref.gen.go
index aa545f1..3e4fe05 100644
--- a/internal/test/externalref/packageB/externalref.gen.go
+++ b/internal/test/externalref/packageB/externalref.gen.go
@@ -1,7 +1,7 @@
-// Package packageB provides primitives to interact with the openapi HTTP API.
+// Package packageb provides primitives to interact with the openapi HTTP API.
 //
 // Code generated by github.com/deepmap/oapi-codegen version (devel) DO NOT EDIT.
-package packageB
+package packageb
 
 import (
 	"bytes"
diff --git a/internal/test/issues/issue-312/config.yaml b/internal/test/issues/issue-312/config.yaml
index f3d72fb..a0db7e9 100644
--- a/internal/test/issues/issue-312/config.yaml
+++ b/internal/test/issues/issue-312/config.yaml
@@ -1,4 +1,4 @@
-package: issue_312
+package: issue312
 generate:
   echo-server: true
   client: true
diff --git a/internal/test/issues/issue-312/doc.go b/internal/test/issues/issue-312/doc.go
index c27d53b..8eb982d 100644
--- a/internal/test/issues/issue-312/doc.go
+++ b/internal/test/issues/issue-312/doc.go
@@ -1,3 +1,3 @@
-package issue_312
+package issue312
 
 //go:generate go run github.com/deepmap/oapi-codegen/cmd/oapi-codegen --config=config.yaml spec.yaml
diff --git a/internal/test/issues/issue-312/issue.gen.go b/internal/test/issues/issue-312/issue.gen.go
index 0285217..c077475 100644
--- a/internal/test/issues/issue-312/issue.gen.go
+++ b/internal/test/issues/issue-312/issue.gen.go
@@ -1,7 +1,7 @@
-// Package issue_312 provides primitives to interact with the openapi HTTP API.
+// Package issue312 provides primitives to interact with the openapi HTTP API.
 //
 // Code generated by github.com/deepmap/oapi-codegen version (devel) DO NOT EDIT.
-package issue_312
+package issue312
 
 import (
 	"bytes"
diff --git a/internal/test/issues/issue-312/issue_test.go b/internal/test/issues/issue-312/issue_test.go
index 2bf46d8..23a1464 100644
--- a/internal/test/issues/issue-312/issue_test.go
+++ b/internal/test/issues/issue-312/issue_test.go
@@ -1,4 +1,4 @@
-package issue_312
+package issue312
 
 import (
 	"context"
@@ -26,7 +26,8 @@ func TestClient_WhenPathHasColon_RequestHasCorrectPath(t *testing.T) {
 		assert.Equal(t, "http://host/pets:validate", req.URL.String())
 	})
 
-	client.ValidatePetsWithResponse(context.Background(), ValidatePetsJSONRequestBody{
+	// TODO: this err should be checked, but it defaults to returning the "something went wrong", so we should refactor accordingly
+	_, _ = client.ValidatePetsWithResponse(context.Background(), ValidatePetsJSONRequestBody{
 		Names: []string{"fido"},
 	})
 	doer.AssertExpectations(t)
@@ -43,7 +44,8 @@ func TestClient_WhenPathHasId_RequestHasCorrectPath(t *testing.T) {
 		assert.Equal(t, "/pets/id", req.URL.Path)
 	})
 	petID := "id"
-	client.GetPetWithResponse(context.Background(), petID)
+	// TODO: this err should be checked, but it defaults to returning the "something went wrong", so we should refactor accordingly
+	_, _ = client.GetPetWithResponse(context.Background(), petID)
 	doer.AssertExpectations(t)
 }
 
@@ -58,7 +60,8 @@ func TestClient_WhenPathHasIdContainingReservedCharacter_RequestHasCorrectPath(t
 		assert.Equal(t, "http://host/pets/id1%2Fid2", req.URL.String())
 	})
 	petID := "id1/id2"
-	client.GetPetWithResponse(context.Background(), petID)
+	// TODO: this err should be checked, but it defaults to returning the "something went wrong", so we should refactor accordingly
+	_, _ = client.GetPetWithResponse(context.Background(), petID)
 	doer.AssertExpectations(t)
 }
 
diff --git a/internal/test/issues/issue-52/config.yaml b/internal/test/issues/issue-52/config.yaml
index 1aa56b1..8ea198f 100644
--- a/internal/test/issues/issue-52/config.yaml
+++ b/internal/test/issues/issue-52/config.yaml
@@ -1,4 +1,4 @@
-package: issue_52
+package: issue52
 generate:
   echo-server: true
   client: true
diff --git a/internal/test/issues/issue-52/doc.go b/internal/test/issues/issue-52/doc.go
index 2f19f47..f29e0e9 100644
--- a/internal/test/issues/issue-52/doc.go
+++ b/internal/test/issues/issue-52/doc.go
@@ -1,3 +1,3 @@
-package issue_52
+package issue52
 
 //go:generate go run github.com/deepmap/oapi-codegen/cmd/oapi-codegen --config=config.yaml spec.yaml
diff --git a/internal/test/issues/issue-52/issue.gen.go b/internal/test/issues/issue-52/issue.gen.go
index fde84ba..d3f1a23 100644
--- a/internal/test/issues/issue-52/issue.gen.go
+++ b/internal/test/issues/issue-52/issue.gen.go
@@ -1,7 +1,7 @@
-// Package issue_52 provides primitives to interact with the openapi HTTP API.
+// Package issue52 provides primitives to interact with the openapi HTTP API.
 //
 // Code generated by github.com/deepmap/oapi-codegen version (devel) DO NOT EDIT.
-package issue_52
+package issue52
 
 import (
 	"bytes"
diff --git a/internal/test/issues/issue-52/issue_test.go b/internal/test/issues/issue-52/issue_test.go
index 12edb76..0d90bf6 100644
--- a/internal/test/issues/issue-52/issue_test.go
+++ b/internal/test/issues/issue-52/issue_test.go
@@ -1,4 +1,4 @@
-package issue_52
+package issue52
 
 import (
 	_ "embed"
@@ -17,7 +17,7 @@ func TestIssue(t *testing.T) {
 	require.NoError(t, err)
 
 	opts := codegen.Configuration{
-		PackageName: "issue_52",
+		PackageName: "issue52",
 		Generate: codegen.GenerateOptions{
 			EchoServer:   true,
 			Client:       true,
diff --git a/internal/test/issues/issue-579/gen.go b/internal/test/issues/issue-579/gen.go
index a91277b..d34774f 100644
--- a/internal/test/issues/issue-579/gen.go
+++ b/internal/test/issues/issue-579/gen.go
@@ -1,3 +1,3 @@
-package issue_579
+package issue579
 
-//go:generate go run github.com/deepmap/oapi-codegen/cmd/oapi-codegen --package=issue_579 --generate=types,skip-prune --alias-types -o issue.gen.go spec.yaml
+//go:generate go run github.com/deepmap/oapi-codegen/cmd/oapi-codegen --package=issue579 --generate=types,skip-prune --alias-types -o issue.gen.go spec.yaml
diff --git a/internal/test/issues/issue-579/issue.gen.go b/internal/test/issues/issue-579/issue.gen.go
index 93cc60a..b7284ff 100644
--- a/internal/test/issues/issue-579/issue.gen.go
+++ b/internal/test/issues/issue-579/issue.gen.go
@@ -1,7 +1,7 @@
-// Package issue_579 provides primitives to interact with the openapi HTTP API.
+// Package issue579 provides primitives to interact with the openapi HTTP API.
 //
 // Code generated by github.com/deepmap/oapi-codegen version (devel) DO NOT EDIT.
-package issue_579
+package issue579
 
 import (
 	openapi_types "github.com/deepmap/oapi-codegen/pkg/types"
diff --git a/internal/test/issues/issue-579/issue_test.go b/internal/test/issues/issue-579/issue_test.go
index 4c1b901..7c92a42 100644
--- a/internal/test/issues/issue-579/issue_test.go
+++ b/internal/test/issues/issue-579/issue_test.go
@@ -1,4 +1,4 @@
-package issue_579
+package issue579
 
 import (
 	"encoding/json"
diff --git a/internal/test/issues/issue-958/config.yaml b/internal/test/issues/issue-958/config.yaml
new file mode 100644
index 0000000..1cf2e19
--- /dev/null
+++ b/internal/test/issues/issue-958/config.yaml
@@ -0,0 +1,8 @@
+package: issue958
+generate:
+  client: true
+output: issue.gen.go
+output-options:
+  skip-prune: true
+import-mapping:
+  ./pkga/spec.yaml: github.com/deepmap/oapi-codegen/internal/test/issues/issue-958/pkga
diff --git a/internal/test/issues/issue-958/doc.go b/internal/test/issues/issue-958/doc.go
new file mode 100644
index 0000000..3be1f22
--- /dev/null
+++ b/internal/test/issues/issue-958/doc.go
@@ -0,0 +1,3 @@
+package issue958
+
+//go:generate go run github.com/deepmap/oapi-codegen/cmd/oapi-codegen --config=config.yaml spec.yaml
diff --git a/internal/test/issues/issue-958/issue.gen.go b/internal/test/issues/issue-958/issue.gen.go
new file mode 100644
index 0000000..088b3f6
--- /dev/null
+++ b/internal/test/issues/issue-958/issue.gen.go
@@ -0,0 +1,234 @@
+// Package issue958 provides primitives to interact with the openapi HTTP API.
+//
+// Code generated by github.com/deepmap/oapi-codegen version (devel) DO NOT EDIT.
+package issue958
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"io"
+	"net/http"
+	"net/url"
+	"strings"
+)
+
+// RequestEditorFn  is the function signature for the RequestEditor callback function
+type RequestEditorFn func(ctx context.Context, req *http.Request) error
+
+// Doer performs HTTP requests.
+//
+// The standard http.Client implements this interface.
+type HttpRequestDoer interface {
+	Do(req *http.Request) (*http.Response, error)
+}
+
+// Client which conforms to the OpenAPI3 specification for this service.
+type Client struct {
+	// The endpoint of the server conforming to this interface, with scheme,
+	// https://api.deepmap.com for example. This can contain a path relative
+	// to the server, such as https://api.deepmap.com/dev-test, and all the
+	// paths in the swagger spec will be appended to the server.
+	Server string
+
+	// Doer for performing requests, typically a *http.Client with any
+	// customized settings, such as certificate chains.
+	Client HttpRequestDoer
+
+	// A list of callbacks for modifying requests which are generated before sending over
+	// the network.
+	RequestEditors []RequestEditorFn
+}
+
+// ClientOption allows setting custom parameters during construction
+type ClientOption func(*Client) error
+
+// Creates a new Client, with reasonable defaults
+func NewClient(server string, opts ...ClientOption) (*Client, error) {
+	// create a client with sane default values
+	client := Client{
+		Server: server,
+	}
+	// mutate client and add all optional params
+	for _, o := range opts {
+		if err := o(&client); err != nil {
+			return nil, err
+		}
+	}
+	// ensure the server URL always has a trailing slash
+	if !strings.HasSuffix(client.Server, "/") {
+		client.Server += "/"
+	}
+	// create httpClient, if not already present
+	if client.Client == nil {
+		client.Client = &http.Client{}
+	}
+	return &client, nil
+}
+
+// WithHTTPClient allows overriding the default Doer, which is
+// automatically created using http.Client. This is useful for tests.
+func WithHTTPClient(doer HttpRequestDoer) ClientOption {
+	return func(c *Client) error {
+		c.Client = doer
+		return nil
+	}
+}
+
+// WithRequestEditorFn allows setting up a callback function, which will be
+// called right before sending the request. This can be used to mutate the request.
+func WithRequestEditorFn(fn RequestEditorFn) ClientOption {
+	return func(c *Client) error {
+		c.RequestEditors = append(c.RequestEditors, fn)
+		return nil
+	}
+}
+
+// The interface specification for the client above.
+type ClientInterface interface {
+	// ExampleGet request
+	ExampleGet(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error)
+}
+
+func (c *Client) ExampleGet(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) {
+	req, err := NewExampleGetRequest(c.Server)
+	if err != nil {
+		return nil, err
+	}
+	req = req.WithContext(ctx)
+	if err := c.applyEditors(ctx, req, reqEditors); err != nil {
+		return nil, err
+	}
+	return c.Client.Do(req)
+}
+
+// NewExampleGetRequest generates requests for ExampleGet
+func NewExampleGetRequest(server string) (*http.Request, error) {
+	var err error
+
+	serverURL, err := url.Parse(server)
+	if err != nil {
+		return nil, err
+	}
+
+	operationPath := fmt.Sprintf("/example")
+	if operationPath[0] == '/' {
+		operationPath = "." + operationPath
+	}
+
+	queryURL, err := serverURL.Parse(operationPath)
+	if err != nil {
+		return nil, err
+	}
+
+	req, err := http.NewRequest("GET", queryURL.String(), nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return req, nil
+}
+
+func (c *Client) applyEditors(ctx context.Context, req *http.Request, additionalEditors []RequestEditorFn) error {
+	for _, r := range c.RequestEditors {
+		if err := r(ctx, req); err != nil {
+			return err
+		}
+	}
+	for _, r := range additionalEditors {
+		if err := r(ctx, req); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// ClientWithResponses builds on ClientInterface to offer response payloads
+type ClientWithResponses struct {
+	ClientInterface
+}
+
+// NewClientWithResponses creates a new ClientWithResponses, which wraps
+// Client with return type handling
+func NewClientWithResponses(server string, opts ...ClientOption) (*ClientWithResponses, error) {
+	client, err := NewClient(server, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &ClientWithResponses{client}, nil
+}
+
+// WithBaseURL overrides the baseURL.
+func WithBaseURL(baseURL string) ClientOption {
+	return func(c *Client) error {
+		newBaseURL, err := url.Parse(baseURL)
+		if err != nil {
+			return err
+		}
+		c.Server = newBaseURL.String()
+		return nil
+	}
+}
+
+// ClientWithResponsesInterface is the interface specification for the client with responses above.
+type ClientWithResponsesInterface interface {
+	// ExampleGet request
+	ExampleGetWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*ExampleGetResponse, error)
+}
+
+type ExampleGetResponse struct {
+	Body         []byte
+	HTTPResponse *http.Response
+	JSON200      *Document
+}
+
+// Status returns HTTPResponse.Status
+func (r ExampleGetResponse) Status() string {
+	if r.HTTPResponse != nil {
+		return r.HTTPResponse.Status
+	}
+	return http.StatusText(0)
+}
+
+// StatusCode returns HTTPResponse.StatusCode
+func (r ExampleGetResponse) StatusCode() int {
+	if r.HTTPResponse != nil {
+		return r.HTTPResponse.StatusCode
+	}
+	return 0
+}
+
+// ExampleGetWithResponse request returning *ExampleGetResponse
+func (c *ClientWithResponses) ExampleGetWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*ExampleGetResponse, error) {
+	rsp, err := c.ExampleGet(ctx, reqEditors...)
+	if err != nil {
+		return nil, err
+	}
+	return ParseExampleGetResponse(rsp)
+}
+
+// ParseExampleGetResponse parses an HTTP response from a ExampleGetWithResponse call
+func ParseExampleGetResponse(rsp *http.Response) (*ExampleGetResponse, error) {
+	bodyBytes, err := io.ReadAll(rsp.Body)
+	defer func() { _ = rsp.Body.Close() }()
+	if err != nil {
+		return nil, err
+	}
+
+	response := &ExampleGetResponse{
+		Body:         bodyBytes,
+		HTTPResponse: rsp,
+	}
+
+	switch {
+	case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200:
+		var dest Document
+		if err := json.Unmarshal(bodyBytes, &dest); err != nil {
+			return nil, err
+		}
+		response.JSON200 = &dest
+
+	}
+
+	return response, nil
+}
diff --git a/internal/test/issues/issue-958/pkga/config.yaml b/internal/test/issues/issue-958/pkga/config.yaml
new file mode 100644
index 0000000..25f3610
--- /dev/null
+++ b/internal/test/issues/issue-958/pkga/config.yaml
@@ -0,0 +1,9 @@
+package: pkga
+generate:
+  echo-server: false
+  client: false
+  models: true
+  embedded-spec: false
+output-options:
+  skip-prune: true
+output: responses.gen.go
diff --git a/internal/test/issues/issue-958/pkga/doc.go b/internal/test/issues/issue-958/pkga/doc.go
new file mode 100644
index 0000000..92d00eb
--- /dev/null
+++ b/internal/test/issues/issue-958/pkga/doc.go
@@ -0,0 +1,3 @@
+package pkga
+
+//go:generate go run github.com/deepmap/oapi-codegen/cmd/oapi-codegen --config=config.yaml spec.yaml
diff --git a/internal/test/issues/issue-958/pkga/responses.gen.go b/internal/test/issues/issue-958/pkga/responses.gen.go
new file mode 100644
index 0000000..81d18b3
--- /dev/null
+++ b/internal/test/issues/issue-958/pkga/responses.gen.go
@@ -0,0 +1,21 @@
+// Package pkga provides primitives to interact with the openapi HTTP API.
+//
+// Code generated by github.com/deepmap/oapi-codegen version (devel) DO NOT EDIT.
+package pkga
+
+// ArrayValue defines model for ArrayValue.
+type ArrayValue = []Value
+
+// Document defines model for Document.
+type Document struct {
+	Fields *map[string]Value `json:"fields,omitempty"`
+}
+
+// Value defines model for Value.
+type Value struct {
+	ArrayValue  *ArrayValue `json:"arrayValue,omitempty"`
+	StringValue *string     `json:"stringValue,omitempty"`
+}
+
+// N200 defines model for 200.
+type N200 = Document
diff --git a/internal/test/issues/issue-958/pkga/spec.yaml b/internal/test/issues/issue-958/pkga/spec.yaml
new file mode 100644
index 0000000..3fc5ea0
--- /dev/null
+++ b/internal/test/issues/issue-958/pkga/spec.yaml
@@ -0,0 +1,45 @@
+openapi: 3.0.2
+info:
+  version: '0.0.1'
+  title: example
+  description: |
+    Make sure client with responses can reference external responses
+paths:
+  /example:
+    get:
+      operationId: exampleGet
+      responses:
+        '200':
+          description: "OK"
+          content:
+            'application/json':
+              schema:
+                $ref: '#/components/schemas/Document'
+components:
+  responses:
+    200:
+      description: "OK"
+      content:
+        'application/json':
+          schema:
+            $ref: '#/components/schemas/Document'
+  schemas:
+    Document:
+      type: object
+      properties:
+        fields:
+          type: object
+          additionalProperties:
+            $ref: '#/components/schemas/Value'
+    Value:
+      type: object
+      properties:
+        stringValue:
+          type: string
+        arrayValue:
+          $ref: '#/components/schemas/ArrayValue'
+    ArrayValue:
+      type: array
+      items:
+        $ref: '#/components/schemas/Value'
+
diff --git a/internal/test/issues/issue-958/spec.yaml b/internal/test/issues/issue-958/spec.yaml
new file mode 100644
index 0000000..685ab4f
--- /dev/null
+++ b/internal/test/issues/issue-958/spec.yaml
@@ -0,0 +1,14 @@
+openapi: 3.0.2
+info:
+  version: '0.0.1'
+  title: example
+  description: |
+    Make sure client with responses can reference external responses
+paths:
+  /example:
+    get:
+      operationId: exampleGet
+      responses:
+        200:
+          $ref: "./pkga/spec.yaml#/components/responses/200"
+
diff --git a/internal/test/issues/issue-grab_import_names/config.yaml b/internal/test/issues/issue-grab_import_names/config.yaml
index 7327e2a..3248a48 100644
--- a/internal/test/issues/issue-grab_import_names/config.yaml
+++ b/internal/test/issues/issue-grab_import_names/config.yaml
@@ -1,4 +1,4 @@
-package: grab_import_names
+package: grabimportnames
 generate:
   echo-server: true
   client: true
diff --git a/internal/test/issues/issue-grab_import_names/doc.go b/internal/test/issues/issue-grab_import_names/doc.go
index 0762ddb..5c73385 100644
--- a/internal/test/issues/issue-grab_import_names/doc.go
+++ b/internal/test/issues/issue-grab_import_names/doc.go
@@ -1,3 +1,3 @@
-package grab_import_names
+package grabimportnames
 
 //go:generate go run github.com/deepmap/oapi-codegen/cmd/oapi-codegen --config=config.yaml spec.yaml
diff --git a/internal/test/issues/issue-grab_import_names/issue.gen.go b/internal/test/issues/issue-grab_import_names/issue.gen.go
index 275e6a7..b9904fc 100644
--- a/internal/test/issues/issue-grab_import_names/issue.gen.go
+++ b/internal/test/issues/issue-grab_import_names/issue.gen.go
@@ -1,7 +1,7 @@
-// Package grab_import_names provides primitives to interact with the openapi HTTP API.
+// Package grabimportnames provides primitives to interact with the openapi HTTP API.
 //
 // Code generated by github.com/deepmap/oapi-codegen version (devel) DO NOT EDIT.
-package grab_import_names
+package grabimportnames
 
 import (
 	"bytes"
@@ -363,12 +363,12 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
 // Base64 encoded, gzipped, json marshaled Swagger object
 var swaggerSpec = []string{
 
-	"H4sIAAAAAAAC/3yRQWv7MAzFv4rQ2aih/fM/5DjGxu67jTHcVG08YstY6mhX8t2HnZ7KulyERPTz03sX",
-	"HCRmSZxMsb/MDkPaC/YXtGATY49EhA6/uGiQhD121FGHs0PJnHwO2OOGOlqjw+xtrBRc7aUxDmy17FiH",
-	"ErItgAUomYuvk5cd9vjM9iTSEMVHNi6K/dvt5tYr//9HsD0bK8EwBoJBkvHJCHgYhYBLkaIE+2gEh++Q",
-	"CUazTBCE4FMlEVx1b6qKULEj+x0XdJh8rBcvSnQYOfrmxDnXsVoJ6YDz7G51XYkf9UclqDYQlGOyEJlg",
-	"2VOC1j4el7OX7jVEhmOZCE5xIjj7ON2V9eDLn7LeHRbWLEm5hbDuulqaQanl4HOewtCeX1Uv6uw+b3a/",
-	"BDe37ycAAP//wjdd4jYCAAA=",
+	"H4sIAAAAAAAC/3yRzWrrQAyFX0VoPSgmudyFl6W0dN9dKWXiKPEUzw+SUpIGv3uZcVahqTdCwvrm6JwL",
+	"hrTP2F/Qgk2MPRIROvxi0ZAT9thRRx3ODnPh5EvAHjfU0RodFm+j1t3VPjfGga2WHesgodgCWIC5sPg6",
+	"edlhj89sTzk3hPjIxqLYv91ubr3y/38E27OxEgxjIBhyMj4ZAQ9jJmCRLEqwj0Zw+A6FYDQrBCETfGpO",
+	"BFfdm6oiVOzIfseCDpOP9eJFiQ4jR9+cOJc6VpOQDjjP7lbXlfhRf1SCagOBHJOFyATLnhK09vG4nL10",
+	"ryEyHGUiOMWJ4OzjdFfWg5c/Zb07FNaSk3ILYd11tTSDUsvBlzKFoT2/ql7U2X3e7H4Jbm7fTwAAAP//",
+	"VfuleiYCAAA=",
 }
 
 // GetSwagger returns the content of the embedded swagger specification file
diff --git a/internal/test/issues/issue-grab_import_names/issue_test.go b/internal/test/issues/issue-grab_import_names/issue_test.go
index c00b42d..8dffcd2 100644
--- a/internal/test/issues/issue-grab_import_names/issue_test.go
+++ b/internal/test/issues/issue-grab_import_names/issue_test.go
@@ -1,4 +1,4 @@
-package grab_import_names
+package grabimportnames
 
 import (
 	"testing"
@@ -13,7 +13,7 @@ func TestLineComments(t *testing.T) {
 	require.NoError(t, err)
 
 	opts := codegen.Configuration{
-		PackageName: "grab_import_names",
+		PackageName: "grabimportnames",
 		Generate: codegen.GenerateOptions{
 			EchoServer:   true,
 			Client:       true,
diff --git a/internal/test/issues/issue-head-digit-of-httpheader/config.yaml b/internal/test/issues/issue-head-digit-of-httpheader/config.yaml
index f3709ac..1f7ce9d 100644
--- a/internal/test/issues/issue-head-digit-of-httpheader/config.yaml
+++ b/internal/test/issues/issue-head-digit-of-httpheader/config.yaml
@@ -1,5 +1,5 @@
 ---
-package: head_digit_of_httpheader
+package: headdigitofhttpheader
 generate:
   strict-server: true
 output: issue.gen.go
diff --git a/internal/test/issues/issue-head-digit-of-httpheader/doc.go b/internal/test/issues/issue-head-digit-of-httpheader/doc.go
index 4a2cdf8..0c4cfc1 100644
--- a/internal/test/issues/issue-head-digit-of-httpheader/doc.go
+++ b/internal/test/issues/issue-head-digit-of-httpheader/doc.go
@@ -1,3 +1,3 @@
-package head_digit_of_httpheader
+package headdigitofhttpheader
 
 //go:generate go run github.com/deepmap/oapi-codegen/cmd/oapi-codegen --config=config.yaml spec.yaml
diff --git a/internal/test/issues/issue-head-digit-of-httpheader/issue.gen.go b/internal/test/issues/issue-head-digit-of-httpheader/issue.gen.go
index c512e7a..703c262 100644
--- a/internal/test/issues/issue-head-digit-of-httpheader/issue.gen.go
+++ b/internal/test/issues/issue-head-digit-of-httpheader/issue.gen.go
@@ -1,7 +1,7 @@
-// Package head_digit_of_httpheader provides primitives to interact with the openapi HTTP API.
+// Package headdigitofhttpheader provides primitives to interact with the openapi HTTP API.
 //
 // Code generated by github.com/deepmap/oapi-codegen version (devel) DO NOT EDIT.
-package head_digit_of_httpheader
+package headdigitofhttpheader
 
 import (
 	"context"
diff --git a/internal/test/issues/issue-illegal_enum_names/config.yaml b/internal/test/issues/issue-illegal_enum_names/config.yaml
index 592a3cb..9b426a0 100644
--- a/internal/test/issues/issue-illegal_enum_names/config.yaml
+++ b/internal/test/issues/issue-illegal_enum_names/config.yaml
@@ -1,4 +1,4 @@
-package: illegal_enum_names
+package: illegalenumnames
 generate:
   echo-server: true
   client: true
diff --git a/internal/test/issues/issue-illegal_enum_names/doc.go b/internal/test/issues/issue-illegal_enum_names/doc.go
index 4bc0db2..de0c23f 100644
--- a/internal/test/issues/issue-illegal_enum_names/doc.go
+++ b/internal/test/issues/issue-illegal_enum_names/doc.go
@@ -1,3 +1,3 @@
-package illegal_enum_names
+package illegalenumnames
 
 //go:generate go run github.com/deepmap/oapi-codegen/cmd/oapi-codegen --config=config.yaml spec.yaml
diff --git a/internal/test/issues/issue-illegal_enum_names/issue.gen.go b/internal/test/issues/issue-illegal_enum_names/issue.gen.go
index 6a81336..3f0d8e0 100644
--- a/internal/test/issues/issue-illegal_enum_names/issue.gen.go
+++ b/internal/test/issues/issue-illegal_enum_names/issue.gen.go
@@ -1,7 +1,7 @@
-// Package illegal_enum_names provides primitives to interact with the openapi HTTP API.
+// Package illegalenumnames provides primitives to interact with the openapi HTTP API.
 //
 // Code generated by github.com/deepmap/oapi-codegen version (devel) DO NOT EDIT.
-package illegal_enum_names
+package illegalenumnames
 
 import (
 	"bytes"
diff --git a/internal/test/issues/issue-illegal_enum_names/issue_test.go b/internal/test/issues/issue-illegal_enum_names/issue_test.go
index 4d7c2c8..3df57c8 100644
--- a/internal/test/issues/issue-illegal_enum_names/issue_test.go
+++ b/internal/test/issues/issue-illegal_enum_names/issue_test.go
@@ -1,4 +1,4 @@
-package illegal_enum_names
+package illegalenumnames
 
 import (
 	"go/ast"
@@ -16,7 +16,7 @@ func TestIllegalEnumNames(t *testing.T) {
 	require.NoError(t, err)
 
 	opts := codegen.Configuration{
-		PackageName: "illegal_enum_names",
+		PackageName: "illegalenumnames",
 		Generate: codegen.GenerateOptions{
 			EchoServer:   true,
 			Client:       true,
diff --git a/internal/test/schemas/schemas.gen.go b/internal/test/schemas/schemas.gen.go
index b6a9f20..a042df1 100644
--- a/internal/test/schemas/schemas.gen.go
+++ b/internal/test/schemas/schemas.gen.go
@@ -48,6 +48,24 @@ type AnyType2 = interface{}
 // CustomStringType defines model for CustomStringType.
 type CustomStringType = string
 
+// DeprecatedProperty defines model for DeprecatedProperty.
+type DeprecatedProperty struct {
+	// NewProp Use this now!
+	NewProp string `json:"newProp"`
+	// Deprecated:
+	OldProp1 *string `json:"oldProp1,omitempty"`
+
+	// OldProp2 It used to do this and that
+	// Deprecated:
+	OldProp2 *string `json:"oldProp2,omitempty"`
+	// Deprecated: Use NewProp instead!
+	OldProp3 *string `json:"oldProp3,omitempty"`
+
+	// OldProp4 It used to do this and that
+	// Deprecated: Use NewProp instead!
+	OldProp4 *string `json:"oldProp4,omitempty"`
+}
+
 // EnumInObjInArray defines model for EnumInObjInArray.
 type EnumInObjInArray = []struct {
 	Val *EnumInObjInArrayVal `json:"val,omitempty"`
@@ -184,6 +202,9 @@ type ClientInterface interface {
 	Issue9WithBody(ctx context.Context, params *Issue9Params, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
 
 	Issue9(ctx context.Context, params *Issue9Params, body Issue9JSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error)
+
+	// Issue975 request
+	Issue975(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error)
 }
 
 func (c *Client) EnsureEverythingIsReferenced(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) {
@@ -306,6 +327,18 @@ func (c *Client) Issue9(ctx context.Context, params *Issue9Params, body Issue9JS
 	return c.Client.Do(req)
 }
 
+func (c *Client) Issue975(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) {
+	req, err := NewIssue975Request(c.Server)
+	if err != nil {
+		return nil, err
+	}
+	req = req.WithContext(ctx)
+	if err := c.applyEditors(ctx, req, reqEditors); err != nil {
+		return nil, err
+	}
+	return c.Client.Do(req)
+}
+
 // NewEnsureEverythingIsReferencedRequest generates requests for EnsureEverythingIsReferenced
 func NewEnsureEverythingIsReferencedRequest(server string) (*http.Request, error) {
 	var err error
@@ -585,6 +618,33 @@ func NewIssue9RequestWithBody(server string, params *Issue9Params, contentType s
 	return req, nil
 }
 
+// NewIssue975Request generates requests for Issue975
+func NewIssue975Request(server string) (*http.Request, error) {
+	var err error
+
+	serverURL, err := url.Parse(server)
+	if err != nil {
+		return nil, err
+	}
+
+	operationPath := fmt.Sprintf("/issues/975")
+	if operationPath[0] == '/' {
+		operationPath = "." + operationPath
+	}
+
+	queryURL, err := serverURL.Parse(operationPath)
+	if err != nil {
+		return nil, err
+	}
+
+	req, err := http.NewRequest("GET", queryURL.String(), nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return req, nil
+}
+
 func (c *Client) applyEditors(ctx context.Context, req *http.Request, additionalEditors []RequestEditorFn) error {
 	for _, r := range c.RequestEditors {
 		if err := r(ctx, req); err != nil {
@@ -655,6 +715,9 @@ type ClientWithResponsesInterface interface {
 	Issue9WithBodyWithResponse(ctx context.Context, params *Issue9Params, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*Issue9Response, error)
 
 	Issue9WithResponse(ctx context.Context, params *Issue9Params, body Issue9JSONRequestBody, reqEditors ...RequestEditorFn) (*Issue9Response, error)
+
+	// Issue975 request
+	Issue975WithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*Issue975Response, error)
 }
 
 type EnsureEverythingIsReferencedResponse struct {
@@ -839,6 +902,28 @@ func (r Issue9Response) StatusCode() int {
 	return 0
 }
 
+type Issue975Response struct {
+	Body         []byte
+	HTTPResponse *http.Response
+	JSON200      *DeprecatedProperty
+}
+
+// Status returns HTTPResponse.Status
+func (r Issue975Response) Status() string {
+	if r.HTTPResponse != nil {
+		return r.HTTPResponse.Status
+	}
+	return http.StatusText(0)
+}
+
+// StatusCode returns HTTPResponse.StatusCode
+func (r Issue975Response) StatusCode() int {
+	if r.HTTPResponse != nil {
+		return r.HTTPResponse.StatusCode
+	}
+	return 0
+}
+
 // EnsureEverythingIsReferencedWithResponse request returning *EnsureEverythingIsReferencedResponse
 func (c *ClientWithResponses) EnsureEverythingIsReferencedWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*EnsureEverythingIsReferencedResponse, error) {
 	rsp, err := c.EnsureEverythingIsReferenced(ctx, reqEditors...)
@@ -927,6 +1012,15 @@ func (c *ClientWithResponses) Issue9WithResponse(ctx context.Context, params *Is
 	return ParseIssue9Response(rsp)
 }
 
+// Issue975WithResponse request returning *Issue975Response
+func (c *ClientWithResponses) Issue975WithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*Issue975Response, error) {
+	rsp, err := c.Issue975(ctx, reqEditors...)
+	if err != nil {
+		return nil, err
+	}
+	return ParseIssue975Response(rsp)
+}
+
 // ParseEnsureEverythingIsReferencedResponse parses an HTTP response from a EnsureEverythingIsReferencedWithResponse call
 func ParseEnsureEverythingIsReferencedResponse(rsp *http.Response) (*EnsureEverythingIsReferencedResponse, error) {
 	bodyBytes, err := io.ReadAll(rsp.Body)
@@ -1120,6 +1214,32 @@ func ParseIssue9Response(rsp *http.Response) (*Issue9Response, error) {
 	return response, nil
 }
 
+// ParseIssue975Response parses an HTTP response from a Issue975WithResponse call
+func ParseIssue975Response(rsp *http.Response) (*Issue975Response, error) {
+	bodyBytes, err := io.ReadAll(rsp.Body)
+	defer func() { _ = rsp.Body.Close() }()
+	if err != nil {
+		return nil, err
+	}
+
+	response := &Issue975Response{
+		Body:         bodyBytes,
+		HTTPResponse: rsp,
+	}
+
+	switch {
+	case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200:
+		var dest DeprecatedProperty
+		if err := json.Unmarshal(bodyBytes, &dest); err != nil {
+			return nil, err
+		}
+		response.JSON200 = &dest
+
+	}
+
+	return response, nil
+}
+
 // ServerInterface represents all server handlers.
 type ServerInterface interface {
 
@@ -1146,6 +1266,9 @@ type ServerInterface interface {
 
 	// (GET /issues/9)
 	Issue9(ctx echo.Context, params Issue9Params) error
+
+	// (GET /issues/975)
+	Issue975(ctx echo.Context) error
 }
 
 // ServerInterfaceWrapper converts echo contexts to parameters.
@@ -1271,6 +1394,17 @@ func (w *ServerInterfaceWrapper) Issue9(ctx echo.Context) error {
 	return err
 }
 
+// Issue975 converts echo context to params.
+func (w *ServerInterfaceWrapper) Issue975(ctx echo.Context) error {
+	var err error
+
+	ctx.Set(Access_tokenScopes, []string{""})
+
+	// Invoke the callback with all the unmarshalled arguments
+	err = w.Handler.Issue975(ctx)
+	return err
+}
+
 // This is a simple interface which specifies echo.Route addition functions which
 // are present on both echo.Echo and echo.Group, since we want to allow using
 // either of them for path registration
@@ -1307,33 +1441,37 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
 	router.GET(baseURL+"/issues/375", wrapper.GetIssues375)
 	router.GET(baseURL+"/issues/41/:1param", wrapper.Issue41)
 	router.GET(baseURL+"/issues/9", wrapper.Issue9)
+	router.GET(baseURL+"/issues/975", wrapper.Issue975)
 
 }
 
 // Base64 encoded, gzipped, json marshaled Swagger object
 var swaggerSpec = []string{
 
-	"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",
+	"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",
+	"7tMAMZKIRc6LEVfE8H8FAAD//5edhkCXEgAA",
 }
 
 // GetSwagger returns the content of the embedded swagger specification file
diff --git a/internal/test/schemas/schemas.yaml b/internal/test/schemas/schemas.yaml
index 3d73527..319faa7 100644
--- a/internal/test/schemas/schemas.yaml
+++ b/internal/test/schemas/schemas.yaml
@@ -121,6 +121,19 @@ paths:
             application/json:
               schema:
                 $ref: "#/components/schemas/EnumInObjInArray"
+  /issues/975:
+    get:
+      operationId: Issue975
+      description: |
+        Deprecated fields should get a proper comment
+      responses:
+        200:
+          description: A struct with deprecated fields with varying level of documentation
+          content:
+            application/json:
+              schema:
+                $ref: "#/components/schemas/DeprecatedProperty"
+
 components:
   schemas:
     GenericObject:
@@ -165,6 +178,32 @@ components:
             enum:
               - first
               - second
+    DeprecatedProperty:
+      type: object
+      required:
+        - newProp
+        - oldProp
+      properties:
+        newProp:
+          type: string
+          description: Use this now!
+        oldProp1:
+          type: string
+          deprecated: true
+          # description: No description on this one to test generation in that case
+        oldProp2:
+          type: string
+          deprecated: true
+          description: It used to do this and that
+        oldProp3:
+          type: string
+          deprecated: true
+          x-deprecated-reason: Use NewProp instead!
+        oldProp4:
+          type: string
+          deprecated: true
+          x-deprecated-reason: Use NewProp instead!
+          description: It used to do this and that
   parameters:
     StringInPath:
       name: str
@@ -183,4 +222,3 @@ components:
         JWT-format access token.
 security:
   - access-token: [ ]
-
diff --git a/internal/test/strict-server/chi/server.gen.go b/internal/test/strict-server/chi/server.gen.go
index 124c057..236277c 100644
--- a/internal/test/strict-server/chi/server.gen.go
+++ b/internal/test/strict-server/chi/server.gen.go
@@ -34,6 +34,9 @@ type ServerInterface interface {
 	// (POST /multiple)
 	MultipleRequestAndResponseTypes(w http.ResponseWriter, r *http.Request)
 
+	// (GET /reserved-go-keyword-parameters/{type})
+	ReservedGoKeywordParameters(w http.ResponseWriter, r *http.Request, pType string)
+
 	// (POST /reusable-responses)
 	ReusableResponses(w http.ResponseWriter, r *http.Request)
 
@@ -107,6 +110,32 @@ func (siw *ServerInterfaceWrapper) MultipleRequestAndResponseTypes(w http.Respon
 	handler.ServeHTTP(w, r.WithContext(ctx))
 }
 
+// ReservedGoKeywordParameters operation middleware
+func (siw *ServerInterfaceWrapper) ReservedGoKeywordParameters(w http.ResponseWriter, r *http.Request) {
+	ctx := r.Context()
+
+	var err error
+
+	// ------------- Path parameter "type" -------------
+	var pType string
+
+	err = runtime.BindStyledParameterWithLocation("simple", false, "type", runtime.ParamLocationPath, chi.URLParam(r, "type"), &pType)
+	if err != nil {
+		siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "type", Err: err})
+		return
+	}
+
+	var handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		siw.Handler.ReservedGoKeywordParameters(w, r, pType)
+	})
+
+	for _, middleware := range siw.HandlerMiddlewares {
+		handler = middleware(handler)
+	}
+
+	handler.ServeHTTP(w, r.WithContext(ctx))
+}
+
 // ReusableResponses operation middleware
 func (siw *ServerInterfaceWrapper) ReusableResponses(w http.ResponseWriter, r *http.Request) {
 	ctx := r.Context()
@@ -368,6 +397,9 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl
 	r.Group(func(r chi.Router) {
 		r.Post(options.BaseURL+"/multiple", wrapper.MultipleRequestAndResponseTypes)
 	})
+	r.Group(func(r chi.Router) {
+		r.Get(options.BaseURL+"/reserved-go-keyword-parameters/{type}", wrapper.ReservedGoKeywordParameters)
+	})
 	r.Group(func(r chi.Router) {
 		r.Post(options.BaseURL+"/reusable-responses", wrapper.ReusableResponses)
 	})
@@ -553,6 +585,24 @@ func (response MultipleRequestAndResponseTypes400Response) VisitMultipleRequestA
 	return nil
 }
 
+type ReservedGoKeywordParametersRequestObject struct {
+	Type string `json:"type"`
+}
+
+type ReservedGoKeywordParametersResponseObject interface {
+	VisitReservedGoKeywordParametersResponse(w http.ResponseWriter) error
+}
+
+type ReservedGoKeywordParameters200TextResponse string
+
+func (response ReservedGoKeywordParameters200TextResponse) VisitReservedGoKeywordParametersResponse(w http.ResponseWriter) error {
+	w.Header().Set("Content-Type", "text/plain")
+	w.WriteHeader(200)
+
+	_, err := w.Write([]byte(response))
+	return err
+}
+
 type ReusableResponsesRequestObject struct {
 	Body *ReusableResponsesJSONRequestBody
 }
@@ -820,6 +870,9 @@ type StrictServerInterface interface {
 	// (POST /multiple)
 	MultipleRequestAndResponseTypes(ctx context.Context, request MultipleRequestAndResponseTypesRequestObject) (MultipleRequestAndResponseTypesResponseObject, error)
 
+	// (GET /reserved-go-keyword-parameters/{type})
+	ReservedGoKeywordParameters(ctx context.Context, request ReservedGoKeywordParametersRequestObject) (ReservedGoKeywordParametersResponseObject, error)
+
 	// (POST /reusable-responses)
 	ReusableResponses(ctx context.Context, request ReusableResponsesRequestObject) (ReusableResponsesResponseObject, error)
 
@@ -996,6 +1049,32 @@ func (sh *strictHandler) MultipleRequestAndResponseTypes(w http.ResponseWriter,
 	}
 }
 
+// ReservedGoKeywordParameters operation middleware
+func (sh *strictHandler) ReservedGoKeywordParameters(w http.ResponseWriter, r *http.Request, pType string) {
+	var request ReservedGoKeywordParametersRequestObject
+
+	request.Type = pType
+
+	handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) {
+		return sh.ssi.ReservedGoKeywordParameters(ctx, request.(ReservedGoKeywordParametersRequestObject))
+	}
+	for _, middleware := range sh.middlewares {
+		handler = middleware(handler, "ReservedGoKeywordParameters")
+	}
+
+	response, err := handler(r.Context(), w, r, request)
+
+	if err != nil {
+		sh.options.ResponseErrorHandlerFunc(w, r, err)
+	} else if validResponse, ok := response.(ReservedGoKeywordParametersResponseObject); ok {
+		if err := validResponse.VisitReservedGoKeywordParametersResponse(w); err != nil {
+			sh.options.ResponseErrorHandlerFunc(w, r, err)
+		}
+	} else if response != nil {
+		sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("Unexpected response type: %T", response))
+	}
+}
+
 // ReusableResponses operation middleware
 func (sh *strictHandler) ReusableResponses(w http.ResponseWriter, r *http.Request) {
 	var request ReusableResponsesRequestObject
@@ -1184,21 +1263,23 @@ func (sh *strictHandler) HeadersExample(w http.ResponseWriter, r *http.Request,
 // Base64 encoded, gzipped, json marshaled Swagger object
 var swaggerSpec = []string{
 
-	"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",
+	"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",
+	"AP//O0NNuucUAAA=",
 }
 
 // GetSwagger returns the content of the embedded swagger specification file
diff --git a/internal/test/strict-server/chi/server.go b/internal/test/strict-server/chi/server.go
index 5b70268..b0724db 100644
--- a/internal/test/strict-server/chi/server.go
+++ b/internal/test/strict-server/chi/server.go
@@ -100,3 +100,7 @@ func (s StrictServer) HeadersExample(ctx context.Context, request HeadersExample
 func (s StrictServer) ReusableResponses(ctx context.Context, request ReusableResponsesRequestObject) (ReusableResponsesResponseObject, error) {
 	return ReusableResponses200JSONResponse{ReusableresponseJSONResponse: ReusableresponseJSONResponse{Body: *request.Body}}, nil
 }
+
+func (s StrictServer) ReservedGoKeywordParameters(ctx context.Context, request ReservedGoKeywordParametersRequestObject) (ReservedGoKeywordParametersResponseObject, error) {
+	return ReservedGoKeywordParameters200TextResponse(""), nil
+}
diff --git a/internal/test/strict-server/client/client.gen.go b/internal/test/strict-server/client/client.gen.go
index 68105f2..5ec0210 100644
--- a/internal/test/strict-server/client/client.gen.go
+++ b/internal/test/strict-server/client/client.gen.go
@@ -156,6 +156,9 @@ type ClientInterface interface {
 
 	MultipleRequestAndResponseTypesWithTextBody(ctx context.Context, body MultipleRequestAndResponseTypesTextRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error)
 
+	// ReservedGoKeywordParameters request
+	ReservedGoKeywordParameters(ctx context.Context, pType string, reqEditors ...RequestEditorFn) (*http.Response, error)
+
 	// ReusableResponses request with any body
 	ReusableResponsesWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
 
@@ -267,6 +270,18 @@ func (c *Client) MultipleRequestAndResponseTypesWithTextBody(ctx context.Context
 	return c.Client.Do(req)
 }
 
+func (c *Client) ReservedGoKeywordParameters(ctx context.Context, pType string, reqEditors ...RequestEditorFn) (*http.Response, error) {
+	req, err := NewReservedGoKeywordParametersRequest(c.Server, pType)
+	if err != nil {
+		return nil, err
+	}
+	req = req.WithContext(ctx)
+	if err := c.applyEditors(ctx, req, reqEditors); err != nil {
+		return nil, err
+	}
+	return c.Client.Do(req)
+}
+
 func (c *Client) ReusableResponsesWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) {
 	req, err := NewReusableResponsesRequestWithBody(c.Server, contentType, body)
 	if err != nil {
@@ -514,6 +529,40 @@ func NewMultipleRequestAndResponseTypesRequestWithBody(server string, contentTyp
 	return req, nil
 }
 
+// NewReservedGoKeywordParametersRequest generates requests for ReservedGoKeywordParameters
+func NewReservedGoKeywordParametersRequest(server string, pType string) (*http.Request, error) {
+	var err error
+
+	var pathParam0 string
+
+	pathParam0, err = runtime.StyleParamWithLocation("simple", false, "type", runtime.ParamLocationPath, pType)
+	if err != nil {
+		return nil, err
+	}
+
+	serverURL, err := url.Parse(server)
+	if err != nil {
+		return nil, err
+	}
+
+	operationPath := fmt.Sprintf("/reserved-go-keyword-parameters/%s", pathParam0)
+	if operationPath[0] == '/' {
+		operationPath = "." + operationPath
+	}
+
+	queryURL, err := serverURL.Parse(operationPath)
+	if err != nil {
+		return nil, err
+	}
+
+	req, err := http.NewRequest("GET", queryURL.String(), nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return req, nil
+}
+
 // NewReusableResponsesRequest calls the generic ReusableResponses builder with application/json body
 func NewReusableResponsesRequest(server string, body ReusableResponsesJSONRequestBody) (*http.Request, error) {
 	var bodyReader io.Reader
@@ -808,6 +857,9 @@ type ClientWithResponsesInterface interface {
 
 	MultipleRequestAndResponseTypesWithTextBodyWithResponse(ctx context.Context, body MultipleRequestAndResponseTypesTextRequestBody, reqEditors ...RequestEditorFn) (*MultipleRequestAndResponseTypesResponse, error)
 
+	// ReservedGoKeywordParameters request
+	ReservedGoKeywordParametersWithResponse(ctx context.Context, pType string, reqEditors ...RequestEditorFn) (*ReservedGoKeywordParametersResponse, error)
+
 	// ReusableResponses request with any body
 	ReusableResponsesWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ReusableResponsesResponse, error)
 
@@ -900,6 +952,27 @@ func (r MultipleRequestAndResponseTypesResponse) StatusCode() int {
 	return 0
 }
 
+type ReservedGoKeywordParametersResponse struct {
+	Body         []byte
+	HTTPResponse *http.Response
+}
+
+// Status returns HTTPResponse.Status
+func (r ReservedGoKeywordParametersResponse) Status() string {
+	if r.HTTPResponse != nil {
+		return r.HTTPResponse.Status
+	}
+	return http.StatusText(0)
+}
+
+// StatusCode returns HTTPResponse.StatusCode
+func (r ReservedGoKeywordParametersResponse) StatusCode() int {
+	if r.HTTPResponse != nil {
+		return r.HTTPResponse.StatusCode
+	}
+	return 0
+}
+
 type ReusableResponsesResponse struct {
 	Body         []byte
 	HTTPResponse *http.Response
@@ -1087,6 +1160,15 @@ func (c *ClientWithResponses) MultipleRequestAndResponseTypesWithTextBodyWithRes
 	return ParseMultipleRequestAndResponseTypesResponse(rsp)
 }
 
+// ReservedGoKeywordParametersWithResponse request returning *ReservedGoKeywordParametersResponse
+func (c *ClientWithResponses) ReservedGoKeywordParametersWithResponse(ctx context.Context, pType string, reqEditors ...RequestEditorFn) (*ReservedGoKeywordParametersResponse, error) {
+	rsp, err := c.ReservedGoKeywordParameters(ctx, pType, reqEditors...)
+	if err != nil {
+		return nil, err
+	}
+	return ParseReservedGoKeywordParametersResponse(rsp)
+}
+
 // ReusableResponsesWithBodyWithResponse request with arbitrary body returning *ReusableResponsesResponse
 func (c *ClientWithResponses) ReusableResponsesWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ReusableResponsesResponse, error) {
 	rsp, err := c.ReusableResponsesWithBody(ctx, contentType, body, reqEditors...)
@@ -1244,6 +1326,22 @@ func ParseMultipleRequestAndResponseTypesResponse(rsp *http.Response) (*Multiple
 	return response, nil
 }
 
+// ParseReservedGoKeywordParametersResponse parses an HTTP response from a ReservedGoKeywordParametersWithResponse call
+func ParseReservedGoKeywordParametersResponse(rsp *http.Response) (*ReservedGoKeywordParametersResponse, error) {
+	bodyBytes, err := io.ReadAll(rsp.Body)
+	defer func() { _ = rsp.Body.Close() }()
+	if err != nil {
+		return nil, err
+	}
+
+	response := &ReservedGoKeywordParametersResponse{
+		Body:         bodyBytes,
+		HTTPResponse: rsp,
+	}
+
+	return response, nil
+}
+
 // ParseReusableResponsesResponse parses an HTTP response from a ReusableResponsesWithResponse call
 func ParseReusableResponsesResponse(rsp *http.Response) (*ReusableResponsesResponse, error) {
 	bodyBytes, err := io.ReadAll(rsp.Body)
diff --git a/internal/test/strict-server/echo/server.gen.go b/internal/test/strict-server/echo/server.gen.go
index 46531bd..ebd374b 100644
--- a/internal/test/strict-server/echo/server.gen.go
+++ b/internal/test/strict-server/echo/server.gen.go
@@ -34,6 +34,9 @@ type ServerInterface interface {
 	// (POST /multiple)
 	MultipleRequestAndResponseTypes(ctx echo.Context) error
 
+	// (GET /reserved-go-keyword-parameters/{type})
+	ReservedGoKeywordParameters(ctx echo.Context, pType string) error
+
 	// (POST /reusable-responses)
 	ReusableResponses(ctx echo.Context) error
 
@@ -85,6 +88,22 @@ func (w *ServerInterfaceWrapper) MultipleRequestAndResponseTypes(ctx echo.Contex
 	return err
 }
 
+// ReservedGoKeywordParameters converts echo context to params.
+func (w *ServerInterfaceWrapper) ReservedGoKeywordParameters(ctx echo.Context) error {
+	var err error
+	// ------------- Path parameter "type" -------------
+	var pType string
+
+	err = runtime.BindStyledParameterWithLocation("simple", false, "type", runtime.ParamLocationPath, ctx.Param("type"), &pType)
+	if err != nil {
+		return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter type: %s", err))
+	}
+
+	// Invoke the callback with all the unmarshalled arguments
+	err = w.Handler.ReservedGoKeywordParameters(ctx, pType)
+	return err
+}
+
 // ReusableResponses converts echo context to params.
 func (w *ServerInterfaceWrapper) ReusableResponses(ctx echo.Context) error {
 	var err error
@@ -207,6 +226,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
 	router.POST(baseURL+"/json", wrapper.JSONExample)
 	router.POST(baseURL+"/multipart", wrapper.MultipartExample)
 	router.POST(baseURL+"/multiple", wrapper.MultipleRequestAndResponseTypes)
+	router.GET(baseURL+"/reserved-go-keyword-parameters/:type", wrapper.ReservedGoKeywordParameters)
 	router.POST(baseURL+"/reusable-responses", wrapper.ReusableResponses)
 	router.POST(baseURL+"/text", wrapper.TextExample)
 	router.POST(baseURL+"/unknown", wrapper.UnknownExample)
@@ -379,6 +399,24 @@ func (response MultipleRequestAndResponseTypes400Response) VisitMultipleRequestA
 	return nil
 }
 
+type ReservedGoKeywordParametersRequestObject struct {
+	Type string `json:"type"`
+}
+
+type ReservedGoKeywordParametersResponseObject interface {
+	VisitReservedGoKeywordParametersResponse(w http.ResponseWriter) error
+}
+
+type ReservedGoKeywordParameters200TextResponse string
+
+func (response ReservedGoKeywordParameters200TextResponse) VisitReservedGoKeywordParametersResponse(w http.ResponseWriter) error {
+	w.Header().Set("Content-Type", "text/plain")
+	w.WriteHeader(200)
+
+	_, err := w.Write([]byte(response))
+	return err
+}
+
 type ReusableResponsesRequestObject struct {
 	Body *ReusableResponsesJSONRequestBody
 }
@@ -646,6 +684,9 @@ type StrictServerInterface interface {
 	// (POST /multiple)
 	MultipleRequestAndResponseTypes(ctx context.Context, request MultipleRequestAndResponseTypesRequestObject) (MultipleRequestAndResponseTypesResponseObject, error)
 
+	// (GET /reserved-go-keyword-parameters/{type})
+	ReservedGoKeywordParameters(ctx context.Context, request ReservedGoKeywordParametersRequestObject) (ReservedGoKeywordParametersResponseObject, error)
+
 	// (POST /reusable-responses)
 	ReusableResponses(ctx context.Context, request ReusableResponsesRequestObject) (ReusableResponsesResponseObject, error)
 
@@ -796,6 +837,31 @@ func (sh *strictHandler) MultipleRequestAndResponseTypes(ctx echo.Context) error
 	return nil
 }
 
+// ReservedGoKeywordParameters operation middleware
+func (sh *strictHandler) ReservedGoKeywordParameters(ctx echo.Context, pType string) error {
+	var request ReservedGoKeywordParametersRequestObject
+
+	request.Type = pType
+
+	handler := func(ctx echo.Context, request interface{}) (interface{}, error) {
+		return sh.ssi.ReservedGoKeywordParameters(ctx.Request().Context(), request.(ReservedGoKeywordParametersRequestObject))
+	}
+	for _, middleware := range sh.middlewares {
+		handler = middleware(handler, "ReservedGoKeywordParameters")
+	}
+
+	response, err := handler(ctx, request)
+
+	if err != nil {
+		return err
+	} else if validResponse, ok := response.(ReservedGoKeywordParametersResponseObject); ok {
+		return validResponse.VisitReservedGoKeywordParametersResponse(ctx.Response())
+	} else if response != nil {
+		return fmt.Errorf("Unexpected response type: %T", response)
+	}
+	return nil
+}
+
 // ReusableResponses operation middleware
 func (sh *strictHandler) ReusableResponses(ctx echo.Context) error {
 	var request ReusableResponsesRequestObject
@@ -974,21 +1040,23 @@ func (sh *strictHandler) HeadersExample(ctx echo.Context, params HeadersExampleP
 // Base64 encoded, gzipped, json marshaled Swagger object
 var swaggerSpec = []string{
 
-	"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",
+	"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",
+	"AP//O0NNuucUAAA=",
 }
 
 // GetSwagger returns the content of the embedded swagger specification file
diff --git a/internal/test/strict-server/echo/server.go b/internal/test/strict-server/echo/server.go
index d4007e0..b0724db 100644
--- a/internal/test/strict-server/echo/server.go
+++ b/internal/test/strict-server/echo/server.go
@@ -94,9 +94,13 @@ func (s StrictServer) URLEncodedExample(ctx context.Context, request URLEncodedE
 }
 
 func (s StrictServer) HeadersExample(ctx context.Context, request HeadersExampleRequestObject) (HeadersExampleResponseObject, error) {
-	return HeadersExample200JSONResponse{Body: Example(*request.Body), Headers: HeadersExample200ResponseHeaders{Header1: request.Params.Header1, Header2: *request.Params.Header2}}, nil
+	return HeadersExample200JSONResponse{Body: *request.Body, Headers: HeadersExample200ResponseHeaders{Header1: request.Params.Header1, Header2: *request.Params.Header2}}, nil
 }
 
 func (s StrictServer) ReusableResponses(ctx context.Context, request ReusableResponsesRequestObject) (ReusableResponsesResponseObject, error) {
 	return ReusableResponses200JSONResponse{ReusableresponseJSONResponse: ReusableresponseJSONResponse{Body: *request.Body}}, nil
 }
+
+func (s StrictServer) ReservedGoKeywordParameters(ctx context.Context, request ReservedGoKeywordParametersRequestObject) (ReservedGoKeywordParametersResponseObject, error) {
+	return ReservedGoKeywordParameters200TextResponse(""), nil
+}
diff --git a/internal/test/strict-server/gin/server.gen.go b/internal/test/strict-server/gin/server.gen.go
index 52c7290..618db70 100644
--- a/internal/test/strict-server/gin/server.gen.go
+++ b/internal/test/strict-server/gin/server.gen.go
@@ -34,6 +34,9 @@ type ServerInterface interface {
 	// (POST /multiple)
 	MultipleRequestAndResponseTypes(c *gin.Context)
 
+	// (GET /reserved-go-keyword-parameters/{type})
+	ReservedGoKeywordParameters(c *gin.Context, pType string)
+
 	// (POST /reusable-responses)
 	ReusableResponses(c *gin.Context)
 
@@ -67,6 +70,9 @@ func (siw *ServerInterfaceWrapper) JSONExample(c *gin.Context) {
 
 	for _, middleware := range siw.HandlerMiddlewares {
 		middleware(c)
+		if c.IsAborted() {
+			return
+		}
 	}
 
 	siw.Handler.JSONExample(c)
@@ -77,6 +83,9 @@ func (siw *ServerInterfaceWrapper) MultipartExample(c *gin.Context) {
 
 	for _, middleware := range siw.HandlerMiddlewares {
 		middleware(c)
+		if c.IsAborted() {
+			return
+		}
 	}
 
 	siw.Handler.MultipartExample(c)
@@ -87,16 +96,46 @@ func (siw *ServerInterfaceWrapper) MultipleRequestAndResponseTypes(c *gin.Contex
 
 	for _, middleware := range siw.HandlerMiddlewares {
 		middleware(c)
+		if c.IsAborted() {
+			return
+		}
 	}
 
 	siw.Handler.MultipleRequestAndResponseTypes(c)
 }
 
+// ReservedGoKeywordParameters operation middleware
+func (siw *ServerInterfaceWrapper) ReservedGoKeywordParameters(c *gin.Context) {
+
+	var err error
+
+	// ------------- Path parameter "type" -------------
+	var pType string
+
+	err = runtime.BindStyledParameter("simple", false, "type", c.Param("type"), &pType)
+	if err != nil {
+		siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter type: %s", err), http.StatusBadRequest)
+		return
+	}
+
+	for _, middleware := range siw.HandlerMiddlewares {
+		middleware(c)
+		if c.IsAborted() {
+			return
+		}
+	}
+
+	siw.Handler.ReservedGoKeywordParameters(c, pType)
+}
+
 // ReusableResponses operation middleware
 func (siw *ServerInterfaceWrapper) ReusableResponses(c *gin.Context) {
 
 	for _, middleware := range siw.HandlerMiddlewares {
 		middleware(c)
+		if c.IsAborted() {
+			return
+		}
 	}
 
 	siw.Handler.ReusableResponses(c)
@@ -107,6 +146,9 @@ func (siw *ServerInterfaceWrapper) TextExample(c *gin.Context) {
 
 	for _, middleware := range siw.HandlerMiddlewares {
 		middleware(c)
+		if c.IsAborted() {
+			return
+		}
 	}
 
 	siw.Handler.TextExample(c)
@@ -117,6 +159,9 @@ func (siw *ServerInterfaceWrapper) UnknownExample(c *gin.Context) {
 
 	for _, middleware := range siw.HandlerMiddlewares {
 		middleware(c)
+		if c.IsAborted() {
+			return
+		}
 	}
 
 	siw.Handler.UnknownExample(c)
@@ -127,6 +172,9 @@ func (siw *ServerInterfaceWrapper) UnspecifiedContentType(c *gin.Context) {
 
 	for _, middleware := range siw.HandlerMiddlewares {
 		middleware(c)
+		if c.IsAborted() {
+			return
+		}
 	}
 
 	siw.Handler.UnspecifiedContentType(c)
@@ -137,6 +185,9 @@ func (siw *ServerInterfaceWrapper) URLEncodedExample(c *gin.Context) {
 
 	for _, middleware := range siw.HandlerMiddlewares {
 		middleware(c)
+		if c.IsAborted() {
+			return
+		}
 	}
 
 	siw.Handler.URLEncodedExample(c)
@@ -195,6 +246,9 @@ func (siw *ServerInterfaceWrapper) HeadersExample(c *gin.Context) {
 
 	for _, middleware := range siw.HandlerMiddlewares {
 		middleware(c)
+		if c.IsAborted() {
+			return
+		}
 	}
 
 	siw.Handler.HeadersExample(c, params)
@@ -208,15 +262,13 @@ type GinServerOptions struct {
 }
 
 // RegisterHandlers creates http.Handler with routing matching OpenAPI spec.
-func RegisterHandlers(router *gin.Engine, si ServerInterface) *gin.Engine {
-	return RegisterHandlersWithOptions(router, si, GinServerOptions{})
+func RegisterHandlers(router gin.IRouter, si ServerInterface) {
+	RegisterHandlersWithOptions(router, si, GinServerOptions{})
 }
 
 // RegisterHandlersWithOptions creates http.Handler with additional options
-func RegisterHandlersWithOptions(router *gin.Engine, si ServerInterface, options GinServerOptions) *gin.Engine {
-
+func RegisterHandlersWithOptions(router gin.IRouter, si ServerInterface, options GinServerOptions) {
 	errorHandler := options.ErrorHandler
-
 	if errorHandler == nil {
 		errorHandler = func(c *gin.Context, err error, statusCode int) {
 			c.JSON(statusCode, gin.H{"msg": err.Error()})
@@ -230,24 +282,15 @@ func RegisterHandlersWithOptions(router *gin.Engine, si ServerInterface, options
 	}
 
 	router.POST(options.BaseURL+"/json", wrapper.JSONExample)
-
 	router.POST(options.BaseURL+"/multipart", wrapper.MultipartExample)
-
 	router.POST(options.BaseURL+"/multiple", wrapper.MultipleRequestAndResponseTypes)
-
+	router.GET(options.BaseURL+"/reserved-go-keyword-parameters/:type", wrapper.ReservedGoKeywordParameters)
 	router.POST(options.BaseURL+"/reusable-responses", wrapper.ReusableResponses)
-
 	router.POST(options.BaseURL+"/text", wrapper.TextExample)
-
 	router.POST(options.BaseURL+"/unknown", wrapper.UnknownExample)
-
 	router.POST(options.BaseURL+"/unspecified-content-type", wrapper.UnspecifiedContentType)
-
 	router.POST(options.BaseURL+"/urlencoded", wrapper.URLEncodedExample)
-
 	router.POST(options.BaseURL+"/with-headers", wrapper.HeadersExample)
-
-	return router
 }
 
 type BadrequestResponse struct {
@@ -413,6 +456,24 @@ func (response MultipleRequestAndResponseTypes400Response) VisitMultipleRequestA
 	return nil
 }
 
+type ReservedGoKeywordParametersRequestObject struct {
+	Type string `json:"type"`
+}
+
+type ReservedGoKeywordParametersResponseObject interface {
+	VisitReservedGoKeywordParametersResponse(w http.ResponseWriter) error
+}
+
+type ReservedGoKeywordParameters200TextResponse string
+
+func (response ReservedGoKeywordParameters200TextResponse) VisitReservedGoKeywordParametersResponse(w http.ResponseWriter) error {
+	w.Header().Set("Content-Type", "text/plain")
+	w.WriteHeader(200)
+
+	_, err := w.Write([]byte(response))
+	return err
+}
+
 type ReusableResponsesRequestObject struct {
 	Body *ReusableResponsesJSONRequestBody
 }
@@ -680,6 +741,9 @@ type StrictServerInterface interface {
 	// (POST /multiple)
 	MultipleRequestAndResponseTypes(ctx context.Context, request MultipleRequestAndResponseTypesRequestObject) (MultipleRequestAndResponseTypesResponseObject, error)
 
+	// (GET /reserved-go-keyword-parameters/{type})
+	ReservedGoKeywordParameters(ctx context.Context, request ReservedGoKeywordParametersRequestObject) (ReservedGoKeywordParametersResponseObject, error)
+
 	// (POST /reusable-responses)
 	ReusableResponses(ctx context.Context, request ReusableResponsesRequestObject) (ReusableResponsesResponseObject, error)
 
@@ -841,6 +905,32 @@ func (sh *strictHandler) MultipleRequestAndResponseTypes(ctx *gin.Context) {
 	}
 }
 
+// ReservedGoKeywordParameters operation middleware
+func (sh *strictHandler) ReservedGoKeywordParameters(ctx *gin.Context, pType string) {
+	var request ReservedGoKeywordParametersRequestObject
+
+	request.Type = pType
+
+	handler := func(ctx *gin.Context, request interface{}) (interface{}, error) {
+		return sh.ssi.ReservedGoKeywordParameters(ctx, request.(ReservedGoKeywordParametersRequestObject))
+	}
+	for _, middleware := range sh.middlewares {
+		handler = middleware(handler, "ReservedGoKeywordParameters")
+	}
+
+	response, err := handler(ctx, request)
+
+	if err != nil {
+		ctx.Error(err)
+	} else if validResponse, ok := response.(ReservedGoKeywordParametersResponseObject); ok {
+		if err := validResponse.VisitReservedGoKeywordParametersResponse(ctx.Writer); err != nil {
+			ctx.Error(err)
+		}
+	} else if response != nil {
+		ctx.Error(fmt.Errorf("Unexpected response type: %T", response))
+	}
+}
+
 // ReusableResponses operation middleware
 func (sh *strictHandler) ReusableResponses(ctx *gin.Context) {
 	var request ReusableResponsesRequestObject
@@ -1031,21 +1121,23 @@ func (sh *strictHandler) HeadersExample(ctx *gin.Context, params HeadersExampleP
 // Base64 encoded, gzipped, json marshaled Swagger object
 var swaggerSpec = []string{
 
-	"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",
+	"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",
+	"AP//O0NNuucUAAA=",
 }
 
 // GetSwagger returns the content of the embedded swagger specification file
diff --git a/internal/test/strict-server/gin/server.go b/internal/test/strict-server/gin/server.go
index 5b70268..b0724db 100644
--- a/internal/test/strict-server/gin/server.go
+++ b/internal/test/strict-server/gin/server.go
@@ -100,3 +100,7 @@ func (s StrictServer) HeadersExample(ctx context.Context, request HeadersExample
 func (s StrictServer) ReusableResponses(ctx context.Context, request ReusableResponsesRequestObject) (ReusableResponsesResponseObject, error) {
 	return ReusableResponses200JSONResponse{ReusableresponseJSONResponse: ReusableresponseJSONResponse{Body: *request.Body}}, nil
 }
+
+func (s StrictServer) ReservedGoKeywordParameters(ctx context.Context, request ReservedGoKeywordParametersRequestObject) (ReservedGoKeywordParametersResponseObject, error) {
+	return ReservedGoKeywordParameters200TextResponse(""), nil
+}
diff --git a/internal/test/strict-server/strict-schema.yaml b/internal/test/strict-server/strict-schema.yaml
index a9a2c41..da0ed07 100644
--- a/internal/test/strict-server/strict-schema.yaml
+++ b/internal/test/strict-server/strict-schema.yaml
@@ -228,6 +228,23 @@ paths:
           $ref: "#/components/responses/badrequest"
         default:
           description: Unknown error
+  /reserved-go-keyword-parameters/{type}:
+    get:
+        operationId: ReservedGoKeywordParameters
+        description: Parameters can be named after Go keywords
+        parameters:
+          - name: type
+            in: path
+            required: true
+            schema:
+                type: string
+        responses:
+          200:
+            description: OK
+            content:
+              text/plain:
+                schema:
+                  type: string
 components:
   responses:
     badrequest:
diff --git a/internal/test/strict-server/strict_test.go b/internal/test/strict-server/strict_test.go
index 0075f32..860cc4c 100644
--- a/internal/test/strict-server/strict_test.go
+++ b/internal/test/strict-server/strict_test.go
@@ -1,4 +1,4 @@
-package strict_server
+package strictserver
 
 import (
 	"bytes"
@@ -11,16 +11,17 @@ import (
 	"strings"
 	"testing"
 
+	"github.com/gin-gonic/gin"
+	"github.com/go-chi/chi/v5"
+	"github.com/labstack/echo/v4"
+	"github.com/stretchr/testify/assert"
+
 	"github.com/deepmap/oapi-codegen/internal/test/strict-server/chi"
 	api3 "github.com/deepmap/oapi-codegen/internal/test/strict-server/client"
 	api4 "github.com/deepmap/oapi-codegen/internal/test/strict-server/echo"
 	api2 "github.com/deepmap/oapi-codegen/internal/test/strict-server/gin"
 	"github.com/deepmap/oapi-codegen/pkg/runtime"
 	"github.com/deepmap/oapi-codegen/pkg/testutil"
-	"github.com/gin-gonic/gin"
-	"github.com/go-chi/chi/v5"
-	"github.com/labstack/echo/v4"
-	"github.com/stretchr/testify/assert"
 )
 
 func TestChiServer(t *testing.T) {
@@ -44,8 +45,8 @@ func TestGinServer(t *testing.T) {
 	strictHandler := api2.NewStrictHandler(server, nil)
 	gin.SetMode(gin.ReleaseMode)
 	r := gin.New()
-	handler := api2.RegisterHandlers(r, strictHandler)
-	testImpl(t, handler)
+	api2.RegisterHandlers(r, strictHandler)
+	testImpl(t, r)
 }
 
 func testImpl(t *testing.T, handler http.Handler) {
diff --git a/pkg/codegen/codegen_test.go b/pkg/codegen/codegen_test.go
index 4a85eb1..6ae6121 100644
--- a/pkg/codegen/codegen_test.go
+++ b/pkg/codegen/codegen_test.go
@@ -145,8 +145,11 @@ func TestExampleOpenAPICodeGeneration(t *testing.T) {
 		},
 	}
 
+	loader := openapi3.NewLoader()
+	loader.IsExternalRefsAllowed = true
+
 	// Get a spec from the test definition in this file:
-	swagger, err := openapi3.NewLoader().LoadFromData([]byte(testOpenAPIDefinition))
+	swagger, err := loader.LoadFromData([]byte(testOpenAPIDefinition))
 	assert.NoError(t, err)
 
 	// Run our code generation:
@@ -188,6 +191,11 @@ type GetTestByNameResponse struct {
 	assert.Contains(t, code, "func (c *Client) GetTestByName(ctx context.Context, name string, params *GetTestByNameParams, reqEditors ...RequestEditorFn) (*http.Response, error) {")
 	assert.Contains(t, code, "func (c *ClientWithResponses) GetTestByNameWithResponse(ctx context.Context, name string, params *GetTestByNameParams, reqEditors ...RequestEditorFn) (*GetTestByNameResponse, error) {")
 	assert.Contains(t, code, "DeadSince *time.Time    `json:\"dead_since,omitempty\" tag1:\"value1\" tag2:\"value2\"`")
+	assert.Contains(t, code, "type EnumTestNumerics int")
+	assert.Contains(t, code, "N2 EnumTestNumerics = 2")
+	assert.Contains(t, code, "type EnumTestEnumNames int")
+	assert.Contains(t, code, "Two  EnumTestEnumNames = 2")
+	assert.Contains(t, code, "Double EnumTestEnumVarnames = 2")
 
 	// Make sure the generated code is valid:
 	checkLint(t, "test.gen.go", []byte(code))
diff --git a/pkg/codegen/extension_test.go b/pkg/codegen/extension_test.go
index 64681a6..1d5a215 100644
--- a/pkg/codegen/extension_test.go
+++ b/pkg/codegen/extension_test.go
@@ -9,7 +9,7 @@ import (
 
 func Test_extTypeName(t *testing.T) {
 	type args struct {
-		extPropValue interface{}
+		extPropValue json.RawMessage
 	}
 	tests := []struct {
 		name    string
@@ -24,21 +24,27 @@ func Test_extTypeName(t *testing.T) {
 			wantErr: false,
 		},
 		{
-			name:    "type conversion error",
+			name:    "nil conversion error",
 			args:    args{nil},
 			want:    "",
 			wantErr: true,
 		},
 		{
-			name:    "json unmarshal error",
-			args:    args{json.RawMessage("invalid json format")},
+			name:    "type conversion error",
+			args:    args{json.RawMessage(`12`)},
 			want:    "",
 			wantErr: true,
 		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			got, err := extTypeName(tt.args.extPropValue)
+			// kin-openapi no longer returns these as RawMessage
+			var extPropValue interface{}
+			if tt.args.extPropValue != nil {
+				err := json.Unmarshal(tt.args.extPropValue, &extPropValue)
+				assert.NoError(t, err)
+			}
+			got, err := extTypeName(extPropValue)
 			if tt.wantErr {
 				assert.Error(t, err)
 				return
diff --git a/pkg/codegen/filter_test.go b/pkg/codegen/filter_test.go
index d3a5aec..774d016 100644
--- a/pkg/codegen/filter_test.go
+++ b/pkg/codegen/filter_test.go
@@ -23,8 +23,11 @@ func TestFilterOperationsByTag(t *testing.T) {
 			},
 		}
 
+		loader := openapi3.NewLoader()
+		loader.IsExternalRefsAllowed = true
+
 		// Get a spec from the test definition in this file:
-		swagger, err := openapi3.NewLoader().LoadFromData([]byte(testOpenAPIDefinition))
+		swagger, err := loader.LoadFromData([]byte(testOpenAPIDefinition))
 		assert.NoError(t, err)
 
 		// Run our code generation:
@@ -49,8 +52,11 @@ func TestFilterOperationsByTag(t *testing.T) {
 			},
 		}
 
+		loader := openapi3.NewLoader()
+		loader.IsExternalRefsAllowed = true
+
 		// Get a spec from the test definition in this file:
-		swagger, err := openapi3.NewLoader().LoadFromData([]byte(testOpenAPIDefinition))
+		swagger, err := loader.LoadFromData([]byte(testOpenAPIDefinition))
 		assert.NoError(t, err)
 
 		// Run our code generation:
diff --git a/pkg/codegen/test_schema.json b/pkg/codegen/test_schema.json
new file mode 100644
index 0000000..d649394
--- /dev/null
+++ b/pkg/codegen/test_schema.json
@@ -0,0 +1,15 @@
+{
+  "title": "node",
+  "type": "object",
+  "description": "Represents a node",
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uri-reference"
+    },
+    "type": {
+      "type": "string",
+      "pattern": "^[A-Z][a-zA-Z0-9]*$"
+    }
+  }
+}
\ No newline at end of file
diff --git a/pkg/codegen/test_spec.yaml b/pkg/codegen/test_spec.yaml
index 62a9871..b50f749 100644
--- a/pkg/codegen/test_spec.yaml
+++ b/pkg/codegen/test_spec.yaml
@@ -87,6 +87,46 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/Error'
+  /enum:
+    get:
+      tags:
+        - enum
+      summary: References enum
+      operationId: getEnum
+      responses:
+        200:
+          description: Success
+          content:
+            application/json:
+              schema:
+                type: array
+                items:
+                  $ref: '#/components/schemas/EnumTest'
+        default:
+          description: Error
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Error'
+  /user:
+    get:
+      tags:
+        - mergeAllOf
+      summary: Merges allOf ref-ing a JSON schema
+      operationId: getUser
+      responses:
+        200:
+          description: Success
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/User'
+        default:
+          description: Error
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Error'
 
 components:
   schemas:
@@ -136,3 +176,32 @@ components:
         cause:
           type: string
           enum: [ car, dog, oldage ]
+
+    EnumTest:
+      properties:
+        numerics:
+          type: integer
+          enum: [0, 1, 2]
+        enumNames:
+          type: integer
+          enum: [0, 1, 2]
+          x-enumNames:
+            - zero
+            - one
+            - two
+        enumVarnames:
+          type: integer
+          enum: [0, 1, 2]
+          x-enum-varnames:
+            - na
+            - single
+            - double
+    User:
+      allOf:
+        - $ref: ./test_schema.json
+        - type: object
+          additionalProperties: false
+          properties:
+            name:
+              type: string
+              description: User name
diff --git a/pkg/codegen/utils_test.go b/pkg/codegen/utils_test.go
index 518e287..32708f0 100644
--- a/pkg/codegen/utils_test.go
+++ b/pkg/codegen/utils_test.go
@@ -432,3 +432,17 @@ func TestSchemaNameToTypeName(t *testing.T) {
 		assert.Equal(t, want, SchemaNameToTypeName(in))
 	}
 }
+
+func TestRefPathToObjName(t *testing.T) {
+	t.Parallel()
+
+	for in, want := range map[string]string{
+		"#/components/schemas/Foo":                         "Foo",
+		"#/components/parameters/Bar":                      "Bar",
+		"#/components/responses/baz_baz":                   "baz_baz",
+		"document.json#/Foo":                               "Foo",
+		"http://deepmap.com/schemas/document.json#/objObj": "objObj",
+	} {
+		assert.Equal(t, want, RefPathToObjName(in))
+	}
+}
diff --git a/pkg/runtime/bindform_test.go b/pkg/runtime/bindform_test.go
index 9660ce4..159cef2 100644
--- a/pkg/runtime/bindform_test.go
+++ b/pkg/runtime/bindform_test.go
@@ -29,7 +29,7 @@ func TestBindURLForm(t *testing.T) {
 		OptStruct       *testSubStruct   `json:"opt_struct,omitempty"`
 		OptStructSlice  *[]testSubStruct `json:"opt_struct_slice,omitempty"`
 		NotSerializable int              `json:"-"`
-		unexported      int
+		unexported      int              //nolint:unused
 	}
 
 	testCases := map[string]testStruct{
@@ -137,7 +137,7 @@ func TestMarshalForm(t *testing.T) {
 		OptStruct       *testSubStruct   `json:"opt_struct,omitempty"`
 		OptStructSlice  *[]testSubStruct `json:"opt_struct_slice,omitempty"`
 		NotSerializable int              `json:"-"`
-		unexported      int
+		unexported      int              //nolint:unused
 	}
 
 	testCases := map[string]testStruct{
diff --git a/pkg/runtime/styleparam_test.go b/pkg/runtime/styleparam_test.go
index 5500820..1943ae0 100644
--- a/pkg/runtime/styleparam_test.go
+++ b/pkg/runtime/styleparam_test.go
@@ -394,10 +394,10 @@ func TestStyleParam(t *testing.T) {
 
 	// ------------------------  spaceDelimited Style --------------------------
 
-	result, err = StyleParamWithLocation("spaceDelimited", false, "id", ParamLocationQuery, primitive)
+	_, err = StyleParamWithLocation("spaceDelimited", false, "id", ParamLocationQuery, primitive)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("spaceDelimited", true, "id", ParamLocationQuery, primitive)
+	_, err = StyleParamWithLocation("spaceDelimited", true, "id", ParamLocationQuery, primitive)
 	assert.Error(t, err)
 
 	result, err = StyleParamWithLocation("spaceDelimited", false, "id", ParamLocationQuery, array)
@@ -408,60 +408,60 @@ func TestStyleParam(t *testing.T) {
 	assert.NoError(t, err)
 	assert.EqualValues(t, "id=3&id=4&id=5", result)
 
-	result, err = StyleParamWithLocation("spaceDelimited", false, "id", ParamLocationQuery, object)
+	_, err = StyleParamWithLocation("spaceDelimited", false, "id", ParamLocationQuery, object)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("spaceDelimited", true, "id", ParamLocationQuery, object)
+	_, err = StyleParamWithLocation("spaceDelimited", true, "id", ParamLocationQuery, object)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("spaceDelimited", false, "id", ParamLocationQuery, dict)
+	_, err = StyleParamWithLocation("spaceDelimited", false, "id", ParamLocationQuery, dict)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("spaceDelimited", true, "id", ParamLocationQuery, dict)
+	_, err = StyleParamWithLocation("spaceDelimited", true, "id", ParamLocationQuery, dict)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("spaceDelimited", false, "id", ParamLocationQuery, timestamp)
+	_, err = StyleParamWithLocation("spaceDelimited", false, "id", ParamLocationQuery, timestamp)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("spaceDelimited", true, "id", ParamLocationQuery, timestamp)
+	_, err = StyleParamWithLocation("spaceDelimited", true, "id", ParamLocationQuery, timestamp)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("spaceDelimited", false, "id", ParamLocationQuery, &timestamp)
+	_, err = StyleParamWithLocation("spaceDelimited", false, "id", ParamLocationQuery, &timestamp)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("spaceDelimited", true, "id", ParamLocationQuery, &timestamp)
+	_, err = StyleParamWithLocation("spaceDelimited", true, "id", ParamLocationQuery, &timestamp)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("spaceDelimited", false, "id", ParamLocationQuery, date)
+	_, err = StyleParamWithLocation("spaceDelimited", false, "id", ParamLocationQuery, date)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("spaceDelimited", true, "id", ParamLocationQuery, date)
+	_, err = StyleParamWithLocation("spaceDelimited", true, "id", ParamLocationQuery, date)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("spaceDelimited", false, "id", ParamLocationQuery, &date)
+	_, err = StyleParamWithLocation("spaceDelimited", false, "id", ParamLocationQuery, &date)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("spaceDelimited", true, "id", ParamLocationQuery, &date)
+	_, err = StyleParamWithLocation("spaceDelimited", true, "id", ParamLocationQuery, &date)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("spaceDelimited", false, "id", ParamLocationQuery, aUUID)
+	_, err = StyleParamWithLocation("spaceDelimited", false, "id", ParamLocationQuery, aUUID)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("spaceDelimited", true, "id", ParamLocationQuery, aUUID)
+	_, err = StyleParamWithLocation("spaceDelimited", true, "id", ParamLocationQuery, aUUID)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("spaceDelimited", false, "id", ParamLocationQuery, &aUUID)
+	_, err = StyleParamWithLocation("spaceDelimited", false, "id", ParamLocationQuery, &aUUID)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("spaceDelimited", true, "id", ParamLocationQuery, &aUUID)
+	_, err = StyleParamWithLocation("spaceDelimited", true, "id", ParamLocationQuery, &aUUID)
 	assert.Error(t, err)
 
 	// -------------------------  pipeDelimited Style --------------------------
 
-	result, err = StyleParamWithLocation("pipeDelimited", false, "id", ParamLocationQuery, primitive)
+	_, err = StyleParamWithLocation("pipeDelimited", false, "id", ParamLocationQuery, primitive)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("pipeDelimited", true, "id", ParamLocationQuery, primitive)
+	_, err = StyleParamWithLocation("pipeDelimited", true, "id", ParamLocationQuery, primitive)
 	assert.Error(t, err)
 
 	result, err = StyleParamWithLocation("pipeDelimited", false, "id", ParamLocationQuery, array)
@@ -472,69 +472,69 @@ func TestStyleParam(t *testing.T) {
 	assert.NoError(t, err)
 	assert.EqualValues(t, "id=3&id=4&id=5", result)
 
-	result, err = StyleParamWithLocation("pipeDelimited", false, "id", ParamLocationQuery, object)
+	_, err = StyleParamWithLocation("pipeDelimited", false, "id", ParamLocationQuery, object)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("pipeDelimited", true, "id", ParamLocationQuery, object)
+	_, err = StyleParamWithLocation("pipeDelimited", true, "id", ParamLocationQuery, object)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("pipeDelimited", false, "id", ParamLocationQuery, dict)
+	_, err = StyleParamWithLocation("pipeDelimited", false, "id", ParamLocationQuery, dict)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("pipeDelimited", true, "id", ParamLocationQuery, dict)
+	_, err = StyleParamWithLocation("pipeDelimited", true, "id", ParamLocationQuery, dict)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("pipeDelimited", false, "id", ParamLocationQuery, timestamp)
+	_, err = StyleParamWithLocation("pipeDelimited", false, "id", ParamLocationQuery, timestamp)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("pipeDelimited", true, "id", ParamLocationQuery, timestamp)
+	_, err = StyleParamWithLocation("pipeDelimited", true, "id", ParamLocationQuery, timestamp)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("pipeDelimited", false, "id", ParamLocationQuery, &timestamp)
+	_, err = StyleParamWithLocation("pipeDelimited", false, "id", ParamLocationQuery, &timestamp)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("pipeDelimited", true, "id", ParamLocationQuery, &timestamp)
+	_, err = StyleParamWithLocation("pipeDelimited", true, "id", ParamLocationQuery, &timestamp)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("pipeDelimited", false, "id", ParamLocationQuery, date)
+	_, err = StyleParamWithLocation("pipeDelimited", false, "id", ParamLocationQuery, date)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("pipeDelimited", true, "id", ParamLocationQuery, date)
+	_, err = StyleParamWithLocation("pipeDelimited", true, "id", ParamLocationQuery, date)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("pipeDelimited", false, "id", ParamLocationQuery, &date)
+	_, err = StyleParamWithLocation("pipeDelimited", false, "id", ParamLocationQuery, &date)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("pipeDelimited", true, "id", ParamLocationQuery, &date)
+	_, err = StyleParamWithLocation("pipeDelimited", true, "id", ParamLocationQuery, &date)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("pipeDelimited", false, "id", ParamLocationQuery, aUUID)
+	_, err = StyleParamWithLocation("pipeDelimited", false, "id", ParamLocationQuery, aUUID)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("pipeDelimited", true, "id", ParamLocationQuery, aUUID)
+	_, err = StyleParamWithLocation("pipeDelimited", true, "id", ParamLocationQuery, aUUID)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("pipeDelimited", false, "id", ParamLocationQuery, &aUUID)
+	_, err = StyleParamWithLocation("pipeDelimited", false, "id", ParamLocationQuery, &aUUID)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("pipeDelimited", true, "id", ParamLocationQuery, &aUUID)
+	_, err = StyleParamWithLocation("pipeDelimited", true, "id", ParamLocationQuery, &aUUID)
 	assert.Error(t, err)
 
 	// ---------------------------  deepObject Style ---------------------------
-	result, err = StyleParamWithLocation("deepObject", false, "id", ParamLocationQuery, primitive)
+	_, err = StyleParamWithLocation("deepObject", false, "id", ParamLocationQuery, primitive)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("deepObject", true, "id", ParamLocationQuery, primitive)
+	_, err = StyleParamWithLocation("deepObject", true, "id", ParamLocationQuery, primitive)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("deepObject", false, "id", ParamLocationQuery, array)
+	_, err = StyleParamWithLocation("deepObject", false, "id", ParamLocationQuery, array)
 	assert.Error(t, err)
 
 	result, err = StyleParamWithLocation("deepObject", true, "id", ParamLocationQuery, array)
 	assert.NoError(t, err)
 	assert.EqualValues(t, "id[0]=3&id[1]=4&id[2]=5", result)
 
-	result, err = StyleParamWithLocation("deepObject", false, "id", ParamLocationQuery, object)
+	_, err = StyleParamWithLocation("deepObject", false, "id", ParamLocationQuery, object)
 	assert.Error(t, err)
 
 	result, err = StyleParamWithLocation("deepObject", true, "id", ParamLocationQuery, object)
@@ -545,40 +545,40 @@ func TestStyleParam(t *testing.T) {
 	assert.NoError(t, err)
 	assert.EqualValues(t, "id[firstName]=Alex&id[role]=admin", result)
 
-	result, err = StyleParamWithLocation("deepObject", false, "id", ParamLocationQuery, timestamp)
+	_, err = StyleParamWithLocation("deepObject", false, "id", ParamLocationQuery, timestamp)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("deepObject", true, "id", ParamLocationQuery, timestamp)
+	_, err = StyleParamWithLocation("deepObject", true, "id", ParamLocationQuery, timestamp)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("deepObject", false, "id", ParamLocationQuery, &timestamp)
+	_, err = StyleParamWithLocation("deepObject", false, "id", ParamLocationQuery, &timestamp)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("deepObject", true, "id", ParamLocationQuery, &timestamp)
+	_, err = StyleParamWithLocation("deepObject", true, "id", ParamLocationQuery, &timestamp)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("deepObject", false, "id", ParamLocationQuery, date)
+	_, err = StyleParamWithLocation("deepObject", false, "id", ParamLocationQuery, date)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("deepObject", true, "id", ParamLocationQuery, date)
+	_, err = StyleParamWithLocation("deepObject", true, "id", ParamLocationQuery, date)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("deepObject", false, "id", ParamLocationQuery, &date)
+	_, err = StyleParamWithLocation("deepObject", false, "id", ParamLocationQuery, &date)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("deepObject", true, "id", ParamLocationQuery, &date)
+	_, err = StyleParamWithLocation("deepObject", true, "id", ParamLocationQuery, &date)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("deepObject", false, "id", ParamLocationQuery, aUUID)
+	_, err = StyleParamWithLocation("deepObject", false, "id", ParamLocationQuery, aUUID)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("deepObject", true, "id", ParamLocationQuery, aUUID)
+	_, err = StyleParamWithLocation("deepObject", true, "id", ParamLocationQuery, aUUID)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("deepObject", false, "id", ParamLocationQuery, &aUUID)
+	_, err = StyleParamWithLocation("deepObject", false, "id", ParamLocationQuery, &aUUID)
 	assert.Error(t, err)
 
-	result, err = StyleParamWithLocation("deepObject", true, "id", ParamLocationQuery, &aUUID)
+	_, err = StyleParamWithLocation("deepObject", true, "id", ParamLocationQuery, &aUUID)
 	assert.Error(t, err)
 
 	// Misc tests
diff --git a/pkg/types/file_test.go b/pkg/types/file_test.go
index 3e66c7d..fb4ce98 100644
--- a/pkg/types/file_test.go
+++ b/pkg/types/file_test.go
@@ -48,6 +48,7 @@ func TestFileJSON(t *testing.T) {
 	err = json.Unmarshal(buf, &o4)
 	require.NoError(t, err)
 	o4Bytes, err := o4.BinaryFieldPtr.Bytes()
+	require.NoError(t, err)
 	assert.Equal(t, []byte("hello"), o4Bytes)
 
 }