remove mapstructure from blockstorage,cdn,compute,db pkgs
diff --git a/openstack/blockstorage/v1/apiversions/requests_test.go b/openstack/blockstorage/v1/apiversions/requests_test.go
index 15a7660..3a14c99 100644
--- a/openstack/blockstorage/v1/apiversions/requests_test.go
+++ b/openstack/blockstorage/v1/apiversions/requests_test.go
@@ -54,10 +54,7 @@
 	List(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) {
 		count++
 		actual, err := ExtractAPIVersions(page)
-		if err != nil {
-			t.Errorf("Failed to extract API versions: %v", err)
-			return false, err
-		}
+		th.AssertNoErr(t, err)
 
 		expected := []APIVersion{
 			APIVersion{
@@ -77,9 +74,7 @@
 		return true, nil
 	})
 
-	if count != 1 {
-		t.Errorf("Expected 1 page, got %d", count)
-	}
+	th.AssertEquals(t, 1, count)
 }
 
 func TestAPIInfo(t *testing.T) {
@@ -129,9 +124,7 @@
 	})
 
 	actual, err := Get(client.ServiceClient(), "v1").Extract()
-	if err != nil {
-		t.Errorf("Failed to extract version: %v", err)
-	}
+	th.AssertNoErr(t, err)
 
 	expected := APIVersion{
 		ID:      "v1.0",
diff --git a/openstack/blockstorage/v1/apiversions/results.go b/openstack/blockstorage/v1/apiversions/results.go
index 854f8dd..79a89de 100644
--- a/openstack/blockstorage/v1/apiversions/results.go
+++ b/openstack/blockstorage/v1/apiversions/results.go
@@ -3,15 +3,13 @@
 import (
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
-
-	"github.com/mitchellh/mapstructure"
 )
 
 // APIVersion represents an API version for Cinder.
 type APIVersion struct {
-	ID      string `json:"id" mapstructure:"id"`           // unique identifier
-	Status  string `json:"status" mapstructure:"status"`   // current status
-	Updated string `json:"updated" mapstructure:"updated"` // date last updated
+	ID      string `json:"id"`      // unique identifier
+	Status  string `json:"status"`  // current status
+	Updated string `json:"updated"` // date last updated
 }
 
 // APIVersionPage is the page returned by a pager when traversing over a
@@ -23,22 +21,18 @@
 // IsEmpty checks whether an APIVersionPage struct is empty.
 func (r APIVersionPage) IsEmpty() (bool, error) {
 	is, err := ExtractAPIVersions(r)
-	if err != nil {
-		return true, err
-	}
-	return len(is) == 0, nil
+	return len(is) == 0, err
 }
 
 // ExtractAPIVersions takes a collection page, extracts all of the elements,
 // and returns them a slice of APIVersion structs. It is effectively a cast.
 func ExtractAPIVersions(page pagination.Page) ([]APIVersion, error) {
-	var resp struct {
-		Versions []APIVersion `mapstructure:"versions"`
+	r := page.(APIVersionPage)
+	var s struct {
+		Versions []APIVersion `json:"versions"`
 	}
-
-	err := mapstructure.Decode(page.(APIVersionPage).Body, &resp)
-
-	return resp.Versions, err
+	err := r.ExtractInto(&s)
+	return s.Versions, err
 }
 
 // GetResult represents the result of a get operation.
@@ -48,11 +42,9 @@
 
 // Extract is a function that accepts a result and extracts an API version resource.
 func (r GetResult) Extract() (*APIVersion, error) {
-	var resp struct {
-		Version *APIVersion `mapstructure:"version"`
+	var s struct {
+		Version *APIVersion `json:"version"`
 	}
-
-	err := mapstructure.Decode(r.Body, &resp)
-
-	return resp.Version, err
+	err := r.ExtractInto(&s)
+	return s.Version, err
 }
diff --git a/openstack/blockstorage/v1/snapshots/requests.go b/openstack/blockstorage/v1/snapshots/requests.go
index 5e9f55c..b3b3cff 100644
--- a/openstack/blockstorage/v1/snapshots/requests.go
+++ b/openstack/blockstorage/v1/snapshots/requests.go
@@ -124,7 +124,7 @@
 	}
 
 	createPage := func(r pagination.PageResult) pagination.Page {
-		return ListResult{pagination.SinglePageBase(r)}
+		return SnapshotPage{pagination.SinglePageBase(r)}
 	}
 	return pagination.NewPager(client, url, createPage)
 }
diff --git a/openstack/blockstorage/v1/snapshots/results.go b/openstack/blockstorage/v1/snapshots/results.go
index 71d1489..f0f8864 100644
--- a/openstack/blockstorage/v1/snapshots/results.go
+++ b/openstack/blockstorage/v1/snapshots/results.go
@@ -3,50 +3,48 @@
 import (
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
-
-	"github.com/mitchellh/mapstructure"
 )
 
 // Snapshot contains all the information associated with an OpenStack Snapshot.
 type Snapshot struct {
 	// Currect status of the Snapshot.
-	Status string `mapstructure:"status"`
+	Status string `json:"status"`
 
 	// Display name.
-	Name string `mapstructure:"display_name"`
+	Name string `json:"display_name"`
 
 	// Instances onto which the Snapshot is attached.
-	Attachments []string `mapstructure:"attachments"`
+	Attachments []string `json:"attachments"`
 
 	// Logical group.
-	AvailabilityZone string `mapstructure:"availability_zone"`
+	AvailabilityZone string `json:"availability_zone"`
 
 	// Is the Snapshot bootable?
-	Bootable string `mapstructure:"bootable"`
+	Bootable string `json:"bootable"`
 
 	// Date created.
-	CreatedAt string `mapstructure:"created_at"`
+	CreatedAt gophercloud.JSONRFC3339Milli `json:"created_at"`
 
 	// Display description.
-	Description string `mapstructure:"display_discription"`
+	Description string `json:"display_discription"`
 
 	// See VolumeType object for more information.
-	VolumeType string `mapstructure:"volume_type"`
+	VolumeType string `json:"volume_type"`
 
 	// ID of the Snapshot from which this Snapshot was created.
-	SnapshotID string `mapstructure:"snapshot_id"`
+	SnapshotID string `json:"snapshot_id"`
 
 	// ID of the Volume from which this Snapshot was created.
-	VolumeID string `mapstructure:"volume_id"`
+	VolumeID string `json:"volume_id"`
 
 	// User-defined key-value pairs.
-	Metadata map[string]string `mapstructure:"metadata"`
+	Metadata map[string]string `json:"metadata"`
 
 	// Unique identifier.
-	ID string `mapstructure:"id"`
+	ID string `json:"id"`
 
 	// Size of the Snapshot, in GB.
-	Size int `mapstructure:"size"`
+	Size int `json:"size"`
 }
 
 // CreateResult contains the response body and error from a Create request.
@@ -64,28 +62,25 @@
 	gophercloud.ErrResult
 }
 
