remove mapstructure from identity,networking,objectstorage,orchestration,pagination
diff --git a/openstack/objectstorage/v1/accounts/fixtures.go b/openstack/objectstorage/v1/accounts/fixtures.go
index 66589bf..16327e8 100644
--- a/openstack/objectstorage/v1/accounts/fixtures.go
+++ b/openstack/objectstorage/v1/accounts/fixtures.go
@@ -20,6 +20,7 @@
 		w.Header().Set("X-Account-Container-Count", "2")
 		w.Header().Set("X-Account-Bytes-Used", "14")
 		w.Header().Set("X-Account-Meta-Subject", "books")
+		w.Header().Set("Date", "Fri, 17 Jan 2014 16:09:56 GMT")
 
 		w.WriteHeader(http.StatusNoContent)
 	})
@@ -33,6 +34,7 @@
 		th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
 		th.TestHeader(t, r, "X-Account-Meta-Gophercloud-Test", "accounts")
 
+		w.Header().Set("Date", "Fri, 17 Jan 2014 16:09:56 GMT")
 		w.WriteHeader(http.StatusNoContent)
 	})
 }
diff --git a/openstack/objectstorage/v1/accounts/requests_test.go b/openstack/objectstorage/v1/accounts/requests_test.go
index 31ebccc..8aba591 100644
--- a/openstack/objectstorage/v1/accounts/requests_test.go
+++ b/openstack/objectstorage/v1/accounts/requests_test.go
@@ -13,8 +13,8 @@
 	HandleUpdateAccountSuccessfully(t)
 
 	options := &UpdateOpts{Metadata: map[string]string{"gophercloud-test": "accounts"}}
-	res := Update(fake.ServiceClient(), options)
-	th.AssertNoErr(t, res.Err)
+	_, err := Update(fake.ServiceClient(), options).Extract()
+	th.AssertNoErr(t, err)
 }
 
 func TestGetAccount(t *testing.T) {
@@ -27,6 +27,6 @@
 	th.AssertNoErr(t, res.Err)
 	actualMetadata, _ := res.ExtractMetadata()
 	th.CheckDeepEquals(t, expectedMetadata, actualMetadata)
-	//headers, err := res.Extract()
-	//th.AssertNoErr(t, err)
+	_, err := res.Extract()
+	th.AssertNoErr(t, err)
 }
diff --git a/openstack/objectstorage/v1/accounts/results.go b/openstack/objectstorage/v1/accounts/results.go
index 89cd905..50032bd 100644
--- a/openstack/objectstorage/v1/accounts/results.go
+++ b/openstack/objectstorage/v1/accounts/results.go
@@ -2,7 +2,6 @@
 
 import (
 	"strings"
-	"time"
 
 	"github.com/gophercloud/gophercloud"
 )
@@ -14,46 +13,31 @@
 
 // UpdateHeader represents the headers returned in the response from an Update request.
 type UpdateHeader struct {
-	ContentLength string    `mapstructure:"Content-Length"`
-	ContentType   string    `mapstructure:"Content-Type"`
-	Date          time.Time `mapstructure:"-"`
-	TransID       string    `mapstructure:"X-Trans-Id"`
+	ContentLength string                  `json:"Content-Length"`
+	ContentType   string                  `json:"Content-Type"`
+	Date          gophercloud.JSONRFC1123 `json:"Date"`
+	TransID       string                  `json:"X-Trans-Id"`
 }
 
 // Extract will return a struct of headers returned from a call to Get. To obtain
 // a map of headers, call the ExtractHeader method on the GetResult.
