remove mapstructure from identity,networking,objectstorage,orchestration,pagination
diff --git a/openstack/identity/v2/extensions/admin/roles/results.go b/openstack/identity/v2/extensions/admin/roles/results.go
index 6cfe3ac..608f206 100644
--- a/openstack/identity/v2/extensions/admin/roles/results.go
+++ b/openstack/identity/v2/extensions/admin/roles/results.go
@@ -1,7 +1,6 @@
 package roles
 
 import (
-	"github.com/mitchellh/mapstructure"
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
 )
@@ -29,21 +28,17 @@
 // IsEmpty determines whether or not a page of Tenants contains any results.
 func (page RolePage) IsEmpty() (bool, error) {
 	users, err := ExtractRoles(page)
-	if err != nil {
-		return false, err
-	}
-	return len(users) == 0, nil
+	return len(users) == 0, err
 }
 
 // ExtractRoles returns a slice of roles contained in a single page of results.
 func ExtractRoles(page pagination.Page) ([]Role, error) {
-	casted := page.(RolePage).Body
-	var response struct {
-		Roles []Role `mapstructure:"roles"`
+	r := page.(RolePage)
+	var s struct {
+		Roles []Role `json:"roles"`
 	}
-
-	err := mapstructure.Decode(casted, &response)
-	return response.Roles, err
+	err := r.ExtractInto(&s)
+	return s.Roles, err
 }
 
 // UserRoleResult represents the result of either an AddUserRole or
diff --git a/openstack/identity/v2/extensions/delegate.go b/openstack/identity/v2/extensions/delegate.go
index e6af80e..4b2c6a7 100644
--- a/openstack/identity/v2/extensions/delegate.go
+++ b/openstack/identity/v2/extensions/delegate.go
@@ -1,7 +1,6 @@
 package extensions
 
 import (
-	"github.com/mitchellh/mapstructure"
 	"github.com/gophercloud/gophercloud"
 	common "github.com/gophercloud/gophercloud/openstack/common/extensions"
 	"github.com/gophercloud/gophercloud/pagination"
@@ -24,16 +23,15 @@
 // ExtractExtensions accepts a Page struct, specifically an ExtensionPage struct, and extracts the
 // elements into a slice of Extension structs.
 func ExtractExtensions(page pagination.Page) ([]common.Extension, error) {
+	r := page.(ExtensionPage)
 	// Identity v2 adds an intermediate "values" object.
-
-	var resp struct {
+	var s struct {
 		Extensions struct {
-			Values []common.Extension `mapstructure:"values"`
-		} `mapstructure:"extensions"`
+			Values []common.Extension `json:"values"`
+		} `json:"extensions"`
 	}
-
-	err := mapstructure.Decode(page.(ExtensionPage).Body, &resp)
-	return resp.Extensions.Values, err
+	err := r.ExtractInto(&s)
+	return s.Extensions.Values, err
 }
 
 // Get retrieves information for a specific extension using its alias.
diff --git a/openstack/identity/v2/tenants/results.go b/openstack/identity/v2/tenants/results.go
index cee7568..bf52554 100644
--- a/openstack/identity/v2/tenants/results.go
+++ b/openstack/identity/v2/tenants/results.go
@@ -1,7 +1,6 @@
 package tenants
 
 import (
-	"github.com/mitchellh/mapstructure"
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
 )
@@ -9,16 +8,16 @@
 // Tenant is a grouping of users in the identity service.
 type Tenant struct {
 	// ID is a unique identifier for this tenant.
-	ID string `mapstructure:"id"`
+	ID string `json:"id"`
 
 	// Name is a friendlier user-facing name for this tenant.
-	Name string `mapstructure:"name"`
+	Name string `json:"name"`
 
 	// Description is a human-readable explanation of this Tenant's purpose.
-	Description string `mapstructure:"description"`
+	Description string `json:"description"`
 
 	// Enabled indicates whether or not a tenant is active.
-	Enabled bool `mapstructure:"enabled"`
+	Enabled bool `json:"enabled"`
 }
 
 // TenantPage is a single page of Tenant results.
@@ -29,34 +28,27 @@
 // IsEmpty determines whether or not a page of Tenants contains any results.
 func (page TenantPage) IsEmpty() (bool, error) {
 	tenants, err := ExtractTenants(page)
-	if err != nil {
-		return false, err
-	}
-	return len(tenants) == 0, nil
+	return len(tenants) == 0, err
 }
 
 // NextPageURL extracts the "next" link from the tenants_links section of the result.
 func (page TenantPage) NextPageURL() (string, error) {
-	type resp struct {
-		Links []gophercloud.Link `mapstructure:"tenants_links"`
+	var s struct {
+		Links []gophercloud.Link `json:"tenants_links"`
 	}
-
-	var r resp
-	err := mapstructure.Decode(page.Body, &r)
+	err := page.ExtractInto(&s)
 	if err != nil {
 		return "", err
 	}
-
-	return gophercloud.ExtractNextURL(r.Links)
+	return gophercloud.ExtractNextURL(s.Links)
 }
 
 // ExtractTenants returns a slice of Tenants contained in a single page of results.
 func ExtractTenants(page pagination.Page) ([]Tenant, error) {
-	casted := page.(TenantPage).Body
-	var response struct {
-		Tenants []Tenant `mapstructure:"tenants"`
+	r := page.(TenantPage)
+	var s struct {
+		Tenants []Tenant `json:"tenants"`
 	}
-
-	err := mapstructure.Decode(casted, &response)
-	return response.Tenants, err
+	err := r.ExtractInto(&s)
+	return s.Tenants, err
 }
diff --git a/openstack/identity/v2/tokens/results.go b/openstack/identity/v2/tokens/results.go
index 9ef45b6..93c0554 100644
--- a/openstack/identity/v2/tokens/results.go
+++ b/openstack/identity/v2/tokens/results.go
@@ -3,7 +3,6 @@
 import (
 	"time"
 
-	"github.com/mitchellh/mapstructure"
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/openstack/identity/v2/tenants"
 )
@@ -25,15 +24,17 @@
 	Tenant tenants.Tenant
 }
 
-// Authorization need user info which can get from token authentication's response
+// Role is a role for a user.
 type Role struct {
-	Name string `mapstructure:"name"`
+	Name string `json:"name"`
 }
+
+// User is an OpenStack user.
 type User struct {
-	ID       string `mapstructure:"id"`
-	Name     string `mapstructure:"name"`
-	UserName string `mapstructure:"username"`
-	Roles    []Role `mapstructure:"roles"`
+	ID       string `json:"id"`
+	Name     string `json:"name"`
+	UserName string `json:"username"`
+	Roles    []Role `json:"roles"`
 }
 
 // Endpoint represents a single API endpoint offered by a service.
@@ -45,14 +46,14 @@
 //
 // In all cases, fields which aren't supported by the provider and service combined will assume a zero-value ("").
 type Endpoint struct {
-	TenantID    string `mapstructure:"tenantId"`
-	PublicURL   string `mapstructure:"publicURL"`
-	InternalURL string `mapstructure:"internalURL"`
-	AdminURL    string `mapstructure:"adminURL"`
-	Region      string `mapstructure:"region"`
-	VersionID   string `mapstructure:"versionId"`
-	VersionInfo string `mapstructure:"versionInfo"`
-	VersionList string `mapstructure:"versionList"`
+	TenantID    string `json:"tenantId"`
+	PublicURL   string `json:"publicURL"`
+	InternalURL string `json:"internalURL"`
+	AdminURL    string `json:"adminURL"`
+	Region      string `json:"region"`
+	VersionID   string `json:"versionId"`
+	VersionInfo string `json:"versionInfo"`
+	VersionList string `json:"versionList"`
 }
 
 // CatalogEntry provides a type-safe interface to an Identity API V2 service catalog listing.
@@ -63,15 +64,15 @@
 // Otherwise, you'll tie the representation of the service to a specific provider.
 type CatalogEntry struct {
 	// Name will contain the provider-specified name for the service.
-	Name string `mapstructure:"name"`
+	Name string `json:"name"`
 
 	// Type will contain a type string if OpenStack defines a type for the service.
 	// Otherwise, for provider-specific services, the provider may assign their own type strings.
-	Type string `mapstructure:"type"`
+	Type string `json:"type"`
 
 	// Endpoints will let the caller iterate over all the different endpoints that may exist for
 	// the service.
-	Endpoints []Endpoint `mapstructure:"endpoints"`
+	Endpoints []Endpoint `json:"endpoints"`
 }
 
 // ServiceCatalog provides a view into the service catalog from a previous, successful authentication.
@@ -92,56 +93,43 @@
 }
 
 // ExtractToken returns the just-created Token from a CreateResult.
-func (result CreateResult) ExtractToken() (*Token, error) {
-	if result.Err != nil {
-		return nil, result.Err
-	}
-
-	var response struct {
+func (r CreateResult) ExtractToken() (*Token, error) {
+	var s struct {
 		Access struct {
 			Token struct {
-				Expires string         `mapstructure:"expires"`
-				ID      string         `mapstructure:"id"`
-				Tenant  tenants.Tenant `mapstructure:"tenant"`
-			} `mapstructure:"token"`
-		} `mapstructure:"access"`
+				Expires string         `json:"expires"`
+				ID      string         `json:"id"`
+				Tenant  tenants.Tenant `json:"tenant"`
+			} `json:"token"`
+		} `json:"access"`
 	}
 
-	err := mapstructure.Decode(result.Body, &response)
+	err := r.ExtractInto(&s)
 	if err != nil {
 		return nil, err
 	}
 
-	expiresTs, err := time.Parse(gophercloud.RFC3339Milli, response.Access.Token.Expires)
+	expiresTs, err := time.Parse(gophercloud.RFC3339Milli, s.Access.Token.Expires)
 	if err != nil {
 		return nil, err
 	}
 
 	return &Token{
-		ID:        response.Access.Token.ID,
+		ID:        s.Access.Token.ID,
 		ExpiresAt: expiresTs,
-		Tenant:    response.Access.Token.Tenant,
+		Tenant:    s.Access.Token.Tenant,
 	}, nil
 }
 
 // ExtractServiceCatalog returns the ServiceCatalog that was generated along with the user's Token.
-func (result CreateResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
-	if result.Err != nil {
-		return nil, result.Err
-	}
-
-	var response struct {
+func (r CreateResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
+	var s struct {
 		Access struct {
-			Entries []CatalogEntry `mapstructure:"serviceCatalog"`
-		} `mapstructure:"access"`
+			Entries []CatalogEntry `json:"serviceCatalog"`
+		} `json:"access"`
 	}
-
-	err := mapstructure.Decode(result.Body, &response)
-	if err != nil {
-		return nil, err
-	}
-
-	return &ServiceCatalog{Entries: response.Access.Entries}, nil
+	err := r.ExtractInto(&s)
+	return &ServiceCatalog{Entries: s.Access.Entries}, err
 }
 
 // createErr quickly packs an error in a CreateResult.
@@ -150,21 +138,12 @@
 }
 
 // ExtractUser returns the User from a GetResult.
-func (result GetResult) ExtractUser() (*User, error) {
-	if result.Err != nil {
-		return nil, result.Err
-	}
-
-	var response struct {
+func (r GetResult) ExtractUser() (*User, error) {
+	var s struct {
 		Access struct {
-			User User `mapstructure:"user"`
-		} `mapstructure:"access"`
+			User User `json:"user"`
+		} `json:"access"`
 	}
-
-	err := mapstructure.Decode(result.Body, &response)
-	if err != nil {
-		return nil, err
-	}
-
-	return &response.Access.User, nil
+	err := r.ExtractInto(&s)
+	return &s.Access.User, err
 }
diff --git a/openstack/identity/v2/users/results.go b/openstack/identity/v2/users/results.go
index 37ba1be..c353c61 100644
--- a/openstack/identity/v2/users/results.go
+++ b/openstack/identity/v2/users/results.go
@@ -1,8 +1,6 @@
 package users
 
 import (
-	"github.com/mitchellh/mapstructure"
-
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
 )
@@ -25,7 +23,7 @@
 	Email string
 
 	// The ID of the tenant to which this user belongs.
-	TenantID string `mapstructure:"tenant_id"`
+	TenantID string `json:"tenant_id"`
 }
 
 // Role assigns specific responsibilities to users, allowing them to accomplish
@@ -51,41 +49,33 @@
 // IsEmpty determines whether or not a page of Tenants contains any results.
 func (page UserPage) IsEmpty() (bool, error) {
 	users, err := ExtractUsers(page)
-	if err != nil {
-		return false, err
-	}
-	return len(users) == 0, nil
+	return len(users) == 0, err
 }
 
 // ExtractUsers returns a slice of Tenants contained in a single page of results.
 func ExtractUsers(page pagination.Page) ([]User, error) {
-	casted := page.(UserPage).Body
-	var response struct {
-		Users []User `mapstructure:"users"`
+	r := page.(UserPage)
+	var s struct {
+		Users []User `json:"users"`
 	}
-
-	err := mapstructure.Decode(casted, &response)
-	return response.Users, err
+	err := r.ExtractInto(&s)
+	return s.Users, err
 }
 
 // IsEmpty determines whether or not a page of Tenants contains any results.
 func (page RolePage) IsEmpty() (bool, error) {
 	users, err := ExtractRoles(page)
-	if err != nil {
-		return false, err
-	}
-	return len(users) == 0, nil
+	return len(users) == 0, err
 }
 
 // ExtractRoles returns a slice of Roles contained in a single page of results.
 func ExtractRoles(page pagination.Page) ([]Role, error) {
-	casted := page.(RolePage).Body
-	var response struct {
-		Roles []Role `mapstructure:"roles"`
+	r := page.(RolePage)
+	var s struct {
+		Roles []Role `json:"roles"`
 	}
-
-	err := mapstructure.Decode(casted, &response)
-	return response.Roles, err
+	err := r.ExtractInto(&s)
+	return s.Roles, err
 }
 
 type commonResult struct {
@@ -94,17 +84,11 @@
 
 // Extract interprets any commonResult as a User, if possible.
 func (r commonResult) Extract() (*User, error) {
-	if r.Err != nil {
-		return nil, r.Err
+	var s struct {
+		User *User `json:"user"`
 	}
-
-	var response struct {
-		User User `mapstructure:"user"`
-	}
-
-	err := mapstructure.Decode(r.Body, &response)
-
-	return &response.User, err
+	err := r.ExtractInto(&s)
+	return s.User, err
 }
 
 // CreateResult represents the result of a Create operation
diff --git a/openstack/identity/v3/endpoints/results.go b/openstack/identity/v3/endpoints/results.go
index 7c20b8c..09e58e5 100644
--- a/openstack/identity/v3/endpoints/results.go
+++ b/openstack/identity/v3/endpoints/results.go
@@ -1,7 +1,6 @@
 package endpoints
 
 import (
-	"github.com/mitchellh/mapstructure"
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
 )
@@ -13,17 +12,11 @@
 // Extract interprets a GetResult, CreateResult or UpdateResult as a concrete Endpoint.
 // An error is returned if the original call or the extraction failed.
 func (r commonResult) Extract() (*Endpoint, error) {
-	if r.Err != nil {
-		return nil, r.Err
+	var s struct {
+		Endpoint *Endpoint `json:"endpoint"`
 	}
-
-	var res struct {
-		Endpoint `json:"endpoint"`
-	}
-
-	err := mapstructure.Decode(r.Body, &res)
-
-	return &res.Endpoint, err
+	err := r.ExtractInto(&s)
+	return s.Endpoint, err
 }
 
 // CreateResult is the deferred result of a Create call.
@@ -48,12 +41,12 @@
 
 // Endpoint describes the entry point for another service's API.
 type Endpoint struct {
-	ID           string                   `mapstructure:"id" json:"id"`
-	Availability gophercloud.Availability `mapstructure:"interface" json:"interface"`
-	Name         string                   `mapstructure:"name" json:"name"`
-	Region       string                   `mapstructure:"region" json:"region"`
-	ServiceID    string                   `mapstructure:"service_id" json:"service_id"`
-	URL          string                   `mapstructure:"url" json:"url"`
+	ID           string                   `json:"id"`
+	Availability gophercloud.Availability `json:"interface"`
+	Name         string                   `json:"name"`
+	Region       string                   `json:"region"`
+	ServiceID    string                   `json:"service_id"`
+	URL          string                   `json:"url"`
 }
 
 // EndpointPage is a single page of Endpoint results.
@@ -64,19 +57,15 @@
 // IsEmpty returns true if no Endpoints were returned.
 func (p EndpointPage) IsEmpty() (bool, error) {
 	es, err := ExtractEndpoints(p)
-	if err != nil {
-		return true, err
-	}
-	return len(es) == 0, nil
+	return len(es) == 0, err
 }
 
 // ExtractEndpoints extracts an Endpoint slice from a Page.
 func ExtractEndpoints(page pagination.Page) ([]Endpoint, error) {
-	var response struct {
-		Endpoints []Endpoint `mapstructure:"endpoints"`
+	r := page.(EndpointPage)
+	var s struct {
+		Endpoints []Endpoint `json:"endpoints"`
 	}
-
-	err := mapstructure.Decode(page.(EndpointPage).Body, &response)
-
-	return response.Endpoints, err
+	err := r.ExtractInto(&s)
+	return s.Endpoints, err
 }
diff --git a/openstack/identity/v3/roles/results.go b/openstack/identity/v3/roles/results.go
index 75549d3..86f21a0 100644
--- a/openstack/identity/v3/roles/results.go
+++ b/openstack/identity/v3/roles/results.go
@@ -1,10 +1,6 @@
 package roles
 
-import (
-	"github.com/gophercloud/gophercloud/pagination"
-
-	"github.com/mitchellh/mapstructure"
-)
+import "github.com/gophercloud/gophercloud/pagination"
 
 // RoleAssignment is the result of a role assignments query.
 type RoleAssignment struct {
@@ -20,7 +16,7 @@
 
 type Scope struct {
 	Domain  Domain  `json:"domain,omitempty"`
-	Project Project `json:"domain,omitempty"`
+	Project Project `json:"project,omitempty"`
 }
 
 type Domain struct {
@@ -47,35 +43,26 @@
 // IsEmpty returns true if the page contains no results.
 func (p RoleAssignmentsPage) IsEmpty() (bool, error) {
 	roleAssignments, err := ExtractRoleAssignments(p)
-	if err != nil {
-		return true, err
-	}
-	return len(roleAssignments) == 0, nil
+	return len(roleAssignments) == 0, err
 }
 
 // NextPageURL uses the response's embedded link reference to navigate to the next page of results.
 func (page RoleAssignmentsPage) NextPageURL() (string, error) {
-	type resp struct {
+	var s struct {
 		Links struct {
-			Next string `mapstructure:"next"`
-		} `mapstructure:"links"`
+			Next string `json:"next"`
+		} `json:"links"`
 	}
-
-	var r resp
-	err := mapstructure.Decode(page.Body, &r)
-	if err != nil {
-		return "", err
-	}
-
-	return r.Links.Next, nil
+	err := page.ExtractInto(&s)
+	return s.Links.Next, err
 }
 
 // ExtractRoleAssignments extracts a slice of RoleAssignments from a Collection acquired from List.
 func ExtractRoleAssignments(page pagination.Page) ([]RoleAssignment, error) {
-	var response struct {
-		RoleAssignments []RoleAssignment `mapstructure:"role_assignments"`
+	r := page.(RoleAssignmentsPage)
+	var s struct {
+		RoleAssignments []RoleAssignment `json:"role_assignments"`
 	}
-
-	err := mapstructure.Decode(page.(RoleAssignmentsPage).Body, &response)
-	return response.RoleAssignments, err
+	err := r.ExtractInto(&s)
+	return s.RoleAssignments, err
 }
diff --git a/openstack/identity/v3/services/results.go b/openstack/identity/v3/services/results.go
index c55ee62..45040c6 100644
--- a/openstack/identity/v3/services/results.go
+++ b/openstack/identity/v3/services/results.go
@@ -3,8 +3,6 @@
 import (
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
-
-	"github.com/mitchellh/mapstructure"
 )
 
 type commonResult struct {
@@ -14,17 +12,11 @@
 // Extract interprets a GetResult, CreateResult or UpdateResult as a concrete Service.
 // An error is returned if the original call or the extraction failed.
 func (r commonResult) Extract() (*Service, error) {
-	if r.Err != nil {
-		return nil, r.Err
+	var s struct {
+		Service *Service `json:"service"`
 	}
-
-	var res struct {
-		Service `json:"service"`
-	}
-
-	err := mapstructure.Decode(r.Body, &res)
-
-	return &res.Service, err
+	err := r.ExtractInto(&s)
+	return s.Service, err
 }
 
 // CreateResult is the deferred result of a Create call.
@@ -63,18 +55,15 @@
 // IsEmpty returns true if the page contains no results.
 func (p ServicePage) IsEmpty() (bool, error) {
 	services, err := ExtractServices(p)
-	if err != nil {
-		return true, err
-	}
-	return len(services) == 0, nil
+	return len(services) == 0, err
 }
 
 // ExtractServices extracts a slice of Services from a Collection acquired from List.
 func ExtractServices(page pagination.Page) ([]Service, error) {
-	var response struct {
-		Services []Service `mapstructure:"services"`
+	r := page.(ServicePage)
+	var s struct {
+		Services []Service `json:"services"`
 	}
-
-	err := mapstructure.Decode(page.(ServicePage).Body, &response)
-	return response.Services, err
+	err := r.ExtractInto(&s)
+	return s.Services, err
 }
diff --git a/openstack/identity/v3/tokens/results.go b/openstack/identity/v3/tokens/results.go
index ec98c1c..7dd2c0b 100644
--- a/openstack/identity/v3/tokens/results.go
+++ b/openstack/identity/v3/tokens/results.go
@@ -3,7 +3,6 @@
 import (
 	"time"
 
-	"github.com/mitchellh/mapstructure"
 	"github.com/gophercloud/gophercloud"
 )
 
@@ -12,10 +11,10 @@
 // If supported, it contains a region specifier, again if provided.
 // The significance of the Region field will depend upon your provider.
 type Endpoint struct {
-	ID        string `mapstructure:"id"`
-	Region    string `mapstructure:"region"`
-	Interface string `mapstructure:"interface"`
-	URL       string `mapstructure:"url"`
+	ID        string `json:"id"`
+	Region    string `json:"region"`
+	Interface string `json:"interface"`
+	URL       string `json:"url"`
 }
 
 // CatalogEntry provides a type-safe interface to an Identity API V3 service catalog listing.
@@ -27,18 +26,18 @@
 type CatalogEntry struct {
 
 	// Service ID
-	ID string `mapstructure:"id"`
+	ID string `json:"id"`
 
 	// Name will contain the provider-specified name for the service.
-	Name string `mapstructure:"name"`
+	Name string `json:"name"`
 
 	// Type will contain a type string if OpenStack defines a type for the service.
 	// Otherwise, for provider-specific services, the provider may assign their own type strings.
-	Type string `mapstructure:"type"`
+	Type string `json:"type"`
 
 	// Endpoints will let the caller iterate over all the different endpoints that may exist for
 	// the service.
-	Endpoints []Endpoint `mapstructure:"endpoints"`
+	Endpoints []Endpoint `json:"endpoints"`
 }
 
 // ServiceCatalog provides a view into the service catalog from a previous, successful authentication.
@@ -59,14 +58,10 @@
 
 // ExtractToken interprets a commonResult as a Token.
 func (r commonResult) ExtractToken() (*Token, error) {
-	if r.Err != nil {
-		return nil, r.Err
-	}
-
-	var response struct {
+	var s struct {
 		Token struct {
-			ExpiresAt string `mapstructure:"expires_at"`
-		} `mapstructure:"token"`
+			ExpiresAt string `json:"expires_at"`
+		} `json:"token"`
 	}
 
 	var token Token
@@ -74,35 +69,26 @@
 	// Parse the token itself from the stored headers.
 	token.ID = r.Header.Get("X-Subject-Token")
 
-	err := mapstructure.Decode(r.Body, &response)
+	err := r.ExtractInto(&s)
 	if err != nil {
 		return nil, err
 	}
 
 	// Attempt to parse the timestamp.
-	token.ExpiresAt, err = time.Parse(gophercloud.RFC3339Milli, response.Token.ExpiresAt)
+	token.ExpiresAt, err = time.Parse(gophercloud.RFC3339Milli, s.Token.ExpiresAt)
 
 	return &token, err
 }
 
 // ExtractServiceCatalog returns the ServiceCatalog that was generated along with the user's Token.
-func (result CreateResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
-	if result.Err != nil {
-		return nil, result.Err
-	}
-
-	var response struct {
+func (r CreateResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
+	var s struct {
 		Token struct {
-			Entries []CatalogEntry `mapstructure:"catalog"`
-		} `mapstructure:"token"`
+			Entries []CatalogEntry `json:"catalog"`
+		} `json:"token"`
 	}
-
-	err := mapstructure.Decode(result.Body, &response)
-	if err != nil {
-		return nil, err
-	}
-
-	return &ServiceCatalog{Entries: response.Token.Entries}, nil
+	err := r.ExtractInto(&s)
+	return &ServiceCatalog{Entries: s.Token.Entries}, err
 }
 
 // CreateResult defers the interpretation of a created token.