Finalizing snapshots
diff --git a/rackspace/blockstorage/snapshots/results.go b/rackspace/blockstorage/snapshots/results.go
deleted file mode 100644
index c2c608e..0000000
--- a/rackspace/blockstorage/snapshots/results.go
+++ /dev/null
@@ -1,85 +0,0 @@
-package snapshots
-
-import (
-	"github.com/rackspace/gophercloud"
-	os "github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots"
-
-	"github.com/mitchellh/mapstructure"
-)
-
-// Status is the type used to represent a snapshot's status
-type Status string
-
-// Constants to use for supported statuses
-const (
-	Creating    Status = "CREATING"
-	Available   Status = "AVAILABLE"
-	Deleting    Status = "DELETING"
-	Error       Status = "ERROR"
-	DeleteError Status = "ERROR_DELETING"
-)
-
-// Snapshot is the Rackspace representation of an external block storage device.
-type Snapshot struct {
-	// The timestamp when this snapshot was created.
-	CreatedAt string `mapstructure:"created_at"`
-
-	// The human-readable description for this snapshot.
-	Description string `mapstructure:"display_description"`
-
-	// The human-readable name for this snapshot.
-	Name string `mapstructure:"display_name"`
-
-	// The UUID for this snapshot.
-	ID string `mapstructure:"id"`
-
-	// The random metadata associated with this snapshot. Note: unlike standard
-	// OpenStack snapshots, this cannot actually be set.
-	Metadata map[string]string `mapstructure:"metadata"`
-
-	// Indicates the current progress of the snapshot's backup procedure.
-	Progress string `mapstructure:"os-extended-snapshot-attributes:progress"`
-
-	// The project ID.
-	ProjectID string `mapstructure:"os-extended-snapshot-attributes:project_id"`
-
-	// The size of the volume which this snapshot backs up.
-	Size int `mapstructure:"size"`
-
-	// The status of the snapshot.
-	Status Status `mapstructure:"status"`
-
-	// The ID of the volume which this snapshot seeks to back up.
-	VolumeID string `mapstructure:"volume_id"`
-}
-
-type commonResult struct {
-	gophercloud.CommonResult
-}
-
-// CreateResult represents the result of a create operation
-type CreateResult struct {
-	Common os.CreateResult
-	commonResult
-}
-
-// GetResult represents the result of a get operation
-type GetResult struct {
-	Common os.GetResult
-	commonResult
-}
-
-// 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 {
-		Snapshot *Snapshot `json:"snapshot"`
-	}
-
-	err := mapstructure.Decode(r.Resp, &res)
-
-	return res.Snapshot, err
-}
diff --git a/rackspace/blockstorage/v1/snapshots/delegate.go b/rackspace/blockstorage/v1/snapshots/delegate.go
index fa87360..345d2fe 100644
--- a/rackspace/blockstorage/v1/snapshots/delegate.go
+++ b/rackspace/blockstorage/v1/snapshots/delegate.go
@@ -3,12 +3,18 @@
 import (
 	"fmt"
 
+	"github.com/racker/perigee"
+
 	"github.com/rackspace/gophercloud"
 	"github.com/rackspace/gophercloud/pagination"
 
 	os "github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots"
 )
 
+func updateURL(c *gophercloud.ServiceClient, id string) string {
+	return c.ServiceURL("snapshots", id)
+}
+
 // CreateOptsBuilder allows extensions to add additional parameters to the
 // Create request.
 type CreateOptsBuilder interface {
@@ -75,3 +81,54 @@
 func List(client *gophercloud.ServiceClient) pagination.Pager {
 	return os.List(client, os.ListOpts{})
 }
+
+// UpdateOptsBuilder is the interface options structs have to satisfy in order
+// to be used in the main Update operation in this package. Since many
+// extensions decorate or modify the common logic, it is useful for them to
+// satisfy a basic interface in order for them to be used.
+type UpdateOptsBuilder interface {
+	ToSnapshotUpdateMap() (map[string]interface{}, error)
+}
+
+// UpdateOpts is the common options struct used in this package's Update
+// operation.
+type UpdateOpts struct {
+	Name        string
+	Description string
+}
+
+// ToSnapshotUpdateMap casts a UpdateOpts struct to a map.
+func (opts UpdateOpts) ToSnapshotUpdateMap() (map[string]interface{}, error) {
+	s := make(map[string]interface{})
+
+	if opts.Name != "" {
+		s["display_name"] = opts.Name
+	}
+	if opts.Description != "" {
+		s["display_description"] = opts.Description
+	}
+
+	return map[string]interface{}{"snapshot": s}, nil
+}
+
+// Update accepts a UpdateOpts struct and updates an existing snapshot using the
+// values provided.
+func Update(c *gophercloud.ServiceClient, snapshotID string, opts UpdateOptsBuilder) UpdateResult {
+	var res UpdateResult
+
+	reqBody, err := opts.ToSnapshotUpdateMap()
+	if err != nil {
+		res.Err = err
+		return res
+	}
+
+	// Send request to API
+	_, res.Err = perigee.Request("PUT", updateURL(c, snapshotID), perigee.Options{
+		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		ReqBody:     &reqBody,
+		Results:     &res.Resp,
+		OkCodes:     []int{200, 201},
+	})
+
+	return res
+}
diff --git a/rackspace/blockstorage/v1/snapshots/delegate_test.go b/rackspace/blockstorage/v1/snapshots/delegate_test.go
index 45ab0ac..5c027a2 100644
--- a/rackspace/blockstorage/v1/snapshots/delegate_test.go
+++ b/rackspace/blockstorage/v1/snapshots/delegate_test.go
@@ -3,12 +3,25 @@
 import (
 	"testing"
 
+	"github.com/rackspace/gophercloud"
 	os "github.com/rackspace/gophercloud/openstack/blockstorage/v1/snapshots"
 	"github.com/rackspace/gophercloud/pagination"
 	th "github.com/rackspace/gophercloud/testhelper"
 	fake "github.com/rackspace/gophercloud/testhelper/client"
 )
 
+const endpoint = "http://localhost:57909/v1/12345"
+
+func endpointClient() *gophercloud.ServiceClient {
+	return &gophercloud.ServiceClient{Endpoint: endpoint}
+}
+
+func TestUpdateURL(t *testing.T) {
+	actual := updateURL(endpointClient(), "foo")
+	expected := endpoint + "snapshots/foo"
+	th.AssertEquals(t, expected, actual)
+}
+
 func TestList(t *testing.T) {
 	th.SetupHTTP()
 	defer th.TeardownHTTP()
diff --git a/rackspace/blockstorage/v1/snapshots/results.go b/rackspace/blockstorage/v1/snapshots/results.go
index b35e719..9acf0bb 100644
--- a/rackspace/blockstorage/v1/snapshots/results.go
+++ b/rackspace/blockstorage/v1/snapshots/results.go
@@ -68,6 +68,11 @@
 	os.GetResult
 }
 
+// UpdateResult represents the result of an update operation
+type UpdateResult struct {
+	gophercloud.CommonResult
+}
+
 func commonExtract(resp map[string]interface{}, err error) (*Snapshot, error) {
 	if err != nil {
 		return nil, err
@@ -92,6 +97,11 @@
 	return commonExtract(r.Resp, r.Err)
 }
 
+// Extract will get the Snapshot object out of the UpdateResult object.
+func (r UpdateResult) Extract() (*Snapshot, error) {
+	return commonExtract(r.Resp, r.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 {