-func (ur UpdateResult) Extract() (UpdateHeader, error) {
-	var uh UpdateHeader
-	if ur.Err != nil {
-		return uh, ur.Err
-	}
-
-	if err := gophercloud.DecodeHeader(ur.Header, &uh); err != nil {
-		return uh, err
-	}
-
-	if date, ok := ur.Header["Date"]; ok && len(date) > 0 {
-		t, err := time.Parse(time.RFC1123, ur.Header["Date"][0])
-		if err != nil {
-			return uh, err
-		}
-		uh.Date = t
-	}
-
-	return uh, nil
+func (ur UpdateResult) Extract() (*UpdateHeader, error) {
+	var uh *UpdateHeader
+	err := ur.ExtractInto(&uh)
+	return uh, err
 }
 
 // GetHeader represents the headers returned in the response from a Get request.
 type GetHeader struct {
-	BytesUsed      int64     `mapstructure:"X-Account-Bytes-Used"`
-	ContainerCount int       `mapstructure:"X-Account-Container-Count"`
-	ContentLength  int64     `mapstructure:"Content-Length"`
-	ContentType    string    `mapstructure:"Content-Type"`
-	Date           time.Time `mapstructure:"-"`
-	ObjectCount    int64     `mapstructure:"X-Account-Object-Count"`
-	TransID        string    `mapstructure:"X-Trans-Id"`
-	TempURLKey     string    `mapstructure:"X-Account-Meta-Temp-URL-Key"`
-	TempURLKey2    string    `mapstructure:"X-Account-Meta-Temp-URL-Key-2"`
+	BytesUsed      string                  `json:"X-Account-Bytes-Used"`
+	ContainerCount string                  `json:"X-Account-Container-Count"`
+	ContentLength  string                  `json:"Content-Length"`
+	ContentType    string                  `json:"Content-Type"`
+	Date           gophercloud.JSONRFC1123 `json:"Date"`
+	ObjectCount    string                  `json:"X-Account-Object-Count"`
+	TransID        string                  `json:"X-Trans-Id"`
+	TempURLKey     string                  `json:"X-Account-Meta-Temp-URL-Key"`
+	TempURLKey2    string                  `json:"X-Account-Meta-Temp-URL-Key-2"`
 }
 
 // GetResult is returned from a call to the Get function.
@@ -63,25 +47,10 @@
 
 // Extract will return a struct of headers returned from a call to Get. To obtain
 // a map of headers, call the ExtractHeader method on the GetResult.
-func (gr GetResult) Extract() (GetHeader, error) {
-	var gh GetHeader
-	if gr.Err != nil {
-		return gh, gr.Err
-	}
-
-	if err := gophercloud.DecodeHeader(gr.Header, &gh); err != nil {
-		return gh, err
-	}
-
-	if date, ok := gr.Header["Date"]; ok && len(date) > 0 {
-		t, err := time.Parse(time.RFC1123, gr.Header["Date"][0])
-		if err != nil {
-			return gh, err
-		}
-		gh.Date = t
-	}
-
-	return gh, nil
+func (gr GetResult) Extract() (*GetHeader, error) {
+	var gh *GetHeader
+	err := gr.ExtractInto(&gh)
+	return gh, err
 }
 
 // ExtractMetadata is a function that takes a GetResult (of type *http.Response)
diff --git a/openstack/objectstorage/v1/containers/results.go b/openstack/objectstorage/v1/containers/results.go
index 4413c74..9eec3f4 100644
--- a/openstack/objectstorage/v1/containers/results.go
+++ b/openstack/objectstorage/v1/containers/results.go
@@ -3,24 +3,21 @@
 import (
 	"fmt"
 	"strings"
-	"time"
 
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
-
-	"github.com/mitchellh/mapstructure"
 )
 
 // Container represents a container resource.
 type Container struct {
 	// The total number of bytes stored in the container.
-	Bytes int `json:"bytes" mapstructure:"bytes"`
+	Bytes int `json:"bytes"`
 
 	// The total number of objects stored in the container.
-	Count int `json:"count" mapstructure:"count"`
+	Count int `json:"count"`
 
 	// The name of the container.
-	Name string `json:"name" mapstructure:"name"`
+	Name string `json:"name"`
 }
 
 // ContainerPage is the page returned by a pager when traversing over a
@@ -29,13 +26,10 @@
 	pagination.MarkerPageBase
 }
 
-// IsEmpty returns true if a ListResult contains no container names.
+//IsEmpty returns true if a ListResult contains no container names.
 func (r ContainerPage) IsEmpty() (bool, error) {
 	names, err := ExtractNames(r)
-	if err != nil {
-		return true, err
-	}
-	return len(names) == 0, nil
+	return len(names) == 0, err
 }
 
 // LastMarker returns the last container name in a ListResult.
@@ -51,17 +45,10 @@
 }
 
 // ExtractInfo is a function that takes a ListResult and returns the containers' information.
