Repository: go-swagger/go-swagger
Pull request #2173 (2020-01-10 14:13:00)

CLI: refactored CLI commands to introduce command groups
* introduced flags groups in CLI for more readable usage text
* refactored CLI to simplify the process of transforming input flags into GenOpts

Sample help from CLI:
```
Usage:
  swagger [OPTIONS] generate model [model-OPTIONS]

generate one or more models from the swagger spec

Application Options:
  -q, --quiet                                                                     silence logs
      --log-output=LOG-FILE                                                       redirect logs to file

Help Options:
  -h, --help                                                                      Show this help message

[model command options]
          --skip-struct                                                           when present will not generate the model struct
      -n, --name=                                                                 the model to generate, repeat for multiple (defaults to all). Same as --models

    Options common to all code generation commands:
      -f, --spec=                                                                 the spec file to use (default swagger.{json,yml,yaml})
      -t, --target=                                                               the base directory for generating the files (default: ./)
          --template=[stratoscale]                                                load contributed templates
      -T, --template-dir=                                                         alternative template override directory
      -C, --config-file=                                                          configuration file to use for overriding template options
      -r, --copyright-file=                                                       copyright file used to add copyright header
          --additional-initialism=                                                consecutive capitals that should be considered intialisms
          --allow-template-override                                               allows overriding protected templates
          --skip-validation                                                       skips validation of spec prior to generation
          --dump-data                                                             when present dumps the json for the template generator instead of generating files
          --with-expand                                                           expands all $ref's in spec prior to generation (shorthand to --with-flatten=expand)
          --with-flatten=[minimal|full|expand|verbose|noverbose|remove-unused]    flattens all $ref's in spec prior to generation (default: minimal, verbose)

    Options for model generation:
      -m, --model-package=                                                        the package to save the models (default: models)
      -M, --model=                                                                specify a model to include in generation, repeat for multiple (defaults to all)
          --existing-models=                                                      use pre-generated models e.g. github.com/foobar/model
          --strict-additional-properties                                          disallow extra properties when additionalProperties is set to false
          --keep-spec-order                                                       keep schema properties order identical to spec file

```
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>

