initial paging implementation and create volume rewrite
diff --git a/openstack/blockstorage/v1/volumes/requests.go b/openstack/blockstorage/v1/volumes/requests.go
index c4a72c2..18f8a41 100644
--- a/openstack/blockstorage/v1/volumes/requests.go
+++ b/openstack/blockstorage/v1/volumes/requests.go
@@ -2,47 +2,95 @@
 
 import (
 	"github.com/racker/perigee"
-	blockstorage "github.com/rackspace/gophercloud/openstack/blockstorage/v1"
+	"github.com/rackspace/gophercloud"
+	"github.com/rackspace/gophercloud/pagination"
+	"github.com/rackspace/gophercloud/utils"
 )
 
-func Create(c *blockstorage.Client, opts CreateOpts) (Volume, error) {
-	var v Volume
-	h, err := c.GetHeaders()
-	if err != nil {
-		return v, err
-	}
-	url := c.GetVolumesURL()
-	_, err = perigee.Request("POST", url, perigee.Options{
-		Results: &struct {
-			Volume *Volume `json:"volume"`
-		}{&v},
-		ReqBody: map[string]interface{}{
-			"volume": opts,
-		},
-		MoreHeaders: h,
-	})
-	return v, err
+type VolumeOpts struct {
+	Availability string
+	Description  string
+	ImageID      string
+	Metadata     map[string]string
+	Name         string
+	Size         int
+	SnapshotID   string
+	Type         string
 }
 
-func List(c *blockstorage.Client, opts ListOpts) ([]Volume, error) {
-	var v []Volume
-	var url string
-	h, err := c.GetHeaders()
-	if err != nil {
-		return v, err
+func Create(client *gophercloud.ServiceClient, opts VolumeOpts) (Volume, error) {
+
+	type volume struct {
+		Availability *string           `json:"availability_zone,omitempty"`
+		Description  *string           `json:"display_description,omitempty"`
+		ImageID      *string           `json:"imageRef,omitempty"`
+		Metadata     map[string]string `json:"metadata,omitempty"`
+		Name         *string           `json:"display_name,omitempty"`
+		Size         *int              `json:"size,omitempty"`
+		SnapshotID   *string           `json:"snapshot_id,omitempty"`
+		SourceVolID  *string           `json:"source_volid,omitempty"`
+		VolumeType   *string           `json:"volume_type,omitempty"`
 	}
-	if full := opts["full"]; full {
-		url = c.GetVolumesURL()
-	} else {
-		url = c.GetVolumeURL("detail")
+
+	type request struct {
+		Volume volume `json:"volume"`
 	}
-	_, err = perigee.Request("GET", url, perigee.Options{
-		Results: &struct {
-			Volume *[]Volume `json:"volumes"`
-		}{&v},
-		MoreHeaders: h,
+
+	reqBody := request{
+		Volume: volume{},
+	}
+
+	reqBody.Volume.Availability = utils.MaybeString(opts.Availability)
+	reqBody.Volume.Description = utils.MaybeString(opts.Description)
+	reqBody.Volume.ImageID = utils.MaybeString(opts.ImageID)
+	reqBody.Volume.Name = utils.MaybeString(opts.Name)
+	reqBody.Volume.Size = utils.MaybeInt(opts.Size)
+	reqBody.Volume.SnapshotID = utils.MaybeString(opts.SnapshotID)
+	reqBody.Volume.SourceVolID = utils.MaybeString(opts.SourceVolID)
+	reqBody.Volume.VolumeType = utils.MaybeString(opts.VolumeType)
+
+	type response struct {
+		Volume Volume `json:"volume"`
+	}
+
+	var respBody response
+
+	_, err = perigee.Request("POST", volumesURL(client), perigee.Options{
+		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		OkCodes:     []int{201},
+		ReqBody:     &reqBody,
+		Results:     &respBody,
 	})
-	return v, err
+	if err != nil {
+		return nil, err
+	}
+
+	return &respBody.Volume, nil
+}
+
+func List(client *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
+	var url string
+
+	query := utils.BuildQuery(opts.Params)
+
+	if !opts.Full {
+		url = c.volumesURL()
+	} else {
+		url = c.volumeURL("detail")
+	}
+
+	createPage := func(r pagination.LastHTTPResponse) pagination.Page {
+		p := ListResult{
+			pagination.MarkerPageBase{
+				LastHTTPResponse: r,
+			},
+		}
+		p.MarkerPageBase.Owner = p
+		return p
+	}
+
+	pager := pagination.NewPager(client, url, createPage)
+	return pager
 }
 
 func Get(c *blockstorage.Client, opts GetOpts) (Volume, error) {
diff --git a/openstack/blockstorage/v1/volumes/volumes.go b/openstack/blockstorage/v1/volumes/volumes.go
index 8120863..230543c 100644
--- a/openstack/blockstorage/v1/volumes/volumes.go
+++ b/openstack/blockstorage/v1/volumes/volumes.go
@@ -1,20 +1,48 @@
 package volumes
 
+import (
+	"github.com/rackspace/gophercloud/pagination"
+
+	"github.com/mitchellh/mapstructure"
+)
+
 type Volume struct {
-	Status              string
-	Display_name        string
-	Attachments         []string
-	Availability_zone   string
-	Bootable            bool
-	Created_at          string
-	Display_description string
-	Volume_type         string
-	Snapshot_id         string
-	Source_volid        string
-	Metadata            map[string]string
-	Id                  string
-	Size                int
+	Status           string
+	Name             string
+	Attachments      []string
+	AvailabilityZone string
+	Bootable         bool
+	CreatedAt        string
+	Description      string
+	VolumeType       string
+	SnapshotID       string
+	SourceVolID      string
+	Metadata         map[string]string
+	Id               string
+	Size             int
 }
+
+type VolumePage struct {
+	pagination.LinkedPageBase
+}
+
+func (p VolumPage) IsEmpty() (bool, error) {
+	volumes, err := ExtractVolumes(p)
+	if err != nil {
+		return true, err
+	}
+	return len(volumes) == 0, nil
+}
+
+func ExtractVolumes(page pagination.page) ([]Volume, error) {
+	var response struct {
+		Volumes []Volume `json:"volumes"`
+	}
+
+	err := mapstructure.Decode(page.(VolumePage).Body, &response)
+	return response.Volumes, err
+}
+
 type CreateOpts map[string]interface{}
 type ListOpts map[string]bool
 type GetOpts map[string]string