-func ExtractInfo(page pagination.Page) ([]Container, error) {
-	untyped := page.(ContainerPage).Body.([]interface{})
-	results := make([]Container, len(untyped))
-	for index, each := range untyped {
-		container := each.(map[string]interface{})
-		err := mapstructure.Decode(container, &results[index])
-		if err != nil {
-			return results, err
-		}
-	}
-	return results, nil
+func ExtractInfo(r pagination.Page) ([]Container, error) {
+	var s []Container
+	err := (r.(ContainerPage)).ExtractInto(&s)
+	return s, err
 }
 
 // ExtractNames is a function that takes a ListResult and returns the containers' names.
@@ -99,16 +86,16 @@
 
 // GetHeader represents the headers returned in the response from a Get request.
 type GetHeader struct {
-	AcceptRanges     string    `mapstructure:"Accept-Ranges"`
-	BytesUsed        int64     `mapstructure:"X-Account-Bytes-Used"`
-	ContentLength    int64     `mapstructure:"Content-Length"`
-	ContentType      string    `mapstructure:"Content-Type"`
-	Date             time.Time `mapstructure:"-"`
-	ObjectCount      int64     `mapstructure:"X-Container-Object-Count"`
-	Read             string    `mapstructure:"X-Container-Read"`
-	TransID          string    `mapstructure:"X-Trans-Id"`
-	VersionsLocation string    `mapstructure:"X-Versions-Location"`
-	Write            string    `mapstructure:"X-Container-Write"`
+	AcceptRanges     string                  `json:"Accept-Ranges"`
+	BytesUsed        string                  `json:"X-Account-Bytes-Used"`
+	ContentLength    string                  `json:"Content-Length"`
+	ContentType      string                  `json:"Content-Type"`
+	Date             gophercloud.JSONRFC1123 `json:"Date"`
+	ObjectCount      string                  `json:"X-Container-Object-Count"`
+	Read             string                  `json:"X-Container-Read"`
+	TransID          string                  `json:"X-Trans-Id"`
+	VersionsLocation string                  `json:"X-Versions-Location"`
+	Write            string                  `json:"X-Container-Write"`
 }
 
 // GetResult represents the result of a get operation.
@@ -118,35 +105,20 @@
 
 // Extract will return a struct of headers returned from a call to Get. To obtain
 // a map of headers, call the ExtractHeader method on the GetResult.
-func (gr GetResult) Extract() (GetHeader, error) {
-	var gh GetHeader
-	if gr.Err != nil {
-		return gh, gr.Err
-	}
-
-	if err := gophercloud.DecodeHeader(gr.Header, &gh); err != nil {
-		return gh, err
-	}
-
-	if date, ok := gr.Header["Date"]; ok && len(date) > 0 {
-		t, err := time.Parse(time.RFC1123, gr.Header["Date"][0])
-		if err != nil {
-			return gh, err
-		}
-		gh.Date = t
-	}
-
-	return gh, nil
+func (r GetResult) Extract() (*GetHeader, error) {
+	var s *GetHeader
+	err := r.ExtractInto(&s)
+	return s, err
 }
 
 // ExtractMetadata is a function that takes a GetResult (of type *http.Response)
 // and returns the custom metadata associated with the container.
-func (gr GetResult) ExtractMetadata() (map[string]string, error) {
-	if gr.Err != nil {
-		return nil, gr.Err
+func (r GetResult) ExtractMetadata() (map[string]string, error) {
+	if r.Err != nil {
+		return nil, r.Err
 	}
 	metadata := make(map[string]string)
-	for k, v := range gr.Header {
+	for k, v := range r.Header {
 		if strings.HasPrefix(k, "X-Container-Meta-") {
 			key := strings.TrimPrefix(k, "X-Container-Meta-")
 			metadata[key] = v[0]
@@ -157,10 +129,10 @@
 
 // CreateHeader represents the headers returned in the response from a Create request.
 type CreateHeader struct {
-	ContentLength int64     `mapstructure:"Content-Length"`
-	ContentType   string    `mapstructure:"Content-Type"`
-	Date          time.Time `mapstructure:"-"`
-	TransID       string    `mapstructure:"X-Trans-Id"`
+	ContentLength string                  `json:"Content-Length"`
+	ContentType   string                  `json:"Content-Type"`
+	Date          gophercloud.JSONRFC1123 `json:"Date"`
+	TransID       string                  `json:"X-Trans-Id"`
 }
 
 // CreateResult represents the result of a create operation. To extract the
@@ -172,33 +144,18 @@
 
 // Extract will return a struct of headers returned from a call to Create. To obtain
 // a map of headers, call the ExtractHeader method on the CreateResult.
-func (cr CreateResult) Extract() (CreateHeader, error) {
-	var ch CreateHeader
-	if cr.Err != nil {
-		return ch, cr.Err
-	}
-
-	if err := gophercloud.DecodeHeader(cr.Header, &ch); err != nil {
-		return ch, err
-	}
-
-	if date, ok := cr.Header["Date"]; ok && len(date) > 0 {
-		t, err := time.Parse(time.RFC1123, cr.Header["Date"][0])
-		if err != nil {
-			return ch, err
-		}
-		ch.Date = t
-	}
-
-	return ch, nil
+func (r CreateResult) Extract() (*CreateHeader, error) {
+	var s *CreateHeader
+	err := r.ExtractInto(&s)
+	return s, err
 }
 
 // UpdateHeader represents the headers returned in the response from a Update request.
 type UpdateHeader struct {
-	ContentLength int64     `mapstructure:"Content-Length"`
-	ContentType   string    `mapstructure:"Content-Type"`
-	Date          time.Time `mapstructure:"-"`
-	TransID       string    `mapstructure:"X-Trans-Id"`
+	ContentLength string                  `json:"Content-Length"`
+	ContentType   string                  `json:"Content-Type"`
+	Date          gophercloud.JSONRFC1123 `json:"Date"`
+	TransID       string                  `json:"X-Trans-Id"`
 }
 
 // UpdateResult represents the result of an update operation. To extract the
@@ -210,33 +167,18 @@
 
 // Extract will return a struct of headers returned from a call to Update. To obtain
 // a map of headers, call the ExtractHeader method on the UpdateResult.
-func (ur UpdateResult) Extract() (UpdateHeader, error) {
-	var uh UpdateHeader
-	if ur.Err != nil {
-		return uh, ur.Err
-	}
-
-	if err := gophercloud.DecodeHeader(ur.Header, &uh); err != nil {
-		return uh, err
-	}
-
-	if date, ok := ur.Header["Date"]; ok && len(date) > 0 {
-		t, err := time.Parse(time.RFC1123, ur.Header["Date"][0])
-		if err != nil {
-			return uh, err
-		}
-		uh.Date = t
-	}
-
-	return uh, nil
+func (r UpdateResult) Extract() (*UpdateHeader, error) {
+	var s *UpdateHeader
+	err := r.ExtractInto(&s)
+	return s, err
 }
 
 // DeleteHeader represents the headers returned in the response from a Delete request.
 type DeleteHeader struct {
-	ContentLength int64     `mapstructure:"Content-Length"`
-	ContentType   string    `mapstructure:"Content-Type"`
-	Date          time.Time `mapstructure:"-"`
-	TransID       string    `mapstructure:"X-Trans-Id"`
+	ContentLength string                  `json:"Content-Length"`
+	ContentType   string                  `json:"Content-Type"`
+	Date          gophercloud.JSONRFC1123 `json:"Date"`
+	TransID       string                  `json:"X-Trans-Id"`
 }
 
 // DeleteResult represents the result of a delete operation. To extract the
@@ -248,23 +190,8 @@
 
 // Extract will return a struct of headers returned from a call to Delete. To obtain
 // a map of headers, call the ExtractHeader method on the DeleteResult.
-func (dr DeleteResult) Extract() (DeleteHeader, error) {
-	var dh DeleteHeader
-	if dr.Err != nil {
-		return dh, dr.Err
-	}
-
-	if err := gophercloud.DecodeHeader(dr.Header, &dh); err != nil {
-		return dh, err
-	}
-
-	if date, ok := dr.Header["Date"]; ok && len(date) > 0 {
-		t, err := time.Parse(time.RFC1123, dr.Header["Date"][0])
-		if err != nil {
-			return dh, err
-		}
-		dh.Date = t
-	}
-
-	return dh, nil
+func (r DeleteResult) Extract() (*DeleteHeader, error) {
+	var s *DeleteHeader
+	err := r.ExtractInto(&s)
+	return s, err
 }
diff --git a/openstack/objectstorage/v1/objects/results.go b/openstack/objectstorage/v1/objects/results.go
index 530b072..c0d532b 100644
--- a/openstack/objectstorage/v1/objects/results.go
+++ b/openstack/objectstorage/v1/objects/results.go
@@ -4,34 +4,30 @@
 	"fmt"
 	"io"
 	"io/ioutil"
-	"strconv"
 	"strings"
-	"time"
 
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
-
-	"github.com/mitchellh/mapstructure"
 )
 
 // Object is a structure that holds information related to a storage object.
 type Object struct {
 	// Bytes is the total number of bytes that comprise the object.
-	Bytes int64 `json:"bytes" mapstructure:"bytes"`
+	Bytes int64 `json:"bytes"`
 
 	// ContentType is the content type of the object.
-	ContentType string `json:"content_type" mapstructure:"content_type"`
+	ContentType string `json:"content_type"`
 
 	// Hash represents the MD5 checksum value of the object's content.
-	Hash string `json:"hash" mapstructure:"hash"`
+	Hash string `json:"hash"`
 
 	// LastModified is the RFC3339Milli time the object was last modified, represented
 	// as a string. For any given object (obj), this value may be parsed to a time.Time:
 	// lastModified, err := time.Parse(gophercloud.RFC3339Milli, obj.LastModified)
-	LastModified string `json:"last_modified" mapstructure:"last_modified"`
+	LastModified string `json:"last_modified"`
 
 	// Name is the unique name for the object.
-	Name string `json:"name" mapstructure:"name"`
+	Name string `json:"name"`
 }
 
 // ObjectPage is a single page of objects that is returned from a call to the
@@ -43,10 +39,7 @@
 // IsEmpty returns true if a ListResult contains no object names.
 func (r ObjectPage) IsEmpty() (bool, error) {
 	names, err := ExtractNames(r)
-	if err != nil {
-		return true, err
-	}
-	return len(names) == 0, nil
+	return len(names) == 0, err
 }
 
 // LastMarker returns the last object name in a ListResult.
@@ -62,26 +55,19 @@
 }
 
 // ExtractInfo is a function that takes a page of objects and returns their full information.
-func ExtractInfo(page pagination.Page) ([]Object, error) {
-	untyped := page.(ObjectPage).Body.([]interface{})
-	results := make([]Object, len(untyped))
-	for index, each := range untyped {
-		object := each.(map[string]interface{})
-		err := mapstructure.Decode(object, &results[index])
-		if err != nil {
-			return results, err
-		}
-	}
-	return results, nil
+func ExtractInfo(r pagination.Page) ([]Object, error) {
+	var s []Object
+	err := (r.(ObjectPage)).ExtractInto(&s)
+	return s, err
 }
 
 // ExtractNames is a function that takes a page of objects and returns only their names.
-func ExtractNames(page pagination.Page) ([]string, error) {
-	casted := page.(ObjectPage)
+func ExtractNames(r pagination.Page) ([]string, error) {
+	casted := r.(ObjectPage)
 	ct := casted.Header.Get("Content-Type")
 	switch {
 	case strings.HasPrefix(ct, "application/json"):
-		parsed, err := ExtractInfo(page)
+		parsed, err := ExtractInfo(r)
 		if err != nil {
 			return nil, err
 		}
@@ -95,7 +81,7 @@
 	case strings.HasPrefix(ct, "text/plain"):
 		names := make([]string, 0, 50)
 
-		body := string(page.(ObjectPage).Body.([]uint8))
+		body := string(r.(ObjectPage).Body.([]uint8))
 		for _, name := range strings.Split(body, "\n") {
 			if len(name) > 0 {
 				names = append(names, name)
@@ -112,18 +98,18 @@
 
 // DownloadHeader represents the headers returned in the response from a Download request.
 type DownloadHeader struct {
-	AcceptRanges       string    `mapstructure:"Accept-Ranges"`
-	ContentDisposition string    `mapstructure:"Content-Disposition"`
-	ContentEncoding    string    `mapstructure:"Content-Encoding"`
-	ContentLength      int64     `mapstructure:"Content-Length"`
-	ContentType        string    `mapstructure:"Content-Type"`
-	Date               time.Time `mapstructure:"-"`
-	DeleteAt           time.Time `mapstructure:"-"`
-	ETag               string    `mapstructure:"Etag"`
-	LastModified       time.Time `mapstructure:"-"`
-	ObjectManifest     string    `mapstructure:"X-Object-Manifest"`
-	StaticLargeObject  bool      `mapstructure:"X-Static-Large-Object"`
-	TransID            string    `mapstructure:"X-Trans-Id"`
+	AcceptRanges       string                  `json:"Accept-Ranges"`
+	ContentDisposition string                  `json:"Content-Disposition"`
+	ContentEncoding    string                  `json:"Content-Encoding"`
+	ContentLength      string                  `json:"Content-Length"`
+	ContentType        string                  `json:"Content-Type"`
+	Date               gophercloud.JSONRFC1123 `json:"Date"`
+	DeleteAt           gophercloud.JSONUnix    `json:"X-Delete-At"`
+	ETag               string                  `json:"Etag"`
+	LastModified       gophercloud.JSONRFC1123 `json:"Last-Modified"`
+	ObjectManifest     string                  `json:"X-Object-Manifest"`
+	StaticLargeObject  bool                    `json:"X-Static-Large-Object"`
+	TransID            string                  `json:"X-Trans-Id"`
 }
 
 // DownloadResult is a *http.Response that is returned from a call to the Download function.
@@ -134,41 +120,10 @@
 
 // Extract will return a struct of headers returned from a call to Download. To obtain
 // a map of headers, call the ExtractHeader method on the DownloadResult.
-func (dr DownloadResult) Extract() (DownloadHeader, error) {
-	var dh DownloadHeader
-	if dr.Err != nil {
-		return dh, dr.Err
-	}
-
-	if err := gophercloud.DecodeHeader(dr.Header, &dh); err != nil {
-		return dh, err
-	}
-
-	if date, ok := dr.Header["Date"]; ok && len(date) > 0 {
-		t, err := time.Parse(time.RFC1123, date[0])
-		if err != nil {
-			return dh, err
-		}
-		dh.Date = t
-	}
-
-	if date, ok := dr.Header["Last-Modified"]; ok && len(date) > 0 {
-		t, err := time.Parse(time.RFC1123, date[0])
-		if err != nil {
-			return dh, err
-		}
-		dh.LastModified = t
-	}
-
-	if date, ok := dr.Header["X-Delete-At"]; ok && len(date) > 0 {
-		unix, err := strconv.ParseInt(date[0], 10, 64)
-		if err != nil {
-			return dh, err
-		}
-		dh.DeleteAt = time.Unix(unix, 0)
-	}
-
-	return dh, nil
+func (r DownloadResult) Extract() (*DownloadHeader, error) {
+	var s *DownloadHeader
+	err := r.ExtractInto(&s)
+	return s, err
 }
 
 // ExtractContent is a function that takes a DownloadResult's io.Reader body
@@ -176,31 +131,32 @@
 // the nature of io.Reader is forward-only - meaning that it can only be read
 // once and not rewound. You can recreate a reader from the output of this
 // function by using bytes.NewReader(downloadBytes)
-func (dr DownloadResult) ExtractContent() ([]byte, error) {
-	if dr.Err != nil {
-		return nil, dr.Err
+func (r *DownloadResult) ExtractContent() ([]byte, error) {
+	if r.Err != nil {
+		return nil, r.Err
 	}
-	body, err := ioutil.ReadAll(dr.Body)
+	defer r.Body.Close()
+	body, err := ioutil.ReadAll(r.Body)
 	if err != nil {
 		return nil, err
 	}
-	dr.Body.Close()
+	r.Body.Close()
 	return body, nil
 }
 
 // GetHeader represents the headers returned in the response from a Get request.
 type GetHeader struct {
-	ContentDisposition string    `mapstructure:"Content-Disposition"`
-	ContentEncoding    string    `mapstructure:"Content-Encoding"`
-	ContentLength      int64     `mapstructure:"Content-Length"`
-	ContentType        string    `mapstructure:"Content-Type"`
-	Date               time.Time `mapstructure:"-"`
-	DeleteAt           time.Time `mapstructure:"-"`
-	ETag               string    `mapstructure:"Etag"`
-	LastModified       time.Time `mapstructure:"-"`
-	ObjectManifest     string    `mapstructure:"X-Object-Manifest"`
-	StaticLargeObject  bool      `mapstructure:"X-Static-Large-Object"`
-	TransID            string    `mapstructure:"X-Trans-Id"`
+	ContentDisposition string                  `json:"Content-Disposition"`
+	ContentEncoding    string                  `json:"Content-Encoding"`
+	ContentLength      string                  `json:"Content-Length"`
+	ContentType        string                  `json:"Content-Type"`
+	Date               gophercloud.JSONRFC1123 `json:"Date"`
+	DeleteAt           gophercloud.JSONUnix    `json:"X-Delete-At"`
+	ETag               string                  `json:"Etag"`
+	LastModified       gophercloud.JSONRFC1123 `json:"Last-Modified"`
+	ObjectManifest     string                  `json:"X-Object-Manifest"`
+	StaticLargeObject  bool                    `json:"X-Static-Large-Object"`
+	TransID            string                  `json:"X-Trans-Id"`
 }
 
 // GetResult is a *http.Response that is returned from a call to the Get function.
@@ -210,51 +166,20 @@
 
 // Extract will return a struct of headers returned from a call to Get. To obtain
 // a map of headers, call the ExtractHeader method on the GetResult.
-func (gr GetResult) Extract() (GetHeader, error) {
-	var gh GetHeader
-	if gr.Err != nil {
-		return gh, gr.Err
-	}
-
-	if err := gophercloud.DecodeHeader(gr.Header, &gh); err != nil {
-		return gh, err
-	}
-
-	if date, ok := gr.Header["Date"]; ok && len(date) > 0 {
-		t, err := time.Parse(time.RFC1123, gr.Header["Date"][0])
-		if err != nil {
-			return gh, err
-		}
-		gh.Date = t
-	}
-
-	if date, ok := gr.Header["Last-Modified"]; ok && len(date) > 0 {
-		t, err := time.Parse(time.RFC1123, gr.Header["Last-Modified"][0])
-		if err != nil {
-			return gh, err
-		}
-		gh.LastModified = t
-	}
-
-	if date, ok := gr.Header["X-Delete-At"]; ok && len(date) > 0 {
-		unix, err := strconv.ParseInt(date[0], 10, 64)
-		if err != nil {
-			return gh, err
-		}
-		gh.DeleteAt = time.Unix(unix, 0)
-	}
-
-	return gh, nil
+func (r GetResult) Extract() (*GetHeader, error) {
+	var s *GetHeader
+	err := r.ExtractInto(&s)
+	return s, err
 }
 
 // ExtractMetadata is a function that takes a GetResult (of type *http.Response)
 // and returns the custom metadata associated with the object.
-func (gr GetResult) ExtractMetadata() (map[string]string, error) {
-	if gr.Err != nil {
-		return nil, gr.Err
+func (r GetResult) ExtractMetadata() (map[string]string, error) {
+	if r.Err != nil {
+		return nil, r.Err
 	}
 	metadata := make(map[string]string)
-	for k, v := range gr.Header {
+	for k, v := range r.Header {
 		if strings.HasPrefix(k, "X-Object-Meta-") {
 			key := strings.TrimPrefix(k, "X-Object-Meta-")
 			metadata[key] = v[0]
@@ -265,12 +190,12 @@
 
 // CreateHeader represents the headers returned in the response from a Create request.
 type CreateHeader struct {
-	ContentLength int64     `mapstructure:"Content-Length"`
-	ContentType   string    `mapstructure:"Content-Type"`
-	Date          time.Time `mapstructure:"-"`
-	ETag          string    `mapstructure:"Etag"`
-	LastModified  time.Time `mapstructure:"-"`
-	TransID       string    `mapstructure:"X-Trans-Id"`
+	ContentLength string                  `json:"Content-Length"`
+	ContentType   string                  `json:"Content-Type"`
+	Date          gophercloud.JSONRFC1123 `json:"Date"`
+	ETag          string                  `json:"Etag"`
+	LastModified  gophercloud.JSONRFC1123 `json:"Last-Modified"`
+	TransID       string                  `json:"X-Trans-Id"`
 }
 
 // CreateResult represents the result of a create operation.
@@ -280,41 +205,18 @@
 
 // Extract will return a struct of headers returned from a call to Create. To obtain
 // a map of headers, call the ExtractHeader method on the CreateResult.
-func (cr CreateResult) Extract() (CreateHeader, error) {
-	var ch CreateHeader
-	if cr.Err != nil {
-		return ch, cr.Err
-	}
-
-	if err := gophercloud.DecodeHeader(cr.Header, &ch); err != nil {
-		return ch, err
-	}
-
-	if date, ok := cr.Header["Date"]; ok && len(date) > 0 {
-		t, err := time.Parse(time.RFC1123, cr.Header["Date"][0])
-		if err != nil {
-			return ch, err
-		}
-		ch.Date = t
-	}
-
-	if date, ok := cr.Header["Last-Modified"]; ok && len(date) > 0 {
-		t, err := time.Parse(time.RFC1123, cr.Header["Last-Modified"][0])
-		if err != nil {
-			return ch, err
-		}
-		ch.LastModified = t
-	}
-
-	return ch, nil
+func (r CreateResult) Extract() (*CreateHeader, error) {
+	var s *CreateHeader
+	err := r.ExtractInto(&s)
+	return s, err
 }
 
 // UpdateHeader represents the headers returned in the response from a Update request.
 type UpdateHeader struct {
-	ContentLength int64     `mapstructure:"Content-Length"`
-	ContentType   string    `mapstructure:"Content-Type"`
-	Date          time.Time `mapstructure:"-"`
-	TransID       string    `mapstructure:"X-Trans-Id"`
+	ContentLength string                  `json:"Content-Length"`
+	ContentType   string                  `json:"Content-Type"`
+	Date          gophercloud.JSONRFC1123 `json:"Date"`
+	TransID       string                  `json:"X-Trans-Id"`
 }
 
 // UpdateResult represents the result of an update operation.
@@ -324,33 +226,18 @@
 
 // Extract will return a struct of headers returned from a call to Update. To obtain
 // a map of headers, call the ExtractHeader method on the UpdateResult.
-func (ur UpdateResult) Extract() (UpdateHeader, error) {
-	var uh UpdateHeader
-	if ur.Err != nil {
-		return uh, ur.Err
-	}
-
-	if err := gophercloud.DecodeHeader(ur.Header, &uh); err != nil {
-		return uh, err
-	}
-
-	if date, ok := ur.Header["Date"]; ok && len(date) > 0 {
-		t, err := time.Parse(time.RFC1123, ur.Header["Date"][0])
-		if err != nil {
-			return uh, err
-		}
-		uh.Date = t
-	}
-
-	return uh, nil
+func (r UpdateResult) Extract() (*UpdateHeader, error) {
+	var s *UpdateHeader
+	err := r.ExtractInto(&s)
+	return s, err
 }
 
 // DeleteHeader represents the headers returned in the response from a Delete request.
 type DeleteHeader struct {
-	ContentLength int64     `mapstructure:"Content-Length"`
-	ContentType   string    `mapstructure:"Content-Type"`
-	Date          time.Time `mapstructure:"-"`
-	TransID       string    `mapstructure:"X-Trans-Id"`
+	ContentLength string                  `json:"Content-Length"`
+	ContentType   string                  `json:"Content-Type"`
+	Date          gophercloud.JSONRFC1123 `json:"Date"`
+	TransID       string                  `json:"X-Trans-Id"`
 }
 
 // DeleteResult represents the result of a delete operation.
@@ -360,37 +247,22 @@
 
 // Extract will return a struct of headers returned from a call to Delete. To obtain
 // a map of headers, call the ExtractHeader method on the DeleteResult.
-func (dr DeleteResult) Extract() (DeleteHeader, error) {
-	var dh DeleteHeader
-	if dr.Err != nil {
-		return dh, dr.Err
-	}
-
-	if err := gophercloud.DecodeHeader(dr.Header, &dh); err != nil {
-		return dh, err
-	}
-
-	if date, ok := dr.Header["Date"]; ok && len(date) > 0 {
-		t, err := time.Parse(time.RFC1123, dr.Header["Date"][0])
-		if err != nil {
-			return dh, err
-		}
-		dh.Date = t
-	}
-
-	return dh, nil
+func (r DeleteResult) Extract() (*DeleteHeader, error) {
+	var s *DeleteHeader
+	err := r.ExtractInto(&s)
+	return s, err
 }
 
 // CopyHeader represents the headers returned in the response from a Copy request.
 type CopyHeader struct {
-	ContentLength          int64     `mapstructure:"Content-Length"`
-	ContentType            string    `mapstructure:"Content-Type"`
-	CopiedFrom             string    `mapstructure:"X-Copied-From"`
-	CopiedFromLastModified time.Time `mapstructure:"-"`
-	Date                   time.Time `mapstructure:"-"`
-	ETag                   string    `mapstructure:"Etag"`
-	LastModified           time.Time `mapstructure:"-"`
-	TransID                string    `mapstructure:"X-Trans-Id"`
+	ContentLength          int64                   `json:"Content-Length"`
+	ContentType            string                  `json:"Content-Type"`
+	CopiedFrom             string                  `json:"X-Copied-From"`
+	CopiedFromLastModified gophercloud.JSONRFC1123 `json:"X-Copied-From-Last-Modified"`
+	Date                   gophercloud.JSONRFC1123 `json:"Date"`
+	ETag                   string                  `json:"Etag"`
+	LastModified           gophercloud.JSONRFC1123 `json:"Last-Modified"`
+	TransID                string                  `json:"X-Trans-Id"`
 }
 
 // CopyResult represents the result of a copy operation.
@@ -400,39 +272,8 @@
 
 // Extract will return a struct of headers returned from a call to Copy. To obtain
 // a map of headers, call the ExtractHeader method on the CopyResult.
-func (cr CopyResult) Extract() (CopyHeader, error) {
-	var ch CopyHeader
-	if cr.Err != nil {
-		return ch, cr.Err
-	}
-
-	if err := gophercloud.DecodeHeader(cr.Header, &ch); err != nil {
-		return ch, err
-	}
-
-	if date, ok := cr.Header["Date"]; ok && len(date) > 0 {
-		t, err := time.Parse(time.RFC1123, cr.Header["Date"][0])
-		if err != nil {
-			return ch, err
-		}
-		ch.Date = t
-	}
-
-	if date, ok := cr.Header["Last-Modified"]; ok && len(date) > 0 {
-		t, err := time.Parse(time.RFC1123, cr.Header["Last-Modified"][0])
-		if err != nil {
-			return ch, err
-		}
-		ch.LastModified = t
-	}
-
-	if date, ok := cr.Header["X-Copied-From-Last-Modified"]; ok && len(date) > 0 {
-		t, err := time.Parse(time.RFC1123, cr.Header["X-Copied-From-Last-Modified"][0])
-		if err != nil {
-			return ch, err
-		}
-		ch.CopiedFromLastModified = t
-	}
-
-	return ch, nil
+func (r CopyResult) Extract() (*CopyHeader, error) {
+	var s *CopyHeader
+	err := r.ExtractInto(&s)
+	return s, err
 }