func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
	if opts.Scope == nil {
		opts.Scope = new(AuthScope)
		if opts.TenantID != "" {
			opts.Scope.ProjectID = opts.TenantID
		} else {
			if opts.TenantName != "" {
				opts.Scope.ProjectName = opts.TenantName
				opts.Scope.DomainID = opts.DomainID
				opts.Scope.DomainName = opts.DomainName
			}
		}
	}
	if opts.Scope.System {
		return map[string]interface{}{
			"system": map[string]interface{}{
				"all": true,
			},
		}, nil
	}
	if opts.Scope.ProjectName != "" {
		if opts.Scope.DomainID == "" && opts.Scope.DomainName == "" {
			return nil, ErrScopeDomainIDOrDomainName{}
		}
		if opts.Scope.ProjectID != "" {
			return nil, ErrScopeProjectIDOrProjectName{}
		}
		if opts.Scope.DomainID != "" {
			return map[string]interface{}{
				"project": map[string]interface{}{
					"name":   &opts.Scope.ProjectName,
					"domain": map[string]interface{}{"id": &opts.Scope.DomainID},
				},
			}, nil
		}
		if opts.Scope.DomainName != "" {
			return map[string]interface{}{
				"project": map[string]interface{}{
					"name":   &opts.Scope.ProjectName,
					"domain": map[string]interface{}{"name": &opts.Scope.DomainName},
				},
			}, nil
		}
	} else if opts.Scope.ProjectID != "" {
		if opts.Scope.DomainID != "" {
			return nil, ErrScopeProjectIDAlone{}
		}
		if opts.Scope.DomainName != "" {
			return nil, ErrScopeProjectIDAlone{}
		}
		return map[string]interface{}{
			"project": map[string]interface{}{
				"id": &opts.Scope.ProjectID,
			},
		}, nil
	} else if opts.Scope.DomainID != "" {
		if opts.Scope.DomainName != "" {
			return nil, ErrScopeDomainIDOrDomainName{}
		}
		return map[string]interface{}{
			"domain": map[string]interface{}{
				"id": &opts.Scope.DomainID,
			},
		}, nil
	} else if opts.Scope.DomainName != "" {
		return map[string]interface{}{
			"domain": map[string]interface{}{
				"name": &opts.Scope.DomainName,
			},
		}, nil
	}
	return nil, nil
}
ToTokenV3ScopeMap builds a scope from AuthOptions and satisfies interface in
the v3 tokens package.
package gophercloud
type AuthOptions struct {
	IdentityEndpoint string `json:"-"`
	Username string `json:"username,omitempty"`
	UserID   string `json:"-"`
	Password string `json:"password,omitempty"`
	Passcode string `json:"passcode,omitempty"`
	DomainID   string `json:"-"`
	DomainName string `json:"name,omitempty"`
	TenantID   string `json:"tenantId,omitempty"`
	TenantName string `json:"tenantName,omitempty"`
	AllowReauth bool `json:"-"`
	TokenID string `json:"-"`
	Scope *AuthScope `json:"-"`
	ApplicationCredentialID     string `json:"-"`
	ApplicationCredentialName   string `json:"-"`
	ApplicationCredentialSecret string `json:"-"`
}
type AuthScope struct {
	ProjectID   string
	ProjectName string
	DomainID    string
	DomainName  string
	System      bool
}
func (opts AuthOptions) ToTokenV2CreateMap() (map[string]interface{}, error) {
	authMap := make(map[string]interface{})
	if opts.Username != "" {
		if opts.Password != "" {
			authMap["passwordCredentials"] = map[string]interface{}{
				"username": opts.Username,
				"password": opts.Password,
			}
		} else {
			return nil, ErrMissingInput{Argument: "Password"}
		}
	} else if opts.TokenID != "" {
		authMap["token"] = map[string]interface{}{
			"id": opts.TokenID,
		}
	} else {
		return nil, ErrMissingInput{Argument: "Username"}
	}
	if opts.TenantID != "" {
		authMap["tenantId"] = opts.TenantID
	}
	if opts.TenantName != "" {
		authMap["tenantName"] = opts.TenantName
	}
	return map[string]interface{}{"auth": authMap}, nil
}
func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[string]interface{}, error) {
	type domainReq struct {
		ID   *string `json:"id,omitempty"`
		Name *string `json:"name,omitempty"`
	}
	type projectReq struct {
		Domain *domainReq `json:"domain,omitempty"`
		Name   *string    `json:"name,omitempty"`
		ID     *string    `json:"id,omitempty"`
	}
	type userReq struct {
		ID       *string    `json:"id,omitempty"`
		Name     *string    `json:"name,omitempty"`
		Password *string    `json:"password,omitempty"`
		Passcode *string    `json:"passcode,omitempty"`
		Domain   *domainReq `json:"domain,omitempty"`
	}
	type passwordReq struct {
		User userReq `json:"user"`
	}
	type tokenReq struct {
		ID string `json:"id"`
	}
	type applicationCredentialReq struct {
		ID     *string  `json:"id,omitempty"`
		Name   *string  `json:"name,omitempty"`
		User   *userReq `json:"user,omitempty"`
		Secret *string  `json:"secret,omitempty"`
	}
	type totpReq struct {
		User *userReq `json:"user,omitempty"`
	}
	type identityReq struct {
		Methods               []string                  `json:"methods"`
		Password              *passwordReq              `json:"password,omitempty"`
		Token                 *tokenReq                 `json:"token,omitempty"`
		ApplicationCredential *applicationCredentialReq `json:"application_credential,omitempty"`
		TOTP                  *totpReq                  `json:"totp,omitempty"`
	}
	type authReq struct {
		Identity identityReq `json:"identity"`
	}
	type request struct {
		Auth authReq `json:"auth"`
	}
	var req request
	if opts.Password == "" && opts.Passcode == "" {
		if opts.TokenID != "" {
			if opts.Username != "" {
				return nil, ErrUsernameWithToken{}
			}
			if opts.UserID != "" {
				return nil, ErrUserIDWithToken{}
			}
			if opts.DomainID != "" {
				return nil, ErrDomainIDWithToken{}
			}
			if opts.DomainName != "" {
				return nil, ErrDomainNameWithToken{}
			}
			req.Auth.Identity.Methods = []string{"token"}
			req.Auth.Identity.Token = &tokenReq{
				ID: opts.TokenID,
			}
		} else if opts.ApplicationCredentialID != "" {
			if opts.ApplicationCredentialSecret == "" {
				return nil, ErrAppCredMissingSecret{}
			}
			req.Auth.Identity.Methods = []string{"application_credential"}
			req.Auth.Identity.ApplicationCredential = &applicationCredentialReq{
				ID:     &opts.ApplicationCredentialID,
				Secret: &opts.ApplicationCredentialSecret,
			}
		} else if opts.ApplicationCredentialName != "" {
			if opts.ApplicationCredentialSecret == "" {
				return nil, ErrAppCredMissingSecret{}
			}
			var userRequest *userReq
			if opts.UserID != "" {
				userRequest = &userReq{
					ID: &opts.UserID,
				}
			}
			if userRequest == nil && opts.Username == "" {
				return nil, ErrUsernameOrUserID{}
			}
			if userRequest == nil && opts.DomainID != "" {
				userRequest = &userReq{
					Name:   &opts.Username,
					Domain: &domainReq{ID: &opts.DomainID},
				}
			}
			if userRequest == nil && opts.DomainName != "" {
				userRequest = &userReq{
					Name:   &opts.Username,
					Domain: &domainReq{Name: &opts.DomainName},
				}
			}
			if userRequest == nil {
				return nil, ErrDomainIDOrDomainName{}
			}
			req.Auth.Identity.Methods = []string{"application_credential"}
			req.Auth.Identity.ApplicationCredential = &applicationCredentialReq{
				Name:   &opts.ApplicationCredentialName,
				User:   userRequest,
				Secret: &opts.ApplicationCredentialSecret,
			}
		} else {
			return nil, ErrMissingPassword{}
		}
	} else {
		if opts.Password != "" {
			req.Auth.Identity.Methods = append(req.Auth.Identity.Methods, "password")
		}
		if opts.Passcode != "" {
			req.Auth.Identity.Methods = append(req.Auth.Identity.Methods, "totp")
		}
		if opts.Username == "" && opts.UserID == "" {
			return nil, ErrUsernameOrUserID{}
		}
		if opts.Username != "" {
			if opts.UserID != "" {
				return nil, ErrUsernameOrUserID{}
			}
			if opts.DomainID == "" && opts.DomainName == "" {
				return nil, ErrDomainIDOrDomainName{}
			}
			if opts.DomainID != "" {
				if opts.DomainName != "" {
					return nil, ErrDomainIDOrDomainName{}
				}
				if opts.Password != "" {
					req.Auth.Identity.Password = &passwordReq{
						User: userReq{
							Name:     &opts.Username,
							Password: &opts.Password,
							Domain:   &domainReq{ID: &opts.DomainID},
						},
					}
				}
				if opts.Passcode != "" {
					req.Auth.Identity.TOTP = &totpReq{
						User: &userReq{
							Name:     &opts.Username,
							Passcode: &opts.Passcode,
							Domain:   &domainReq{ID: &opts.DomainID},
						},
					}
				}
			}
			if opts.DomainName != "" {
				if opts.Password != "" {
					req.Auth.Identity.Password = &passwordReq{
						User: userReq{
							Name:     &opts.Username,
							Password: &opts.Password,
							Domain:   &domainReq{Name: &opts.DomainName},
						},
					}
				}
				if opts.Passcode != "" {
					req.Auth.Identity.TOTP = &totpReq{
						User: &userReq{
							Name:     &opts.Username,
							Passcode: &opts.Passcode,
							Domain:   &domainReq{Name: &opts.DomainName},
						},
					}
				}
			}
		}
		if opts.UserID != "" {
			if opts.DomainID != "" {
				return nil, ErrDomainIDWithUserID{}
			}
			if opts.DomainName != "" {
				return nil, ErrDomainNameWithUserID{}
			}
			if opts.Password != "" {
				req.Auth.Identity.Password = &passwordReq{
					User: userReq{
						ID:       &opts.UserID,
						Password: &opts.Password,
					},
				}
			}
			if opts.Passcode != "" {
				req.Auth.Identity.TOTP = &totpReq{
					User: &userReq{
						ID:       &opts.UserID,
						Passcode: &opts.Passcode,
					},
				}
			}
		}
	}
	b, err := BuildRequestBody(req, "")
	if err != nil {
		return nil, err
	}
	if len(scope) != 0 {
		b["auth"].(map[string]interface{})["scope"] = scope
	}
	return b, nil
}