codecov[bot]: # [Codecov](https://codecov.io/gh/go-swagger/go-swagger/pull/2173?src=pr&el=h1) Report
> Merging [#2173](https://codecov.io/gh/go-swagger/go-swagger/pull/2173?src=pr&el=desc) into [master](https://codecov.io/gh/go-swagger/go-swagger/commit/f613f6ec23bf9ecbd5612b035eeaf29ce3092f3a?src=pr&el=desc) will **decrease** coverage by `<.01%`.
> The diff coverage is `95.45%`.

[![Impacted file tree graph](https://codecov.io/gh/go-swagger/go-swagger/pull/2173/graphs/tree.svg?width=650&token=aQS1DepR8C&height=150&src=pr)](https://codecov.io/gh/go-swagger/go-swagger/pull/2173?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #2173      +/-   ##
==========================================
- Coverage   80.42%   80.42%   -0.01%     
==========================================
  Files          47       47              
  Lines        8287     8255      -32     
==========================================
- Hits         6665     6639      -26     
+ Misses       1104     1099       -5     
+ Partials      518      517       -1
```


| [Impacted Files](https://codecov.io/gh/go-swagger/go-swagger/pull/2173?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [cmd/swagger/commands/generate/contrib.go](https://codecov.io/gh/go-swagger/go-swagger/pull/2173/diff?src=pr&el=tree#diff-Y21kL3N3YWdnZXIvY29tbWFuZHMvZ2VuZXJhdGUvY29udHJpYi5nbw==) | `100% <ø> (ø)` | :arrow_up: |
| [cmd/swagger/commands/generate/model.go](https://codecov.io/gh/go-swagger/go-swagger/pull/2173/diff?src=pr&el=tree#diff-Y21kL3N3YWdnZXIvY29tbWFuZHMvZ2VuZXJhdGUvbW9kZWwuZ28=) | `100% <100%> (ø)` | :arrow_up: |
| [cmd/swagger/commands/generate/server.go](https://codecov.io/gh/go-swagger/go-swagger/pull/2173/diff?src=pr&el=tree#diff-Y21kL3N3YWdnZXIvY29tbWFuZHMvZ2VuZXJhdGUvc2VydmVyLmdv) | `100% <100%> (+5.26%)` | :arrow_up: |
| [cmd/swagger/commands/generate/support.go](https://codecov.io/gh/go-swagger/go-swagger/pull/2173/diff?src=pr&el=tree#diff-Y21kL3N3YWdnZXIvY29tbWFuZHMvZ2VuZXJhdGUvc3VwcG9ydC5nbw==) | `100% <100%> (ø)` | :arrow_up: |
| [cmd/swagger/commands/generate/client.go](https://codecov.io/gh/go-swagger/go-swagger/pull/2173/diff?src=pr&el=tree#diff-Y21kL3N3YWdnZXIvY29tbWFuZHMvZ2VuZXJhdGUvY2xpZW50Lmdv) | `100% <100%> (ø)` | :arrow_up: |
| [cmd/swagger/commands/generate/operation.go](https://codecov.io/gh/go-swagger/go-swagger/pull/2173/diff?src=pr&el=tree#diff-Y21kL3N3YWdnZXIvY29tbWFuZHMvZ2VuZXJhdGUvb3BlcmF0aW9uLmdv) | `100% <100%> (ø)` | :arrow_up: |
| [cmd/swagger/commands/generate/shared.go](https://codecov.io/gh/go-swagger/go-swagger/pull/2173/diff?src=pr&el=tree#diff-Y21kL3N3YWdnZXIvY29tbWFuZHMvZ2VuZXJhdGUvc2hhcmVkLmdv) | `79.27% <87.93%> (+7%)` | :arrow_up: |
| [generator/structs.go](https://codecov.io/gh/go-swagger/go-swagger/pull/2173/diff?src=pr&el=tree#diff-Z2VuZXJhdG9yL3N0cnVjdHMuZ28=) | `75.89% <0%> (-1.79%)` | :arrow_down: |
| [generator/model.go](https://codecov.io/gh/go-swagger/go-swagger/pull/2173/diff?src=pr&el=tree#diff-Z2VuZXJhdG9yL21vZGVsLmdv) | `84.43% <0%> (-0.08%)` | :arrow_down: |
| [generator/operation.go](https://codecov.io/gh/go-swagger/go-swagger/pull/2173/diff?src=pr&el=tree#diff-Z2VuZXJhdG9yL29wZXJhdGlvbi5nbw==) | `92.72% <0%> (-0.06%)` | :arrow_down: |
| ... and [2 more](https://codecov.io/gh/go-swagger/go-swagger/pull/2173/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/go-swagger/go-swagger/pull/2173?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/go-swagger/go-swagger/pull/2173?src=pr&el=footer). Last update [f613f6e...fbcc026](https://codecov.io/gh/go-swagger/go-swagger/pull/2173?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 9b08941c..72e777ab 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -222,7 +222,7 @@ jobs:
 
       - run:
           name: Test codegen builds
-          command: go test -v -timeout 60m hack/codegen_nonreg_test.go -args -fixture-file codegen-fixtures.yaml -skip-models -skip-full-flatten
+          command: go test -v -timeout 20m -parallel 3 hack/codegen_nonreg_test.go -args -fixture-file codegen-fixtures.yaml -skip-models -skip-full-flatten
           no_output_timeout: 30m
 
   canary_tests:
@@ -246,7 +246,7 @@ jobs:
 
       - run:
           name: Test canary builds
-          command: go test -v -timeout 60m hack/codegen_nonreg_test.go -args -fixture-file canary-fixtures.yaml -skip-models -skip-full-flatten -skip-expand
+          command: go test -v -timeout 20m hack/codegen_nonreg_test.go -args -fixture-file canary-fixtures.yaml -skip-models -skip-full-flatten -skip-expand
           no_output_timeout: 30m
 
   publish_release:
diff --git a/Dockerfile.alpine.ci b/Dockerfile.alpine.ci
index c1208314..40610330 100644
--- a/Dockerfile.alpine.ci
+++ b/Dockerfile.alpine.ci
@@ -13,7 +13,7 @@ RUN set -e -x \
   && go get -u -t github.com/cee-dub/go-junit-report \
   && go get -u github.com/aktau/github-release \
   && go get -u github.com/mitchellh/gox \
-  && gem install --no-ri --no-rdoc fpm etc \
+  && gem install --no-document fpm etc \
   && gem sources -c
 
 VOLUME /usr/share/coverage
diff --git a/Dockerfile.ci b/Dockerfile.ci
index 55513b7f..ceff6113 100644
--- a/Dockerfile.ci
+++ b/Dockerfile.ci
@@ -18,7 +18,7 @@ RUN set -e -x \
   && go get -u github.com/aktau/github-release \
   && go get -u github.com/mitchellh/gox \
   && go get -u gotest.tools/gotestsum \
-  && gem install --no-ri --no-rdoc fpm etc \
+  && gem install --no-document fpm etc \
   && gem sources -c
 
 VOLUME /usr/share/coverage
diff --git a/cmd/swagger/commands/generate/client.go b/cmd/swagger/commands/generate/client.go
index 360513a7..d46c0ab6 100644
--- a/cmd/swagger/commands/generate/client.go
+++ b/cmd/swagger/commands/generate/client.go
@@ -20,57 +20,51 @@ import (
 	"github.com/go-swagger/go-swagger/generator"
 )
 
+type clientOptions struct {
+	ClientPackage string `long:"client-package" short:"c" description:"the package to save the client specific code" default:"client"`
+}
+
+func (co clientOptions) apply(opts *generator.GenOpts) {
+	opts.ClientPackage = co.ClientPackage
+}
+
 // Client the command to generate a swagger client
 type Client struct {
-	shared
-	Name            string   `long:"name" short:"A" description:"the name of the application, defaults to a mangled value of info.title"`
-	Operations      []string `long:"operation" short:"O" description:"specify an operation to include, repeat for multiple"`
-	Tags            []string `long:"tags" description:"the tags to include, if not specified defaults to all"`
-	Principal       string   `long:"principal" short:"P" description:"the model to use for the security principal"`
-	Models          []string `long:"model" short:"M" description:"specify a model to include, repeat for multiple"`
-	DefaultScheme   string   `long:"default-scheme" description:"the default scheme for this client" default:"http"`
-	DefaultProduces string   `long:"default-produces" description:"the default mime type that API operations produce" default:"application/json"`
-	SkipModels      bool     `long:"skip-models" description:"no models will be generated when this flag is specified"`
-	SkipOperations  bool     `long:"skip-operations" description:"no operations will be generated when this flag is specified"`
-	DumpData        bool     `long:"dump-data" description:"when present dumps the json for the template generator instead of generating files"`
-	SkipValidation  bool     `long:"skip-validation" description:"skips validation of spec prior to generation"`
-}
+	WithShared
+	WithModels
+	WithOperations
 
-func (c *Client) getOpts() (*generator.GenOpts, error) {
-	return &generator.GenOpts{
-		Spec: string(c.Spec),
-
-		Target:                string(c.Target),
-		APIPackage:            c.APIPackage,
-		ModelPackage:          c.ModelPackage,
-		ServerPackage:         c.ServerPackage,
-		ClientPackage:         c.ClientPackage,
-		Principal:             c.Principal,
-		DefaultScheme:         c.DefaultScheme,
-		DefaultProduces:       c.DefaultProduces,
-		IncludeModel:          !c.SkipModels,
-		IncludeValidator:      !c.SkipModels,
-		IncludeHandler:        !c.SkipOperations,
-		IncludeParameters:     !c.SkipOperations,
-		IncludeResponses:      !c.SkipOperations,
-		ValidateSpec:          !c.SkipValidation,
-		Tags:                  c.Tags,
-		IncludeSupport:        true,
-		Template:              c.Template,
-		TemplateDir:           string(c.TemplateDir),
-		DumpData:              c.DumpData,
-		ExistingModels:        c.ExistingModels,
-		AllowTemplateOverride: c.AllowTemplateOverride,
-		IsClient:              true,
-	}, nil
+	clientOptions
+	schemeOptions
+	mediaOptions
+
+	SkipModels     bool `long:"skip-models" description:"no models will be generated when this flag is specified"`
+	SkipOperations bool `long:"skip-operations" description:"no operations will be generated when this flag is specified"`
+
+	Name string `long:"name" short:"A" description:"the name of the application, defaults to a mangled value of info.title"`
 }
 
-func (c *Client) getShared() *shared {
-	return &c.shared
+func (c Client) apply(opts *generator.GenOpts) {
+	c.Shared.apply(opts)
+	c.Models.apply(opts)
+	c.Operations.apply(opts)
+	c.clientOptions.apply(opts)
+	c.schemeOptions.apply(opts)
+	c.mediaOptions.apply(opts)
+
+	opts.IncludeModel = !c.SkipModels
+	opts.IncludeValidator = !c.SkipModels
+	opts.IncludeHandler = !c.SkipOperations
+	opts.IncludeParameters = !c.SkipOperations
+	opts.IncludeResponses = !c.SkipOperations
+	opts.Name = c.Name
+
+	opts.IsClient = true
+	opts.IncludeSupport = true
 }
 
 func (c *Client) generate(opts *generator.GenOpts) error {
-	return generator.GenerateClient(c.Name, c.Models, c.Operations, opts)
+	return generator.GenerateClient(c.Name, c.Models.Models, c.Operations.Operations, opts)
 }
 
 func (c *Client) log(rp string) {
diff --git a/cmd/swagger/commands/generate/contrib.go b/cmd/swagger/commands/generate/contrib.go
index accec044..196558e7 100644
--- a/cmd/swagger/commands/generate/contrib.go
+++ b/cmd/swagger/commands/generate/contrib.go
@@ -6,6 +6,7 @@ import (
 
 // contribOptionsOverride gives contributed templates the ability to override the options if they need
 func contribOptionsOverride(opts *generator.GenOpts) {
+	// nolint: gocritic
 	switch opts.Template {
 	case "stratoscale":
 		// Stratoscale template needs to regenerate the configureapi on every run.
diff --git a/cmd/swagger/commands/generate/model.go b/cmd/swagger/commands/generate/model.go
index 2e14d43a..a3eeabd2 100644
--- a/cmd/swagger/commands/generate/model.go
+++ b/cmd/swagger/commands/generate/model.go
@@ -17,37 +17,78 @@ package generate
 import (
 	"errors"
 	"log"
+
+	"github.com/go-swagger/go-swagger/generator"
 )
 
+type modelOptions struct {
+	ModelPackage               string   `long:"model-package" short:"m" description:"the package to save the models" default:"models"`
+	Models                     []string `long:"model" short:"M" description:"specify a model to include in generation, repeat for multiple (defaults to all)"`
+	ExistingModels             string   `long:"existing-models" description:"use pre-generated models e.g. github.com/foobar/model"`
+	StrictAdditionalProperties bool     `long:"strict-additional-properties" description:"disallow extra properties when additionalProperties is set to false"`
+	KeepSpecOrder              bool     `long:"keep-spec-order" description:"keep schema properties order identical to spec file"`
+}
+
+func (mo modelOptions) apply(opts *generator.GenOpts) {
+	opts.ModelPackage = mo.ModelPackage
+	opts.Models = mo.Models
+	opts.ExistingModels = mo.ExistingModels
+	opts.StrictAdditionalProperties = mo.StrictAdditionalProperties
+	opts.PropertiesSpecOrder = mo.KeepSpecOrder
+}
+
+// WithModels adds the model options group
+type WithModels struct {
+	Models modelOptions `group:"Options for model generation"`
+}
+
 // Model the generate model file command
 type Model struct {
-	shared
-	Name           []string `long:"name" short:"n" description:"the model to generate"`
-	NoStruct       bool     `long:"skip-struct" description:"when present will not generate the model struct"`
-	DumpData       bool     `long:"dump-data" description:"when present dumps the json for the template generator instead of generating files"`
-	SkipValidation bool     `long:"skip-validation" description:"skips validation of spec prior to generation"`
+	WithShared
+	WithModels
+
+	NoStruct bool `long:"skip-struct" description:"when present will not generate the model struct"`
+
+	Name []string `long:"name" short:"n" description:"the model to generate, repeat for multiple (defaults to all). Same as --models"`
+}
+
+func (m Model) apply(opts *generator.GenOpts) {
+	m.Shared.apply(opts)
+	m.Models.apply(opts)
+
+	opts.IncludeModel = !m.NoStruct
+	opts.IncludeValidator = !m.NoStruct
+}
+
+func (m Model) log(rp string) {
+	log.Printf(`Generation completed!
+
+For this generation to compile you need to have some packages in your GOPATH:
+
+	* github.com/go-openapi/validate
+	* github.com/go-openapi/strfmt
+
+You can get these now with: go get -u -f %s/...
+`, rp)
+}
+
+func (m *Model) generate(opts *generator.GenOpts) error {
+	// NOTE: at the moment, the model generator (generator.GenerateDefinition)
+	// is not standalone: use server generator as a proxy
+	opts.IncludeSupport = false
+	opts.IncludeMain = false
+	return generator.GenerateServer("", append(m.Name, m.Models.Models...), nil, opts)
 }
 
 // Execute generates a model file
 func (m *Model) Execute(args []string) error {
 
-	if m.DumpData && len(m.Name) > 1 {
+	if m.Shared.DumpData && (len(m.Name) > 1 || len(m.Models.Models) > 1) {
 		return errors.New("only 1 model at a time is supported for dumping data")
 	}
 
-	if m.ExistingModels != "" {
+	if m.Models.ExistingModels != "" {
 		log.Println("warning: Ignoring existing-models flag when generating models.")
 	}
-	s := &Server{
-		shared:         m.shared,
-		Models:         m.Name,
-		DumpData:       m.DumpData,
-		ExcludeMain:    true,
-		ExcludeSpec:    true,
-		SkipSupport:    true,
-		SkipOperations: true,
-		SkipModels:     m.NoStruct,
-		SkipValidation: m.SkipValidation,
-	}
-	return s.Execute(args)
+	return createSwagger(m)
 }
diff --git a/cmd/swagger/commands/generate/operation.go b/cmd/swagger/commands/generate/operation.go
index dc1f2c25..458da1c7 100644
--- a/cmd/swagger/commands/generate/operation.go
+++ b/cmd/swagger/commands/generate/operation.go
@@ -21,51 +21,60 @@ import (
 	"github.com/go-swagger/go-swagger/generator"
 )
 
+type operationOptions struct {
+	Operations []string `long:"operation" short:"O" description:"specify an operation to include, repeat for multiple (defaults to all)"`
+	Tags       []string `long:"tags" description:"the tags to include, if not specified defaults to all" group:"operations"`
+	APIPackage string   `long:"api-package" short:"a" description:"the package to save the operations" default:"operations"`
+}
+
+func (oo operationOptions) apply(opts *generator.GenOpts) {
+	opts.Operations = oo.Operations
+	opts.Tags = oo.Tags
+	opts.APIPackage = oo.APIPackage
+}
+
+// WithOperations adds the operations options group
+type WithOperations struct {
+	Operations operationOptions `group:"Options for operation generation"`
+}
+
 // Operation the generate operation files command
 type Operation struct {
-	shared
-	Name           []string `long:"name" short:"n" required:"true" description:"the operations to generate, repeat for multiple"`
-	Tags           []string `long:"tags" description:"the tags to include, if not specified defaults to all"`
-	Principal      string   `short:"P" long:"principal" description:"the model to use for the security principal"`
-	DefaultScheme  string   `long:"default-scheme" description:"the default scheme for this API" default:"http"`
-	NoHandler      bool     `long:"skip-handler" description:"when present will not generate an operation handler"`
-	NoStruct       bool     `long:"skip-parameters" description:"when present will not generate the parameter model struct"`
-	NoResponses    bool     `long:"skip-responses" description:"when present will not generate the response model struct"`
-	NoURLBuilder   bool     `long:"skip-url-builder" description:"when present will not generate a URL builder"`
-	DumpData       bool     `long:"dump-data" description:"when present dumps the json for the template generator instead of generating files"`
-	SkipValidation bool     `long:"skip-validation" description:"skips validation of spec prior to generation"`
-}
+	WithShared
+	WithOperations
+
+	clientOptions
+	serverOptions
+	schemeOptions
+	mediaOptions
 
-func (o *Operation) getOpts() (*generator.GenOpts, error) {
-	return &generator.GenOpts{
-		Spec:              string(o.Spec),
-		Target:            string(o.Target),
-		APIPackage:        o.APIPackage,
-		ModelPackage:      o.ModelPackage,
-		ServerPackage:     o.ServerPackage,
-		ClientPackage:     o.ClientPackage,
-		Principal:         o.Principal,
-		DumpData:          o.DumpData,
-		DefaultScheme:     o.DefaultScheme,
-		TemplateDir:       string(o.TemplateDir),
-		IncludeHandler:    !o.NoHandler,
-		IncludeResponses:  !o.NoResponses,
-		IncludeParameters: !o.NoStruct,
-		IncludeURLBuilder: !o.NoURLBuilder,
-		Tags:              o.Tags,
-		ValidateSpec:      !o.SkipValidation,
-	}, nil
+	NoHandler    bool `long:"skip-handler" description:"when present will not generate an operation handler"`
+	NoStruct     bool `long:"skip-parameters" description:"when present will not generate the parameter model struct"`
+	NoResponses  bool `long:"skip-responses" description:"when present will not generate the response model struct"`
+	NoURLBuilder bool `long:"skip-url-builder" description:"when present will not generate a URL builder"`
+
+	Name []string `long:"name" short:"n" required:"true" description:"the operations to generate, repeat for multiple (defaults to all). Same as --operations"`
 }
 
-func (o *Operation) getShared() *shared {
-	return &o.shared
+func (o Operation) apply(opts *generator.GenOpts) {
+	o.Shared.apply(opts)
+	o.Operations.apply(opts)
+	o.clientOptions.apply(opts)
+	o.serverOptions.apply(opts)
+	o.schemeOptions.apply(opts)
+	o.mediaOptions.apply(opts)
+
+	opts.IncludeHandler = !o.NoHandler
+	opts.IncludeResponses = !o.NoResponses
+	opts.IncludeParameters = !o.NoStruct
+	opts.IncludeURLBuilder = !o.NoURLBuilder
 }
 
 func (o *Operation) generate(opts *generator.GenOpts) error {
-	return generator.GenerateServerOperation(o.Name, opts)
+	return generator.GenerateServerOperation(append(o.Name, o.Operations.Operations...), opts)
 }
 
-func (o *Operation) log(rp string) {
+func (o Operation) log(rp string) {
 
 	log.Printf(`Generation completed!
 
@@ -79,7 +88,7 @@ You can get these now with: go get -u -f %s/...
 
 // Execute generates a model file
 func (o *Operation) Execute(args []string) error {
-	if o.DumpData && len(o.Name) > 1 {
+	if o.Shared.DumpData && (len(o.Name) > 1 || len(o.Operations.Operations) > 1) {
 		return errors.New("only 1 operation at a time is supported for dumping data")
 	}
 
diff --git a/cmd/swagger/commands/generate/server.go b/cmd/swagger/commands/generate/server.go
index a8c4e5a0..fdbdd9c2 100644
--- a/cmd/swagger/commands/generate/server.go
+++ b/cmd/swagger/commands/generate/server.go
@@ -21,87 +21,79 @@ import (
 	"github.com/go-swagger/go-swagger/generator"
 )
 
+type serverOptions struct {
+	ServerPackage string `long:"server-package" short:"s" description:"the package to save the server specific code" default:"restapi"`
+}
+
+func (cs serverOptions) apply(opts *generator.GenOpts) {
+	opts.ServerPackage = cs.ServerPackage
+}
+
 // Server the command to generate an entire server application
 type Server struct {
-	shared
-	Name                       string   `long:"name" short:"A" description:"the name of the application, defaults to a mangled value of info.title"`
-	Operations                 []string `long:"operation" short:"O" description:"specify an operation to include, repeat for multiple"`
-	Tags                       []string `long:"tags" description:"the tags to include, if not specified defaults to all"`
-	Principal                  string   `long:"principal" short:"P" description:"the model to use for the security principal"`
-	DefaultScheme              string   `long:"default-scheme" description:"the default scheme for this API" default:"http"`
-	Models                     []string `long:"model" short:"M" description:"specify a model to include, repeat for multiple"`
-	SkipModels                 bool     `long:"skip-models" description:"no models will be generated when this flag is specified"`
-	SkipOperations             bool     `long:"skip-operations" description:"no operations will be generated when this flag is specified"`
-	SkipSupport                bool     `long:"skip-support" description:"no supporting files will be generated when this flag is specified"`
-	ExcludeMain                bool     `long:"exclude-main" description:"exclude main function, so just generate the library"`
-	ExcludeSpec                bool     `long:"exclude-spec" description:"don't embed the swagger specification"`
-	WithContext                bool     `long:"with-context" description:"handlers get a context as first arg (deprecated)"`
-	DumpData                   bool     `long:"dump-data" description:"when present dumps the json for the template generator instead of generating files"`
-	FlagStrategy               string   `long:"flag-strategy" description:"the strategy to provide flags for the server" default:"go-flags" choice:"go-flags" choice:"pflag" choice:"flag"`
-	CompatibilityMode          string   `long:"compatibility-mode" description:"the compatibility mode for the tls server" default:"modern" choice:"modern" choice:"intermediate"`
-	SkipValidation             bool     `long:"skip-validation" description:"skips validation of spec prior to generation"`
-	RegenerateConfigureAPI     bool     `long:"regenerate-configureapi" description:"Force regeneration of configureapi.go"`
-	KeepSpecOrder              bool     `long:"keep-spec-order" description:"Keep schema properties order identical to spec file"`
-	StrictAdditionalProperties bool     `long:"strict-additional-properties" description:"disallow extra properties when additionalProperties is set to false"`
+	WithShared
+	WithModels
+	WithOperations
+
+	serverOptions
+	schemeOptions
+	mediaOptions
+
+	SkipModels             bool   `long:"skip-models" description:"no models will be generated when this flag is specified"`
+	SkipOperations         bool   `long:"skip-operations" description:"no operations will be generated when this flag is specified"`
+	SkipSupport            bool   `long:"skip-support" description:"no supporting files will be generated when this flag is specified"`
+	ExcludeMain            bool   `long:"exclude-main" description:"exclude main function, so just generate the library"`
+	ExcludeSpec            bool   `long:"exclude-spec" description:"don't embed the swagger specification"`
+	FlagStrategy           string `long:"flag-strategy" description:"the strategy to provide flags for the server" default:"go-flags" choice:"go-flags" choice:"pflag" choice:"flag"` // nolint: staticcheck
+	CompatibilityMode      string `long:"compatibility-mode" description:"the compatibility mode for the tls server" default:"modern" choice:"modern" choice:"intermediate"`          // nolint: staticcheck
+	RegenerateConfigureAPI bool   `long:"regenerate-configureapi" description:"Force regeneration of configureapi.go"`
+
+	Name string `long:"name" short:"A" description:"the name of the application, defaults to a mangled value of info.title"`
+	// TODO(fredbi): CmdName string `long:"cmd-name" short:"A" description:"the name of the server command, when main is generated (defaults to {name}-server)"`
+
+	//deprecated flags
+	WithContext bool `long:"with-context" description:"handlers get a context as first arg (deprecated)"`
 }
 
-func (s *Server) getOpts() (*generator.GenOpts, error) {
-	// warning: deprecation
+func (s Server) apply(opts *generator.GenOpts) {
 	if s.WithContext {
 		log.Printf("warning: deprecated option --with-context is ignored")
 	}
 
-	return &generator.GenOpts{
-		Spec:                       string(s.Spec),
-		Target:                     string(s.Target),
-		APIPackage:                 s.APIPackage,
-		ModelPackage:               s.ModelPackage,
-		ServerPackage:              s.ServerPackage,
-		ClientPackage:              s.ClientPackage,
-		Principal:                  s.Principal,
-		DefaultScheme:              s.DefaultScheme,
-		IncludeModel:               !s.SkipModels,
-		IncludeValidator:           !s.SkipModels,
-		IncludeHandler:             !s.SkipOperations,
-		IncludeParameters:          !s.SkipOperations,
-		IncludeResponses:           !s.SkipOperations,
-		IncludeURLBuilder:          !s.SkipOperations,
-		IncludeMain:                !s.ExcludeMain,
-		IncludeSupport:             !s.SkipSupport,
-		PropertiesSpecOrder:        s.KeepSpecOrder,
-		ValidateSpec:               !s.SkipValidation,
-		ExcludeSpec:                s.ExcludeSpec,
-		StrictAdditionalProperties: s.StrictAdditionalProperties,
-		Template:                   s.Template,
-		RegenerateConfigureAPI:     s.RegenerateConfigureAPI,
-		TemplateDir:                string(s.TemplateDir),
-		DumpData:                   s.DumpData,
-		Models:                     s.Models,
-		Operations:                 s.Operations,
-		Tags:                       s.Tags,
-		Name:                       s.Name,
-		FlagStrategy:               s.FlagStrategy,
-		CompatibilityMode:          s.CompatibilityMode,
-		ExistingModels:             s.ExistingModels,
-		AllowTemplateOverride:      s.AllowTemplateOverride,
-	}, nil
-}
+	s.Shared.apply(opts)
+	s.Models.apply(opts)
+	s.Operations.apply(opts)
+	s.serverOptions.apply(opts)
+	s.schemeOptions.apply(opts)
+	s.mediaOptions.apply(opts)
+
+	opts.IncludeModel = !s.SkipModels
+	opts.IncludeValidator = !s.SkipModels
+	opts.IncludeHandler = !s.SkipOperations
+	opts.IncludeParameters = !s.SkipOperations
+	opts.IncludeResponses = !s.SkipOperations
+	opts.IncludeURLBuilder = !s.SkipOperations
+	opts.IncludeSupport = !s.SkipSupport
+	opts.IncludeMain = !s.ExcludeMain
+	opts.FlagStrategy = s.FlagStrategy
+	opts.CompatibilityMode = s.CompatibilityMode
+	opts.RegenerateConfigureAPI = s.RegenerateConfigureAPI
 
-func (s *Server) getShared() *shared {
-	return &s.shared
+	opts.Name = s.Name
 }
 
 func (s *Server) generate(opts *generator.GenOpts) error {
-	return generator.GenerateServer(s.Name, s.Models, s.Operations, opts)
+	return generator.GenerateServer(s.Name, s.Models.Models, s.Operations.Operations, opts)
 }
 
-func (s *Server) log(rp string) {
+func (s Server) log(rp string) {
 	var flagsPackage string
-	if strings.HasPrefix(s.FlagStrategy, "pflag") {
+	switch {
+	case strings.HasPrefix(s.FlagStrategy, "pflag"):
 		flagsPackage = "github.com/spf13/pflag"
-	} else if strings.HasPrefix(s.FlagStrategy, "flag") {
+	case strings.HasPrefix(s.FlagStrategy, "flag"):
 		flagsPackage = "flag"
-	} else {
+	default:
 		flagsPackage = "github.com/jessevdk/go-flags"
 	}
 
diff --git a/cmd/swagger/commands/generate/shared.go b/cmd/swagger/commands/generate/shared.go
index 90bd3513..28121548 100644
--- a/cmd/swagger/commands/generate/shared.go
+++ b/cmd/swagger/commands/generate/shared.go
@@ -1,6 +1,7 @@
 package generate
 
 import (
+	"fmt"
 	"io/ioutil"
 	"log"
 	"os"
@@ -15,8 +16,8 @@ import (
 
 // FlattenCmdOptions determines options to the flatten spec preprocessing
 type FlattenCmdOptions struct {
-	WithExpand  bool     `long:"with-expand" description:"expands all $ref's in spec prior to generation (shorthand to --with-flatten=expand)"`
-	WithFlatten []string `long:"with-flatten" description:"flattens all $ref's in spec prior to generation" choice:"minimal" choice:"full" choice:"expand" choice:"verbose" choice:"noverbose" choice:"remove-unused" default:"minimal" default:"verbose"`
+	WithExpand  bool     `long:"with-expand" description:"expands all $ref's in spec prior to generation (shorthand to --with-flatten=expand)"  group:"shared"`
+	WithFlatten []string `long:"with-flatten" description:"flattens all $ref's in spec prior to generation" choice:"minimal" choice:"full" choice:"expand" choice:"verbose" choice:"noverbose" choice:"remove-unused" default:"minimal" default:"verbose" group:"shared"` // nolint: staticcheck
 }
 
 // SetFlattenOptions builds flatten options from command line args
@@ -30,138 +31,154 @@ func (f *FlattenCmdOptions) SetFlattenOptions(dflt *analysis.FlattenOpts) (res *
 	}
 	verboseIsSet := false
 	minimalIsSet := false
-	//removeUnusedIsSet := false
 	expandIsSet := false
 	if f.WithExpand {
 		res.Expand = true
 		expandIsSet = true
 	}
 	for _, opt := range f.WithFlatten {
-		if opt == "verbose" {
+		switch opt {
+		case "verbose":
 			res.Verbose = true
 			verboseIsSet = true
-		}
-		if opt == "noverbose" && !verboseIsSet {
-			// verbose flag takes precedence
-			res.Verbose = false
-			verboseIsSet = true
-		}
-		if opt == "remove-unused" {
+		case "noverbose":
+			if !verboseIsSet {
+				// verbose flag takes precedence
+				res.Verbose = false
+				verboseIsSet = true
+			}
+		case "remove-unused":
 			res.RemoveUnused = true
-			//removeUnusedIsSet = true
-		}
-		if opt == "expand" {
+		case "expand":
 			res.Expand = true
 			expandIsSet = true
-		}
-		if opt == "full" && !minimalIsSet && !expandIsSet {
-			// minimal flag takes precedence
-			res.Minimal = false
-			minimalIsSet = true
-		}
-		if opt == "minimal" && !expandIsSet {
-			// expand flag takes precedence
-			res.Minimal = true
-			minimalIsSet = true
+		case "full":
+			if !minimalIsSet && !expandIsSet {
+				// minimal flag takes precedence
+				res.Minimal = false
+				minimalIsSet = true
+			}
+		case "minimal":
+			if !expandIsSet {
+				// expand flag takes precedence
+				res.Minimal = true
+				minimalIsSet = true
+			}
 		}
 	}
 	return
 }
 
-type shared struct {
-	Spec                  flags.Filename `long:"spec" short:"f" description:"the spec file to use (default swagger.{json,yml,yaml})"`
-	APIPackage            string         `long:"api-package" short:"a" description:"the package to save the operations" default:"operations"`
-	ModelPackage          string         `long:"model-package" short:"m" description:"the package to save the models" default:"models"`
-	ServerPackage         string         `long:"server-package" short:"s" description:"the package to save the server specific code" default:"restapi"`
-	ClientPackage         string         `long:"client-package" short:"c" description:"the package to save the client specific code" default:"client"`
-	Target                flags.Filename `long:"target" short:"t" default:"./" description:"the base directory for generating the files"`
-	Template              string         `long:"template" description:"Load contributed templates" choice:"stratoscale"`
-	TemplateDir           flags.Filename `long:"template-dir" short:"T" description:"alternative template override directory"`
-	ConfigFile            flags.Filename `long:"config-file" short:"C" description:"configuration file to use for overriding template options"`
-	CopyrightFile         flags.Filename `long:"copyright-file" short:"r" description:"copyright file used to add copyright header"`
-	ExistingModels        string         `long:"existing-models" description:"use pre-generated models e.g. github.com/foobar/model"`
-	AdditionalInitialisms []string       `long:"additional-initialism" description:"consecutive capitals that should be considered intialisms"`
-	AllowTemplateOverride bool           `long:"allow-template-override" description:"allows overriding protected templates"`
-	FlattenCmdOptions
-}
-
 type sharedCommand interface {
-	getOpts() (*generator.GenOpts, error)
-	getShared() *shared
-	getConfigFile() flags.Filename
-	getAdditionalInitialisms() []string
+	apply(*generator.GenOpts)
+	getConfigFile() string
 	generate(*generator.GenOpts) error
 	log(string)
 }
 
-func (s *shared) getConfigFile() flags.Filename {
-	return s.ConfigFile
+type schemeOptions struct {
+	Principal     string `short:"P" long:"principal" description:"the model to use for the security principal"`
+	DefaultScheme string `long:"default-scheme" description:"the default scheme for this API" default:"http"`
 }
 
-func (s *shared) getAdditionalInitialisms() []string {
-	return s.AdditionalInitialisms
+func (so schemeOptions) apply(opts *generator.GenOpts) {
+	opts.Principal = so.Principal
+	opts.DefaultScheme = so.DefaultScheme
 }
 
-func (s *shared) setCopyright() (string, error) {
-	var copyrightstr string
-	copyrightfile := string(s.CopyrightFile)
-	if copyrightfile != "" {
-		//Read the Copyright from file path in opts
-		bytebuffer, err := ioutil.ReadFile(copyrightfile)
-		if err != nil {
-			return "", err
-		}
-		copyrightstr = string(bytebuffer)
-	} else {
-		copyrightstr = ""
+type mediaOptions struct {
+	DefaultProduces string `long:"default-produces" description:"the default mime type that API operations produce" default:"application/json"`
+	DefaultConsumes string `long:"default-consumes" description:"the default mime type that API operations consume" default:"application/json"`
+}
+
+func (m mediaOptions) apply(opts *generator.GenOpts) {
+	opts.DefaultProduces = m.DefaultProduces
+	opts.DefaultConsumes = m.DefaultConsumes
+}
+
+// WithShared adds the shared options group
+type WithShared struct {
+	Shared sharedOptions `group:"Options common to all code generation commands"`
+}
+
+func (w WithShared) getConfigFile() string {
+	return string(w.Shared.ConfigFile)
+}
+
+type sharedOptions struct {
+	Spec                  flags.Filename `long:"spec" short:"f" description:"the spec file to use (default swagger.{json,yml,yaml})" group:"shared"`
+	Target                flags.Filename `long:"target" short:"t" default:"./" description:"the base directory for generating the files" group:"shared"`
+	Template              string         `long:"template" description:"load contributed templates" choice:"stratoscale" group:"shared"`
+	TemplateDir           flags.Filename `long:"template-dir" short:"T" description:"alternative template override directory" group:"shared"`
+	ConfigFile            flags.Filename `long:"config-file" short:"C" description:"configuration file to use for overriding template options" group:"shared"`
+	CopyrightFile         flags.Filename `long:"copyright-file" short:"r" description:"copyright file used to add copyright header" group:"shared"`
+	AdditionalInitialisms []string       `long:"additional-initialism" description:"consecutive capitals that should be considered intialisms" group:"shared"`
+	AllowTemplateOverride bool           `long:"allow-template-override" description:"allows overriding protected templates" group:"shared"`
+	SkipValidation        bool           `long:"skip-validation" description:"skips validation of spec prior to generation" group:"shared"`
+	DumpData              bool           `long:"dump-data" description:"when present dumps the json for the template generator instead of generating files" group:"shared"`
+	FlattenCmdOptions
+}
+
+func (s sharedOptions) apply(opts *generator.GenOpts) {
+	opts.Spec = string(s.Spec)
+	opts.Target = string(s.Target)
+	opts.Template = s.Template
+	opts.TemplateDir = string(s.TemplateDir)
+	opts.AllowTemplateOverride = s.AllowTemplateOverride
+	opts.ValidateSpec = !s.SkipValidation
+	opts.DumpData = s.DumpData
+	opts.FlattenOpts = s.FlattenCmdOptions.SetFlattenOptions(opts.FlattenOpts)
+	opts.Copyright = string(s.CopyrightFile)
+
+	swag.AddInitialisms(s.AdditionalInitialisms...)
+}
+
+func setCopyright(copyrightFile string) (string, error) {
+	// read the Copyright from file path in opts
+	if copyrightFile == "" {
+		return "", nil
 	}
-	return copyrightstr, nil
+	bytebuffer, err := ioutil.ReadFile(copyrightFile)
+	if err != nil {
+		return "", err
+	}
+	return string(bytebuffer), nil
 }
 
 func createSwagger(s sharedCommand) error {
-	cfg, erc := readConfig(string(s.getConfigFile()))
-	if erc != nil {
-		return erc
+	cfg, err := readConfig(s.getConfigFile())
+	if err != nil {
+		return err
 	}
-	setDebug(cfg)
+	setDebug(cfg) // viper config Debug
 
-	opts, ero := s.getOpts()
-	if ero != nil {
-		return ero
+	opts := new(generator.GenOpts)
+	s.apply(opts)
+
+	opts.Copyright, err = setCopyright(opts.Copyright)
+	if err != nil {
+		return fmt.Errorf("could not load copyright file: %v", err)
 	}
 
 	if opts.Template != "" {
 		contribOptionsOverride(opts)
 	}
 
-	if err := opts.EnsureDefaults(); err != nil {
+	if err = opts.EnsureDefaults(); err != nil {
 		return err
 	}
 
-	if err := configureOptsFromConfig(cfg, opts); err != nil {
+	if err = configureOptsFromConfig(cfg, opts); err != nil {
 		return err
 	}
 
-	swag.AddInitialisms(s.getAdditionalInitialisms()...)
-
-	if sharedOpts := s.getShared(); sharedOpts != nil {
-		// process shared options
-		opts.FlattenOpts = sharedOpts.FlattenCmdOptions.SetFlattenOptions(opts.FlattenOpts)
-
-		copyrightStr, erc := sharedOpts.setCopyright()
-		if erc != nil {
-			return erc
-		}
-		opts.Copyright = copyrightStr
-	}
-
-	if err := s.generate(opts); err != nil {
+	if err = s.generate(opts); err != nil {
 		return err
 	}
 
-	basepath, era := filepath.Abs(".")
-	if era != nil {
-		return era
+	basepath, err := filepath.Abs(".")
+	if err != nil {
+		return err
 	}
 
 	targetAbs, err := filepath.Abs(opts.Target)
@@ -204,11 +221,12 @@ func configureOptsFromConfig(cfg *viper.Viper, opts *generator.GenOpts) error {
 }
 
 func setDebug(cfg *viper.Viper) {
+	// viper config debug
 	if os.Getenv("DEBUG") != "" || os.Getenv("SWAGGER_DEBUG") != "" {
 		if cfg != nil {
 			cfg.Debug()
 		} else {
-			log.Println("NO config read")
+			log.Println("No config read")
 		}
 	}
 }
diff --git a/cmd/swagger/commands/generate/support.go b/cmd/swagger/commands/generate/support.go
index fc32d725..ad790afd 100644
--- a/cmd/swagger/commands/generate/support.go
+++ b/cmd/swagger/commands/generate/support.go
@@ -22,40 +22,33 @@ import (
 
 // Support generates the supporting files
 type Support struct {
-	shared
-	Name          string   `long:"name" short:"A" description:"the name of the application, defaults to a mangled value of info.title"`
-	Operations    []string `long:"operation" short:"O" description:"specify an operation to include, repeat for multiple"`
-	Principal     string   `long:"principal" description:"the model to use for the security principal"`
-	Models        []string `long:"model" short:"M" description:"specify a model to include, repeat for multiple"`
-	DumpData      bool     `long:"dump-data" description:"when present dumps the json for the template generator instead of generating files"`
-	DefaultScheme string   `long:"default-scheme" description:"the default scheme for this API" default:"http"`
-}
+	WithShared
+	WithModels
+	WithOperations
+
+	clientOptions
+	serverOptions
+	schemeOptions
+	mediaOptions
 
-func (s *Support) getOpts() (*generator.GenOpts, error) {
-	return &generator.GenOpts{
-		Spec:          string(s.Spec),
-		Target:        string(s.Target),
-		APIPackage:    s.APIPackage,
-		ModelPackage:  s.ModelPackage,
-		ServerPackage: s.ServerPackage,
-		ClientPackage: s.ClientPackage,
-		Principal:     s.Principal,
-		DumpData:      s.DumpData,
-		DefaultScheme: s.DefaultScheme,
-		Template:      s.Template,
-		TemplateDir:   string(s.TemplateDir),
-	}, nil
+	Name string `long:"name" short:"A" description:"the name of the application, defaults to a mangled value of info.title"`
 }
 
-func (s *Support) getShared() *shared {
-	return &s.shared
+func (s *Support) apply(opts *generator.GenOpts) {
+	s.Shared.apply(opts)
+	s.Models.apply(opts)
+	s.Operations.apply(opts)
+	s.clientOptions.apply(opts)
+	s.serverOptions.apply(opts)
+	s.schemeOptions.apply(opts)
+	s.mediaOptions.apply(opts)
 }
 
 func (s *Support) generate(opts *generator.GenOpts) error {
-	return generator.GenerateSupport(s.Name, nil, nil, opts)
+	return generator.GenerateSupport(s.Name, s.Models.Models, s.Operations.Operations, opts)
 }
 
-func (s *Support) log(rp string) {
+func (s Support) log(rp string) {
 
 	log.Printf(`Generation completed!
 
diff --git a/codescan/application.go b/codescan/application.go
index 3eb6b7fc..7b156a85 100644
--- a/codescan/application.go
+++ b/codescan/application.go
@@ -3,6 +3,7 @@ package codescan
 import (
 	"fmt"
 	"go/ast"
+	"go/token"
 	"go/types"
 	"log"
 	"os"
@@ -352,6 +353,36 @@ func (s *scanCtx) FindComments(pkg *packages.Package, name string) (*ast.Comment
 	return nil, false
 }
 
+func (s *scanCtx) FindEnumValues(pkg *packages.Package, enumName string) (list []interface{}, _ bool) {
+	for _, f := range pkg.Syntax {
+		for _, d := range f.Decls {
+			gd, ok := d.(*ast.GenDecl)
+			if !ok {
+				continue
+			}
+
+			if gd.Tok != token.CONST {
+				continue
+			}
+
+			for _, s := range gd.Specs {
+				if vs, ok := s.(*ast.ValueSpec); ok {
+					if vsIdent, ok := vs.Type.(*ast.Ident); ok {
+						if vsIdent.Name == enumName {
+							if len(vs.Values) > 0 {
+								if bl, ok := vs.Values[0].(*ast.BasicLit); ok {
+									list = append(list, getEnumBasicLitValue(bl))
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	return list, true
+}
+
 func newTypeIndex(pkgs []*packages.Package,
 	excludeDeps bool, includeTags, excludeTags map[string]bool,
 	includePkgs, excludePkgs []string) (*typeIndex, error) {
diff --git a/codescan/enum.go b/codescan/enum.go
new file mode 100644
index 00000000..b8bd8aff
--- /dev/null
+++ b/codescan/enum.go
@@ -0,0 +1,23 @@
+package codescan
+
+import (
+	"go/ast"
+	"strconv"
+	"strings"
+)
+
+func getEnumBasicLitValue(basicLit *ast.BasicLit) interface{} {
+	switch basicLit.Kind.String() {
+	case "INT":
+		if result, err := strconv.ParseInt(basicLit.Value, 10, 64); err == nil {
+			return result
+		}
+	case "FLOAT":
+		if result, err := strconv.ParseFloat(basicLit.Value, 64); err == nil {
+			return result
+		}
+	default:
+		return strings.Trim(basicLit.Value, "\"")
+	}
+	return nil
+}
diff --git a/codescan/parameters.go b/codescan/parameters.go
index 5e5bc7f8..b5f0a936 100644
--- a/codescan/parameters.go
+++ b/codescan/parameters.go
@@ -59,6 +59,10 @@ func (pt paramTypable) AddExtension(key string, value interface{}) {
 	}
 }
 
+func (pt paramTypable) WithEnum(values ...interface{}) {
+	pt.param.WithEnum(values...)
+}
+
 type itemsTypable struct {
 	items *spec.Items
 	level int
@@ -90,6 +94,10 @@ func (pt itemsTypable) AddExtension(key string, value interface{}) {
 	pt.items.AddExtension(key, value)
 }
 
+func (pt itemsTypable) WithEnum(values ...interface{}) {
+	pt.items.WithEnum(values...)
+}
+
 type paramValidations struct {
 	current *spec.Parameter
 }
diff --git a/codescan/parser.go b/codescan/parser.go
index bbdae2df..8c45aedf 100644
--- a/codescan/parser.go
+++ b/codescan/parser.go
@@ -200,6 +200,7 @@ type swaggerTypable interface {
 	Schema() *spec.Schema
 	Level() int
 	AddExtension(key string, value interface{})
+	WithEnum(...interface{})
 }
 
 // Map all Go builtin types that have Json representation to Swagger/Json types.
diff --git a/codescan/responses.go b/codescan/responses.go
index e2279c52..7c92c488 100644
--- a/codescan/responses.go
+++ b/codescan/responses.go
@@ -72,13 +72,19 @@ func (ht responseTypable) Schema() *spec.Schema {
 func (ht responseTypable) SetSchema(schema *spec.Schema) {
 	ht.response.Schema = schema
 }
+
 func (ht responseTypable) CollectionOf(items *spec.Items, format string) {
 	ht.header.CollectionOf(items, format)
 }
+
 func (ht responseTypable) AddExtension(key string, value interface{}) {
 	ht.response.AddExtension(key, value)
 }
 
+func (ht responseTypable) WithEnum(values ...interface{}) {
+	ht.header.WithEnum(values)
+}
+
 type headerValidations struct {
 	current *spec.Header
 }
diff --git a/codescan/schema.go b/codescan/schema.go
index 27a04a16..c5fd0898 100644
--- a/codescan/schema.go
+++ b/codescan/schema.go
@@ -65,11 +65,17 @@ func (st schemaTypable) AdditionalProperties() swaggerTypable {
 	st.schema.Typed("object", "")
 	return schemaTypable{st.schema.AdditionalProperties.Schema, st.level + 1}
 }
+
 func (st schemaTypable) Level() int { return st.level }
+
 func (st schemaTypable) AddExtension(key string, value interface{}) {
 	addExtension(&st.schema.VendorExtensible, key, value)
 }
 
+func (st schemaTypable) WithEnum(values ...interface{}) {
+	st.schema.WithEnum(values...)
+}
+
 type schemaValidations struct {
 	current *spec.Schema
 }
@@ -302,7 +308,12 @@ func (s *schemaBuilder) buildFromType(tpe types.Type, tgt swaggerTypable) error
 			}
 
 			if enumName, ok := enumName(cmt); ok {
-				debugLog(enumName)
+				enumValues, _ := s.ctx.FindEnumValues(pkg, enumName)
+				if len(enumValues) > 0 {
+					tgt.WithEnum(enumValues...)
+					enumTypeName := reflect.TypeOf(enumValues[0]).String()
+					_ = swaggerSchemaForType(enumTypeName, tgt)
+				}
 				return nil
 			}
 
diff --git a/docs/generate/client.md b/docs/generate/client.md
index d8fdbb28..5d22b0a0 100644
--- a/docs/generate/client.md
+++ b/docs/generate/client.md
@@ -18,32 +18,40 @@ Help Options:
   -h, --help                                                                      Show this help message
 
 [client command options]
-      -f, --spec=                                                                 the spec file to use (default swagger.{json,yml,yaml})
-      -a, --api-package=                                                          the package to save the operations (default: operations)
-      -m, --model-package=                                                        the package to save the models (default: models)
-      -s, --server-package=                                                       the package to save the server specific code (default: restapi)
       -c, --client-package=                                                       the package to save the client specific code (default: client)
+      -P, --principal=                                                            the model to use for the security principal
+          --default-scheme=                                                       the default scheme for this API (default: http)
+          --default-produces=                                                     the default mime type that API operations produce (default: application/json)
+          --default-consumes=                                                     the default mime type that API operations consume (default: application/json)
+          --skip-models                                                           no models will be generated when this flag is specified
+          --skip-operations                                                       no operations will be generated when this flag is specified
+      -A, --name=                                                                 the name of the application, defaults to a mangled value of info.title
+
+    Options common to all code generation commands:
+      -f, --spec=                                                                 the spec file to use (default swagger.{json,yml,yaml})
       -t, --target=                                                               the base directory for generating the files (default: ./)
-          --template=[stratoscale]                                                Load contributed templates
+          --template=[stratoscale]                                                load contributed templates
       -T, --template-dir=                                                         alternative template override directory
-          --allow-template-override                                               allows overriding protected templates
       -C, --config-file=                                                          configuration file to use for overriding template options
       -r, --copyright-file=                                                       copyright file used to add copyright header
-          --existing-models=                                                      use pre-generated models e.g. github.com/foobar/model
           --additional-initialism=                                                consecutive capitals that should be considered intialisms
+          --allow-template-override                                               allows overriding protected templates
+          --skip-validation                                                       skips validation of spec prior to generation
+          --dump-data                                                             when present dumps the json for the template generator instead of generating files
           --with-expand                                                           expands all $ref's in spec prior to generation (shorthand to --with-flatten=expand)
           --with-flatten=[minimal|full|expand|verbose|noverbose|remove-unused]    flattens all $ref's in spec prior to generation (default: minimal, verbose)
-      -A, --name=                                                                 the name of the application, defaults to a mangled value of info.title
-      -O, --operation=                                                            specify an operation to include, repeat for multiple
+
+    Options for model generation:
+      -m, --model-package=                                                        the package to save the models (default: models)
+      -M, --model=                                                                specify a model to include in generation, repeat for multiple (defaults to all)
+          --existing-models=                                                      use pre-generated models e.g. github.com/foobar/model
+          --strict-additional-properties                                          disallow extra properties when additionalProperties is set to false
+          --keep-spec-order                                                       keep schema properties order identical to spec file
+
+    Options for operation generation:
+      -O, --operation=                                                            specify an operation to include, repeat for multiple (defaults to all)
           --tags=                                                                 the tags to include, if not specified defaults to all
-      -P, --principal=                                                            the model to use for the security principal
-      -M, --model=                                                                specify a model to include, repeat for multiple
-          --default-scheme=                                                       the default scheme for this client (default: http)
-          --default-produces=                                                     the default mime type that API operations produce (default: application/json)
-          --skip-models                                                           no models will be generated when this flag is specified
-          --skip-operations                                                       no operations will be generated when this flag is specified
-          --dump-data                                                             when present dumps the json for the template generator instead of generating files
-          --skip-validation                                                       skips validation of spec prior to generation
+      -a, --api-package=                                                          the package to save the operations (default: operations)
 ```
 
 ### Build a client
diff --git a/docs/generate/model.md b/docs/generate/model.md
index 23df4b52..f6c490d6 100644
--- a/docs/generate/model.md
+++ b/docs/generate/model.md
@@ -15,25 +15,29 @@ Help Options:
   -h, --help                                                                      Show this help message
 
 [model command options]
+          --skip-struct                                                           when present will not generate the model struct
+      -n, --name=                                                                 the model to generate, repeat for multiple (defaults to all). Same as --models
+
+    Options common to all code generation commands:
       -f, --spec=                                                                 the spec file to use (default swagger.{json,yml,yaml})
-      -a, --api-package=                                                          the package to save the operations (default: operations)
-      -m, --model-package=                                                        the package to save the models (default: models)
-      -s, --server-package=                                                       the package to save the server specific code (default: restapi)
-      -c, --client-package=                                                       the package to save the client specific code (default: client)
       -t, --target=                                                               the base directory for generating the files (default: ./)
-          --template=[stratoscale]                                                Load contributed templates
+          --template=[stratoscale]                                                load contributed templates
       -T, --template-dir=                                                         alternative template override directory
-          --allow-template-override                                               allows overriding protected templates
       -C, --config-file=                                                          configuration file to use for overriding template options
       -r, --copyright-file=                                                       copyright file used to add copyright header
-          --existing-models=                                                      use pre-generated models e.g. github.com/foobar/model
           --additional-initialism=                                                consecutive capitals that should be considered intialisms
+          --allow-template-override                                               allows overriding protected templates
+          --skip-validation                                                       skips validation of spec prior to generation
+          --dump-data                                                             when present dumps the json for the template generator instead of generating files
           --with-expand                                                           expands all $ref's in spec prior to generation (shorthand to --with-flatten=expand)
           --with-flatten=[minimal|full|expand|verbose|noverbose|remove-unused]    flattens all $ref's in spec prior to generation (default: minimal, verbose)
-      -n, --name=                                                                 the model to generate
-          --skip-struct                                                           when present will not generate the model struct
-          --dump-data                                                             when present dumps the json for the template generator instead of generating files
-          --skip-validation                                                       skips validation of spec prior to generation
+
+    Options for model generation:
+      -m, --model-package=                                                        the package to save the models (default: models)
+      -M, --model=                                                                specify a model to include in generation, repeat for multiple (defaults to all)
+          --existing-models=                                                      use pre-generated models e.g. github.com/foobar/model
+          --strict-additional-properties                                          disallow extra properties when additionalProperties is set to false
+          --keep-spec-order                                                       keep schema properties order identical to spec file
 ```
 
 Schema generation rules are detailed [here](../use/model.md).
diff --git a/docs/generate/server.md b/docs/generate/server.md
index 8ae1eee1..b4812348 100644
--- a/docs/generate/server.md
+++ b/docs/generate/server.md
@@ -27,40 +27,47 @@ Help Options:
   -h, --help                                                                      Show this help message
 
 [server command options]
-      -f, --spec=                                                                 the spec file to use (default swagger.{json,yml,yaml})
-      -a, --api-package=                                                          the package to save the operations (default: operations)
-      -m, --model-package=                                                        the package to save the models (default: models)
       -s, --server-package=                                                       the package to save the server specific code (default: restapi)
-      -c, --client-package=                                                       the package to save the client specific code (default: client)
-      -t, --target=                                                               the base directory for generating the files (default: ./)
-          --template=[stratoscale]                                                Load contributed templates
-      -T, --template-dir=                                                         alternative template override directory
-          --allow-template-override                                               allows overriding protected templates
-      -C, --config-file=                                                          configuration file to use for overriding template options
-      -r, --copyright-file=                                                       copyright file used to add copyright header
-          --existing-models=                                                      use pre-generated models e.g. github.com/foobar/model
-          --additional-initialism=                                                consecutive capitals that should be considered intialisms
-          --with-expand                                                           expands all $ref's in spec prior to generation (shorthand to --with-flatten=expand)
-          --with-flatten=[minimal|full|expand|verbose|noverbose|remove-unused]    flattens all $ref's in spec prior to generation (default: minimal, verbose)
-      -A, --name=                                                                 the name of the application, defaults to a mangled value of info.title
-      -O, --operation=                                                            specify an operation to include, repeat for multiple
-          --tags=                                                                 the tags to include, if not specified defaults to all
       -P, --principal=                                                            the model to use for the security principal
           --default-scheme=                                                       the default scheme for this API (default: http)
-      -M, --model=                                                                specify a model to include, repeat for multiple
+          --default-produces=                                                     the default mime type that API operations produce (default: application/json)
+          --default-consumes=                                                     the default mime type that API operations consume (default: application/json)
           --skip-models                                                           no models will be generated when this flag is specified
           --skip-operations                                                       no operations will be generated when this flag is specified
           --skip-support                                                          no supporting files will be generated when this flag is specified
           --exclude-main                                                          exclude main function, so just generate the library
           --exclude-spec                                                          don't embed the swagger specification
-          --with-context                                                          handlers get a context as first arg (deprecated)
-          --dump-data                                                             when present dumps the json for the template generator instead of generating files
           --flag-strategy=[go-flags|pflag|flag]                                   the strategy to provide flags for the server (default: go-flags)
           --compatibility-mode=[modern|intermediate]                              the compatibility mode for the tls server (default: modern)
-          --skip-validation                                                       skips validation of spec prior to generation
           --regenerate-configureapi                                               Force regeneration of configureapi.go
-          --keep-spec-order                                                       Keep schema properties order identical to spec file
+      -A, --name=                                                                 the name of the application, defaults to a mangled value of info.title
+          --with-context                                                          handlers get a context as first arg (deprecated)
+
+    Options common to all code generation commands:
+      -f, --spec=                                                                 the spec file to use (default swagger.{json,yml,yaml})
+      -t, --target=                                                               the base directory for generating the files (default: ./)
+          --template=[stratoscale]                                                load contributed templates
+      -T, --template-dir=                                                         alternative template override directory
+      -C, --config-file=                                                          configuration file to use for overriding template options
+      -r, --copyright-file=                                                       copyright file used to add copyright header
+          --additional-initialism=                                                consecutive capitals that should be considered intialisms
+          --allow-template-override                                               allows overriding protected templates
+          --skip-validation                                                       skips validation of spec prior to generation
+          --dump-data                                                             when present dumps the json for the template generator instead of generating files
+          --with-expand                                                           expands all $ref's in spec prior to generation (shorthand to --with-flatten=expand)
+          --with-flatten=[minimal|full|expand|verbose|noverbose|remove-unused]    flattens all $ref's in spec prior to generation (default: minimal, verbose)
+
+    Options for model generation:
+      -m, --model-package=                                                        the package to save the models (default: models)
+      -M, --model=                                                                specify a model to include in generation, repeat for multiple (defaults to all)
+          --existing-models=                                                      use pre-generated models e.g. github.com/foobar/model
           --strict-additional-properties                                          disallow extra properties when additionalProperties is set to false
+          --keep-spec-order                                                       keep schema properties order identical to spec file
+
+    Options for operation generation:
+      -O, --operation=                                                            specify an operation to include, repeat for multiple (defaults to all)
+          --tags=                                                                 the tags to include, if not specified defaults to all
+      -a, --api-package=                                                          the package to save the operations (default: operations)
 ```
 
 ### Build a server
@@ -70,12 +77,26 @@ The server application gets generated with all the handlers stubbed out with a n
 The generated server allows for a number of command line parameters to customize it.
 
 ```
---host=            the IP to listen on (default: localhost) [$HOST]
---port=            the port to listen on for insecure connections, defaults to a random value [$PORT]
---tls-host=        the IP to listen on for tls, when not specified it's the same as --host [$TLS_HOST]
---tls-port=        the port to listen on for secure connections, defaults to a random value [$TLS_PORT]
---tls-certificate= the certificate to use for secure connections [$TLS_CERTIFICATE]
---tls-key=         the private key to use for secure connections [$TLS_PRIVATE_KEY]
+      --cleanup-timeout duration     grace period for which to wait before killing idle connections (default 10s)
+      --graceful-timeout duration    grace period for which to wait before shutting down the server (default 15s)
+      --host string                  the IP to listen on (default "localhost")
+      --keep-alive duration          sets the TCP keep-alive timeouts on accepted connections. It prunes dead TCP connections ( e.g. closing laptop mid-download) (default 3m0s)
+      --listen-limit int             limit the number of outstanding requests
+      --max-header-size byte-size    controls the maximum number of bytes the server will read parsing the request header's keys and values, including the request line. It does not limit the size of the request body (default 1MB)
+      --port int                     the port to listen on for insecure connections, defaults to a random value
+      --read-timeout duration        maximum duration before timing out read of the request (default 30s)
+      --scheme strings               the listeners to enable, this can be repeated and defaults to the schemes in the swagger spec (default [http,https,unix])
+      --socket-path string           the unix socket to listen on (default "/var/run/todo-list.sock")
+      --tls-ca string                the certificate authority certificate file to be used with mutual tls auth
+      --tls-certificate string       the certificate file to use for secure connections
+      --tls-host string              the IP to listen on (default "localhost")
+      --tls-keep-alive duration      sets the TCP keep-alive timeouts on accepted connections. It prunes dead TCP connections ( e.g. closing laptop mid-download) (default 3m0s)
+      --tls-key string               the private key file to use for secure connections (without passphrase)
+      --tls-listen-limit int         limit the number of outstanding requests
+      --tls-port int                 the port to listen on for secure connections, defaults to a random value
+      --tls-read-timeout duration    maximum duration before timing out read of the request (default 30s)
+      --tls-write-timeout duration   maximum duration before timing out write of the response (default 30s)
+      --write-timeout duration       maximum duration before timing out write of the response (default 30s)
 ```
 
 The server takes care of a number of things when a request arrives:
diff --git a/fixtures/bugs/2116/.gitignore b/fixtures/bugs/2116/.gitignore
new file mode 100644
index 00000000..1e16265b
--- /dev/null
+++ b/fixtures/bugs/2116/.gitignore
@@ -0,0 +1,3 @@
+gen-*
+!gen-fixtures.sh
+*.log
diff --git a/fixtures/bugs/2116/fixture-2116.yaml b/fixtures/bugs/2116/fixture-2116.yaml
new file mode 100644
index 00000000..ed451b19
--- /dev/null
+++ b/fixtures/bugs/2116/fixture-2116.yaml
@@ -0,0 +1,123 @@
+swagger: "2.0"
+info:
+  title: ""
+  version: ""
+paths:
+  /:
+    get:
+      description: ""
+      responses:
+        200:
+          description: ""
+definitions:
+  Case-1--Fail--omitempty-false-not-hoisted-by-ref:
+    type: object
+    properties:
+      Body:
+        $ref: '#/definitions/Object-with-omitempty-false'
+
+  Case-2--Fail--omitempty-false-not-overridden-by-ref-sibling:
+    type: object
+    properties:
+      Body:
+        $ref: '#/definitions/Object-with-omitempty-true'
+        x-omitempty: false
+
+  Case-3--Pass--object-nullable-false-hoisted-by-ref:
+    type: object
+    properties:
+      Body:
+        $ref: '#/definitions/Object-with-nullable-false'
+
+  Case-4--Pass--object-nullable-false-overriden-by-ref-sibling:
+    type: object
+    properties:
+      Body:
+        $ref: '#/definitions/Object-with-nullable-true'
+        x-nullable: false
+
+  Object-with-omitempty-true:
+    type: object
+    properties:
+      Data:
+        type: object
+
+  Object-with-omitempty-false:
+    type: object
+    properties:
+      Data:
+        type: object
+    x-omitempty: false
+
+  Object-with-nullable-true:
+    type: object
+    properties:
+      Data:
+        type: object
+    x-nullable: true
+
+  Object-with-nullable-false:
+    type: object
+    properties:
+      Data:
+        type: object
+    x-nullable: false
+
+  arrayWithNullable:
+    type: array
+    items:
+      type: string
+    x-nullable: true
+
+  arrayWithNullableItems:
+    type: array
+    items:
+      type: string
+      x-nullable: true
+
+  arrayWithDefault:
+    type: array
+    items:
+      type: string
+
+  arrayWithOmitEmpty:
+    type: array
+    items:
+      type: string
+    x-omitempty: true
+
+  arrayWithNoOmitEmpty:
+    type: array
+    items:
+      type: string
+    x-omitempty: false
+
+  arrayWithOmitEmptyItems:
+    type: array
+    items:
+      type: string
+      x-omitempty: false
+
+  objectWithArrays:
+    type: object
+    properties:
+      array0: # <- expect property to be omit empty
+        $ref: '#/definitions/arrayWithDefault'
+      array1: # <- expect property to be no omit empty
+        type: array
+        items:
+          type: string
+        x-omitempty: false
+      array11: # <- expect property to be omit empty
+        type: array
+        items:
+          type: string
+        x-omitempty: true
+      array12: # <- expect property to be no omit empty
+        type: array
+        items:
+          type: string
+      array2: # <- expect property to be omit empty
+        $ref: '#/definitions/arrayWithOmitEmpty'
+      array3: # <- expect property to be no omit empty
+        $ref: '#/definitions/arrayWithNoOmitEmpty'
diff --git a/fixtures/bugs/2116/gen-fixtures.sh b/fixtures/bugs/2116/gen-fixtures.sh
new file mode 100755
index 00000000..9d08c679
--- /dev/null
+++ b/fixtures/bugs/2116/gen-fixtures.sh
@@ -0,0 +1,74 @@
+#! /bin/bash
+if [[ ${1} == "--clean" ]] ; then
+    clean=1
+fi
+continueOnError=
+# A small utility to build fixture servers
+# Fixtures with models only
+testcases="${testcases} fixture-2116.yaml"
+for opts in  "" "--with-expand" ; do
+for testcase in ${testcases} ; do
+    grep -q discriminator ${testcase}
+    discriminated=$?
+    if [[ ${discriminated} -eq 0 && ${opts} == "--with-expand" ]] ; then
+        echo "Skipped ${testcase} with ${opts}: discriminator not supported with ${opts}"
+        continue
+    fi
+    if [[ ${testcase} == "../1479/fixture-1479-part.yaml" && ${opts} == "--with-expand" ]] ; then
+        echo "Skipped ${testcase} with ${opts}: known issue with enum in anonymous allOf not validated. See you next PR"
+        continue
+    fi
+
+    spec=${testcase}
+    testcase=`basename ${testcase}`
+    if [[ -z ${opts} ]]; then
+        target=./gen-${testcase%.*}-flatten
+    else
+        target=./gen-${testcase%.*}-expand
+    fi
+    serverName="codegensrv"
+    rm -rf ${target}
+    mkdir ${target}
+    echo "Model generation for ${spec} with opts=${opts}"
+    serverName="nrcodegen"
+    swagger generate server --skip-validation ${opts} --spec ${spec} --target ${target} --name=${serverName} 1>${testcase%.*}.log 2>&1
+    # 1>x.log 2>&1
+    #
+    if [[ $? != 0 ]] ; then
+        echo "Generation failed for ${spec}"
+        if [[ ! -z ${continueOnError} ]] ; then
+            failures="${failures} codegen:${spec}"
+            continue
+        else
+            exit 1
+        fi
+    fi
+    echo "${spec}: Generation OK"
+    if [[ ! -d ${target}/models ]] ; then
+        echo "No model in this spec! Continue building server"
+    fi
+    if [[ -d ${target}/cmd/${serverName}"-server" ]] ; then
+        (cd ${target}/cmd/${serverName}"-server"; go build)
+        #(cd ${target}/models; go build)
+        if [[ $? != 0 ]] ; then
+            echo "Build failed for ${spec}"
+            if [[ ! -z ${continueOnError} ]] ; then
+                failures="${failures} build:${spec}"
+                continue
+            else
+                exit 1
+            fi
+        fi
+        echo "${spec}: Build OK"
+        if [[ -n ${clean} ]] ; then
+             rm -rf ${target}
+        fi
+    fi
+done
+done
+if [[ ! -z ${failures} ]] ; then
+    echo ${failures}|tr ' ' '\n'
+else
+    echo "No failures"
+fi
+exit
diff --git a/fixtures/enhancements/1623/swagger.yml b/fixtures/enhancements/1623/swagger.yml
index cb1da6f5..d7537415 100644
--- a/fixtures/enhancements/1623/swagger.yml
+++ b/fixtures/enhancements/1623/swagger.yml
@@ -49,10 +49,10 @@ definitions:
         x-omitempty: false
       generalNoOmitEmpty:
         type: string
-      refHasOmitEmptyTrue:
+      refHasOmitEmptyTrue: # <- discarded ($ref siblings are ignored, however, true is the default)
         x-omitempty: true
         $ref: "#/definitions/bar"
-      refHasOmitEmptyFalse:
+      refHasOmitEmptyFalse:  # <- discarded ($ref siblings are ignored)
         x-omitempty: false
         $ref: "#/definitions/bar"
       refNoOmitEmpty:
diff --git a/fixtures/goparsing/petstore/enums/status.go b/fixtures/goparsing/petstore/enums/status.go
new file mode 100644
index 00000000..c551fbb9
--- /dev/null
+++ b/fixtures/goparsing/petstore/enums/status.go
@@ -0,0 +1,25 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package enums
+
+// pet status in the store
+// swagger:enum Status
+type Status string
+
+const (
+	STATUS_AVAILABLE Status = "available"
+	STATUS_PENDING   Status = "pending"
+	STATUS_SOLD      Status = "sold"
+)
diff --git a/fixtures/goparsing/petstore/models/pet.go b/fixtures/goparsing/petstore/models/pet.go
index af4eb6b7..92d87826 100644
--- a/fixtures/goparsing/petstore/models/pet.go
+++ b/fixtures/goparsing/petstore/models/pet.go
@@ -14,7 +14,11 @@
 
 package models
 
-import "time"
+import (
+	"time"
+
+	"github.com/go-swagger/go-swagger/fixtures/goparsing/petstore/enums"
+)
 
 // A Pet is the main product in the store.
 // It is used to describe the animals available in the store.
@@ -41,7 +45,7 @@ type Pet struct {
 	PhotoURLs []string `json:"photoUrls,omitempty"`
 
 	// The current status of the pet in the store.
-	Status string `json:"status,omitempty"`
+	Status enums.Status `json:"status,omitempty"`
 
 	// Extra bits of information attached to this pet.
 	//
diff --git a/fixtures/goparsing/petstore/rest/handlers/pets.go b/fixtures/goparsing/petstore/rest/handlers/pets.go
index e2d8d0b0..83015060 100644
--- a/fixtures/goparsing/petstore/rest/handlers/pets.go
+++ b/fixtures/goparsing/petstore/rest/handlers/pets.go
@@ -19,6 +19,7 @@ import (
 	"time"
 
 	"github.com/go-openapi/runtime/middleware/denco"
+	"github.com/go-swagger/go-swagger/fixtures/goparsing/petstore/enums"
 	"github.com/go-swagger/go-swagger/fixtures/goparsing/petstore/models"
 )
 
@@ -51,7 +52,7 @@ type ValidationError struct {
 // swagger:parameters listPets
 type PetQueryFlags struct {
 	// Status
-	Status string `json:"status"`
+	Status enums.Status `json:"status"`
 
 	// Birthday
 	//
diff --git a/generator/bindata.go b/generator/bindata.go
index 90f3f807..9163b762 100644
--- a/generator/bindata.go
+++ b/generator/bindata.go
@@ -16,7 +16,7 @@
 // templates/schema.gotmpl (11.283kB)
 // templates/schemabody.gotmpl (13.077kB)
 // templates/schematype.gotmpl (854B)
-// templates/schemavalidator.gotmpl (31.005kB)
+// templates/schemavalidator.gotmpl (31.172kB)
 // templates/server/builder.gotmpl (17.451kB)
 // templates/server/configureapi.gotmpl (6.421kB)
 // templates/server/doc.gotmpl (1.52kB)
@@ -420,7 +420,7 @@ func templatesSchematypeGotmpl() (*asset, error) {
 	return a, nil
 }
 
-var _templatesSchemavalidatorGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5d\xdf\x73\xdb\x36\xf2\x7f\xfe\xea\xaf\xd8\xaf\x26\x77\x23\xa5\x2e\xd5\x87\x4e\x1f\xdc\xf3\xcd\xa4\x6d\xda\x7a\xae\x69\x32\x4d\xdb\x87\xeb\x64\x2e\x30\xb5\x92\xd0\x50\x24\x03\x50\xb2\x7d\x1c\xfd\xef\x37\x00\x48\x10\x04\x01\x8a\xd4\x0f\x47\x76\xe5\x27\x89\x04\x81\xc5\x62\xf7\xb3\xbb\x1f\x80\x72\x9e\xc3\x14\x67\x34\x46\x18\xa6\x8c\x2e\x69\x46\xd7\x38\xa3\x18\x4d\xd7\x24\xa2\x53\x92\x25\x6c\x08\x9b\xcd\x00\x20\xcf\x81\xce\x20\xf8\x05\x3f\xae\x28\xc3\xa9\xba\x48\x67\x80\x8c\xc1\xe5\x15\x14\xcd\x51\x37\x50\xed\x49\x3c\x85\x11\x7e\x84\xe0\x87\xe4\xd7\xfb\x14\x61\xc8\x33\x46\xe3\xf9\x70\x0c\xa3\x38\xc9\x20\xb8\xe6\x3f\xaf\xa2\x88\xdc\x44\x38\x86\xcd\xe6\xad\xbc\x99\xe7\x80\xb1\x18\x60\x54\x8c\xf9\x86\x64\x0b\xd8\x6c\xf2\xdc\xfc\x88\x11\x47\xd8\x6c\x86\x43\xdd\xfc\x42\xc8\x98\x32\x1a\x67\x33\x18\xfe\xed\xe3\x10\x82\x9f\x92\x90\x64\x34\x89\xcb\x9b\x74\x06\x62\xd4\x51\xc2\xc4\xc8\x2f\xe2\x24\xbe\x5f\x26\x2b\x6e\x8b\x21\x06\x2a\xe4\x55\x42\xa8\xfe\xf3\x3c\xf8\x9d\x44\x2b\x7c\x79\x97\x32\xe4\x5c\xf5\xdb\xbd\xd7\xb1\xee\x68\xfc\xb5\xd4\xda\xff\x5f\x41\x4c\x23\xc8\x07\x00\x00\x0c\xb3\x15\x8b\xc5\xf5\x01\x40\xa1\x6f\xd5\xba\xd2\xfd\x2b\x1a\xff\x84\xf1\x5c\x6a\xc0\xad\x7c\xdd\xe2\xb0\xaa\x53\x8b\x56\xf6\x59\x4d\x0b\x36\x9b\xe7\xed\xea\x19\x8b\x9e\x6b\x82\xef\x3c\x79\x72\xb7\x6d\xf2\x65\x8b\x13\x9b\xbc\x21\xf8\xae\x93\x7f\x43\xb2\x0c\x59\xec\x9d\x7a\x71\xff\x84\x26\xfe\x3e\xcf\x0d\xa9\xdf\xef\x61\xf2\x74\xb9\x5a\xb6\x19\xbc\xb8\xaf\x5a\x0b\x9c\x79\x7b\x4b\xe6\x73\x64\x0a\x6c\x68\x9c\xe1\x1c\x25\x82\x5d\xc7\xd9\x51\x71\xa5\x6d\x6c\xaa\xc6\x56\x1d\xcf\xa2\x84\x54\xa2\x7c\xf5\xe5\x5e\x5e\x55\xe8\x46\x7e\x7d\x79\x17\x46\x2b\x4e\xd7\x58\x5d\xdf\xc3\xd7\xda\xb5\xae\xee\xff\x35\xb5\xae\x75\x63\x69\x5d\x5f\xdf\x59\xeb\xab\x28\xa3\x69\x84\xaf\x67\x7e\xc5\xeb\x26\x87\xd5\xa6\x54\xcf\x5e\x5a\x31\x65\xdf\x55\x01\x2f\xe3\xd2\xe6\x26\x13\x31\xe7\x15\x02\xc6\xab\x65\x4d\x15\x79\x1e\xfc\x82\x21\xd2\x35\xb2\x9f\xc9\x52\xc8\x17\x94\xda\x11\x33\x24\x3c\x24\x11\xfd\x2f\x42\x50\xdc\x15\x8a\x79\xbb\x9a\xcd\xe8\x1d\x6c\x36\x62\x80\x63\x98\x61\x3f\x85\xf5\xd7\xce\xe7\x65\x2a\x15\x5c\xf3\x6f\x57\x3c\x4b\x96\xdf\x27\x6c\x29\xd1\x55\xe7\x51\x6f\x33\x86\x64\x59\xe5\x55\xdf\x10\x8e\x5f\x7d\x39\x56\x5d\xc8\x0e\x33\x5c\xa6\x11\xc9\x10\x86\x85\xc6\x68\x12\xab\xde\x66\xb2\xb7\x21\x04\x7a\x39\x8a\xc1\xab\x4f\x83\x3c\x2f\xf3\x44\x1e\xd1\x10\x3b\xa5\x87\xad\x09\xe2\xc1\x17\xa2\xa3\xae\x2d\x6d\xfb\xac\x51\x64\x73\xaf\x68\x7c\x9d\xe1\x92\x4b\x44\x54\x9f\x2a\x75\x06\xd7\xf1\x14\xef\x7e\x27\x4c\x49\xdc\x34\xbd\xb7\xe2\xcb\xe5\x15\xd0\x58\xb8\x56\x84\x22\x3c\xbb\x64\x1c\x7b\x43\x5f\x6d\x48\x77\xf4\x93\x4d\x0e\xaf\xca\x2e\x73\x2b\x83\x50\x29\xe5\x1e\xca\x6e\xe8\xd7\x1d\x74\x3e\xf9\x64\x2b\x29\xf7\x99\xec\x6f\x31\xfd\xb8\xc2\x6d\xf3\x35\x5a\x1d\x7a\xca\x87\xf5\x14\x03\xb7\x25\x72\xcf\x12\x06\x12\x23\xac\x99\xf5\x85\xee\x63\xa0\xf5\x81\x67\x6e\x61\x82\xc6\x69\x55\x0b\x8a\x9b\x15\x22\x16\xdf\x7f\x24\xfc\x77\x0d\xbf\xbc\xbc\xaa\xf0\x5a\xe6\x30\xfa\xca\x8b\x88\x12\x8e\x53\x0d\xe9\xc5\xe5\xeb\x38\x43\x36\x23\x21\xda\x37\xca\x08\x50\x88\x03\x72\x21\xf2\xdc\x34\x6f\xb1\x0c\x5f\x7c\x6d\x5f\xfc\x07\xf8\xc1\xc9\x6e\xfc\xd9\x67\x5a\x45\x62\xbe\xb7\x34\x5b\x58\x6a\xb0\x54\x61\xc6\x46\x25\x6f\xa9\x91\x2a\x56\xbd\x22\xa9\x68\xf3\x7a\x8d\x8c\xd1\x29\x8e\xcd\xae\xa4\x05\xf1\x5b\x32\x0f\xae\xf9\xbf\x91\x25\x23\x0f\xd2\x43\x2e\x6c\x4f\x74\xc8\x8a\xfe\x8d\x2e\x00\xc2\x24\xce\x68\xbc\x42\xe3\x62\x5d\x5c\xbd\xb4\xe5\x25\x23\x5e\xa6\x2c\x49\x91\x65\xf7\x46\xd0\x0b\xaa\xc6\x8d\xa7\x2b\x73\xa8\xc5\xf0\xc2\x5c\x4d\x5b\x29\x28\x03\xb5\xd0\x30\x8a\xb1\x39\xb5\x9a\xcf\x28\x76\x62\xf2\x1c\x52\x86\x6b\x8c\x33\x0e\x73\x8c\x91\x91\x0c\xa7\x10\x26\x53\x84\x2c\x81\x90\x44\x11\xd0\x8c\x63\x34\xbb\x84\x6c\x41\x39\x50\x0e\x0c\x39\xb2\x35\x4e\xa5\x4d\x90\x62\xbc\xec\x3e\x45\x0e\xcf\x27\xb5\x99\x78\x97\xcd\xbf\x4c\x74\xe6\x09\xbf\xb6\x53\x35\x34\x55\x03\x87\xe6\xf3\x41\xe1\x29\x38\x52\x19\x0a\x77\xfb\xaa\xec\x67\x8d\x17\x90\x7c\x10\x5d\x21\x63\xc1\xe8\x39\x32\x96\x30\x1e\x54\xbe\x36\xfe\x5a\xdc\xcf\x0d\x03\x28\x7c\x7c\x8d\x7a\x1c\xa1\xe3\x9e\x90\x33\x1e\x34\xed\xc9\x02\x8f\xea\xd6\x8e\x0a\xf6\x58\x5a\xd3\xc2\xec\xac\xcd\x60\xf7\x96\x24\xad\xe5\x6c\xd2\x8c\x4a\xfc\xe5\x40\xa6\x53\x2a\xb4\x44\xa2\x37\xca\xd8\x69\x65\x1a\x85\x42\x7e\x24\xfc\x85\xab\x55\xdd\xa4\x21\x70\x35\xb2\x61\xaf\x78\x46\x21\x94\xe7\x91\x7f\xe1\x7d\x85\x5a\x8c\xc4\x73\xf4\x99\x59\x65\x5f\x05\x20\xb5\xc9\x69\x43\xb5\x85\x49\xf5\x5c\x5e\x6a\x89\x7f\xa0\x29\xdc\x2e\x30\x86\x78\x15\x49\xaf\x11\x2e\x45\xc2\x10\x53\xe1\x78\x86\x03\xed\x0d\x55\x16\x4c\x59\x10\x25\x8c\xaf\x14\xdb\x01\xa3\x2f\x18\x23\xf7\x1a\x22\x74\xe0\x91\xb1\x58\x48\x9c\xb2\x24\x44\x2e\x3c\xff\x06\xa3\xe4\xd6\x12\xfc\xa1\xf2\xf4\xce\x21\xb8\xc5\x8f\x3c\x90\xfd\x79\x51\x8c\xbd\x29\x99\xec\x7a\x20\xa9\x1a\x94\x88\x5b\xbb\xad\x1b\x94\xea\xd4\x4c\xae\xa9\xa6\x35\x89\x4a\xa0\x71\x2f\x6f\x03\x66\xf6\x70\xfc\x6a\xcc\xa6\x72\xbc\x7a\xb0\x56\xb3\x33\x88\x7a\x74\x5e\xd7\xfb\xde\xd3\x71\x75\xe5\x88\x9e\xb5\xdb\xca\xc8\x4c\xc4\x12\xaa\x4e\x84\x00\xe5\x12\x25\x37\x7f\x62\x98\xd5\xa2\x59\xd5\x45\x81\x1e\xc1\x8b\x28\x2a\xc9\x15\x5f\x13\x37\x5e\xd4\x5a\x76\xcd\x0b\x6a\x0f\x35\xd6\xc8\xbb\x78\x7d\xe4\xd9\x41\x1a\xb7\x2c\x1e\x49\xaa\x4d\x9c\xe0\x9a\xff\xba\x4a\x23\x34\xb1\xd5\x4a\xfb\x26\x13\xf8\xf5\xf5\x77\xaf\x2f\xf5\x1a\xc5\x73\x23\xac\x00\x95\xad\xf9\x22\x59\x45\x53\x98\x27\xb0\x40\x86\x17\xa2\xfb\xfb\x64\x05\x1c\x51\xe5\x2a\x8c\x50\x8e\x40\x62\xa0\x9c\x6b\x18\x9c\x4c\x80\x64\xb0\xc8\xb2\x94\x5f\x4e\x26\x73\x9a\x2d\x56\x37\x41\x98\x2c\x27\xf3\xe4\x73\xae\xe8\x3f\xf3\xa3\x7c\x94\xdb\x13\x69\x4c\xaf\x82\x2f\xbb\xa9\xa9\x53\xcf\x9e\x58\xd0\xec\xab\x89\x46\x26\x60\xbb\xa8\x1b\x91\xfe\xd9\xf5\x40\x05\xeb\x85\xc5\x87\xf2\x29\x50\xce\x2b\xb1\x29\x24\x69\xb6\x12\xc8\x4e\x04\xa6\x97\x50\x67\x59\x7e\x09\x76\xe7\x0d\xbb\x07\xda\xb0\x6b\x75\xa5\x46\xc2\xd1\x46\xd8\xc9\x65\x57\xae\x54\x36\x93\x4f\x5a\xf6\x53\xb8\xd2\x0d\xc2\x72\x95\xad\x48\x14\xdd\x03\x96\x6c\x34\xd0\x58\x25\x2a\x0c\x79\x12\xad\x91\x35\x81\xb1\x0f\x23\xd8\x32\xb7\x72\x65\x8b\xc0\x2a\x52\x90\x86\x6b\x54\xe3\xd8\xdc\x61\xe0\xef\xea\x15\x49\x5b\x3a\xaa\xa7\xb3\x4d\x6f\xb4\x79\x89\x7a\xad\x01\xfd\x98\x08\x65\x45\xc7\x20\x8f\x0f\x93\x0c\x6d\x5b\x18\x65\xe8\xdf\x26\xcb\x34\xc2\xbb\xd7\x32\x52\x1a\x80\x7e\xed\x4e\xeb\x7d\x69\xd2\x96\x24\x69\xc7\x14\x69\xe7\x8c\xa2\x2d\x3d\xfa\x14\xc9\xd1\xce\x13\x69\x0d\xc8\x8d\xb5\x76\x07\xae\xf6\x3c\xe7\x84\xb2\x8a\x0e\x72\xf4\x96\xc2\x0b\xbc\xae\xc8\xff\x14\xd2\x1a\x57\xd2\xe1\x32\x9a\xfa\xd5\xc6\x37\x17\x85\xcb\x92\x25\x2c\x49\xda\x60\x70\x7b\x02\xe7\xa7\xc5\x4c\x07\x87\xdb\xdc\x59\x33\x83\x57\x1d\xee\x4c\x4f\x36\x58\xdc\x8a\x80\x75\xc5\x96\x47\x50\x3e\x3b\x58\xa4\xca\x1b\x44\xd4\x6d\x92\x35\xae\xd2\xab\x50\xd6\x92\xa4\x1c\x6e\x56\x19\x4c\x13\xe4\x32\x2a\x7c\x88\x93\x5b\x20\x37\xc9\x2a\x03\x57\x60\xb9\x04\x0c\xe6\x01\xd0\x0c\xc2\x64\x89\x5c\xd9\x1a\x81\x67\x0c\x67\x0e\x2e\xd2\x5f\x8b\xeb\x26\xcf\x74\xb2\x20\xc5\xbc\x45\xd9\x71\xd9\xef\x92\xa4\x05\xda\xd4\xe9\x8e\xbe\x41\xca\x4f\x38\xec\x52\x05\x3b\x84\xef\x50\xf0\xbb\x90\xbf\x33\xf9\xda\x32\x89\x96\x18\xa9\xac\xb7\x92\x72\x4d\xa2\xca\x6e\xdd\x03\x6b\x5b\x3e\x6c\x70\x3d\x08\xe7\xe0\x5f\xc5\x84\x35\xd6\xa2\xe5\xb1\xde\x4c\xac\xb1\x7f\xae\xa8\x8a\xe6\x06\xfa\xe4\xb9\x80\xde\xef\x5e\x7e\xf3\xdb\x0f\xea\x08\x84\x44\xd1\x4b\xb9\xbc\x05\x9e\x16\xd7\x35\x54\xa9\x9b\x16\x72\x15\x2d\x4a\x8f\xd1\x6d\xea\x2e\xa4\x5a\x95\x6a\x2c\x1b\x19\xd4\x67\xd1\xa6\xc4\xb1\xcb\x02\xfd\xcd\x6a\x52\xf5\x51\xee\x5c\x95\x7d\xe8\x9d\x2c\xdd\xc6\xb2\x91\x4b\x8f\xc5\xea\x11\xab\x08\x73\xe9\x8a\x39\x15\x2f\xdd\x0a\x11\x4e\xfc\x2e\x8a\x3e\x3d\x4f\x43\xde\xf1\x23\xc5\xf3\x6d\x74\x76\x7d\x3d\xda\x31\xe3\xca\x33\x66\x4c\x23\xc7\x98\x2d\x59\xc5\xc3\x6c\x6f\x85\x84\xa3\x19\x8c\x0e\xb5\xa3\x75\xde\xd3\x6a\x20\xe7\x27\xdb\xd3\xaa\xed\x9a\x7a\x2a\x9c\x6d\x15\x45\xaf\xdd\xdc\xd6\x64\xb9\x65\x98\xce\x83\x34\x52\x50\xf7\x49\xaf\xf6\xc2\xe4\x58\x65\xc9\xae\x45\xc9\xb6\xa8\xe7\x50\x88\x39\x67\xd7\xae\x4d\xcb\x7e\x4d\x4d\xd7\x8d\x80\x1a\xd4\xac\xa9\x96\x30\xf5\x64\x77\x5d\xd6\xf9\x49\x48\xdd\x33\x9d\xfb\xe0\x74\xae\xbf\x4e\xea\x78\xe6\xb2\x2f\xc7\xea\xc6\x3e\x07\xb1\xda\x8d\x52\x75\x18\xab\xc8\x6e\x85\x9e\xf4\x8e\xb1\x3e\x62\x54\x34\x28\x1d\xad\x76\xce\x48\x5b\x2d\xde\x85\x98\x66\x72\xd7\x9e\x96\x77\x2f\x20\x5b\x20\x30\x8c\xa7\xc8\x68\x3c\xab\x1d\x30\x91\xb5\x21\xe5\x90\x22\x13\x93\xc5\x29\xdc\xdc\x83\xe5\xad\xa6\x89\x6f\xe3\x77\xcd\x19\x1d\x88\xd3\xec\x04\x24\x3e\x6c\xd3\x87\x2b\x2c\xfc\xd8\x0e\x6c\x3d\x40\xe8\x8c\x39\x67\xcc\x79\x24\x98\x63\x3d\x6f\xd4\xd2\x1d\x7d\xbb\xed\xd4\x79\xb8\xc0\x25\xf1\x1c\x3b\x37\xe9\x4b\x75\x69\xd4\x78\x35\x44\x5b\xa1\xa9\xa9\x67\xf3\x44\x6e\x93\x5d\x5e\x19\xcb\x3f\x08\x93\x98\x67\x30\x6a\x24\x97\xb5\x17\x14\x8c\xa7\xed\x73\xc3\xa2\x4c\x28\x7c\x8b\xcb\x57\x18\x8a\xb7\x19\x6c\x5b\x15\x7d\xfd\xdf\x96\x7e\x6a\xb7\xe1\xca\xd9\x87\x9d\xb9\x8e\xad\x34\x73\x50\x9e\xca\x95\x3a\x1c\xac\x89\x3c\x75\x15\x92\x25\x36\xd8\x5a\xf8\xe3\x9d\x86\xf6\x7c\x33\x98\xad\xe2\x10\x68\x4c\xb3\xd1\x58\x1a\xad\x78\x54\x4c\xea\x8f\x77\xb5\x15\x9d\x22\xc3\xd9\x0c\xa7\x6f\xe5\x00\x42\x8d\x5a\xb2\x0a\x2e\xfe\xe4\x49\x1c\xfc\x16\x2f\x09\xe3\x0b\x12\x8d\xfe\x78\x77\x73\x9f\xe1\xe8\x7d\x9e\xcb\x3b\x5a\xbb\xef\xc7\x17\xf0\x77\x86\xce\xba\x28\x25\x31\x0d\x47\xc8\xd8\xb8\xf0\x18\x31\xab\xff\x5c\xc0\xba\x3a\x22\x26\xa4\xcb\xcb\xf9\xbb\xa7\x78\x05\x24\x4d\x31\x96\xa5\xbc\xb3\xc5\x05\xac\xd5\x00\x9b\x81\xd2\xc0\xc8\xc5\x42\x54\x30\x60\x61\xbc\xf9\x02\x48\xe1\x0a\x2f\xef\xd2\x84\x65\x38\xf5\x1d\x31\xaf\x73\x6a\xc6\x45\x05\x1e\xb0\x9d\x65\x4f\x49\xb6\xb8\x80\xa8\x44\x3f\x65\xed\x17\x95\xe1\xe9\x90\xa9\x23\x64\x23\x76\x7a\x4e\xcd\xd5\xa6\xb3\x7d\xcd\xc7\x20\xcb\x54\xb9\x08\x8e\x58\xe1\x10\xb6\x90\xf2\xc2\xbb\x62\x9d\xc0\xd3\x60\x2a\x36\x2d\xa7\xb5\x4b\x1f\xf6\x39\x41\xd5\xa8\xee\x09\x7b\xb9\x82\x51\xb9\x75\xf7\x07\x53\xdc\xa3\x3a\x45\x35\x50\xab\x67\xe8\x66\xdd\xdc\xe3\x79\x45\x1d\xfb\xac\xff\x99\xd3\xfc\xeb\x97\xbb\x38\x80\x96\xec\x44\xbc\x40\xbf\x24\x72\x58\x57\xd0\xd3\x3c\x80\x3f\x6c\x3f\x27\x6b\x85\xd6\x22\x84\x18\x14\x83\xa8\xe8\xb9\xd7\x8f\xf4\x99\x89\x43\xfa\xd1\x29\x86\x94\x6a\xa2\xad\xde\xa3\x9b\xf5\xf2\x9e\x63\x87\x8e\xea\x64\xcb\x69\x78\xce\xe1\x9d\x46\xcf\x70\x17\xa7\x69\xe4\xc7\xe5\xe7\xc9\x04\x4a\x7e\xd5\x38\x44\x2f\x39\xb5\x3c\x87\xc5\x6a\x49\x62\x53\x08\xbd\xd0\x9e\x24\xe2\x10\x9a\x15\xd6\xf2\x1d\xe5\xa1\x48\x44\x62\x29\x8e\xbc\xdc\x50\x48\xfd\x94\xd5\xbe\xd6\x65\xb3\xd9\xc2\x70\x66\xcb\x2c\xf8\x05\xe7\x94\x67\xec\xde\x5c\xcd\xca\xd3\xe5\xb5\xc1\xc0\xcb\xe8\x9a\x3b\x3b\x2e\xaa\x55\xbd\x1f\x5c\xee\x46\x4b\x5c\x52\xc7\xdd\xc2\x64\x99\x26\x5c\xea\x4a\x41\x5c\xad\xae\xdb\x56\x62\xa9\x65\xa8\xf6\xf7\xed\xd2\xae\xda\x29\x92\x4d\xab\x43\x01\xf5\xda\xdb\x57\x8c\x39\x0b\xfc\xee\x0c\xb6\x2e\x04\x45\xe0\x34\x56\x3a\x61\xdf\x8b\x8e\xd5\xea\x74\x17\x0d\xf6\x7a\x39\xaf\xcb\x96\xae\x58\x6b\x8d\x89\x0c\xf9\x05\x14\x30\x5b\xfe\x75\xdf\x60\xad\x73\xe3\xbe\x37\x51\x8c\x3d\x87\x71\xc7\x57\x5c\x68\x0c\x24\x2e\x38\x29\xb8\x5d\xd0\x70\x01\x54\x1d\x63\x50\x7b\x4c\xc5\x09\x82\xda\xe9\xc9\x6e\x07\x11\x1d\x33\xe8\x71\xea\x68\x8f\x43\x37\xea\x95\xd1\x2d\xeb\xd3\xba\x36\xbe\xbd\x90\xaa\xba\xef\x6a\x64\xed\xd3\xa8\x89\x3f\x9a\xb2\x24\x7d\x43\xc2\x0f\x44\x78\x81\xf2\xd9\x71\x9f\x0d\xb3\x0e\x53\xf2\xed\xd3\x77\x71\xd4\x76\x1f\x3d\xbc\x7f\x1e\xcf\x37\x3b\x29\xca\x15\xf5\x4e\xc6\x0b\x7b\xd1\x49\x5d\x3d\xcf\x2b\xa8\x6a\x20\x64\x84\x4c\x3e\xac\xe5\x38\xae\x97\xb6\xac\x93\xbb\xc2\x95\x33\x94\xa9\xe8\xc8\xa6\x25\xc6\xf6\xb2\x0c\xaa\x38\x5a\xfd\xce\xc6\xfe\x87\xfd\x86\xc3\x0b\x18\xde\x24\xd3\xfb\xe1\x85\xab\x87\x3d\x27\xaa\x52\xc2\x08\x63\xd1\x6a\x0c\xff\x84\x2f\x1a\x89\x5c\xc2\x78\xf0\x6d\x91\x05\x60\xe5\x59\x2f\xc5\x1d\xf1\x54\x10\x04\x63\x57\xb2\xd7\xc9\xbf\xdb\x5c\xd7\x06\xfa\xc0\xc7\x34\xe8\xf2\x56\x20\x9c\x53\x93\x62\xf8\xa7\x5c\x3a\xf5\xd0\x80\xb3\xa6\xea\xfe\xbc\x59\x6c\xd5\x53\xa9\x2e\x04\x31\xb4\x91\xc4\xf5\x26\xa2\x18\x8e\xc5\xd8\xa2\x51\x99\xf5\xd7\x79\x64\x68\xe5\x92\xdd\xac\x88\x71\x55\x8f\xb0\x2f\xdb\xbc\xdf\x48\xdd\xf9\x68\x70\x70\xd2\xd0\xe0\xa5\xc5\x60\x26\x08\x75\x20\x94\xda\xaa\x9c\x06\xa5\xb4\x13\x05\xd5\x9b\x81\x7a\x92\x25\x74\x77\x37\xdb\xad\xb6\xb6\x13\xcc\x6e\x44\xad\xdb\x68\xb7\xd1\xb7\x4f\x8f\xbd\xed\xaa\x87\x76\x04\x6d\x7f\xb8\x27\xd3\x7b\x82\x8e\xd9\x9f\x1a\x2e\x7e\x4d\xa5\xf4\xd1\xe2\xab\xed\xa9\xe5\x6f\xb4\x9c\x1c\x59\xdc\x71\x65\x0f\xec\xb1\xde\x3a\xd6\xd7\xe2\xc4\xb2\x23\xa7\xfc\xdd\x9d\xdd\x33\xb9\x27\x94\x3c\x3d\x4e\xef\xef\xe3\xf8\xf6\x1a\xfa\x2a\xc5\x26\x18\x34\x1b\x1c\x00\x16\x9a\x16\xf9\x68\xa2\xba\x13\x25\xec\xef\x5d\x7f\xa8\xc5\xde\x84\xb2\x36\xa0\x8a\x47\x8c\x04\xb2\x5f\xbe\xf0\xe4\xb7\xa9\xba\x4e\x7f\x87\x34\x61\xb7\x2d\xad\x93\x04\x8a\xa7\xbb\x0f\xd6\x71\x09\x8f\xe1\xeb\x0d\xde\x7b\x7f\x6a\xd4\xbb\x8f\x76\xca\xc6\xd5\x65\x6f\xcc\x54\x55\xed\x15\x1e\x8d\x25\xbb\xff\xb0\x54\xed\x1d\x1e\xff\xc2\xd5\xd8\xdd\x67\xa6\x85\xcb\x97\x42\xcf\xa7\x40\x1f\xf4\x87\x44\x9c\x6f\x2a\x6e\x7f\xbf\xa4\x4b\xd6\xee\x27\xf7\x3d\x9b\xb1\x5b\xde\x7a\x39\xf8\xc6\xe4\x99\x40\x3d\xc9\x1a\xa0\x60\xeb\x84\xd9\x9d\xb9\xba\x53\x0d\xf3\x0f\x98\xd5\x1f\x93\xaf\x3b\x13\x76\x67\xc2\xee\x4c\xd8\x1d\x80\xb0\x6b\x71\xdb\x16\xd2\xee\x4c\xdb\x3d\x8d\x90\xfd\x38\x31\xe0\x4c\xdb\x7d\x9a\x00\xef\xc1\x8a\xe6\x95\x6e\xe4\x5d\xf7\x44\xbe\x17\x35\xf7\xe4\x92\xf8\x07\x62\xe6\xba\x90\xa7\x8f\x13\x2f\xce\xec\xdd\x91\x5c\x7e\x70\x26\xdc\x8e\x4c\xb8\x1d\x93\xd1\xf1\xfc\x74\xbf\xfd\x8f\x8c\xfa\xa4\x79\x47\x2d\xdb\x1e\x51\x36\xd7\xb1\x6a\x3b\xd7\x67\x7f\x9d\x04\xed\x40\x15\x5b\xe5\xbe\xad\xd0\xdb\x5c\x98\x2e\xeb\xd6\x0d\x18\xfd\x6b\x57\xb1\xb7\xf6\x1d\xd7\x59\xd8\xf2\xbf\x7b\x58\xff\x80\xa8\xed\x5f\x79\x04\x7e\xd9\x8d\x5f\xdc\x6a\x07\x4d\x27\x8c\x34\x71\xd2\xfb\x7e\x64\xf5\xe9\x7f\x01\x00\x00\xff\xff\x02\xfb\x91\x0e\x1d\x79\x00\x00")
+var _templatesSchemavalidatorGotmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5d\xdf\x73\xdb\x36\xf2\x7f\xfe\xea\xaf\xd8\xaf\xc6\x77\x23\xa5\x2a\xd5\x87\x4e\x1f\xdc\xf3\xcd\xa4\x6d\xda\x7a\xae\x69\x32\x4d\x9b\x87\xcb\x64\x2e\x30\xb5\x92\xd0\x50\x24\x03\x50\xb2\x7d\x1c\xfd\xef\x37\x00\x48\x10\x24\x01\x0a\xfa\xe5\xc8\xae\xfc\x24\x91\x20\x80\x5d\xec\x7e\x76\xf7\x03\x50\xce\x73\x98\xe0\x94\xc6\x08\xfd\x94\xd1\x05\xcd\xe8\x0a\xa7\x14\xa3\xc9\x8a\x44\x74\x42\xb2\x84\xf5\x61\xbd\xee\x01\xe4\x39\xd0\x29\x04\xbf\xe1\xa7\x25\x65\x38\x51\x17\xe9\x14\x90\x31\xb8\xbc\x82\xa2\x39\xea\x06\xaa\x3d\x89\x27\x30\xc0\x4f\x10\xfc\x94\xfc\x7e\x9f\x22\xf4\x79\xc6\x68\x3c\xeb\x0f\x61\x10\x27\x19\x04\xd7\xfc\xd7\x65\x14\x91\x9b\x08\x87\xb0\x5e\xbf\x91\x37\xf3\x1c\x30\x16\x03\x0c\x8a\x31\x5f\x93\x6c\x0e\xeb\x75\x9e\x9b\x1f\x31\xe2\x08\xeb\x75\xbf\xaf\x9b\x8f\xc4\x1c\x53\x46\xe3\x6c\x0a\xfd\xbf\x7d\xea\x43\xf0\x4b\x12\x92\x8c\x26\x71\x79\x93\x4e\x41\x8c\x3a\x48\x98\x18\xf9\x79\x9c\xc4\xf7\x8b\x64\xc9\x9b\xd3\x10\x03\x15\xf3\x55\x93\x50\xfd\xe7\x79\xf0\x96\x44\x4b\x7c\x71\x97\x32\xe4\x5c\xf5\xeb\xdf\xeb\x50\x77\x34\xfc\x56\x6a\xed\xff\xaf\x20\xa6\x11\xe4\x3d\x00\x00\x86\xd9\x92\xc5\xe2\x7a\x0f\xa0\xd0\xb7\x6a\x5d\xe9\xfe\x25\x8d\x7f\xc1\x78\x26\x35\x60\x57\xbe\x6e\x71\x58\xd5\xa9\x45\x2b\xfb\xac\xc4\x82\xf5\xfa\x59\xb7\x7a\x86\xa2\xe7\xda\xc4\x77\x16\x9e\xdc\x6d\x12\xbe\x6c\x71\x62\xc2\x1b\x13\xdf\x55\xf8\xd7\x24\xcb\x90\xc5\x4e\xd1\x8b\xfb\x27\x24\xf8\x87\x3c\x37\x66\xfd\x61\x0f\x93\xa7\x8b\xe5\xa2\xcb\xe0\xc5\x7d\xd5\x5a\xe0\xcc\x9b\x5b\x32\x9b\x21\x53\x60\x43\xe3\x0c\x67\x28\x11\xec\x3a\xce\x8e\x8a\x2b\x5d\x63\x53\x35\xb6\xea\x78\x1a\x25\xa4\x9a\xca\x37\x5f\xef\xe5\x55\x85\x6e\xe4\xd7\x17\x77\x61\xb4\xe4\x74\x85\xd5\xf5\x3d\x7c\xad\x5b\xeb\xea\xfe\x5f\x53\xeb\x5a\x37\x0d\xad\xeb\xeb\x3b\x6b\x7d\x19\x65\x34\x8d\xf0\xd5\xd4\xad\x78\xdd\xe4\xb0\xda\x94\xea\xd9\x4b\x2b\xe6\xdc\x77\x55\xc0\x8b\xb8\xb4\xb9\xf1\x58\xc8\xbc\x44\xc0\x78\xb9\xa8\xa9\x22\xcf\x83\xdf\x30\x44\xba\x42\xf6\x2b\x59\x88\xf9\x05\xa5\x76\x84\x84\x84\x87\x24\xa2\xff\x45\x08\x8a\xbb\x42\x31\x6f\x96\xd3\x29\xbd\x83\xf5\x5a\x0c\x70\x0c\x33\xdc\x4e\x61\xdb\x6b\xe7\xcb\x32\x95\x0a\xae\xf9\xf7\x4b\x9e\x25\x8b\x1f\x13\xb6\x90\xe8\xaa\xf3\xa8\x37\x19\x43\xb2\xa8\xf2\xaa\xef\x08\xc7\x6f\xbe\x1e\xaa\x2e\x64\x87\x19\x2e\xd2\x88\x64\x08\xfd\x42\x63\x34\x89\x55\x6f\x53\xd9\x5b\x1f\x02\xbd\x1c\xc5\xe0\xd5\xa7\x5e\x9e\x97\x79\x22\x8f\x68\x88\x5e\xe9\x61\x67\x82\x78\xf0\x85\xf0\xd4\x75\x43\xdb\x2e\x6b\x14\xd9\xdc\x4b\x1a\x5f\x67\xb8\xe0\x12\x11\xd5\xa7\x4a\x9d\xc1\x75\x3c\xc1\xbb\xb7\x84\xa9\x19\xb7\x4d\xef\x8d\xf8\x72\x79\x05\x34\x16\xae\x15\xa1\x08\xcf\xb6\x39\x0e\x9d\xa1\xaf\x36\xa4\x3d\xfa\xc9\x26\x87\x57\xa5\x8f\x6c\x65\x10\x2a\x67\xb9\x87\xb2\x5b\xfa\xb5\x07\x9d\xcf\x2e\x6c\x35\xcb\x7d\x84\xfd\x23\xa6\x9f\x96\xb8\x49\x5e\xa3\xd5\xa1\x45\x3e\xac\xa7\x18\xb8\x2d\x91\x7b\x9a\x30\x90\x18\xd1\x90\x6c\x5b\xe8\x3e\x06\x5a\x1f\x58\xf2\x06\x26\x68\x9c\x56\xb5\xa0\xb8\x59\x21\x62\xf1\xfd\x67\xc2\xdf\x6a\xf8\xe5\xe5\x55\x85\xd7\x32\x87\xd1\x57\x9e\x47\x94\x70\x9c\x68\x48\x2f\x2e\x5f\xc7\x19\xb2\x29\x09\xb1\x79\xa3\x8c\x00\xc5\x74\x40\x2e\x44\x9e\x9b\xe6\x2d\x96\xe1\xab\x6f\x9b\x17\xff\x01\x6e\x70\x6a\x36\xfe\xe2\x0b\xad\x22\x21\xef\x2d\xcd\xe6\x0d\x35\x34\x54\x61\xc6\x46\x35\xdf\x52\x23\x55\xac\x7a\x49\x52\xd1\xe6\xd5\x0a\x19\xa3\x13\x1c\x9a\x5d\x49\x0b\xe2\xb7\x64\x16\x5c\xf3\x7f\x23\x4b\x06\x0e\xa4\x87\x5c\xd8\x9e\xe8\x90\x15\xfd\x1b\x5d\x00\x84\x49\x9c\xd1\x78\x89\xc6\xc5\xfa\x74\xf5\xd2\x96\x97\x8c\x78\x99\xb2\x24\x45\x96\xdd\x1b\x41\x2f\xa8\x1a\xb7\x9e\xae\xcc\xa1\x16\xc3\x0b\x73\x35\x6d\xa5\xa0\x0c\xd4\x42\xc3\x20\xc6\xb6\x68\x35\x9f\x51\xec\xc4\xf8\x19\xa4\x0c\x57\x18\x67\x1c\x66\x18\x23\x23\x19\x4e\x20\x4c\x26\x08\x59\x02\x21\x89\x22\xa0\x19\xc7\x68\x7a\x09\xd9\x9c\x72\xa0\x1c\x18\x72\x64\x2b\x9c\x48\x9b\x20\xc5\x78\xd9\x7d\x8a\x1c\x9e\x8d\x6b\x92\x38\x97\xcd\xbd\x4c\x74\xea\x08\xbf\x4d\xa7\x6a\x69\xaa\x06\x0e\xed\xe7\x83\xc2\x53\x70\xa0\x32\x14\x6e\xf7\x55\xd9\xcf\x0a\x47\x90\x7c\x14\x5d\x21\x63\xc1\xe0\x19\x32\x96\x30\x1e\x54\xbe\x36\xfc\x56\xdc\xcf\x0d\x03\x28\x7c\x7c\x85\x7a\x1c\xa1\xe3\x2d\x21\x67\xd8\x6b\xdb\x53\x03\x3c\xaa\x5b\x3b\x2a\xd8\x61\x69\x6d\x0b\x6b\x66\x6d\x06\xbb\xb7\x20\x69\x2d\x67\x93\x66\x54\xe2\x2f\x07\x32\x99\x50\xa1\x25\x12\xbd\x56\xc6\x4e\x2b\xd3\x28\x14\xf2\x33\xe1\xcf\x6d\xad\xea\x26\x0d\x81\xad\x51\x13\xf6\x8c\x67\x2e\xca\x49\x4c\xa4\x01\x70\xb1\x84\x76\xa2\xed\xe2\x23\xde\x0b\x14\x12\x0d\xac\x83\xfc\x4b\xdd\x2f\x3a\x57\xf0\xb7\xa9\xa9\xe8\x8d\x91\x78\x86\x2e\x1b\xae\x8c\xb7\x40\xbb\x2e\x25\x34\xe3\x40\x03\xf0\xea\x85\x82\x5c\x02\xfe\x91\xa6\x70\x3b\xc7\x18\xe2\x65\x24\x5d\x52\xf8\x2b\x09\x43\x4c\x85\x57\x1b\xde\xd9\xc6\xc1\x96\xea\xd6\xeb\x77\x86\x9e\xd6\xeb\xf7\x5d\xb0\xd8\x80\xc4\x06\x1c\x0a\x43\x2f\xa5\xb0\x40\xf6\x73\xc6\xc8\xbd\x86\x23\x1d\xe4\x64\xdc\x17\x02\xa4\x2c\x09\x91\x0b\x94\xb9\xc1\x28\xb9\x6d\xc8\xf1\x60\x35\x81\x87\x86\x1c\x90\xe2\xf4\x61\x47\xb8\xf8\xb2\x28\x04\x5f\x97\x2c\x7a\x3d\x88\x55\x0d\x4a\xb4\xaf\xdd\xd6\x0d\x4a\xf5\x6a\x16\xd9\x54\xdb\x8a\x44\x25\xc8\x79\xc9\xd6\x42\xbc\x3d\x30\xa8\x9a\x42\x5b\x57\x4e\xb5\x34\x16\xdb\x1b\xcf\x1d\x4b\x50\x5f\x86\xbd\xc5\xb1\x75\x65\x09\xe4\xb5\xdb\xca\x06\x4d\xf0\x14\xd6\x96\x88\x09\x94\x2b\x96\xdc\xfc\x89\x61\x56\x0b\xac\x55\x17\x05\xd6\x04\xcf\xa3\xa8\xe4\x79\x5c\x4d\xec\xe8\x52\x6b\xe9\x9b\xa2\xd4\x1e\x6a\xad\x91\x73\xf1\xb6\x99\xcf\x0e\xb3\xb1\xcf\xc5\x31\x93\x6a\x3f\x29\xb8\xe6\xbf\x2f\xd3\x08\x4d\x24\x6e\x64\xa0\xe3\x31\xfc\xfe\xea\x87\x57\x97\x7a\x8d\xe2\x99\x11\xe1\x80\xca\xd6\x7c\x9e\x2c\xa3\x09\xcc\x12\x98\x23\xc3\x91\xe8\xfe\x3e\x59\x02\x47\x54\x69\x13\x23\x94\x23\x90\x18\x28\xe7\x1a\x25\xc7\x63\x20\x19\xcc\xb3\x2c\xe5\x97\xe3\xf1\x8c\x66\xf3\xe5\x4d\x10\x26\x8b\xf1\x2c\xf9\x92\x2b\x26\xd2\xfc\x28\x1f\xe5\x4d\x41\x5a\xe2\x55\xe8\xd6\x6c\x6a\xea\xd4\xb1\x3d\x17\xb4\xfb\x6a\x83\x93\x89\xe7\x36\x16\x49\x64\xa2\xcd\xd2\xa4\x42\xfd\xc2\xe2\x43\xf9\x14\x28\xe7\x95\x50\x15\x92\x34\x5b\x0a\xe0\x27\x02\xf2\x4b\xe4\x6b\x58\x7e\x89\x7d\xe7\xbd\xc3\x07\xda\x3b\xec\x74\xa5\x56\x7a\xd2\xc5\x1d\xca\x65\x57\xae\x54\x36\x93\x4f\x36\xec\xa7\x70\xa5\x1b\x84\xc5\x32\x5b\x92\x28\xba\x07\x2c\x89\x71\xa0\xb1\x4a\x6b\x18\xf2\x24\x5a\x21\x6b\x03\xe3\x36\xe4\x64\x87\x6c\xe5\xca\x16\x71\x56\x64\x28\x2d\xd7\xa8\xc6\x69\xd2\x98\x81\xbb\xab\x97\x24\xed\xe8\xa8\x9e\x59\xb7\xbd\xb1\x49\x91\xd4\xcb\x1e\xd8\x8e\x14\x51\x56\x74\x0c\x1e\xfb\x28\xa9\xd2\xa6\x75\x52\x76\xff\x7d\xb2\x48\x23\xbc\x7b\x25\x03\xa7\x81\xef\xd7\xf6\x82\xc3\x95\x44\x6d\x48\xa1\x0e\x93\x40\xed\x9c\x6f\x74\x25\x4f\x9f\x23\x75\xda\x59\x90\xce\x70\xdd\x5a\x7a\x7b\x58\xeb\xce\x82\x4e\x28\xe7\xf0\x98\xc7\xd6\xb3\x70\xc2\xb2\x2d\x2f\x78\x0a\x49\x8f\x2d\x25\xb1\x19\x4d\xfd\x6a\xeb\x9b\x8d\x6b\x66\xc9\x02\x16\x24\x6d\x51\xcd\x5b\xc2\xea\x51\x10\x75\x1f\xb2\xb9\xbd\x05\x68\x86\xb6\x3a\xfa\x99\x9e\x6c\xd0\xcd\x15\x53\x6c\x8b\x3c\x47\xaf\xbd\xbd\xa5\x77\x06\x10\x0b\xdd\x55\x79\x83\x88\xc9\x6d\x56\xc9\x56\x98\x15\xca\x5a\x90\x94\xc3\xcd\x32\x83\x49\x82\x5c\x06\x89\x8f\x71\x72\x0b\xe4\x26\x59\x66\x60\x8b\x33\x97\x80\xc1\x2c\x00\x9a\x41\x98\x2c\x90\x2b\x5b\x23\x70\xc1\x70\x6a\x21\x4d\xdd\x85\xbb\x6e\x72\xa1\x53\x09\x39\xcd\x5b\x94\x1d\x97\xfd\x2e\x48\x5a\xa0\x4d\x9d\x2b\xa9\xc7\x2c\x8b\x56\x1b\x41\xca\xcd\x4e\xec\x52\x23\x5b\x26\xef\x41\x07\xd8\x90\xdf\x9b\x25\xee\x10\xa2\x23\x46\x2a\xeb\xad\x66\xb9\x22\x51\x65\xb7\xf6\x81\xb5\x2d\x1f\x36\xb8\x1e\x84\x91\x70\xaf\x62\xc2\x5a\x6b\xd1\xf1\xd8\xd6\x94\xb1\xb1\xd1\xaf\x88\x8c\xf6\x4e\xff\xf8\x99\x80\xde\x1f\x5e\x7c\xf7\xc7\x4f\xea\xac\x86\x44\xd1\x4b\xb9\xbc\x05\x9e\x16\xd7\x35\x54\xa9\x9b\x0d\xe4\x2a\x5a\x94\x1e\xa3\xdb\xd4\x5d\x48\xb5\x2a\xd5\x58\x36\x32\x68\xd4\xa2\x4d\x89\x63\x97\x05\xfa\x9b\xb5\xa6\xea\xa3\xdc\x62\x2b\xfb\xd0\x5b\x6e\xba\x4d\xc3\x46\x2e\x1d\x16\xab\x47\xac\x22\xcc\xa5\x2d\xe6\x54\x04\x7a\x27\x44\x58\xf1\xbb\x28\x09\xb5\x9c\xc6\x7c\x87\x8f\x14\xcf\x37\x51\xe3\xf5\xf5\xe8\xc6\x8c\x2b\xc7\x98\x31\x8d\x2c\x63\x76\x64\x15\x0f\xb3\x0f\x17\x12\x8e\x66\x30\x3a\xd4\xd6\xdb\x79\xf3\xad\x85\x9c\x9f\x6d\xf3\xad\xb6\xbd\xeb\xa8\x70\x36\x55\x14\x5b\x6d\x3b\x77\x26\xcb\x1d\xc3\x78\x0f\xd2\x4a\x41\xed\x47\xd2\xba\x0b\x93\x63\x95\x25\xbb\x16\x25\x9b\xa2\x9e\x45\x21\xa6\xcc\xb6\x2d\x9e\x8e\xcd\x9d\x9a\xae\x5b\x01\x35\xa8\x59\x53\x2d\x61\xda\x92\xfb\xb5\x59\xe7\x67\xa1\x7c\xcf\x64\xef\x83\x93\xbd\xee\x3a\xc9\xf3\x70\xe8\xb6\x0c\xac\x1d\xfb\x2c\xb4\xab\x0f\xe1\x6a\x31\x55\x91\xdb\x0a\x2d\xe9\xcd\x66\x7d\x12\xaa\x68\x50\xba\x59\xed\x38\x94\xb6\x59\xbc\x0b\x31\xcd\xe4\xfe\x3f\x2d\xef\x8e\x20\x9b\x23\x30\x8c\x27\xc8\x68\x3c\xad\x9d\x83\x91\x95\x21\xe5\x90\x22\x13\xa2\xe2\x04\x6e\xee\xa1\xe1\xab\xa6\x81\x6f\xe2\x7e\x4d\x89\x0e\x44\x70\x7a\xc1\x88\x0b\xd9\xf4\x19\x90\x06\x7a\x6c\x86\xb5\x2d\x20\xe8\x8c\x38\x67\xc4\x79\x84\x88\x53\xaf\xa4\x3d\x7d\xbb\xeb\x70\x7c\x38\xc7\x05\x71\x9c\x8e\x37\xc9\x4b\x75\x69\xd0\x7a\x83\x45\x5b\xa1\xa9\xa9\x8b\x59\x22\xb7\xd0\x2e\xaf\x8c\xe5\xef\x85\x49\xcc\x33\x18\xb4\x52\xcb\xda\x7b\x14\xc6\xd3\xcd\xe3\xcd\xa2\x48\x28\x7c\x8b\xcb\x37\x2d\x8a\x97\x2e\x9a\xb6\x2a\xfa\xfa\xbf\x0d\xfd\xd4\x6e\xc3\x95\xb5\x8f\x66\xde\x3a\x6c\x24\x99\xbd\xf2\xf0\xb0\xd4\x61\x6f\x45\xe4\xf9\xad\x90\x2c\xb0\xc5\xd5\xc2\xbb\xf7\x1a\xda\xf3\x75\x6f\xba\x8c\x43\xa0\x31\xcd\x06\x43\x69\xb4\xe2\x51\x21\xd4\xbb\xf7\xb5\x15\x9d\x20\xc3\xe9\x14\x27\x6f\xe4\x00\x42\x8d\x7a\x66\x15\x5c\xfc\xc9\x93\x38\xf8\x23\x5e\x10\xc6\xe7\x24\x1a\xbc\x7b\x7f\x73\x9f\xe1\xe0\x43\x9e\xcb\x3b\x5a\xbb\x1f\x86\x23\xf8\x3b\x43\x6b\x55\x94\x92\x98\x86\x03\x64\x6c\x58\x78\x8c\x90\xea\x3f\x23\x58\x55\x87\xcd\xc4\xec\xf2\x52\x7e\xbb\x88\x57\x40\xd2\x14\x63\x59\xc8\x5b\x5b\x8c\x60\xa5\x06\x58\xf7\x94\x06\x06\x36\x0e\xa2\x82\x81\x06\xc6\x9b\xef\xa9\x14\xae\xf0\xe2\x2e\x4d\x58\x86\x13\xd7\x49\xf8\x3a\xa3\x66\x5c\x54\xe0\x01\x9b\x39\xf6\x94\x64\xf3\x11\x44\x25\xfa\x29\x6b\x1f\x55\x86\xa7\x43\xa6\x8e\x90\xad\xd8\xe9\x38\x7f\x57\x13\x67\xf3\x9a\x0f\x41\x16\xa9\x72\x11\x2c\xb1\xc2\x32\xd9\x62\x96\x23\xe7\x8a\x79\x81\xa7\xc1\x53\xac\x3b\x0e\x95\x97\x3e\xec\x72\x82\xaa\x51\xdd\x13\xf6\x72\x05\xa3\x6e\xf3\xf7\x07\x73\xba\x47\x75\x8a\x6a\xa0\x4e\xcf\xd0\xcd\xfc\xdc\xe3\x59\x45\x1c\xbb\xac\xff\xc2\x6a\xfe\xf5\xcb\x3e\x0e\xa0\x67\x76\x22\x5e\xa0\xdf\x65\x39\xac\x2b\x68\x31\x0f\xe0\x0f\x9b\x4f\xdc\x36\x42\x6b\x11\x42\x0c\x82\x41\xd4\xf3\xdc\xe9\x47\xfa\x3c\xc5\x21\xfd\xe8\x14\x43\x4a\x25\x68\xa7\xf7\xe8\x66\x5b\x79\xcf\xb1\x43\x47\x75\xea\xe5\x34\x3c\xe7\xf0\x4e\xa3\x25\xdc\xc5\x69\x5a\xf9\x71\xf9\x79\x3c\x86\x92\x5d\x35\xce\xfa\x4b\x46\x2d\xcf\x61\xbe\x5c\x90\xd8\x9c\x84\x5e\x68\x47\x12\x71\x08\xcd\x0a\x6b\xf9\x81\xf2\x50\x24\x22\xb1\x9c\x8e\xbc\xdc\x52\x48\xfd\x04\xd6\xbe\xd6\xd5\xe4\xb2\x85\xe1\x4c\x17\x59\xf0\x1b\xce\x28\xcf\xd8\xbd\xb9\x9a\x95\xa7\xcb\x6b\xbd\x9e\x93\xcf\x35\xf7\x75\x6c\x44\xab\x7a\x8d\xb9\xdc\x8b\x96\xb8\xa4\x8e\xc2\x85\xc9\x22\x4d\xb8\xd4\x95\x82\xb8\x5a\x5d\xb7\xa9\xc4\x52\xcb\x50\xed\xee\x37\x4b\xbb\x6a\x9f\x48\x36\xad\x8e\x04\xd4\x6b\x6f\x57\x31\x66\x2d\xf0\xfd\xf9\x6b\x5d\x08\x8a\xc0\x69\xac\x74\xc2\x7e\x14\x1d\xab\xd5\xf1\x9f\x1a\xec\xf5\x0e\xa1\xcf\x86\xae\x58\x6b\x8d\x89\x0c\xf9\x08\x0a\x98\x2d\xff\xfc\xb7\x57\xeb\xcc\xb8\xeb\x85\x19\x63\xc7\x61\xe8\xf9\x26\x0e\x8d\x81\xc4\x05\x27\x05\xb7\x73\x1a\xce\x81\xaa\x43\x0c\x6a\x87\xa9\x38\x3f\x50\x3b\x59\xe9\x77\x48\xd1\x22\xc1\x16\x67\x8e\xf6\x38\x72\xa3\xde\x6c\xdd\xb0\x3e\x9d\x6b\xe3\xda\x09\xa9\xaa\x7b\x5f\x23\xeb\x16\xa3\x36\xfd\xc1\x84\x25\xe9\x6b\x12\x7e\x24\xc2\x0b\x94\xcf\x0e\xb7\xd9\x2e\xf3\x10\xc9\xb5\x4b\xef\xe3\xa8\xdd\x3e\x7a\x78\xff\x3c\x9e\x6f\x7a\x29\xca\x16\xf5\x4e\xc6\x0b\xb7\xa2\x93\x7c\x3d\xcf\x39\x51\xd5\x40\xcc\x11\x32\xf9\xb0\x9e\xc7\x71\xbd\xb4\x63\x9d\xec\x15\xae\x94\x50\xa6\xa2\x83\x26\x2d\x31\x6c\x2e\x4b\xaf\x8a\xa3\xd5\xcf\x81\xec\x7f\xd4\xaf\xdf\x1f\x41\xff\x26\x99\xdc\xf7\x47\xb6\x1e\xf6\x14\x54\xa5\x84\x11\xc6\xa2\xd5\x10\xfe\x09\x5f\xb5\x12\xb9\x84\xf1\xe0\xfb\x22\x0b\xc0\xca\xb3\x5e\x88\x3b\xe2\xa9\x20\x08\x86\xb6\x64\xcf\xcb\xbf\xbb\x5c\xb7\x09\xf4\x81\x8b\x69\xd0\xe5\xad\x40\x38\xab\x26\xc5\xf0\x4f\xb9\x74\xda\x42\x03\xd6\x9a\xca\xff\x79\xb3\xd8\xaa\xa7\x52\x3e\x04\x31\x74\x91\xc4\xf5\x26\xa2\x18\x8e\xc5\xd8\xa2\x51\x99\xf5\xd7\x79\x64\xe8\xe4\x92\xed\xac\x88\x71\x55\x8f\xb0\x2f\xdb\xbc\xdf\x48\xfe\x7c\x34\x58\x38\x69\x68\xf1\xd2\x62\x30\x13\x84\x3c\x08\xa5\xae\x2a\xa7\x45\x29\xed\x44\x41\x6d\xcd\x40\x3d\xc9\x12\xda\xdf\xcd\x76\xab\xad\x9b\x09\xa6\x1f\x51\x6b\x37\xda\x4d\xf4\xed\xd3\x63\x6f\x7d\xf5\xd0\x8d\xa0\xdd\x0f\x6f\xc9\xf4\x9e\xa0\x63\x6e\x4f\x0d\x17\x3f\xfa\x52\xfa\x68\xf1\xb5\xe9\xa9\xe5\x4f\xc9\x9c\x1c\x59\xec\xb9\xb2\x07\xf6\x58\x67\x1d\xeb\x6a\x71\x62\xd9\x91\x75\xfe\xfe\xce\xee\x10\xee\x09\x25\x4f\x8f\xd3\xfb\xb7\x71\xfc\xe6\x1a\xba\x2a\xc5\x36\x18\xb4\x1b\x1c\x00\x16\xda\x16\xf9\x68\xa2\xba\x15\x25\x9a\xdf\x7d\x7f\xf2\xa5\xb9\x09\xd5\xd8\x80\x2a\x1e\x31\x12\xc8\xed\xf2\x85\x27\xbf\x4d\xe5\x2b\xfe\x0e\x69\xc2\x6e\x5b\x5a\x27\x09\x14\x4f\x77\x1f\xcc\x73\x09\x8f\xe1\xeb\x2d\xde\x7b\x7f\x6a\xd4\xb9\x8f\x76\xca\xc6\xe5\xb3\x37\x66\xaa\xaa\xf6\x02\x8f\xc6\x92\xdd\x7f\xaa\xaf\xf6\x06\x8f\x7b\xe1\x6a\xec\xee\x85\x69\xe1\xf2\x95\xd0\xf3\x29\xd0\x07\xfd\x91\x11\xeb\x7b\x8a\x9b\xdf\x2e\xf1\xc9\xda\xdd\xe4\xbe\x63\x33\x76\xc3\x3b\x2f\x07\xdf\x98\x3c\x13\xa8\x27\x59\x03\x14\x6c\x9d\x30\xbb\x33\x57\x77\xaa\x61\xfe\x01\xb3\xfa\x63\xf2\x75\x67\xc2\xee\x4c\xd8\x9d\x09\xbb\x03\x10\x76\x1d\x6e\xdb\x41\xda\x9d\x69\xbb\xa7\x11\xb2\x1f\x27\x06\x9c\x69\xbb\xcf\x13\xe0\x1d\x58\xd1\xbe\xe2\x47\xde\xf9\x27\xf2\x5b\x51\x73\x4f\x2e\x89\x7f\x20\x66\xce\x87\x3c\x7d\x9c\x78\x71\x66\xef\x8e\xe4\xf2\xbd\x33\xe1\x76\x64\xc2\xed\x98\x8c\x8e\xe3\x3f\x0c\x34\xff\xdf\xd2\x36\x69\xde\x51\xcb\xb6\x47\x94\xcd\x79\x56\x6d\xe7\xfa\xec\xaf\x93\xa0\x1d\xa8\x62\xab\xdc\xb7\x13\x7a\xdb\x0b\xe3\xb3\x6e\x7e\xc0\xe8\x5e\xbb\x8a\xbd\x6d\xde\xb1\x9d\x85\x2d\xff\x4f\x48\xe3\xff\x24\x75\xfd\x53\x90\xc0\x3d\x77\xe3\xf7\xb6\xba\x41\xd3\x0a\x23\x6d\x9c\x74\xbe\x1f\x59\x7d\xfa\x5f\x00\x00\x00\xff\xff\xeb\xb7\xdf\xb0\xc4\x79\x00\x00")
 
 func templatesSchemavalidatorGotmplBytes() ([]byte, error) {
 	return bindataRead(
@@ -435,8 +435,8 @@ func templatesSchemavalidatorGotmpl() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "templates/schemavalidator.gotmpl", size: 31005, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)}
-	a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x26, 0x6d, 0x6d, 0x1d, 0x89, 0x34, 0xea, 0x0, 0xd7, 0xf7, 0xeb, 0x58, 0x39, 0x87, 0xb8, 0x78, 0x61, 0x65, 0x65, 0xba, 0x95, 0x13, 0x81, 0x3f, 0x5d, 0xab, 0x6b, 0x80, 0x3c, 0x7f, 0x27, 0x62}}
+	info := bindataFileInfo{name: "templates/schemavalidator.gotmpl", size: 31172, mode: os.FileMode(0644), modTime: time.Unix(1482416923, 0)}
+	a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb5, 0xfe, 0xa3, 0x63, 0x70, 0x99, 0x44, 0x85, 0xea, 0xaa, 0xe5, 0x1a, 0x20, 0xb8, 0x91, 0x1c, 0x63, 0x84, 0x2, 0x34, 0x67, 0xcd, 0xd9, 0xe1, 0xe9, 0x58, 0x76, 0xbe, 0xb2, 0xc6, 0x1a, 0xba}}
 	return a, nil
 }
 
diff --git a/generator/shared.go b/generator/shared.go
index 409c8755..a9aa3597 100644
--- a/generator/shared.go
+++ b/generator/shared.go
@@ -675,11 +675,13 @@ func (g *GenOpts) EnsureDefaults() error {
 		g.LanguageOpts = GoLangOpts()
 	}
 	// set defaults for flattening options
-	g.FlattenOpts = &analysis.FlattenOpts{
-		Minimal:      true,
-		Verbose:      true,
-		RemoveUnused: false,
-		Expand:       false,
+	if g.FlattenOpts == nil {
+		g.FlattenOpts = &analysis.FlattenOpts{
+			Minimal:      true,
+			Verbose:      true,
+			RemoveUnused: false,
+			Expand:       false,
+		}
 	}
 	g.defaultsEnsured = true
 	return nil
diff --git a/generator/templates/schemavalidator.gotmpl b/generator/templates/schemavalidator.gotmpl
index 4f1212c2..40b37214 100644
--- a/generator/templates/schemavalidator.gotmpl
+++ b/generator/templates/schemavalidator.gotmpl
@@ -108,21 +108,22 @@
 {{ define "mapvalidator" }}{{/* validates additionalProperties */}}
   {{ if .HasAdditionalProperties }}
     {{- if  .AdditionalProperties.HasValidations }}
+    {{- $validatedValues := .ValueExpression }}{{ $keyVar := .AdditionalProperties.KeyVar }}
     for {{ .AdditionalProperties.KeyVar }} := range {{ .ValueExpression }} {
       {{ with .AdditionalProperties }}
         {{- if and (not .Required) .IsNullable }}{{/* skip when nul type is accepted */}}
-      if swag.IsZero({{ .ValueExpression }}) { // not required
+      if swag.IsZero({{ $validatedValues }}[{{ $keyVar }}]) { // not required
         continue
       }
         {{- else if and (.Required) (not .IsArray) }}{{/* Required slice is processed below */}}
-      if err := validate.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{.ValueExpression }}); err != nil {
+      if err := validate.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ $validatedValues }}[{{ $keyVar }}]); err != nil {
         return err
       }
         {{- end }}
         {{- if .IsPrimitive }}
           {{- if .IsAliased }}
             {{- if not .IsAnonymous }}
-      if val, ok := {{ .ValueExpression }}; ok {
+      if val, ok := {{ $validatedValues }}[{{ $keyVar }}]; ok {
               {{- if and .IsNullable (not .IsMapNullOverride) }}
         if val != nil {
               {{- end }}
@@ -164,13 +165,13 @@
         {{ else if .IsMap }}
           {{ template "mapvalidator" . }}
           {{ if .Enum }}
-      if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}ValueEnum({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .ValueExpression }}); err != nil {
+      if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}ValueEnum({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ $validatedValues }}[{{ $keyVar }}]); err != nil {
         return err
       }
           {{- end }}
         {{ else if or .IsComplexObject .IsTuple .IsAdditionalProperties .IsAliased }}
           {{- if not .IsAnonymous }}
-    if val, ok := {{ .ValueExpression }}; ok {
+    if val, ok := {{ $validatedValues }}[{{ $keyVar }}]; ok {
             {{- if and .IsNullable (not .IsMapNullOverride) }}
       if val != nil {
             {{- end }}
@@ -306,7 +307,7 @@
     {{- end }}
   {{- else if .IsArray }}
     {{ template "slicevalidator" . }}
-    {{- else if and .IsMap (or (not .IsAliased) (and .IsAliased .IsInterface)) }}{{/* except for interface, the renderinf for aliased maps is performed by objectvalidator */}}
+  {{- else if and .IsMap (or (not .IsAliased) (and .IsAliased .IsInterface)) }}{{/* except for interface, the renderinf for aliased maps is performed by objectvalidator */}}
     {{ template "mapvalidator" . }}
   {{- else if or .IsComplexObject .IsTuple .IsAdditionalProperties .IsAliased }}
     {{ template "objectvalidator" . }}
diff --git a/generator/types.go b/generator/types.go
index a80d75bb..75deeca4 100644
--- a/generator/types.go
+++ b/generator/types.go
@@ -222,40 +222,38 @@ func (t *typeResolver) IsNullable(schema *spec.Schema) bool {
 }
 
 func (t *typeResolver) resolveSchemaRef(schema *spec.Schema, isRequired bool) (returns bool, result resolvedType, err error) {
-	if schema.Ref.String() != "" {
-		debugLog("resolving ref (anon: %t, req: %t) %s", false, isRequired, schema.Ref.String())
-		returns = true
-		var ref *spec.Schema
-		var er error
-
-		ref, er = spec.ResolveRef(t.Doc.Spec(), &schema.Ref)
-		if er != nil {
-			debugLog("error resolving ref %s: %v", schema.Ref.String(), er)
-			err = er
-			return
-		}
-		res, er := t.ResolveSchema(ref, false, isRequired)
-		if er != nil {
-			err = er
-			return
-		}
-		result = res
+	if schema.Ref.String() == "" {
+		return
+	}
+	debugLog("resolving ref (anon: %t, req: %t) %s", false, isRequired, schema.Ref.String())
+	returns = true
+	var ref *spec.Schema
+	var er error
 
-		tn := filepath.Base(schema.Ref.GetURL().Fragment)
-		tpe, pkg, alias := knownDefGoType(tn, *ref, t.goTypeName)
-		debugLog("type name %s, package %s, alias %s", tpe, pkg, alias)
-		if tpe != "" {
-			result.GoType = tpe
-			result.Pkg = pkg
-			result.PkgAlias = alias
-		}
-		result.HasDiscriminator = res.HasDiscriminator
-		result.IsBaseType = result.HasDiscriminator
-		result.IsNullable = t.IsNullable(ref)
-		//result.IsAliased = true
+	ref, er = spec.ResolveRef(t.Doc.Spec(), &schema.Ref)
+	if er != nil {
+		debugLog("error resolving ref %s: %v", schema.Ref.String(), er)
+		err = er
+		return
+	}
+	res, er := t.ResolveSchema(ref, false, isRequired)
+	if er != nil {
+		err = er
 		return
+	}
+	result = res
 
+	tn := filepath.Base(schema.Ref.GetURL().Fragment)
+	tpe, pkg, alias := knownDefGoType(tn, *ref, t.goTypeName)
+	debugLog("type name %s, package %s, alias %s", tpe, pkg, alias)
+	if tpe != "" {
+		result.GoType = tpe
+		result.Pkg = pkg
+		result.PkgAlias = alias
 	}
+	result.HasDiscriminator = res.HasDiscriminator
+	result.IsBaseType = result.HasDiscriminator
+	result.IsNullable = t.IsNullable(ref)
 	return
 }
 
@@ -329,32 +327,6 @@ func (t *typeResolver) isNullable(schema *spec.Schema) bool {
 	return len(schema.Properties) > 0
 }
 
-func setIsEmptyOmitted(result *resolvedType, schema *spec.Schema, tpe string) {
-	defaultValue := true
-	if tpe == array {
-		defaultValue = false
-	}
-	v, found := schema.Extensions[xOmitEmpty]
-	if !found {
-		result.IsEmptyOmitted = defaultValue
-		return
-	}
-
-	omitted, cast := v.(bool)
-	result.IsEmptyOmitted = omitted && cast
-}
-
-func setIsJSONString(result *resolvedType, schema *spec.Schema, tpe string) {
-
-	_, found := schema.Extensions[xGoJSONString]
-	if !found {
-		result.IsJSONString = false
-		return
-	}
-
-	result.IsJSONString = true
-}
-
 func (t *typeResolver) firstType(schema *spec.Schema) string {
 	if len(schema.Type) == 0 || schema.Type[0] == "" {
 		return object
@@ -652,9 +624,8 @@ func (t *typeResolver) ResolveSchema(schema *spec.Schema, isAnonymous, isRequire
 	}
 
 	tpe := t.firstType(schema)
-	defer setIsEmptyOmitted(&result, schema, tpe)
-
 	var returns bool
+
 	returns, result, err = t.resolveSchemaRef(schema, isRequired)
 	if returns {
 		if !isAnonymous {
@@ -665,7 +636,10 @@ func (t *typeResolver) ResolveSchema(schema *spec.Schema, isAnonymous, isRequire
 		debugLog("returning after ref")
 		return
 	}
-	defer setIsJSONString(&result, schema, tpe)
+	defer func() {
+		result.setIsEmptyOmitted(schema, tpe)
+		result.setIsJSONString(schema, tpe)
+	}()
 
 	// special case of swagger type "file", rendered as io.ReadCloser interface
 	if t.firstType(schema) == file {
@@ -818,3 +792,22 @@ func (rt *resolvedType) Zero() string {
 
 	return ""
 }
+
+func (rt *resolvedType) setIsEmptyOmitted(schema *spec.Schema, tpe string) {
+	if v, found := schema.Extensions[xOmitEmpty]; found {
+		omitted, cast := v.(bool)
+		rt.IsEmptyOmitted = omitted && cast
+		return
+	}
+	// array of primitives are by default not empty-omitted, but arrays of aliased type are
+	rt.IsEmptyOmitted = (tpe != array) || (tpe == array && rt.IsAliased)
+}
+
+func (rt *resolvedType) setIsJSONString(schema *spec.Schema, tpe string) {
+	_, found := schema.Extensions[xGoJSONString]
+	if !found {
+		rt.IsJSONString = false
+		return
+	}
+	rt.IsJSONString = true
+}
diff --git a/scan/enum.go b/scan/enum.go
new file mode 100644
index 00000000..bfbe601e
--- /dev/null
+++ b/scan/enum.go
@@ -0,0 +1,83 @@
+// +build !go1.11
+
+package scan
+
+import (
+	"go/ast"
+	"strconv"
+	"strings"
+	"unicode"
+)
+
+func upperSnakeCase(s string) string {
+	in := []rune(s)
+	isLower := func(idx int) bool {
+		return idx >= 0 && idx < len(in) && unicode.IsLower(in[idx])
+	}
+
+	out := make([]rune, 0, len(in)+len(in)/2)
+
+	for i, r := range in {
+		if unicode.IsUpper(r) {
+			r = unicode.ToLower(r)
+			if i > 0 && in[i-1] != '_' && (isLower(i-1) || isLower(i+1)) {
+				out = append(out, '_')
+			}
+		}
+		out = append(out, r)
+	}
+
+	return strings.ToUpper(string(out))
+}
+
+func getEnumBasicLitValue(basicLit *ast.BasicLit) interface{} {
+	switch basicLit.Kind.String() {
+	case "INT":
+		if result, err := strconv.ParseInt(basicLit.Value, 10, 64); err == nil {
+			return result
+		}
+	case "FLOAT":
+		if result, err := strconv.ParseFloat(basicLit.Value, 64); err == nil {
+			return result
+		}
+	default:
+		return strings.Trim(basicLit.Value, "\"")
+	}
+	return nil
+}
+
+func getEnumValues(file *ast.File, typeName string) (list []interface{}) {
+	for _, decl := range file.Decls {
+		genDecl, ok := decl.(*ast.GenDecl)
+
+		if !ok {
+			continue
+		}
+
+		if genDecl.Tok.String() == "const" {
+			for _, spec := range genDecl.Specs {
+				if valueSpec, ok := spec.(*ast.ValueSpec); ok {
+					switch valueSpec.Type.(type) {
+					case *ast.Ident:
+						if valueSpec.Type.(*ast.Ident).Name == typeName {
+							if basicLit, ok := valueSpec.Values[0].(*ast.BasicLit); ok {
+								list = append(list, getEnumBasicLitValue(basicLit))
+							}
+						}
+					default:
+						var name = valueSpec.Names[0].Name
+						if strings.HasPrefix(name, upperSnakeCase(typeName)) {
+							var values = strings.SplitN(name, "__", 2)
+							if len(values) == 2 {
+								list = append(list, values[1])
+							}
+						}
+					}
+
+				}
+
+			}
+		}
+	}
+	return
+}
diff --git a/scan/parameters.go b/scan/parameters.go
index a97c34d1..1ebdc71d 100644
--- a/scan/parameters.go
+++ b/scan/parameters.go
@@ -40,6 +40,10 @@ func (pt paramTypable) Typed(tpe, format string) {
 	pt.param.Typed(tpe, format)
 }
 
+func (pt paramTypable) WithEnum(values ...interface{}) {
+	pt.param.WithEnum(values...);
+}
+
 func (pt paramTypable) SetRef(ref spec.Ref) {
 	pt.param.Ref = ref
 }
@@ -68,6 +72,10 @@ func (pt paramTypable) Schema() *spec.Schema {
 	return pt.param.Schema
 }
 
+func (pt paramTypable) WithEnum(values ...interface{}) {
+	pt.param.WithEnum(values...)
+}
+
 type itemsTypable struct {
 	items *spec.Items
 	level int
@@ -83,6 +91,10 @@ func (pt itemsTypable) SetRef(ref spec.Ref) {
 	pt.items.Ref = ref
 }
 
+func (pt itemsTypable) WithEnum(values ...interface{}) {
+	pt.items.WithEnum(values...);
+}
+
 func (pt itemsTypable) Schema() *spec.Schema {
 	return nil
 }
@@ -95,6 +107,10 @@ func (pt itemsTypable) Items() swaggerTypable {
 	return itemsTypable{pt.items.Items, pt.level + 1}
 }
 
+func (pt itemsTypable) WithEnum(values ...interface{}) {
+	pt.items.WithEnum(values...)
+}
+
 type paramValidations struct {
 	current *spec.Parameter
 }
diff --git a/scan/responses.go b/scan/responses.go
index 7b08b16b..331634d3 100644
--- a/scan/responses.go
+++ b/scan/responses.go
@@ -38,6 +38,10 @@ func (ht responseTypable) Typed(tpe, format string) {
 	ht.header.Typed(tpe, format)
 }
 
+func (ht responseTypable) WithEnum(values ...interface{}) {
+	ht.header.WithEnum(values)
+}
+
 func bodyTypable(in string, schema *spec.Schema) (swaggerTypable, *spec.Schema) {
 	if in == "body" {
 		// get the schema for items on the schema property
@@ -85,10 +89,15 @@ func (ht responseTypable) Schema() *spec.Schema {
 func (ht responseTypable) SetSchema(schema *spec.Schema) {
 	ht.response.Schema = schema
 }
+
 func (ht responseTypable) CollectionOf(items *spec.Items, format string) {
 	ht.header.CollectionOf(items, format)
 }
 
+func (ht responseTypable) WithEnum(values ...interface{}) {
+	ht.header.WithEnum(values)
+}
+
 type headerValidations struct {
 	current *spec.Header
 }
diff --git a/scan/scanner.go b/scan/scanner.go
index 98c53305..7c9950bc 100644
--- a/scan/scanner.go
+++ b/scan/scanner.go
@@ -471,8 +471,10 @@ type swaggerTypable interface {
 	Typed(string, string)
 	SetRef(spec.Ref)
 	Items() swaggerTypable
+	WithEnum(...interface{})
 	Schema() *spec.Schema
 	Level() int
+	WithEnum(...interface{})
 }
 
 // Map all Go builtin types that have Json representation to Swagger/Json types.
diff --git a/scan/schema.go b/scan/schema.go
index 7fc14d6a..fb85dd9b 100644
--- a/scan/schema.go
+++ b/scan/schema.go
@@ -81,8 +81,13 @@ func (st schemaTypable) AdditionalProperties() swaggerTypable {
 	st.schema.Typed("object", "")
 	return schemaTypable{st.schema.AdditionalProperties.Schema, st.level + 1}
 }
+
 func (st schemaTypable) Level() int { return st.level }
 
+func (st schemaTypable) WithEnum(values ...interface{}) {
+	st.schema.WithEnum(values...)
+}
+
 type schemaValidations struct {
 	current *spec.Schema
 }
@@ -248,6 +253,18 @@ func (scp *schemaParser) parseDecl(definitions map[string]spec.Schema, decl *sch
 				return err
 			}
 		}
+		if enumName, ok := enumName(decl.Decl.Doc); ok {
+			var enumValues = getEnumValues(decl.File, enumName)
+			if len(enumValues) > 0 {
+				var typeName = reflect.TypeOf(enumValues[0]).String()
+				prop.WithEnum(enumValues...)
+
+				err := swaggerSchemaForType(typeName, prop)
+				if err != nil {
+					return fmt.Errorf("file %s, error is: %v", decl.File.Name, err)
+				}
+			}
+		}
 	case *ast.SelectorExpr:
 		prop := &schemaTypable{schPtr, 0}
 		if strfmtName, ok := strfmtName(decl.Decl.Doc); ok {
@@ -1025,8 +1042,15 @@ func (scp *schemaParser) parseIdentProperty(pkg *loader.PackageInfo, expr *ast.I
 	}
 
 	if enumName, ok := enumName(gd.Doc); ok {
-		log.Println(enumName)
-		return nil
+		var enumValues = getEnumValues(file, enumName)
+		if len(enumValues) > 0 {
+			prop.WithEnum(enumValues...)
+			var typeName = reflect.TypeOf(enumValues[0]).String()
+			err := swaggerSchemaForType(typeName, prop)
+			if err != nil {
+				return fmt.Errorf("file %s, error is: %v", file.Name, err)
+			}
+		}
 	}
 
 	if defaultName, ok := defaultName(gd.Doc); ok {


Test patch:
diff --git a/cmd/swagger/commands/generate/client_test.go b/cmd/swagger/commands/generate/client_test.go
index bbd1831e..8fc01ca5 100644
--- a/cmd/swagger/commands/generate/client_test.go
+++ b/cmd/swagger/commands/generate/client_test.go
@@ -36,7 +36,7 @@ func TestGenerateClient(t *testing.T) {
 			spec:      "todolist.simplequery.yml",
 			wantError: false,
 			prepare: func(c *generate.Client) {
-				c.CopyrightFile = flags.Filename(filepath.Join(base, "LICENSE"))
+				c.Shared.CopyrightFile = flags.Filename(filepath.Join(base, "LICENSE"))
 			},
 		},
 		{
@@ -66,9 +66,9 @@ func TestGenerateClient(t *testing.T) {
 			}()
 			m := &generate.Client{}
 			_, _ = flags.Parse(m)
-			m.Spec = flags.Filename(path)
-			m.Target = flags.Filename(generated)
-			m.Template = tt.template
+			m.Shared.Spec = flags.Filename(path)
+			m.Shared.Target = flags.Filename(generated)
+			m.Shared.Template = tt.template
 
 			if tt.prepare != nil {
 				tt.prepare(m)
@@ -90,7 +90,7 @@ func TestGenerateClient_Check(t *testing.T) {
 
 	m := &generate.Client{}
 	_, _ = flags.Parse(m)
-	m.CopyrightFile = "nullePart"
+	m.Shared.CopyrightFile = "nullePart"
 	err := m.Execute([]string{})
 	assert.Error(t, err)
 }
diff --git a/cmd/swagger/commands/generate/model_test.go b/cmd/swagger/commands/generate/model_test.go
index 434879b0..ef31a5f7 100644
--- a/cmd/swagger/commands/generate/model_test.go
+++ b/cmd/swagger/commands/generate/model_test.go
@@ -41,10 +41,10 @@ func TestGenerateModel(t *testing.T) {
 			m := &generate.Model{}
 			_, _ = flags.Parse(m)
 			if i == 0 {
-				m.ExistingModels = "nonExisting"
+				m.Models.ExistingModels = "nonExisting"
 			}
-			m.Spec = flags.Filename(path)
-			m.Target = flags.Filename(generated)
+			m.Shared.Spec = flags.Filename(path)
+			m.Shared.Target = flags.Filename(generated)
 
 			if err := m.Execute([]string{}); err != nil {
 				t.Error(err)
@@ -59,7 +59,7 @@ func TestGenerateModel_Check(t *testing.T) {
 
 	m := &generate.Model{}
 	_, _ = flags.Parse(m)
-	m.DumpData = true
+	m.Shared.DumpData = true
 	m.Name = []string{"model1", "model2"}
 	err := m.Execute([]string{})
 	assert.Error(t, err)
diff --git a/cmd/swagger/commands/generate/operation_test.go b/cmd/swagger/commands/generate/operation_test.go
index 71fc12d5..cb627f90 100644
--- a/cmd/swagger/commands/generate/operation_test.go
+++ b/cmd/swagger/commands/generate/operation_test.go
@@ -33,11 +33,11 @@ func TestGenerateOperation(t *testing.T) {
 			}()
 			m := &generate.Operation{}
 			if i == 0 {
-				m.CopyrightFile = flags.Filename(filepath.Join(base, "LICENSE"))
+				m.Shared.CopyrightFile = flags.Filename(filepath.Join(base, "LICENSE"))
 			}
 			_, _ = flags.ParseArgs(m, []string{"--name=listTasks"})
-			m.Spec = flags.Filename(path)
-			m.Target = flags.Filename(generated)
+			m.Shared.Spec = flags.Filename(path)
+			m.Shared.Target = flags.Filename(generated)
 
 			if err := m.Execute([]string{}); err != nil {
 				t.Error(err)
@@ -52,7 +52,7 @@ func TestGenerateOperation_Check(t *testing.T) {
 
 	m := &generate.Operation{}
 	_, _ = flags.ParseArgs(m, []string{"--name=op1", "--name=op2"})
-	m.DumpData = true
+	m.Shared.DumpData = true
 	m.Name = []string{"op1", "op2"}
 	err := m.Execute([]string{})
 	assert.Error(t, err)
diff --git a/cmd/swagger/commands/generate/server_internal_test.go b/cmd/swagger/commands/generate/server_internal_test.go
index a797b4bc..8f8c4626 100644
--- a/cmd/swagger/commands/generate/server_internal_test.go
+++ b/cmd/swagger/commands/generate/server_internal_test.go
@@ -6,6 +6,7 @@ import (
 	"os"
 	"testing"
 
+	"github.com/go-swagger/go-swagger/generator"
 	"github.com/stretchr/testify/assert"
 )
 
@@ -16,7 +17,6 @@ func TestDeprecated(t *testing.T) {
 	s := Server{
 		WithContext: true,
 	}
-	_, err := s.getOpts()
-	assert.NoError(t, err)
+	s.apply(new(generator.GenOpts))
 	assert.Contains(t, buf.String(), "warning")
 }
diff --git a/cmd/swagger/commands/generate/server_test.go b/cmd/swagger/commands/generate/server_test.go
index 4e14d83b..446721a5 100644
--- a/cmd/swagger/commands/generate/server_test.go
+++ b/cmd/swagger/commands/generate/server_test.go
@@ -17,6 +17,7 @@ func TestGenerateServer(t *testing.T) {
 	specs := []string{
 		"billforward.discriminators.yml",
 		"todolist.simplequery.yml",
+		"todolist.simplequery.yml",
 	}
 	log.SetOutput(ioutil.Discard)
 	defer log.SetOutput(os.Stdout)
@@ -35,13 +36,16 @@ func TestGenerateServer(t *testing.T) {
 			m := &generate.Server{}
 			_, _ = flags.Parse(m)
 			if i == 0 {
-				m.CopyrightFile = flags.Filename(filepath.Join(base, "LICENSE"))
+				m.Shared.CopyrightFile = flags.Filename(filepath.Join(base, "LICENSE"))
 			}
-			if i == 1 {
+			switch i {
+			case 1:
 				m.FlagStrategy = "pflag"
+			case 2:
+				m.FlagStrategy = "flag"
 			}
-			m.Spec = flags.Filename(path)
-			m.Target = flags.Filename(generated)
+			m.Shared.Spec = flags.Filename(path)
+			m.Shared.Target = flags.Filename(generated)
 
 			if err := m.Execute([]string{}); err != nil {
 				t.Error(err)
@@ -56,7 +60,7 @@ func TestGenerateServer_Checks(t *testing.T) {
 
 	m := &generate.Server{}
 	_, _ = flags.Parse(m)
-	m.CopyrightFile = "nowhere"
+	m.Shared.CopyrightFile = "nowhere"
 	err := m.Execute([]string{})
 	assert.Error(t, err)
 }
diff --git a/cmd/swagger/commands/generate/shared_test.go b/cmd/swagger/commands/generate/shared_test.go
index 320dda97..44313445 100644
--- a/cmd/swagger/commands/generate/shared_test.go
+++ b/cmd/swagger/commands/generate/shared_test.go
@@ -8,6 +8,7 @@ import (
 
 	"github.com/go-openapi/analysis"
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func resetDefaultOpts() *analysis.FlattenOpts {
@@ -117,4 +118,60 @@ func Test_Shared_SetFlattenOptions(t *testing.T) {
 }
 
 func Test_Shared_ReadConfig(t *testing.T) {
+	tmpFile, errio := ioutil.TempFile("", "tmp-config*.yaml")
+	require.NoError(t, errio)
+	defer func() {
+		_ = os.Remove(tmpFile.Name())
+	}()
+	tmpConfig := tmpFile.Name()
+	errio = ioutil.WriteFile(tmpConfig, []byte(`param: 123
+other: abc
+`), 0644)
+	require.NoError(t, errio)
+	_ = tmpFile.Close()
+
+	for _, toPin := range []struct {
+		Name        string
+		Filename    string
+		ExpectError bool
+		Expected    map[string]interface{}
+	}{
+		{
+			Name:     "empty",
+			Filename: "",
+		},
+		{
+			Name:        "no file",
+			Filename:    "nowhere",
+			ExpectError: true,
+		},
+		{
+			Name:     "happy path",
+			Filename: tmpConfig,
+			Expected: map[string]interface{}{
+				"param": 123,
+				"other": "abc",
+			},
+		},
+	} {
+		testCase := toPin
+		t.Run(testCase.Name, func(t *testing.T) {
+			v, err := readConfig(testCase.Filename)
+			if testCase.ExpectError {
+				assert.Error(t, err)
+				return
+			}
+			require.NoError(t, err)
+			if testCase.Expected == nil {
+				require.Nil(t, v)
+				return
+			}
+			require.NotNil(t, v)
+			m := v.AllSettings()
+			for k, expectedValue := range testCase.Expected {
+				require.Contains(t, m, k)
+				assert.EqualValues(t, expectedValue, m[k])
+			}
+		})
+	}
 }
diff --git a/cmd/swagger/commands/generate/support_test.go b/cmd/swagger/commands/generate/support_test.go
index f5f57156..9f19e28b 100644
--- a/cmd/swagger/commands/generate/support_test.go
+++ b/cmd/swagger/commands/generate/support_test.go
@@ -31,11 +31,11 @@ func TestGenerateSupport(t *testing.T) {
 			}()
 			m := &generate.Support{}
 			if i == 0 {
-				m.CopyrightFile = flags.Filename(filepath.Join(base, "LICENSE"))
+				m.Shared.CopyrightFile = flags.Filename(filepath.Join(base, "LICENSE"))
 			}
 			_, _ = flags.Parse(m)
-			m.Spec = flags.Filename(path)
-			m.Target = flags.Filename(generated)
+			m.Shared.Spec = flags.Filename(path)
+			m.Shared.Target = flags.Filename(generated)
 
 			if err := m.Execute([]string{}); err != nil {
 				t.Error(err)
diff --git a/codescan/application_test.go b/codescan/application_test.go
index 876dbef9..9cac3386 100644
--- a/codescan/application_test.go
+++ b/codescan/application_test.go
@@ -156,6 +156,7 @@ func verifyParsedPetStore(t testing.TB, doc *spec.Swagger) {
 	prop, ok = mod.Properties["status"]
 	assert.True(t, ok)
 	assert.Equal(t, "The current status of the pet in the store.", prop.Description)
+	assert.Equal(t, []interface{}{"available", "pending", "sold"}, prop.Enum)
 
 	assertProperty(t, &mod, "string", "birthday", "date", "Birthday")
 	prop, ok = mod.Properties["birthday"]
@@ -253,6 +254,7 @@ func verifyParsedPetStore(t testing.TB, doc *spec.Swagger) {
 	assert.Equal(t, "query", sparam.In)
 	assert.Equal(t, "string", sparam.Type)
 	assert.Equal(t, "", sparam.Format)
+	assert.Equal(t, []interface{}{"available", "pending", "sold"}, sparam.Enum)
 	assert.False(t, sparam.Required)
 	assert.Equal(t, "Status", sparam.Extensions["x-go-name"])
 	assert.Equal(t, "#/responses/genericError", op.Get.Responses.Default.Ref.String())
diff --git a/codescan/enum_test.go b/codescan/enum_test.go
new file mode 100644
index 00000000..90084ddd
--- /dev/null
+++ b/codescan/enum_test.go
@@ -0,0 +1,38 @@
+package codescan
+
+import (
+	"go/ast"
+	"go/token"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func Test_getEnumBasicLitValue(t *testing.T) {
+
+	verifyGetEnumBasicLitValue(t, ast.BasicLit{Kind: token.INT, Value: "0"}, int64(0))
+	verifyGetEnumBasicLitValue(t, ast.BasicLit{Kind: token.INT, Value: "-1"}, int64(-1))
+	verifyGetEnumBasicLitValue(t, ast.BasicLit{Kind: token.INT, Value: "42"}, int64(42))
+	verifyGetEnumBasicLitValue(t, ast.BasicLit{Kind: token.INT, Value: ""}, nil)
+	verifyGetEnumBasicLitValue(t, ast.BasicLit{Kind: token.INT, Value: "word"}, nil)
+
+	verifyGetEnumBasicLitValue(t, ast.BasicLit{Kind: token.FLOAT, Value: "0"}, float64(0))
+	verifyGetEnumBasicLitValue(t, ast.BasicLit{Kind: token.FLOAT, Value: "-1"}, float64(-1))
+	verifyGetEnumBasicLitValue(t, ast.BasicLit{Kind: token.FLOAT, Value: "42"}, float64(42))
+	verifyGetEnumBasicLitValue(t, ast.BasicLit{Kind: token.FLOAT, Value: "1.1234"}, float64(1.1234))
+	verifyGetEnumBasicLitValue(t, ast.BasicLit{Kind: token.FLOAT, Value: "1.9876"}, float64(1.9876))
+	verifyGetEnumBasicLitValue(t, ast.BasicLit{Kind: token.FLOAT, Value: ""}, nil)
+	verifyGetEnumBasicLitValue(t, ast.BasicLit{Kind: token.FLOAT, Value: "word"}, nil)
+
+	verifyGetEnumBasicLitValue(t, ast.BasicLit{Kind: token.STRING, Value: "Foo"}, "Foo")
+	verifyGetEnumBasicLitValue(t, ast.BasicLit{Kind: token.STRING, Value: ""}, "")
+	verifyGetEnumBasicLitValue(t, ast.BasicLit{Kind: token.STRING, Value: "0"}, "0")
+	verifyGetEnumBasicLitValue(t, ast.BasicLit{Kind: token.STRING, Value: "1.1"}, "1.1")
+
+}
+
+func verifyGetEnumBasicLitValue(t *testing.T, basicLit ast.BasicLit, expected interface{}) {
+	actual := getEnumBasicLitValue(&basicLit)
+
+	assert.Equal(t, expected, actual)
+}
diff --git a/generator/build_test.go b/generator/build_test.go
index aab5371a..f4f13887 100644
--- a/generator/build_test.go
+++ b/generator/build_test.go
@@ -77,15 +77,13 @@ func TestGenerateAndBuild(t *testing.T) {
 }
 
 func newTestClient(input, output string) *generate.Client {
-	c := &generate.Client{
-		DefaultScheme:   "http",
-		DefaultProduces: "application/json",
-	}
-	c.Spec = flags.Filename(input)
-	c.Target = flags.Filename(output)
-	c.APIPackage = defaultAPIPackage
-	c.ModelPackage = defaultModelPackage
-	c.ServerPackage = defaultServerPackage
+	c := &generate.Client{}
+	c.DefaultScheme = "http"
+	c.DefaultProduces = "application/json"
+	c.Shared.Spec = flags.Filename(input)
+	c.Shared.Target = flags.Filename(output)
+	c.Operations.APIPackage = defaultAPIPackage
+	c.Models.ModelPackage = defaultModelPackage
 	c.ClientPackage = defaultClientPackage
 	return c
 }
diff --git a/generator/model_test.go b/generator/model_test.go
index 9f442901..10233821 100644
--- a/generator/model_test.go
+++ b/generator/model_test.go
@@ -2487,7 +2487,7 @@ func TestGenModel_Issue1623(t *testing.T) {
 	assertInCode(t, "GeneralHasOmitEmptyFalse string `json:\"generalHasOmitEmptyFalse\"`", res)
 	assertInCode(t, "GeneralHasOmitEmptyTrue string `json:\"generalHasOmitEmptyTrue,omitempty\"`", res)
 	assertInCode(t, "GeneralNoOmitEmpty string `json:\"generalNoOmitEmpty,omitempty\"`", res)
-	assertInCode(t, "RefHasOmitEmptyFalse Bar `json:\"refHasOmitEmptyFalse\"`", res)
+	assertInCode(t, "RefHasOmitEmptyFalse Bar `json:\"refHasOmitEmptyFalse,omitempty\"`", res)
 	assertInCode(t, "RefHasOmitEmptyTrue Bar `json:\"refHasOmitEmptyTrue,omitempty\"`", res)
 	assertInCode(t, "RefNoOmitEmpty Bar `json:\"refNoOmitEmpty,omitempty\"`", res)
 	assertInCode(t, "IntHasJSONString int64 `json:\"intHasJsonString,omitempty,string\"`", res)
diff --git a/generator/moreschemavalidation_fixtures_test.go b/generator/moreschemavalidation_fixtures_test.go
index 2181dbbe..02529490 100644
--- a/generator/moreschemavalidation_fixtures_test.go
+++ b/generator/moreschemavalidation_fixtures_test.go
@@ -14,6 +14,76 @@
 
 package generator
 
+func initFixture2116() {
+	f := newModelFixture("../fixtures/bugs/2116/fixture-2116.yaml", "check x-omitempty and x-nullable with $ref")
+	flattenRun := f.AddRun(false).WithMinimalFlatten(true)
+
+	flattenRun.AddExpectations("case1_fail_omitempty_false_not_hoisted_by_ref.go", []string{
+		"Body *ObjectWithOmitemptyFalse `json:\"Body\"`",
+	}, todo, noLines, noLines)
+
+	flattenRun.AddExpectations("case2_fail_omitempty_false_not_overridden_by_ref_sibling.go", []string{
+		"Body *ObjectWithOmitemptyTrue `json:\"Body,omitempty\"`",
+	}, todo, noLines, noLines)
+
+	flattenRun.AddExpectations("case3_pass_object_nullable_false_hoisted_by_ref.go", []string{
+		"Body ObjectWithNullableFalse `json:\"Body,omitempty\"`",
+	}, todo, noLines, noLines)
+
+	flattenRun.AddExpectations("case4_pass_object_nullable_false_overriden_by_ref_sibling.go", []string{
+		"Body *ObjectWithNullableTrue `json:\"Body,omitempty\"`",
+	}, todo, noLines, noLines)
+
+	flattenRun.AddExpectations("array_with_default.go", []string{
+		"type ArrayWithDefault []string",
+	}, append(todo, "omitempty"), noLines, noLines)
+
+	flattenRun.AddExpectations("array_with_no_omit_empty.go", []string{
+		"type ArrayWithNoOmitEmpty []string",
+	}, append(todo, "omitempty"), noLines, noLines)
+
+	flattenRun.AddExpectations("array_with_nullable.go", []string{
+		"type ArrayWithNullable []string",
+	}, todo, noLines, noLines)
+
+	flattenRun.AddExpectations("array_with_nullable_items.go", []string{
+		"type ArrayWithNullableItems []*string",
+	}, todo, noLines, noLines)
+
+	flattenRun.AddExpectations("array_with_omit_empty.go", []string{
+		"type ArrayWithOmitEmpty []string",
+	}, append(todo, "omitempty"), noLines, noLines)
+
+	flattenRun.AddExpectations("object_with_arrays.go", []string{
+		"Array0 ArrayWithDefault `json:\"array0,omitempty\"`",
+		"Array1 []string `json:\"array1\"`",
+		"Array11 []string `json:\"array11,omitempty\"`",
+		"Array12 []string `json:\"array12\"`",
+		"Array2 ArrayWithOmitEmpty `json:\"array2,omitempty\"`",
+		"Array3 ArrayWithNoOmitEmpty `json:\"array3\"`",
+	}, todo, noLines, noLines)
+
+	flattenRun.AddExpectations("object_with_nullable_false.go", []string{
+		"Data interface{} `json:\"Data,omitempty\"`",
+	}, todo, noLines, noLines)
+
+	flattenRun.AddExpectations("object_with_nullable_true.go", []string{
+		"Data interface{} `json:\"Data,omitempty\"`",
+	}, todo, noLines, noLines)
+
+	flattenRun.AddExpectations("object_with_omitempty_false.go", []string{
+		"Data interface{} `json:\"Data,omitempty\"`",
+	}, todo, noLines, noLines)
+
+	flattenRun.AddExpectations("object_with_omitempty_true.go", []string{
+		"Data interface{} `json:\"Data,omitempty\"`",
+	}, todo, noLines, noLines)
+
+	flattenRun.AddExpectations("array_with_omit_empty_items.go", []string{
+		"type ArrayWithOmitEmptyItems []string",
+	}, append(todo, "omitempty"), noLines, noLines)
+}
+
 func initFixture2071() {
 	f := newModelFixture("../fixtures/bugs/2071/fixture-2071.yaml", "check allOf serializer when x-go-name is present")
 	flattenRun := f.AddRun(false).WithMinimalFlatten(true)
diff --git a/generator/moreschemavalidation_test.go b/generator/moreschemavalidation_test.go
index 8ba4eead..0dd9d597 100644
--- a/generator/moreschemavalidation_test.go
+++ b/generator/moreschemavalidation_test.go
@@ -206,6 +206,9 @@ func initModelFixtures() {
 
 	// allOf marshallers
 	initFixture2071()
+
+	// x-omitempty
+	initFixture2116()
 }
 
 /* Template initTxxx() to prepare and load a fixture:
@@ -338,7 +341,8 @@ func TestMoreModelValidations(t *testing.T) {
 						// please do not inject fixtures with case conflicts on defs...
 						// this one is just easier to retrieve model back from file names when capturing
 						// the generated code.
-						if strings.EqualFold(def, k) {
+						mangled := swag.ToJSONName(def)
+						if strings.EqualFold(mangled, k) {
 							schema = &s
 							definitionName = def
 							break
diff --git a/hack/codegen_nonreg_test.go b/hack/codegen_nonreg_test.go
index 75f806db..3c665504 100644
--- a/hack/codegen_nonreg_test.go
+++ b/hack/codegen_nonreg_test.go
@@ -134,6 +134,12 @@ func gobuild(t *testing.T, runOpts ...icmd.CmdOp) {
 	started := measure(t, nil)
 	cmd := icmd.Command("go", "build")
 	res := icmd.RunCmd(cmd, runOpts...)
+	if res.ExitCode == 127 {
+		// assume a transient error (e.g. memory): retry
+		warn(t, "build failure, assuming transitory issue and retrying")
+		time.Sleep(2 * time.Second)
+		res = icmd.RunCmd(cmd, runOpts...)
+	}
 	if !assert.Equal(t, 0, res.ExitCode) {
 		failure(t, "go build failed")
 		t.Log(res.Stderr())