-// ListResult is a pagination.Pager that is returned from a call to the List function.
-type ListResult struct {
+// SnapshotPage is a pagination.Pager that is returned from a call to the List function.
+type SnapshotPage struct {
 	pagination.SinglePageBase
 }
 
-// IsEmpty returns true if a ListResult contains no Snapshots.
-func (r ListResult) IsEmpty() (bool, error) {
+// IsEmpty returns true if a SnapshotPage contains no Snapshots.
+func (r SnapshotPage) IsEmpty() (bool, error) {
 	volumes, err := ExtractSnapshots(r)
-	if err != nil {
-		return true, err
-	}
-	return len(volumes) == 0, nil
+	return len(volumes) == 0, err
 }
 
 // ExtractSnapshots extracts and returns Snapshots. It is used while iterating over a snapshots.List call.
 func ExtractSnapshots(page pagination.Page) ([]Snapshot, error) {
-	var response struct {
+	r := page.(SnapshotPage)
+	var s struct {
 		Snapshots []Snapshot `json:"snapshots"`
 	}
-
-	err := mapstructure.Decode(page.(ListResult).Body, &response)
-	return response.Snapshots, err
+	err := r.ExtractInto(&s)
+	return s.Snapshots, err
 }
 
 // UpdateMetadataResult contains the response body and error from an UpdateMetadata request.
@@ -109,15 +104,9 @@
 
 // Extract will get the Snapshot object out of the commonResult object.
 func (r commonResult) Extract() (*Snapshot, error) {
-	if r.Err != nil {
-		return nil, r.Err
-	}
-
-	var res struct {
+	var s struct {
 		Snapshot *Snapshot `json:"snapshot"`
 	}
-
-	err := mapstructure.Decode(r.Body, &res)
-
-	return res.Snapshot, err
+	err := r.ExtractInto(&s)
+	return s.Snapshot, err
 }
diff --git a/openstack/blockstorage/v1/volumes/requests.go b/openstack/blockstorage/v1/volumes/requests.go
index 96da8f4..6525d8b 100644
--- a/openstack/blockstorage/v1/volumes/requests.go
+++ b/openstack/blockstorage/v1/volumes/requests.go
@@ -143,7 +143,7 @@
 		url += query
 	}
 	createPage := func(r pagination.PageResult) pagination.Page {
-		return ListResult{pagination.SinglePageBase(r)}
+		return VolumePage{pagination.SinglePageBase(r)}
 	}
 
 	return pagination.NewPager(client, url, createPage)
diff --git a/openstack/blockstorage/v1/volumes/requests_test.go b/openstack/blockstorage/v1/volumes/requests_test.go
index 56139dd..436cfdc 100644
--- a/openstack/blockstorage/v1/volumes/requests_test.go
+++ b/openstack/blockstorage/v1/volumes/requests_test.go
@@ -2,7 +2,9 @@
 
 import (
 	"testing"
+	"time"
 
+	"github.com/gophercloud/gophercloud"
 	fixtures "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes/testing"
 	"github.com/gophercloud/gophercloud/pagination"
 	th "github.com/gophercloud/gophercloud/testhelper"
@@ -78,12 +80,37 @@
 
 	fixtures.MockGetResponse(t)
 
-	v, err := Get(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract()
+	actual, err := Get(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract()
 	th.AssertNoErr(t, err)
 
-	th.AssertEquals(t, v.Name, "vol-001")
-	th.AssertEquals(t, v.ID, "d32019d3-bc6e-4319-9c1d-6722fc136a22")
-	th.AssertEquals(t, v.Attachments[0]["device"], "/dev/vde")
+	expected := &Volume{
+		Status: "active",
+		Name:   "vol-001",
+		Attachments: []map[string]interface{}{
+			{
+				"attachment_id": "03987cd1-0ad5-40d1-9b2a-7cc48295d4fa",
+				"id":            "47e9ecc5-4045-4ee3-9a4b-d859d546a0cf",
+				"volume_id":     "6c80f8ac-e3e2-480c-8e6e-f1db92fe4bfe",
+				"server_id":     "d1c4788b-9435-42e2-9b81-29f3be1cd01f",
+				"host_name":     "mitaka",
+				"device":        "/",
+			},
+		},
+		AvailabilityZone: "us-east1",
+		Bootable:         "false",
+		CreatedAt:        gophercloud.JSONRFC3339Milli(time.Date(2012, 2, 14, 20, 53, 07, 0, time.UTC)),
+		Description:      "Another volume.",
+		VolumeType:       "289da7f8-6440-407c-9fb4-7db01ec49164",
+		SnapshotID:       "",
+		SourceVolID:      "",
+		Metadata: map[string]string{
+			"contents": "junk",
+		},
+		ID:   "521752a6-acf6-4b2d-bc7a-119f9148cd8c",
+		Size: 30,
+	}
+
+	th.AssertDeepEquals(t, expected, actual)
 }
 
 func TestCreate(t *testing.T) {
diff --git a/openstack/blockstorage/v1/volumes/results.go b/openstack/blockstorage/v1/volumes/results.go
index ee584d3..6371840 100644
--- a/openstack/blockstorage/v1/volumes/results.go
+++ b/openstack/blockstorage/v1/volumes/results.go
@@ -3,50 +3,48 @@
 import (
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
-
-	"github.com/mitchellh/mapstructure"
 )
 
 // Volume contains all the information associated with an OpenStack Volume.
 type Volume struct {
 	// Current status of the volume.
-	Status string `mapstructure:"status"`
+	Status string `json:"status"`
 
 	// Human-readable display name for the volume.
-	Name string `mapstructure:"display_name"`
+	Name string `json:"display_name"`
 
 	// Instances onto which the volume is attached.
-	Attachments []map[string]interface{} `mapstructure:"attachments"`
+	Attachments []map[string]interface{} `json:"attachments"`
 
 	// This parameter is no longer used.
-	AvailabilityZone string `mapstructure:"availability_zone"`
+	AvailabilityZone string `json:"availability_zone"`
 
 	// Indicates whether this is a bootable volume.
-	Bootable string `mapstructure:"bootable"`
+	Bootable string `json:"bootable"`
 
 	// The date when this volume was created.
-	CreatedAt string `mapstructure:"created_at"`
+	CreatedAt gophercloud.JSONRFC3339Milli `json:"created_at"`
 
 	// Human-readable description for the volume.
-	Description string `mapstructure:"display_description"`
+	Description string `json:"display_description"`
 
 	// The type of volume to create, either SATA or SSD.
-	VolumeType string `mapstructure:"volume_type"`
+	VolumeType string `json:"volume_type"`
 
 	// The ID of the snapshot from which the volume was created
-	SnapshotID string `mapstructure:"snapshot_id"`
+	SnapshotID string `json:"snapshot_id"`
 
 	// The ID of another block storage volume from which the current volume was created
-	SourceVolID string `mapstructure:"source_volid"`
+	SourceVolID string `json:"source_volid"`
 
 	// Arbitrary key-value pairs defined by the user.
-	Metadata map[string]string `mapstructure:"metadata"`
+	Metadata map[string]string `json:"metadata"`
 
 	// Unique identifier for the volume.
-	ID string `mapstructure:"id"`
+	ID string `json:"id"`
 
 	// Size of the volume in GB.
-	Size int `mapstructure:"size"`
+	Size int `json:"size"`
 }
 
 // CreateResult contains the response body and error from a Create request.
@@ -64,28 +62,25 @@
 	gophercloud.ErrResult
 }
 
-// ListResult is a pagination.pager that is returned from a call to the List function.
-type ListResult struct {
+// VolumePage is a pagination.pager that is returned from a call to the List function.
+type VolumePage struct {
 	pagination.SinglePageBase
 }
 
-// IsEmpty returns true if a ListResult contains no Volumes.
-func (r ListResult) IsEmpty() (bool, error) {
+// IsEmpty returns true if a VolumePage contains no Volumes.
+func (r VolumePage) IsEmpty() (bool, error) {
 	volumes, err := ExtractVolumes(r)
-	if err != nil {
-		return true, err
-	}
-	return len(volumes) == 0, nil
+	return len(volumes) == 0, err
 }
 
 // ExtractVolumes extracts and returns Volumes. It is used while iterating over a volumes.List call.
 func ExtractVolumes(page pagination.Page) ([]Volume, error) {
-	var response struct {
+	r := page.(VolumePage)
+	var s struct {
 		Volumes []Volume `json:"volumes"`
 	}
-
-	err := mapstructure.Decode(page.(ListResult).Body, &response)
-	return response.Volumes, err
+	err := r.ExtractInto(&s)
+	return s.Volumes, err
 }
 
 // UpdateResult contains the response body and error from an Update request.
@@ -99,15 +94,9 @@
 
 // Extract will get the Volume object out of the commonResult object.
 func (r commonResult) Extract() (*Volume, error) {
-	if r.Err != nil {
-		return nil, r.Err
-	}
-
-	var res struct {
+	var s struct {
 		Volume *Volume `json:"volume"`
 	}
-
-	err := mapstructure.Decode(r.Body, &res)
-
-	return res.Volume, err
+	err := r.ExtractInto(&s)
+	return s.Volume, err
 }
diff --git a/openstack/blockstorage/v1/volumes/testing/fixtures.go b/openstack/blockstorage/v1/volumes/testing/fixtures.go
index b72fed0..421cbf4 100644
--- a/openstack/blockstorage/v1/volumes/testing/fixtures.go
+++ b/openstack/blockstorage/v1/volumes/testing/fixtures.go
@@ -42,20 +42,33 @@
 		w.Header().Add("Content-Type", "application/json")
 		w.WriteHeader(http.StatusOK)
 		fmt.Fprintf(w, `
-{
-    "volume": {
-        "display_name": "vol-001",
-        "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22",
- 	"attachments": [
-	  {
-            "device": "/dev/vde",
-            "server_id": "a740d24b-dc5b-4d59-ac75-53971c2920ba",
-            "id": "d6da11e5-2ed3-413e-88d8-b772ba62193d",
-            "volume_id": "d6da11e5-2ed3-413e-88d8-b772ba62193d"
-          }
-        ]
-   }
-}
+			{
+			    "volume": {
+			        "id": "521752a6-acf6-4b2d-bc7a-119f9148cd8c",
+			        "display_name": "vol-001",
+			        "display_description": "Another volume.",
+			        "status": "active",
+			        "size": 30,
+			        "volume_type": "289da7f8-6440-407c-9fb4-7db01ec49164",
+			        "metadata": {
+			            "contents": "junk"
+			        },
+			        "availability_zone": "us-east1",
+			        "bootable": "false",
+			        "snapshot_id": null,
+			        "attachments": [
+			            {
+			                "attachment_id": "03987cd1-0ad5-40d1-9b2a-7cc48295d4fa",
+			                "id": "47e9ecc5-4045-4ee3-9a4b-d859d546a0cf",
+			                "volume_id": "6c80f8ac-e3e2-480c-8e6e-f1db92fe4bfe",
+			                "server_id": "d1c4788b-9435-42e2-9b81-29f3be1cd01f",
+			                "host_name": "mitaka",
+			                "device": "/"
+			            }
+			        ],
+			        "created_at": "2012-02-14T20:53:07Z"
+			    }
+			}
       `)
 	})
 }
diff --git a/openstack/blockstorage/v1/volumetypes/requests.go b/openstack/blockstorage/v1/volumetypes/requests.go
index 50ace44..24e50ad 100644
--- a/openstack/blockstorage/v1/volumetypes/requests.go
+++ b/openstack/blockstorage/v1/volumetypes/requests.go
@@ -69,7 +69,7 @@
 // List returns all volume types.
 func List(client *gophercloud.ServiceClient) pagination.Pager {
 	createPage := func(r pagination.PageResult) pagination.Page {
-		return ListResult{pagination.SinglePageBase(r)}
+		return VolumeTypePage{pagination.SinglePageBase(r)}
 	}
 
 	return pagination.NewPager(client, listURL(client), createPage)
diff --git a/openstack/blockstorage/v1/volumetypes/results.go b/openstack/blockstorage/v1/volumetypes/results.go
index 5948e8f..74e193f 100644
--- a/openstack/blockstorage/v1/volumetypes/results.go
+++ b/openstack/blockstorage/v1/volumetypes/results.go
@@ -1,16 +1,15 @@
 package volumetypes
 
 import (
-	"github.com/mitchellh/mapstructure"
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
 )
 
 // VolumeType contains all information associated with an OpenStack Volume Type.
 type VolumeType struct {
-	ExtraSpecs map[string]interface{} `json:"extra_specs" mapstructure:"extra_specs"` // user-defined metadata
-	ID         string                 `json:"id" mapstructure:"id"`                   // unique identifier
-	Name       string                 `json:"name" mapstructure:"name"`               // display name
+	ExtraSpecs map[string]interface{} `json:"extra_specs"` // user-defined metadata
+	ID         string                 `json:"id"`          // unique identifier
+	Name       string                 `json:"name"`        // display name
 }
 
 // CreateResult contains the response body and error from a Create request.
@@ -28,28 +27,25 @@
 	gophercloud.ErrResult
 }
 
-// ListResult is a pagination.Pager that is returned from a call to the List function.
-type ListResult struct {
+// VolumeTypePage is a pagination.Pager that is returned from a call to the List function.
+type VolumeTypePage struct {
 	pagination.SinglePageBase
 }
 
-// IsEmpty returns true if a ListResult contains no Volume Types.
-func (r ListResult) IsEmpty() (bool, error) {
+// IsEmpty returns true if a VolumeTypePage contains no Volume Types.
+func (r VolumeTypePage) IsEmpty() (bool, error) {
 	volumeTypes, err := ExtractVolumeTypes(r)
-	if err != nil {
-		return true, err
-	}
-	return len(volumeTypes) == 0, nil
+	return len(volumeTypes) == 0, err
 }
 
 // ExtractVolumeTypes extracts and returns Volume Types.
 func ExtractVolumeTypes(page pagination.Page) ([]VolumeType, error) {
-	var response struct {
-		VolumeTypes []VolumeType `mapstructure:"volume_types"`
+	r := page.(VolumeTypePage)
+	var s struct {
+		VolumeTypes []VolumeType `json:"volume_types"`
 	}
-
-	err := mapstructure.Decode(page.(ListResult).Body, &response)
-	return response.VolumeTypes, err
+	err := r.ExtractInto(&s)
+	return s.VolumeTypes, err
 }
 
 type commonResult struct {
@@ -58,15 +54,9 @@
 
 // Extract will get the Volume Type object out of the commonResult object.
 func (r commonResult) Extract() (*VolumeType, error) {
-	if r.Err != nil {
-		return nil, r.Err
+	var s struct {
+		VolumeType *VolumeType `json:"volume_type"`
 	}
-
-	var res struct {
-		VolumeType *VolumeType `json:"volume_type" mapstructure:"volume_type"`
-	}
-
-	err := mapstructure.Decode(r.Body, &res)
-
-	return res.VolumeType, err
+	err := r.ExtractInto(&s)
+	return s.VolumeType, err
 }