more error types for compute v2
diff --git a/errors.go b/errors.go
index b28be11..62af11c 100644
--- a/errors.go
+++ b/errors.go
@@ -4,25 +4,14 @@
 
 // BaseError is an error type that all other error types embed.
 type BaseError struct {
-	OriginalError error
-	Function      string
+	Info     string
+	Function string
 }
 
 func (e BaseError) Error() string {
 	return "An error occurred while executing a Gophercloud request."
 }
 
-// ErrInvalidInput is an error type used for most non-HTTP Gophercloud errors.
-type ErrInvalidInput struct {
-	BaseError
-	Argument string
-	Value    interface{}
-}
-
-func (e *ErrInvalidInput) Error() string {
-	return fmt.Sprintf("Invalid input provided for argument [%s]: [%+v]", e.Argument, e.Value)
-}
-
 // ErrMissingInput is the error when input is required in a particular
 // situation but not provided by the user
 type ErrMissingInput struct {
@@ -30,10 +19,20 @@
 	Argument string
 }
 
-func (e *ErrMissingInput) Error() string {
+func (e ErrMissingInput) Error() string {
 	return fmt.Sprintf("Missing input for argument [%s]", e.Argument)
 }
 
+// ErrInvalidInput is an error type used for most non-HTTP Gophercloud errors.
+type ErrInvalidInput struct {
+	ErrMissingInput
+	Value interface{}
+}
+
+func (e ErrInvalidInput) Error() string {
+	return fmt.Sprintf("Invalid input provided for argument [%s]: [%+v]", e.Argument, e.Value)
+}
+
 // ErrUnexpectedResponseCode is returned by the Request method when a response code other than
 // those listed in OkCodes is encountered.
 type ErrUnexpectedResponseCode struct {
@@ -45,7 +44,7 @@
 	Body     []byte
 }
 
-func (err *ErrUnexpectedResponseCode) Error() string {
+func (err ErrUnexpectedResponseCode) Error() string {
 	return fmt.Sprintf(
 		"Expected HTTP response code %v when accessing [%s %s], but got %d instead\n%s",
 		err.Expected, err.Method, err.URL, err.Actual, err.Body,
@@ -54,42 +53,42 @@
 
 // ErrDefault400 is the default error type returned on a 400 HTTP response code.
 type ErrDefault400 struct {
-	*ErrUnexpectedResponseCode
+	ErrUnexpectedResponseCode
 }
 
 // ErrDefault401 is the default error type returned on a 401 HTTP response code.
 type ErrDefault401 struct {
-	*ErrUnexpectedResponseCode
+	ErrUnexpectedResponseCode
 }
 
 // ErrDefault404 is the default error type returned on a 404 HTTP response code.
 type ErrDefault404 struct {
-	*ErrUnexpectedResponseCode
+	ErrUnexpectedResponseCode
 }
 
 // ErrDefault405 is the default error type returned on a 405 HTTP response code.
 type ErrDefault405 struct {
-	*ErrUnexpectedResponseCode
+	ErrUnexpectedResponseCode
 }
 
 // ErrDefault408 is the default error type returned on a 408 HTTP response code.
 type ErrDefault408 struct {
-	*ErrUnexpectedResponseCode
+	ErrUnexpectedResponseCode
 }
 
 // ErrDefault429 is the default error type returned on a 429 HTTP response code.
 type ErrDefault429 struct {
-	*ErrUnexpectedResponseCode
+	ErrUnexpectedResponseCode
 }
 
 // ErrDefault500 is the default error type returned on a 500 HTTP response code.
 type ErrDefault500 struct {
-	*ErrUnexpectedResponseCode
+	ErrUnexpectedResponseCode
 }
 
 // ErrDefault503 is the default error type returned on a 503 HTTP response code.
 type ErrDefault503 struct {
-	*ErrUnexpectedResponseCode
+	ErrUnexpectedResponseCode
 }
 
 func (e ErrDefault400) Error() string {
@@ -122,49 +121,49 @@
 // Err400er is the interface resource error types implement to override the error message
 // from a 400 error.
 type Err400er interface {
-	Error400(*ErrUnexpectedResponseCode) error
+	Error400(ErrUnexpectedResponseCode) error
 }
 
 // Err401er is the interface resource error types implement to override the error message
 // from a 401 error.
 type Err401er interface {
-	Error401(*ErrUnexpectedResponseCode) error
+	Error401(ErrUnexpectedResponseCode) error
 }
 
 // Err404er is the interface resource error types implement to override the error message
 // from a 404 error.
 type Err404er interface {
-	Error404(*ErrUnexpectedResponseCode) error
+	Error404(ErrUnexpectedResponseCode) error
 }
 
 // Err405er is the interface resource error types implement to override the error message
 // from a 405 error.
 type Err405er interface {
-	Error405(*ErrUnexpectedResponseCode) error
+	Error405(ErrUnexpectedResponseCode) error
 }
 
 // Err408er is the interface resource error types implement to override the error message
 // from a 408 error.
 type Err408er interface {
-	Error408(*ErrUnexpectedResponseCode) error
+	Error408(ErrUnexpectedResponseCode) error
 }
 
 // Err429er is the interface resource error types implement to override the error message
 // from a 429 error.
 type Err429er interface {
-	Error429(*ErrUnexpectedResponseCode) error
+	Error429(ErrUnexpectedResponseCode) error
 }
 
 // Err500er is the interface resource error types implement to override the error message
 // from a 500 error.
 type Err500er interface {
-	Error500(*ErrUnexpectedResponseCode) error
+	Error500(ErrUnexpectedResponseCode) error
 }
 
 // Err503er is the interface resource error types implement to override the error message
 // from a 503 error.
 type Err503er interface {
-	Error503(*ErrUnexpectedResponseCode) error
+	Error503(ErrUnexpectedResponseCode) error
 }
 
 // ErrTimeOut is the error type returned when an operations times out.
@@ -172,27 +171,29 @@
 	BaseError
 }
 
-func (e *ErrTimeOut) Error() string {
+func (e ErrTimeOut) Error() string {
 	return "A time out occurred"
 }
 
 // ErrUnableToReauthenticate is the error type returned when reauthentication fails.
 type ErrUnableToReauthenticate struct {
 	BaseError
+	ErrOriginal error
 }
 
-func (e *ErrUnableToReauthenticate) Error() string {
-	return fmt.Sprintf("Unable to re-authenticate: %s", e.OriginalError)
+func (e ErrUnableToReauthenticate) Error() string {
+	return fmt.Sprintf("Unable to re-authenticate: %s", e.ErrOriginal)
 }
 
 // ErrErrorAfterReauthentication is the error type returned when reauthentication
 // succeeds, but an error occurs afterword (usually an HTTP error).
 type ErrErrorAfterReauthentication struct {
 	BaseError
+	ErrOriginal error
 }
 
-func (e *ErrErrorAfterReauthentication) Error() string {
-	return fmt.Sprintf("Successfully re-authenticated, but got error executing request: %s", e.OriginalError)
+func (e ErrErrorAfterReauthentication) Error() string {
+	return fmt.Sprintf("Successfully re-authenticated, but got error executing request: %s", e.ErrOriginal)
 }
 
 // ErrServiceNotFound is returned when no service in a service catalog matches
@@ -203,7 +204,7 @@
 	BaseError
 }
 
-func (e *ErrServiceNotFound) Error() string {
+func (e ErrServiceNotFound) Error() string {
 	return "No suitable service could be found in the service catalog."
 }
 
@@ -215,7 +216,7 @@
 	BaseError
 }
 
-func (e *ErrEndpointNotFound) Error() string {
+func (e ErrEndpointNotFound) Error() string {
 	return "No suitable endpoint could be found in the service catalog."
 }
 
@@ -223,15 +224,12 @@
 // ID by name and the resource doesn't exist.
 type ErrResourceNotFound struct {
 	BaseError
-	ID, Name     string
+	Name         string
 	ResourceType string
 }
 
-func (e *ErrResourceNotFound) Error() string {
-	if e.Name != "" {
-		return fmt.Sprintf("Unable to find %s with name %s", e.ResourceType, e.Name)
-	}
-	return fmt.Sprintf("Unable to find %s with ID %s", e.ResourceType, e.ID)
+func (e ErrResourceNotFound) Error() string {
+	return fmt.Sprintf("Unable to find %s with name %s", e.ResourceType, e.Name)
 }
 
 // ErrMultipleResourcesFound is the error when trying to retrieve a resource's
@@ -243,6 +241,6 @@
 	ResourceType string
 }
 
-func (e *ErrMultipleResourcesFound) Error() string {
+func (e ErrMultipleResourcesFound) Error() string {
 	return fmt.Sprintf("Found %d %ss matching %s", e.Count, e.ResourceType, e.Name)
 }
diff --git a/openstack/compute/v2/extensions/bootfromvolume/requests.go b/openstack/compute/v2/extensions/bootfromvolume/requests.go
index 6c063be..7171afa 100644
--- a/openstack/compute/v2/extensions/bootfromvolume/requests.go
+++ b/openstack/compute/v2/extensions/bootfromvolume/requests.go
@@ -1,7 +1,7 @@
 package bootfromvolume
 
 import (
-	"errors"
+	"fmt"
 	"strconv"
 
 	"github.com/gophercloud/gophercloud"
@@ -62,7 +62,10 @@
 	}
 
 	if len(opts.BlockDevice) == 0 {
-		return nil, errors.New("Required fields UUID and SourceType not set.")
+		err := gophercloud.ErrMissingInput{}
+		err.Function = "bootfromvolume.ToServerCreateMap"
+		err.Argument = "bootfromvolume.CreateOptsExt.BlockDevice"
+		return nil, err
 	}
 
 	serverMap := base["server"].(map[string]interface{})
@@ -71,7 +74,10 @@
 
 	for i, bd := range opts.BlockDevice {
 		if string(bd.SourceType) == "" {
-			return nil, errors.New("SourceType must be one of: volume, image, snapshot.")
+			err := gophercloud.ErrMissingInput{}
+			err.Function = "bootfromvolume.ToServerCreateMap"
+			err.Argument = fmt.Sprintf("bootfromvolume.CreateOptsExt.BlockDevice[%d].SourceType", i)
+			return nil, err
 		}
 
 		blockDevice[i] = make(map[string]interface{})
diff --git a/openstack/compute/v2/extensions/defsecrules/requests.go b/openstack/compute/v2/extensions/defsecrules/requests.go
index fc3e3a8..5e2d686 100644
--- a/openstack/compute/v2/extensions/defsecrules/requests.go
+++ b/openstack/compute/v2/extensions/defsecrules/requests.go
@@ -1,8 +1,6 @@
 package defsecrules
 
 import (
-	"errors"
-
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
 )
@@ -40,21 +38,33 @@
 
 // ToRuleCreateMap builds the create rule options into a serializable format.
 func (opts CreateOpts) ToRuleCreateMap() (map[string]interface{}, error) {
-	rule := make(map[string]interface{})
-
 	if opts.FromPort == 0 {
-		return rule, errors.New("A FromPort must be set")
+		err := gophercloud.ErrMissingInput{}
+		err.Function = "defsecrules.ToRuleCreateMap"
+		err.Argument = "defsecrules.CreateOpts.FromPort"
+		return nil, err
 	}
 	if opts.ToPort == 0 {
-		return rule, errors.New("A ToPort must be set")
+		err := gophercloud.ErrMissingInput{}
+		err.Function = "defsecrules.ToRuleCreateMap"
+		err.Argument = "defsecrules.CreateOpts.ToPort"
+		return nil, err
 	}
 	if opts.IPProtocol == "" {
-		return rule, errors.New("A IPProtocol must be set")
+		err := gophercloud.ErrMissingInput{}
+		err.Function = "defsecrules.ToRuleCreateMap"
+		err.Argument = "defsecrules.CreateOpts.IPProtocol"
+		return nil, err
 	}
 	if opts.CIDR == "" {
-		return rule, errors.New("A CIDR must be set")
+		err := gophercloud.ErrMissingInput{}
+		err.Function = "defsecrules.ToRuleCreateMap"
+		err.Argument = "defsecrules.CreateOpts.CIDR"
+		return nil, err
 	}
 
+	rule := make(map[string]interface{})
+
 	rule["from_port"] = opts.FromPort
 	rule["to_port"] = opts.ToPort
 	rule["ip_protocol"] = opts.IPProtocol
diff --git a/openstack/compute/v2/extensions/diskconfig/requests.go b/openstack/compute/v2/extensions/diskconfig/requests.go
index 3fd9c9e..19798d7 100644
--- a/openstack/compute/v2/extensions/diskconfig/requests.go
+++ b/openstack/compute/v2/extensions/diskconfig/requests.go
@@ -1,8 +1,7 @@
 package diskconfig
 
 import (
-	"errors"
-
+	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
 )
 
@@ -23,19 +22,6 @@
 	Manual DiskConfig = "MANUAL"
 )
 
-// ErrInvalidDiskConfig is returned if an invalid string is specified for a DiskConfig option.
-var ErrInvalidDiskConfig = errors.New("DiskConfig must be either diskconfig.Auto or diskconfig.Manual.")
-
-// Validate ensures that a DiskConfig contains an appropriate value.
-func (config DiskConfig) validate() error {
-	switch config {
-	case Auto, Manual:
-		return nil
-	default:
-		return ErrInvalidDiskConfig
-	}
-}
-
 // CreateOptsExt adds a DiskConfig option to the base CreateOpts.
 type CreateOptsExt struct {
 	servers.CreateOptsBuilder
@@ -71,8 +57,11 @@
 
 // ToServerRebuildMap adds the diskconfig option to the base server rebuild options.
 func (opts RebuildOptsExt) ToServerRebuildMap() (map[string]interface{}, error) {
-	err := opts.DiskConfig.validate()
-	if err != nil {
+	if opts.DiskConfig != Auto && opts.DiskConfig != Manual {
+		err := gophercloud.ErrInvalidInput{}
+		err.Function = "diskconfig.ToServerRebuildMap"
+		err.Argument = "diskconfig.RebuildOptsExt.DiskConfig"
+		err.Info = "Must be either diskconfig.Auto or diskconfig.Manual"
 		return nil, err
 	}
 
@@ -97,8 +86,11 @@
 
 // ToServerResizeMap adds the diskconfig option to the base server creation options.
 func (opts ResizeOptsExt) ToServerResizeMap() (map[string]interface{}, error) {
-	err := opts.DiskConfig.validate()
-	if err != nil {
+	if opts.DiskConfig != Auto && opts.DiskConfig != Manual {
+		err := gophercloud.ErrInvalidInput{}
+		err.Function = "diskconfig.ToServerResizeMap"
+		err.Argument = "diskconfig.ResizeOptsExt.DiskConfig"
+		err.Info = "Must be either diskconfig.Auto or diskconfig.Manual"
 		return nil, err
 	}
 
diff --git a/openstack/compute/v2/extensions/floatingips/requests.go b/openstack/compute/v2/extensions/floatingips/requests.go
index d99033e..00b2520 100644
--- a/openstack/compute/v2/extensions/floatingips/requests.go
+++ b/openstack/compute/v2/extensions/floatingips/requests.go
@@ -1,8 +1,6 @@
 package floatingips
 
 import (
-	"errors"
-
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
 )
@@ -41,7 +39,10 @@
 // ToFloatingIPCreateMap constructs a request body from CreateOpts.
 func (opts CreateOpts) ToFloatingIPCreateMap() (map[string]interface{}, error) {
 	if opts.Pool == "" {
-		return nil, errors.New("Missing field required for floating IP creation: Pool")
+		err := gophercloud.ErrMissingInput{}
+		err.Function = "floatingips.ToFloatingIPCreateMap"
+		err.Argument = "floatingips.CreateOpts.Pool"
+		return nil, err
 	}
 
 	return map[string]interface{}{"pool": opts.Pool}, nil
@@ -50,11 +51,17 @@
 // ToAssociateMap constructs a request body from AssociateOpts.
 func (opts AssociateOpts) ToAssociateMap() (map[string]interface{}, error) {
 	if opts.ServerID == "" {
-		return nil, errors.New("Required field missing for floating IP association: ServerID")
+		err := gophercloud.ErrMissingInput{}
+		err.Function = "floatingips.ToAssociateMap"
+		err.Argument = "floatingips.AssociateOpts.ServerID"
+		return nil, err
 	}
 
 	if opts.FloatingIP == "" {
-		return nil, errors.New("Required field missing for floating IP association: FloatingIP")
+		err := gophercloud.ErrMissingInput{}
+		err.Function = "floatingips.ToAssociateMap"
+		err.Argument = "floatingips.AssociateOpts.FloatingIP"
+		return nil, err
 	}
 
 	associateInfo := map[string]interface{}{
diff --git a/openstack/compute/v2/extensions/keypairs/requests.go b/openstack/compute/v2/extensions/keypairs/requests.go
index af05a8e..b9b32ee 100644
--- a/openstack/compute/v2/extensions/keypairs/requests.go
+++ b/openstack/compute/v2/extensions/keypairs/requests.go
@@ -1,8 +1,6 @@
 package keypairs
 
 import (
-	"errors"
-
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
 	"github.com/gophercloud/gophercloud/pagination"
@@ -58,7 +56,10 @@
 // ToKeyPairCreateMap constructs a request body from CreateOpts.
 func (opts CreateOpts) ToKeyPairCreateMap() (map[string]interface{}, error) {
 	if opts.Name == "" {
-		return nil, errors.New("Missing field required for keypair creation: Name")
+		err := gophercloud.ErrMissingInput{}
+		err.Function = "keypairs.ToKeyPairCreateMap"
+		err.Argument = "keypairs.CreateOpts.Name"
+		return nil, err
 	}
 
 	keypair := make(map[string]interface{})
diff --git a/openstack/compute/v2/extensions/schedulerhints/requests.go b/openstack/compute/v2/extensions/schedulerhints/requests.go
index d9aa733..5713e72 100644
--- a/openstack/compute/v2/extensions/schedulerhints/requests.go
+++ b/openstack/compute/v2/extensions/schedulerhints/requests.go
@@ -1,11 +1,11 @@
 package schedulerhints
 
 import (
-	"fmt"
 	"net"
 	"regexp"
 	"strings"
 
+	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
 )
 
@@ -47,7 +47,12 @@
 
 	if opts.Group != "" {
 		if !uuidRegex.MatchString(opts.Group) {
-			return nil, fmt.Errorf("Group must be a UUID")
+			err := gophercloud.ErrInvalidInput{}
+			err.Function = "schedulerhints.ToServerSchedulerHintsMap"
+			err.Argument = "schedulerhints.SchedulerHints.Group"
+			err.Value = opts.Group
+			err.Info = "Group must be a UUID"
+			return nil, err
 		}
 		sh["group"] = opts.Group
 	}
@@ -55,7 +60,12 @@
 	if len(opts.DifferentHost) > 0 {
 		for _, diffHost := range opts.DifferentHost {
 			if !uuidRegex.MatchString(diffHost) {
-				return nil, fmt.Errorf("The hosts in DifferentHost must be in UUID format.")
+				err := gophercloud.ErrInvalidInput{}
+				err.Function = "schedulerhints.ToServerSchedulerHintsMap"
+				err.Argument = "schedulerhints.SchedulerHints.DifferentHost"
+				err.Value = opts.DifferentHost
+				err.Info = "The hosts must be in UUID format."
+				return nil, err
 			}
 		}
 		sh["different_host"] = opts.DifferentHost
@@ -64,7 +74,12 @@
 	if len(opts.SameHost) > 0 {
 		for _, sameHost := range opts.SameHost {
 			if !uuidRegex.MatchString(sameHost) {
-				return nil, fmt.Errorf("The hosts in SameHost must be in UUID format.")
+				err := gophercloud.ErrInvalidInput{}
+				err.Function = "schedulerhints.ToServerSchedulerHintsMap"
+				err.Argument = "schedulerhints.SchedulerHints.SameHost"
+				err.Value = opts.SameHost
+				err.Info = "The hosts must be in UUID format."
+				return nil, err
 			}
 		}
 		sh["same_host"] = opts.SameHost
@@ -83,7 +98,12 @@
 	*/
 	if len(opts.Query) > 0 {
 		if len(opts.Query) < 3 {
-			return nil, fmt.Errorf("Query must be a conditional statement in the format of [op,variable,value]")
+			err := gophercloud.ErrInvalidInput{}
+			err.Function = "schedulerhints.ToServerSchedulerHintsMap"
+			err.Argument = "schedulerhints.SchedulerHints.Query"
+			err.Value = opts.Query
+			err.Info = "Must be a conditional statement in the format of [op,variable,value]"
+			return nil, err
 		}
 		sh["query"] = opts.Query
 	}
@@ -94,7 +114,12 @@
 
 	if opts.BuildNearHostIP != "" {
 		if _, _, err := net.ParseCIDR(opts.BuildNearHostIP); err != nil {
-			return nil, fmt.Errorf("BuildNearHostIP must be a valid subnet in the form 192.168.1.1/24")
+			err := gophercloud.ErrInvalidInput{}
+			err.Function = "schedulerhints.ToServerSchedulerHintsMap"
+			err.Argument = "schedulerhints.SchedulerHints.BuildNearHostIP"
+			err.Value = opts.BuildNearHostIP
+			err.Info = "Must be a valid subnet in the form 192.168.1.1/24"
+			return nil, err
 		}
 		ipParts := strings.Split(opts.BuildNearHostIP, "/")
 		sh["build_near_host_ip"] = ipParts[0]
diff --git a/openstack/compute/v2/extensions/secgroups/requests.go b/openstack/compute/v2/extensions/secgroups/requests.go
index 758ba09..a0bb025 100644
--- a/openstack/compute/v2/extensions/secgroups/requests.go
+++ b/openstack/compute/v2/extensions/secgroups/requests.go
@@ -1,8 +1,6 @@
 package secgroups
 
 import (
-	"errors"
-
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
 )
@@ -46,20 +44,21 @@
 	ToSecGroupCreateMap() (map[string]interface{}, error)
 }
 
-var (
-	errName = errors.New("Name is a required field")
-	errDesc = errors.New("Description is a required field")
-)
-
 // ToSecGroupCreateMap builds the create options into a serializable format.
 func (opts CreateOpts) ToSecGroupCreateMap() (map[string]interface{}, error) {
 	sg := make(map[string]interface{})
 
 	if opts.Name == "" {
-		return sg, errName
+		err := gophercloud.ErrMissingInput{}
+		err.Function = "secgroups.ToSecGroupCreateMap"
+		err.Argument = "secgroups.CreateOpts.Name"
+		return nil, err
 	}
 	if opts.Description == "" {
-		return sg, errDesc
+		err := gophercloud.ErrMissingInput{}
+		err.Function = "secgroups.ToSecGroupCreateMap"
+		err.Argument = "secgroups.CreateOpts.Description"
+		return nil, err
 	}
 
 	sg["name"] = opts.Name
@@ -98,10 +97,16 @@
 	sg := make(map[string]interface{})
 
 	if opts.Name == "" {
-		return sg, errName
+		err := gophercloud.ErrMissingInput{}
+		err.Function = "secgroups.ToSecGroupUpdateMap"
+		err.Argument = "secgroups.UpdateOpts.Name"
+		return nil, err
 	}
 	if opts.Description == "" {
-		return sg, errDesc
+		err := gophercloud.ErrMissingInput{}
+		err.Function = "secgroups.ToSecGroupUpdateMap"
+		err.Argument = "secgroups.UpdateOpts.Description"
+		return nil, err
 	}
 
 	sg["name"] = opts.Name
@@ -176,24 +181,39 @@
 
 // ToRuleCreateMap builds the create rule options into a serializable format.
 func (opts CreateRuleOpts) ToRuleCreateMap() (map[string]interface{}, error) {
-	rule := make(map[string]interface{})
-
 	if opts.ParentGroupID == "" {
-		return rule, errors.New("A ParentGroupID must be set")
+		err := gophercloud.ErrMissingInput{}
+		err.Function = "secgroups.ToRuleCreateMap"
+		err.Argument = "secgroups.CreateRuleOpts.ParentGroupID"
+		return nil, err
 	}
 	if opts.FromPort == 0 {
-		return rule, errors.New("A FromPort must be set")
+		err := gophercloud.ErrMissingInput{}
+		err.Function = "secgroups.ToRuleCreateMap"
+		err.Argument = "secgroups.CreateRuleOpts.FromPort"
+		return nil, err
 	}
 	if opts.ToPort == 0 {
-		return rule, errors.New("A ToPort must be set")
+		err := gophercloud.ErrMissingInput{}
+		err.Function = "secgroups.ToRuleCreateMap"
+		err.Argument = "secgroups.CreateRuleOpts.ToPort"
+		return nil, err
 	}
 	if opts.IPProtocol == "" {
-		return rule, errors.New("A IPProtocol must be set")
+		err := gophercloud.ErrMissingInput{}
+		err.Function = "secgroups.ToRuleCreateMap"
+		err.Argument = "secgroups.CreateRuleOpts.IPProtocol"
+		return nil, err
 	}
 	if opts.CIDR == "" && opts.FromGroupID == "" {
-		return rule, errors.New("A CIDR or FromGroupID must be set")
+		err := gophercloud.ErrMissingInput{}
+		err.Function = "secgroups.ToRuleCreateMap"
+		err.Argument = "secgroups.CreateRuleOpts.CIDR/secgroups.CreateRuleOpts.FromGroupID"
+		return nil, err
 	}
 
+	rule := make(map[string]interface{})
+
 	rule["parent_group_id"] = opts.ParentGroupID
 	rule["from_port"] = opts.FromPort
 	rule["to_port"] = opts.ToPort
diff --git a/openstack/compute/v2/extensions/servergroups/requests.go b/openstack/compute/v2/extensions/servergroups/requests.go
index e3b2493..212edac 100644
--- a/openstack/compute/v2/extensions/servergroups/requests.go
+++ b/openstack/compute/v2/extensions/servergroups/requests.go
@@ -1,8 +1,6 @@
 package servergroups
 
 import (
-	"errors"
-
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
 )
@@ -32,11 +30,17 @@
 // ToServerGroupCreateMap constructs a request body from CreateOpts.
 func (opts CreateOpts) ToServerGroupCreateMap() (map[string]interface{}, error) {
 	if opts.Name == "" {
-		return nil, errors.New("Missing field required for server group creation: Name")
+		err := gophercloud.ErrMissingInput{}
+		err.Function = "servergroups.ToServerGroupCreateMap"
+		err.Argument = "servergroups.CreateOpts.Name"
+		return nil, err
 	}
 
 	if len(opts.Policies) < 1 {
-		return nil, errors.New("Missing field required for server group creation: Policies")
+		err := gophercloud.ErrMissingInput{}
+		err.Function = "servergroups.ToServerGroupCreateMap"
+		err.Argument = "servergroups.CreateOpts.Policies"
+		return nil, err
 	}
 
 	serverGroup := make(map[string]interface{})
diff --git a/openstack/compute/v2/extensions/volumeattach/requests.go b/openstack/compute/v2/extensions/volumeattach/requests.go
index 17cb72e..c2bc2ee 100644
--- a/openstack/compute/v2/extensions/volumeattach/requests.go
+++ b/openstack/compute/v2/extensions/volumeattach/requests.go
@@ -1,8 +1,6 @@
 package volumeattach
 
 import (
-	"errors"
-
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
 )
@@ -32,7 +30,10 @@
 // ToVolumeAttachmentCreateMap constructs a request body from CreateOpts.
 func (opts CreateOpts) ToVolumeAttachmentCreateMap() (map[string]interface{}, error) {
 	if opts.VolumeID == "" {
-		return nil, errors.New("Missing field required for volume attachment creation: VolumeID")
+		err := gophercloud.ErrMissingInput{}
+		err.Function = "volumeattach.ToVolumeAttachmentCreateMap"
+		err.Argument = "volumeattach.CreateOpts.VolumeID"
+		return nil, err
 	}
 
 	volumeAttachment := make(map[string]interface{})
diff --git a/openstack/compute/v2/flavors/requests.go b/openstack/compute/v2/flavors/requests.go
index cbd6843..6e8f003 100644
--- a/openstack/compute/v2/flavors/requests.go
+++ b/openstack/compute/v2/flavors/requests.go
@@ -1,8 +1,6 @@
 package flavors
 
 import (
-	"fmt"
-
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
 )
@@ -71,33 +69,47 @@
 
 // IDFromName is a convienience function that returns a flavor's ID given its name.
 func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
-	flavorCount := 0
-	flavorID := ""
+	count := 0
+	id := ""
 	if name == "" {
-		return "", fmt.Errorf("A flavor name must be provided.")
+		err := &gophercloud.ErrMissingInput{}
+		err.Function = "flavors.IDFromName"
+		err.Argument = "name"
+		return "", err
 	}
-	pager := ListDetail(client, nil)
-	pager.EachPage(func(page pagination.Page) (bool, error) {
-		flavorList, err := ExtractFlavors(page)
-		if err != nil {
-			return false, err
-		}
 
-		for _, f := range flavorList {
-			if f.Name == name {
-				flavorCount++
-				flavorID = f.ID
-			}
-		}
-		return true, nil
-	})
+	allPages, err := ListDetail(client, nil).AllPages()
+	if err != nil {
+		return "", err
+	}
 
-	switch flavorCount {
+	all, err := ExtractFlavors(allPages)
+	if err != nil {
+		return "", err
+	}
+
+	for _, f := range all {
+		if f.Name == name {
+			count++
+			id = f.ID
+		}
+	}
+
+	switch count {
 	case 0:
-		return "", fmt.Errorf("Unable to find flavor: %s", name)
+		err := &gophercloud.ErrResourceNotFound{}
+		err.Function = "flavors.IDFromName"
+		err.ResourceType = "flavor"
+		err.Name = name
+		return "", err
 	case 1:
-		return flavorID, nil
+		return id, nil
 	default:
-		return "", fmt.Errorf("Found %d flavors matching %s", flavorCount, name)
+		err := &gophercloud.ErrMultipleResourcesFound{}
+		err.Function = "flavors.IDFromName"
+		err.ResourceType = "flavor"
+		err.Name = name
+		err.Count = count
+		return "", err
 	}
 }
diff --git a/openstack/compute/v2/images/requests.go b/openstack/compute/v2/images/requests.go
index aa09959..88db657 100644
--- a/openstack/compute/v2/images/requests.go
+++ b/openstack/compute/v2/images/requests.go
@@ -1,8 +1,6 @@
 package images
 
 import (
-	"fmt"
-
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
 )
@@ -75,35 +73,47 @@
 
 // IDFromName is a convienience function that returns an image's ID given its name.
 func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
-	imageCount := 0
-	imageID := ""
+	count := 0
+	id := ""
 	if name == "" {
-		return "", fmt.Errorf("An image name must be provided.")
+		err := &gophercloud.ErrMissingInput{}
+		err.Function = "images.IDFromName"
+		err.Argument = "name"
+		return "", err
 	}
-	pager := ListDetail(client, &ListOpts{
-		Name: name,
-	})
-	pager.EachPage(func(page pagination.Page) (bool, error) {
-		imageList, err := ExtractImages(page)
-		if err != nil {
-			return false, err
-		}
 
-		for _, i := range imageList {
-			if i.Name == name {
-				imageCount++
-				imageID = i.ID
-			}
-		}
-		return true, nil
-	})
+	allPages, err := ListDetail(client, nil).AllPages()
+	if err != nil {
+		return "", err
+	}
 
-	switch imageCount {
+	all, err := ExtractImages(allPages)
+	if err != nil {
+		return "", err
+	}
+
+	for _, f := range all {
+		if f.Name == name {
+			count++
+			id = f.ID
+		}
+	}
+
+	switch count {
 	case 0:
-		return "", fmt.Errorf("Unable to find image: %s", name)
+		err := &gophercloud.ErrResourceNotFound{}
+		err.Function = "images.IDFromName"
+		err.ResourceType = "image"
+		err.Name = name
+		return "", err
 	case 1:
-		return imageID, nil
+		return id, nil
 	default:
-		return "", fmt.Errorf("Found %d images matching %s", imageCount, name)
+		err := &gophercloud.ErrMultipleResourcesFound{}
+		err.Function = "images.IDFromName"
+		err.ResourceType = "image"
+		err.Name = name
+		err.Count = count
+		return "", err
 	}
 }
diff --git a/openstack/compute/v2/servers/errors.go b/openstack/compute/v2/servers/errors.go
index ebfcdcd..c9f0e3c 100644
--- a/openstack/compute/v2/servers/errors.go
+++ b/openstack/compute/v2/servers/errors.go
@@ -8,7 +8,7 @@
 
 // ErrNeitherImageIDNorImageNameProvided is the error when neither the image
 // ID nor the image name is provided for a server operation
-type ErrNeitherImageIDNorImageNameProvided struct{ *gophercloud.ErrMissingInput }
+type ErrNeitherImageIDNorImageNameProvided struct{ gophercloud.ErrMissingInput }
 
 func (e ErrNeitherImageIDNorImageNameProvided) Error() string {
 	return "One and only one of the image ID and the image name must be provided."
@@ -16,40 +16,46 @@
 
 // ErrNeitherFlavorIDNorFlavorNameProvided is the error when neither the flavor
 // ID nor the flavor name is provided for a server operation
-type ErrNeitherFlavorIDNorFlavorNameProvided struct{ *gophercloud.ErrMissingInput }
+type ErrNeitherFlavorIDNorFlavorNameProvided struct{ gophercloud.ErrMissingInput }
 
 func (e ErrNeitherFlavorIDNorFlavorNameProvided) Error() string {
 	return "One and only one of the flavor ID and the flavor name must be provided."
 }
 
+type ErrNoClientProvidedForIDByName struct{ gophercloud.ErrMissingInput }
+
+func (e ErrNoClientProvidedForIDByName) Error() string {
+	return "A service client must be provided to find a resource ID by name."
+}
+
 // ErrInvalidHowParameterProvided is the error when an unknown value is given
 // for the `how` argument
-type ErrInvalidHowParameterProvided struct{ *gophercloud.ErrInvalidInput }
+type ErrInvalidHowParameterProvided struct{ gophercloud.ErrInvalidInput }
 
 // ErrNoAdminPassProvided is the error when an administrative password isn't
 // provided for a server operation
-type ErrNoAdminPassProvided struct{ *gophercloud.ErrMissingInput }
+type ErrNoAdminPassProvided struct{ gophercloud.ErrMissingInput }
 
 // ErrNoImageIDProvided is the error when an image ID isn't provided for a server
 // operation
-type ErrNoImageIDProvided struct{ *gophercloud.ErrMissingInput }
+type ErrNoImageIDProvided struct{ gophercloud.ErrMissingInput }
 
 // ErrNoIDProvided is the error when a server ID isn't provided for a server
 // operation
-type ErrNoIDProvided struct{ *gophercloud.ErrMissingInput }
+type ErrNoIDProvided struct{ gophercloud.ErrMissingInput }
 
 // ErrServer is a generic error type for servers HTTP operations.
 type ErrServer struct {
-	*gophercloud.ErrUnexpectedResponseCode
+	gophercloud.ErrUnexpectedResponseCode
 	ID string
 }
 
-func (se *ErrServer) Error() string {
+func (se ErrServer) Error() string {
 	return fmt.Sprintf("Error while executing HTTP request for server [%s]", se.ID)
 }
 
 // Error404 overrides the generic 404 error message.
-func (se *ErrServer) Error404(e *gophercloud.ErrUnexpectedResponseCode) error {
+func (se ErrServer) Error404(e gophercloud.ErrUnexpectedResponseCode) error {
 	se.ErrUnexpectedResponseCode = e
 	return &ErrServerNotFound{se}
 }
@@ -57,9 +63,9 @@
 // ErrServerNotFound is the error when a 404 is received during server HTTP
 // operations.
 type ErrServerNotFound struct {
-	*ErrServer
+	ErrServer
 }
 
-func (e *ErrServerNotFound) Error() string {
+func (e ErrServerNotFound) Error() string {
 	return fmt.Sprintf("I couldn't find server [%s]", e.ID)
 }
diff --git a/openstack/compute/v2/servers/requests.go b/openstack/compute/v2/servers/requests.go
index c6d3a8e..488829e 100644
--- a/openstack/compute/v2/servers/requests.go
+++ b/openstack/compute/v2/servers/requests.go
@@ -4,7 +4,6 @@
 	"encoding/base64"
 	"encoding/json"
 	"errors"
-	"fmt"
 
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/openstack/compute/v2/flavors"
@@ -175,7 +174,7 @@
 	ConfigDrive bool
 
 	// AdminPass [optional] sets the root user password. If not set, a randomly-generated
-	// password will be created and returned in the response.
+	// password will be created and returned in the rponse.
 	AdminPass string
 
 	// AccessIPv4 [optional] specifies an IPv4 address for the instance.
@@ -252,10 +251,16 @@
 	// If ImageRef isn't provided, use ImageName to ascertain the image ID.
 	if opts.ImageRef == "" {
 		if opts.ImageName == "" {
-			return nil, errors.New("One and only one of ImageRef and ImageName must be provided.")
+			err := ErrNeitherImageIDNorImageNameProvided{}
+			err.Function = "servers.CreateOpts.ToServerCreateMap"
+			err.Argument = "ImageRef/ImageName"
+			return nil, err
 		}
 		if opts.ServiceClient == nil {
-			return nil, errors.New("A service client must be provided to find an image ID by name.")
+			err := ErrNoClientProvidedForIDByName{}
+			err.Function = "servers.CreateOpts.ToServerCreateMap"
+			err.Argument = "ServiceClient"
+			return nil, err
 		}
 		imageID, err := images.IDFromName(opts.ServiceClient, opts.ImageName)
 		if err != nil {
@@ -267,10 +272,16 @@
 	// If FlavorRef isn't provided, use FlavorName to ascertain the flavor ID.
 	if opts.FlavorRef == "" {
 		if opts.FlavorName == "" {
-			return nil, errors.New("One and only one of FlavorRef and FlavorName must be provided.")
+			err := ErrNeitherFlavorIDNorFlavorNameProvided{}
+			err.Function = "servers.CreateOpts.ToServerCreateMap"
+			err.Argument = "FlavorRef/FlavorName"
+			return nil, err
 		}
 		if opts.ServiceClient == nil {
-			return nil, errors.New("A service client must be provided to find a flavor ID by name.")
+			err := ErrNoClientProvidedForIDByName{}
+			err.Argument = "ServiceClient"
+			err.Function = "servers.CreateOpts.ToServerCreateMap"
+			return nil, err
 		}
 		flavorID, err := flavors.IDFromName(opts.ServiceClient, opts.FlavorName)
 		if err != nil {
@@ -284,23 +295,23 @@
 
 // Create requests a server to be provisioned to the user in the current tenant.
 func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
-	var res CreateResult
+	var r CreateResult
 
 	reqBody, err := opts.ToServerCreateMap()
 	if err != nil {
-		res.Err = err
-		return res
+		r.Err = err
+		return r
 	}
 
-	_, res.Err = client.Post(listURL(client), reqBody, &res.Body, nil)
-	return res
+	_, r.Err = client.Post(listURL(client), reqBody, &r.Body, nil)
+	return r
 }
 
 // Delete requests that a server previously provisioned be removed from your account.
 func Delete(client *gophercloud.ServiceClient, id string) DeleteResult {
-	var res DeleteResult
-	_, res.Err = client.Delete(deleteURL(client, id), nil)
-	return res
+	var r DeleteResult
+	_, r.Err = client.Delete(deleteURL(client, id), nil)
+	return r
 }
 
 func ForceDelete(client *gophercloud.ServiceClient, id string) ActionResult {
@@ -308,19 +319,19 @@
 		ForceDelete string `json:"forceDelete"`
 	}
 
-	var res ActionResult
-	_, res.Err = client.Post(actionURL(client, id), req, nil, nil)
-	return res
+	var r ActionResult
+	_, r.Err = client.Post(actionURL(client, id), req, nil, nil)
+	return r
 
 }
 
 // Get requests details on a single server, by ID.
 func Get(client *gophercloud.ServiceClient, id string) GetResult {
-	var result GetResult
-	_, result.Err = client.Get(getURL(client, id), &result.Body, &gophercloud.RequestOpts{
+	var r GetResult
+	_, r.Err = client.Get(getURL(client, id), &r.Body, &gophercloud.RequestOpts{
 		OkCodes: []int{200, 203},
 	})
-	return result
+	return r
 }
 
 // UpdateOptsBuilder allows extensions to add additional attributes to the Update request.
@@ -359,12 +370,12 @@
 
 // Update requests that various attributes of the indicated server be changed.
 func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult {
-	var result UpdateResult
-	reqBody := opts.ToServerUpdateMap()
-	_, result.Err = client.Put(updateURL(client, id), reqBody, &result.Body, &gophercloud.RequestOpts{
+	var r UpdateResult
+	b := opts.ToServerUpdateMap()
+	_, r.Err = client.Put(updateURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
 		OkCodes: []int{200},
 	})
-	return result
+	return r
 }
 
 // ChangeAdminPassword alters the administrator or root password for a specified server.
@@ -377,35 +388,9 @@
 
 	req.ChangePassword.AdminPass = newPassword
 
-	var res ActionResult
-	_, res.Err = client.Post(actionURL(client, id), req, nil, nil)
-	return res
-}
-
-// ErrArgument errors occur when an argument supplied to a package function
-// fails to fall within acceptable values.  For example, the Reboot() function
-// expects the "how" parameter to be one of HardReboot or SoftReboot.  These
-// constants are (currently) strings, leading someone to wonder if they can pass
-// other string values instead, perhaps in an effort to break the API of their
-// provider.  Reboot() returns this error in this situation.
-//
-// Function identifies which function was called/which function is generating
-// the error.
-// Argument identifies which formal argument was responsible for producing the
-// error.
-// Value provides the value as it was passed into the function.
-type ErrArgument struct {
-	Function, Argument string
-	Value              interface{}
-}
-
-// Error yields a useful diagnostic for debugging purposes.
-func (e *ErrArgument) Error() string {
-	return fmt.Sprintf("Bad argument in call to %s, formal parameter %s, value %#v", e.Function, e.Argument, e.Value)
-}
-
-func (e *ErrArgument) String() string {
-	return e.Error()
+	var r ActionResult
+	_, r.Err = client.Post(actionURL(client, id), req, nil, nil)
+	return r
 }
 
 // RebootMethod describes the mechanisms by which a server reboot can be requested.
@@ -420,36 +405,53 @@
 	PowerCycle              = HardReboot
 )
 
+type RebootOptsBuilder interface {
+	ToServerRebootMap() (map[string]interface{}, error)
+}
+
+type RebootOpts struct {
+	Type RebootMethod
+}
+
+func (opts *RebootOpts) ToServerRebootMap() (map[string]interface{}, error) {
+	if (opts.Type != SoftReboot) && (opts.Type != HardReboot) {
+		err := &gophercloud.ErrInvalidInput{}
+		err.Argument = "servers.RebootOpts.Type"
+		err.Value = opts.Type
+		err.Function = "servers.Reboot"
+		return nil, err
+	}
+
+	reqBody := map[string]interface{}{
+		"reboot": map[string]interface{}{
+			"type": string(opts.Type),
+		},
+	}
+
+	return reqBody, nil
+}
+
 // Reboot requests that a given server reboot.
 // Two methods exist for rebooting a server:
 //
-// HardReboot (aka PowerCycle) restarts the server instance by physically cutting power to the machine, or if a VM,
+// HardReboot (aka PowerCycle) rtarts the server instance by physically cutting power to the machine, or if a VM,
 // terminating it at the hypervisor level.
 // It's done. Caput. Full stop.
-// Then, after a brief while, power is restored or the VM instance restarted.
+// Then, after a brief while, power is rtored or the VM instance rtarted.
 //
-// SoftReboot (aka OSReboot) simply tells the OS to restart under its own procedures.
-// E.g., in Linux, asking it to enter runlevel 6, or executing "sudo shutdown -r now", or by asking Windows to restart the machine.
-func Reboot(client *gophercloud.ServiceClient, id string, how RebootMethod) ActionResult {
-	var res ActionResult
+// SoftReboot (aka OSReboot) simply tells the OS to rtart under its own procedur.
+// E.g., in Linux, asking it to enter runlevel 6, or executing "sudo shutdown -r now", or by asking Windows to rtart the machine.
+func Reboot(client *gophercloud.ServiceClient, id string, opts RebootOptsBuilder) ActionResult {
+	var r ActionResult
 
-	if (how != SoftReboot) && (how != HardReboot) {
-		res.Err = &ErrArgument{
-			Function: "Reboot",
-			Argument: "how",
-			Value:    how,
-		}
-		return res
+	reqBody, err := opts.ToServerRebootMap()
+	if err != nil {
+		r.Err = err
+		return r
 	}
 
-	reqBody := struct {
-		C map[string]string `json:"reboot"`
-	}{
-		map[string]string{"type": string(how)},
-	}
-
-	_, res.Err = client.Post(actionURL(client, id), reqBody, nil, nil)
-	return res
+	_, r.Err = client.Post(actionURL(client, id), reqBody, nil, nil)
+	return r
 }
 
 // RebuildOptsBuilder is an interface that allows extensions to override the
@@ -490,11 +492,17 @@
 	server := make(map[string]interface{})
 
 	if opts.AdminPass == "" {
-		err = fmt.Errorf("AdminPass is required")
+		err := ErrNoAdminPassProvided{}
+		err.Function = "servers.ToServerRebuildMap"
+		err.Argument = "AdminPass"
+		return nil, err
 	}
 
 	if opts.ImageID == "" {
-		err = fmt.Errorf("ImageID is required")
+		err := ErrNoImageIDProvided{}
+		err.Function = "servers.ToServerRebuildMap"
+		err.Argument = "ImageID"
+		return nil, err
 	}
 
 	if err != nil {
@@ -530,21 +538,24 @@
 // Rebuild will reprovision the server according to the configuration options
 // provided in the RebuildOpts struct.
 func Rebuild(client *gophercloud.ServiceClient, id string, opts RebuildOptsBuilder) RebuildResult {
-	var result RebuildResult
+	var r RebuildResult
 
 	if id == "" {
-		result.Err = fmt.Errorf("ID is required")
-		return result
+		err := ErrNoIDProvided{}
+		err.Function = "servers.Rebuild"
+		err.Argument = "id"
+		r.Err = err
+		return r
 	}
 
-	reqBody, err := opts.ToServerRebuildMap()
+	b, err := opts.ToServerRebuildMap()
 	if err != nil {
-		result.Err = err
-		return result
+		r.Err = err
+		return r
 	}
 
-	_, result.Err = client.Post(actionURL(client, id), reqBody, &result.Body, nil)
-	return result
+	_, r.Err = client.Post(actionURL(client, id), b, &r.Body, nil)
+	return r
 }
 
 // ResizeOptsBuilder is an interface that allows extensions to override the default structure of
@@ -571,42 +582,68 @@
 
 // Resize instructs the provider to change the flavor of the server.
 // Note that this implies rebuilding it.
-// Unfortunately, one cannot pass rebuild parameters to the resize function.
-// When the resize completes, the server will be in RESIZE_VERIFY state.
+// Unfortunately, one cannot pass rebuild parameters to the rize function.
+// When the rize completes, the server will be in RESIZE_VERIFY state.
 // While in this state, you can explore the use of the new server's configuration.
-// If you like it, call ConfirmResize() to commit the resize permanently.
-// Otherwise, call RevertResize() to restore the old configuration.
+// If you like it, call ConfirmResize() to commit the rize permanently.
+// Otherwise, call RevertResize() to rtore the old configuration.
 func Resize(client *gophercloud.ServiceClient, id string, opts ResizeOptsBuilder) ActionResult {
-	var res ActionResult
-	reqBody, err := opts.ToServerResizeMap()
-	if err != nil {
-		res.Err = err
-		return res
+	var r ActionResult
+
+	if id == "" {
+		err := ErrNoIDProvided{}
+		err.Function = "servers.Resize"
+		err.Argument = "id"
+		r.Err = err
+		return r
 	}
 
-	_, res.Err = client.Post(actionURL(client, id), reqBody, nil, nil)
-	return res
+	b, err := opts.ToServerResizeMap()
+	if err != nil {
+		r.Err = err
+		return r
+	}
+
+	_, r.Err = client.Post(actionURL(client, id), b, nil, nil)
+	return r
 }
 
-// ConfirmResize confirms a previous resize operation on a server.
+// ConfirmResize confirms a previous rize operation on a server.
 // See Resize() for more details.
 func ConfirmResize(client *gophercloud.ServiceClient, id string) ActionResult {
-	var res ActionResult
+	var r ActionResult
 
-	reqBody := map[string]interface{}{"confirmResize": nil}
-	_, res.Err = client.Post(actionURL(client, id), reqBody, nil, &gophercloud.RequestOpts{
+	if id == "" {
+		err := ErrNoIDProvided{}
+		err.Function = "servers.ConfirmResize"
+		err.Argument = "id"
+		r.Err = err
+		return r
+	}
+
+	b := map[string]interface{}{"confirmResize": nil}
+	_, r.Err = client.Post(actionURL(client, id), b, nil, &gophercloud.RequestOpts{
 		OkCodes: []int{201, 202, 204},
 	})
-	return res
+	return r
 }
 
-// RevertResize cancels a previous resize operation on a server.
+// RevertResize cancels a previous rize operation on a server.
 // See Resize() for more details.
 func RevertResize(client *gophercloud.ServiceClient, id string) ActionResult {
-	var res ActionResult
-	reqBody := map[string]interface{}{"revertResize": nil}
-	_, res.Err = client.Post(actionURL(client, id), reqBody, nil, nil)
-	return res
+	var r ActionResult
+
+	if id == "" {
+		err := ErrNoIDProvided{}
+		err.Function = "servers.RevertResize"
+		err.Argument = "id"
+		r.Err = err
+		return r
+	}
+
+	b := map[string]interface{}{"revertResize": nil}
+	_, r.Err = client.Post(actionURL(client, id), b, nil, nil)
+	return r
 }
 
 // RescueOptsBuilder is an interface that allows extensions to override the
@@ -635,23 +672,27 @@
 
 // Rescue instructs the provider to place the server into RESCUE mode.
 func Rescue(client *gophercloud.ServiceClient, id string, opts RescueOptsBuilder) RescueResult {
-	var result RescueResult
+	var r RescueResult
 
 	if id == "" {
-		result.Err = fmt.Errorf("ID is required")
-		return result
-	}
-	reqBody, err := opts.ToServerRescueMap()
-	if err != nil {
-		result.Err = err
-		return result
+		err := ErrNoIDProvided{}
+		err.Function = "servers.Rebuild"
+		err.Argument = "id"
+		r.Err = err
+		return r
 	}
 
-	_, result.Err = client.Post(actionURL(client, id), reqBody, &result.Body, &gophercloud.RequestOpts{
+	b, err := opts.ToServerRescueMap()
+	if err != nil {
+		r.Err = err
+		return r
+	}
+
+	_, r.Err = client.Post(actionURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
 		OkCodes: []int{200},
 	})
 
-	return result
+	return r
 }
 
 // ResetMetadataOptsBuilder allows extensions to add additional parameters to the
@@ -678,23 +719,23 @@
 // the new metadata provided. To keep any already-existing metadata, use the
 // UpdateMetadatas or UpdateMetadata function.
 func ResetMetadata(client *gophercloud.ServiceClient, id string, opts ResetMetadataOptsBuilder) ResetMetadataResult {
-	var res ResetMetadataResult
+	var r ResetMetadataResult
 	metadata, err := opts.ToMetadataResetMap()
 	if err != nil {
-		res.Err = err
-		return res
+		r.Err = err
+		return r
 	}
-	_, res.Err = client.Put(metadataURL(client, id), metadata, &res.Body, &gophercloud.RequestOpts{
+	_, r.Err = client.Put(metadataURL(client, id), metadata, &r.Body, &gophercloud.RequestOpts{
 		OkCodes: []int{200},
 	})
-	return res
+	return r
 }
 
 // Metadata requests all the metadata for the given server ID.
 func Metadata(client *gophercloud.ServiceClient, id string) GetMetadataResult {
-	var res GetMetadataResult
-	_, res.Err = client.Get(metadataURL(client, id), &res.Body, nil)
-	return res
+	var r GetMetadataResult
+	_, r.Err = client.Get(metadataURL(client, id), &r.Body, nil)
+	return r
 }
 
 // UpdateMetadataOptsBuilder allows extensions to add additional parameters to the
@@ -707,16 +748,16 @@
 // This operation does not affect already-existing metadata that is not specified
 // by opts.
 func UpdateMetadata(client *gophercloud.ServiceClient, id string, opts UpdateMetadataOptsBuilder) UpdateMetadataResult {
-	var res UpdateMetadataResult
+	var r UpdateMetadataResult
 	metadata, err := opts.ToMetadataUpdateMap()
 	if err != nil {
-		res.Err = err
-		return res
+		r.Err = err
+		return r
 	}
-	_, res.Err = client.Post(metadataURL(client, id), metadata, &res.Body, &gophercloud.RequestOpts{
+	_, r.Err = client.Post(metadataURL(client, id), metadata, &r.Body, &gophercloud.RequestOpts{
 		OkCodes: []int{200},
 	})
-	return res
+	return r
 }
 
 // MetadatumOptsBuilder allows extensions to add additional parameters to the
@@ -743,33 +784,33 @@
 
 // CreateMetadatum will create or update the key-value pair with the given key for the given server ID.
 func CreateMetadatum(client *gophercloud.ServiceClient, id string, opts MetadatumOptsBuilder) CreateMetadatumResult {
-	var res CreateMetadatumResult
+	var r CreateMetadatumResult
 	metadatum, key, err := opts.ToMetadatumCreateMap()
 	if err != nil {
-		res.Err = err
-		return res
+		r.Err = err
+		return r
 	}
 
-	_, res.Err = client.Put(metadatumURL(client, id, key), metadatum, &res.Body, &gophercloud.RequestOpts{
+	_, r.Err = client.Put(metadatumURL(client, id, key), metadatum, &r.Body, &gophercloud.RequestOpts{
 		OkCodes: []int{200},
 	})
-	return res
+	return r
 }
 
 // Metadatum requests the key-value pair with the given key for the given server ID.
 func Metadatum(client *gophercloud.ServiceClient, id, key string) GetMetadatumResult {
-	var res GetMetadatumResult
-	_, res.Err = client.Request("GET", metadatumURL(client, id, key), &gophercloud.RequestOpts{
-		JSONResponse: &res.Body,
+	var r GetMetadatumResult
+	_, r.Err = client.Request("GET", metadatumURL(client, id, key), &gophercloud.RequestOpts{
+		JSONResponse: &r.Body,
 	})
-	return res
+	return r
 }
 
 // DeleteMetadatum will delete the key-value pair with the given key for the given server ID.
 func DeleteMetadatum(client *gophercloud.ServiceClient, id, key string) DeleteMetadatumResult {
-	var res DeleteMetadatumResult
-	_, res.Err = client.Delete(metadatumURL(client, id, key), nil)
-	return res
+	var r DeleteMetadatumResult
+	_, r.Err = client.Delete(metadatumURL(client, id, key), nil)
+	return r
 }
 
 // ListAddresses makes a request against the API to list the servers IP addresses.
@@ -805,7 +846,10 @@
 	var err error
 	img := make(map[string]interface{})
 	if opts.Name == "" {
-		return nil, fmt.Errorf("Cannot create a server image without a name")
+		err := gophercloud.ErrMissingInput{}
+		err.Function = "servers.CreateImageOpts.ToServerCreateImageMap"
+		err.Argument = "CreateImageOpts.Name"
+		return nil, err
 	}
 	img["name"] = opts.Name
 	if opts.Metadata != nil {
@@ -818,49 +862,63 @@
 
 // CreateImage makes a request against the nova API to schedule an image to be created of the server
 func CreateImage(client *gophercloud.ServiceClient, serverID string, opts CreateImageOptsBuilder) CreateImageResult {
-	var res CreateImageResult
-	reqBody, err := opts.ToServerCreateImageMap()
+	var r CreateImageResult
+	b, err := opts.ToServerCreateImageMap()
 	if err != nil {
-		res.Err = err
-		return res
+		r.Err = err
+		return r
 	}
-	response, err := client.Post(actionURL(client, serverID), reqBody, nil, &gophercloud.RequestOpts{
+	resp, err := client.Post(actionURL(client, serverID), b, nil, &gophercloud.RequestOpts{
 		OkCodes: []int{202},
 	})
-	res.Err = err
-	res.Header = response.Header
-	return res
+	r.Err = err
+	r.Header = resp.Header
+	return r
 }
 
 // IDFromName is a convienience function that returns a server's ID given its name.
 func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
-	serverCount := 0
-	serverID := ""
+	count := 0
+	id := ""
 	if name == "" {
-		return "", fmt.Errorf("A server name must be provided.")
+		err := &gophercloud.ErrMissingInput{}
+		err.Function = "servers.IDFromName"
+		err.Argument = "name"
+		return "", err
 	}
-	pager := List(client, nil)
-	pager.EachPage(func(page pagination.Page) (bool, error) {
-		serverList, err := ExtractServers(page)
-		if err != nil {
-			return false, err
-		}
 
-		for _, s := range serverList {
-			if s.Name == name {
-				serverCount++
-				serverID = s.ID
-			}
-		}
-		return true, nil
-	})
+	allPages, err := List(client, nil).AllPages()
+	if err != nil {
+		return "", err
+	}
 
-	switch serverCount {
+	all, err := ExtractServers(allPages)
+	if err != nil {
+		return "", err
+	}
+
+	for _, f := range all {
+		if f.Name == name {
+			count++
+			id = f.ID
+		}
+	}
+
+	switch count {
 	case 0:
-		return "", fmt.Errorf("Unable to find server: %s", name)
+		err := &gophercloud.ErrResourceNotFound{}
+		err.Function = "servers.IDFromName"
+		err.ResourceType = "server"
+		err.Name = name
+		return "", err
 	case 1:
-		return serverID, nil
+		return id, nil
 	default:
-		return "", fmt.Errorf("Found %d servers matching %s", serverCount, name)
+		err := &gophercloud.ErrMultipleResourcesFound{}
+		err.Function = "servers.IDFromName"
+		err.ResourceType = "server"
+		err.Name = name
+		err.Count = count
+		return "", err
 	}
 }
diff --git a/openstack/compute/v2/servers/requests_test.go b/openstack/compute/v2/servers/requests_test.go
index 39abdd7..73d1375 100644
--- a/openstack/compute/v2/servers/requests_test.go
+++ b/openstack/compute/v2/servers/requests_test.go
@@ -129,7 +129,9 @@
 	defer th.TeardownHTTP()
 	HandleRebootSuccessfully(t)
 
-	res := Reboot(client.ServiceClient(), "1234asdf", SoftReboot)
+	res := Reboot(client.ServiceClient(), "1234asdf", &RebootOpts{
+		Type: SoftReboot,
+	})
 	th.AssertNoErr(t, res.Err)
 }
 
diff --git a/provider_client.go b/provider_client.go
index de9fc5f..f868098 100644
--- a/provider_client.go
+++ b/provider_client.go
@@ -67,6 +67,8 @@
 	// fails with a 401 HTTP response code. This a needed because there may be multiple
 	// authentication functions for different Identity service versions.
 	ReauthFunc func() error
+
+	Debug bool
 }
 
 // AuthenticatedHeaders returns a map of HTTP headers that are common for all
@@ -199,10 +201,10 @@
 	if !ok {
 		body, _ := ioutil.ReadAll(resp.Body)
 		resp.Body.Close()
-		//pc := make([]uintptr, 1) // at least 1 entry needed
+		//pc := make([]uintptr, 1)
 		//runtime.Callers(2, pc)
 		//f := runtime.FuncForPC(pc[0])
-		respErr := &ErrUnexpectedResponseCode{
+		respErr := ErrUnexpectedResponseCode{
 			URL:      url,
 			Method:   method,
 			Expected: options.OkCodes,
@@ -223,7 +225,7 @@
 				err = client.ReauthFunc()
 				if err != nil {
 					e := &ErrUnableToReauthenticate{}
-					e.OriginalError = respErr
+					e.ErrOriginal = respErr
 					return nil, e
 				}
 				if options.RawBody != nil {
@@ -236,11 +238,11 @@
 					switch err.(type) {
 					case *ErrUnexpectedResponseCode:
 						e := &ErrErrorAfterReauthentication{}
-						e.OriginalError = err.(*ErrUnexpectedResponseCode)
+						e.ErrOriginal = err.(*ErrUnexpectedResponseCode)
 						return nil, e
 					default:
 						e := &ErrErrorAfterReauthentication{}
-						e.OriginalError = err
+						e.ErrOriginal = err
 						return nil, e
 					}
 				}