objectstorage v1 and orchestration v1 struct tags
diff --git a/openstack/objectstorage/v1/accounts/requests.go b/openstack/objectstorage/v1/accounts/requests.go
index f50cf97..41479a2 100644
--- a/openstack/objectstorage/v1/accounts/requests.go
+++ b/openstack/objectstorage/v1/accounts/requests.go
@@ -24,30 +24,27 @@
 // all the headers that are returned (including the metadata), call the
 // ExtractHeader method on the GetResult.
 func Get(c *gophercloud.ServiceClient, opts GetOptsBuilder) GetResult {
-	var res GetResult
-	h := c.AuthenticatedHeaders()
-
+	var r GetResult
+	h := make(map[string]string)
 	if opts != nil {
 		headers, err := opts.ToAccountGetMap()
 		if err != nil {
-			res.Err = err
-			return res
+			r.Err = err
+			return r
 		}
-
 		for k, v := range headers {
 			h[k] = v
 		}
 	}
-
 	resp, err := c.Request("HEAD", getURL(c), &gophercloud.RequestOpts{
 		MoreHeaders: h,
 		OkCodes:     []int{204},
 	})
 	if resp != nil {
-		res.Header = resp.Header
+		r.Header = resp.Header
 	}
-	res.Err = err
-	return res
+	r.Err = err
+	return r
 }
 
 // UpdateOptsBuilder allows extensions to add additional headers to the Update
@@ -81,27 +78,25 @@
 // Update is a function that creates, updates, or deletes an account's metadata.
 // To extract the headers returned, call the Extract method on the UpdateResult.
 func Update(c *gophercloud.ServiceClient, opts UpdateOptsBuilder) UpdateResult {
-	var res UpdateResult
+	var r UpdateResult
 	h := make(map[string]string)
-
 	if opts != nil {
 		headers, err := opts.ToAccountUpdateMap()
 		if err != nil {
-			res.Err = err
-			return res
+			r.Err = err
+			return r
 		}
 		for k, v := range headers {
 			h[k] = v
 		}
 	}
-
 	resp, err := c.Request("POST", updateURL(c), &gophercloud.RequestOpts{
 		MoreHeaders: h,
 		OkCodes:     []int{201, 202, 204},
 	})
 	if resp != nil {
-		res.Header = resp.Header
+		r.Header = resp.Header
 	}
-	res.Err = err
-	return res
+	r.Err = err
+	return r
 }
diff --git a/openstack/objectstorage/v1/containers/requests.go b/openstack/objectstorage/v1/containers/requests.go
index b2160c3..f575ea7 100644
--- a/openstack/objectstorage/v1/containers/requests.go
+++ b/openstack/objectstorage/v1/containers/requests.go
@@ -26,10 +26,7 @@
 // representing whether to list complete information for each container.
 func (opts ListOpts) ToContainerListParams() (bool, string, error) {
 	q, err := gophercloud.BuildQueryString(opts)
-	if err != nil {
-		return false, "", err
-	}
-	return opts.Full, q.String(), nil
+	return opts.Full, q.String(), err
 }
 
 // List is a function that retrieves containers associated with the account as
@@ -51,13 +48,11 @@
 		}
 	}
 
-	createPage := func(r pagination.PageResult) pagination.Page {
+	pager := pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page {
 		p := ContainerPage{pagination.MarkerPageBase{PageResult: r}}
 		p.MarkerPageBase.Owner = p
 		return p
-	}
-
-	pager := pagination.NewPager(c, url, createPage)
+	})
 	pager.Headers = headers
 	return pager
 }
@@ -95,37 +90,34 @@
 
 // Create is a function that creates a new container.
 func Create(c *gophercloud.ServiceClient, containerName string, opts CreateOptsBuilder) CreateResult {
-	var res CreateResult
-	h := c.AuthenticatedHeaders()
-
+	var r CreateResult
+	h := make(map[string]string)
 	if opts != nil {
 		headers, err := opts.ToContainerCreateMap()
 		if err != nil {
-			res.Err = err
-			return res
+			r.Err = err
+			return r
 		}
-
 		for k, v := range headers {
 			h[k] = v
 		}
 	}
-
 	resp, err := c.Request("PUT", createURL(c, containerName), &gophercloud.RequestOpts{
 		MoreHeaders: h,
 		OkCodes:     []int{201, 202, 204},
 	})
 	if resp != nil {
-		res.Header = resp.Header
+		r.Header = resp.Header
 	}
-	res.Err = err
-	return res
+	r.Err = err
+	return r
 }
 
 // Delete is a function that deletes a container.
 func Delete(c *gophercloud.ServiceClient, containerName string) DeleteResult {
-	var res DeleteResult
-	_, res.Err = c.Delete(deleteURL(c, containerName), nil)
-	return res
+	var r DeleteResult
+	_, r.Err = c.Delete(deleteURL(c, containerName), nil)
+	return r
 }
 
 // UpdateOptsBuilder allows extensions to add additional parameters to the
@@ -163,43 +155,41 @@
 // Update is a function that creates, updates, or deletes a container's
 // metadata.
 func Update(c *gophercloud.ServiceClient, containerName string, opts UpdateOptsBuilder) UpdateResult {
-	var res UpdateResult
-	h := c.AuthenticatedHeaders()
-
+	var r UpdateResult
+	h := make(map[string]string)
 	if opts != nil {
 		headers, err := opts.ToContainerUpdateMap()
 		if err != nil {
-			res.Err = err
-			return res
+			r.Err = err
+			return r
 		}
 
 		for k, v := range headers {
 			h[k] = v
 		}
 	}
-
 	resp, err := c.Request("POST", updateURL(c, containerName), &gophercloud.RequestOpts{
 		MoreHeaders: h,
 		OkCodes:     []int{201, 202, 204},
 	})
 	if resp != nil {
-		res.Header = resp.Header
+		r.Header = resp.Header
 	}
-	res.Err = err
-	return res
+	r.Err = err
+	return r
 }
 
 // Get is a function that retrieves the metadata of a container. To extract just
 // the custom metadata, pass the GetResult response to the ExtractMetadata
 // function.
 func Get(c *gophercloud.ServiceClient, containerName string) GetResult {
-	var res GetResult
+	var r GetResult
 	resp, err := c.Request("HEAD", getURL(c, containerName), &gophercloud.RequestOpts{
 		OkCodes: []int{200, 204},
 	})
 	if resp != nil {
-		res.Header = resp.Header
+		r.Header = resp.Header
 	}
-	res.Err = err
-	return res
+	r.Err = err
+	return r
 }
diff --git a/openstack/objectstorage/v1/objects/requests.go b/openstack/objectstorage/v1/objects/requests.go
index d82aeb2..2505bdb 100644
--- a/openstack/objectstorage/v1/objects/requests.go
+++ b/openstack/objectstorage/v1/objects/requests.go
@@ -1,13 +1,12 @@
 package objects
 
 import (
-	"bufio"
+	"bytes"
 	"crypto/hmac"
 	"crypto/md5"
 	"crypto/sha1"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"strings"
 	"time"
 
@@ -42,10 +41,7 @@
 // representing whether to list complete information for each object.
 func (opts ListOpts) ToObjectListParams() (bool, string, error) {
 	q, err := gophercloud.BuildQueryString(opts)
-	if err != nil {
-		return false, "", err
-	}
-	return opts.Full, q.String(), nil
+	return opts.Full, q.String(), err
 }
 
 // List is a function that retrieves all objects in a container. It also returns the details
@@ -67,13 +63,11 @@
 		}
 	}
 
-	createPage := func(r pagination.PageResult) pagination.Page {
+	pager := pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page {
 		p := ObjectPage{pagination.MarkerPageBase{PageResult: r}}
 		p.MarkerPageBase.Owner = p
 		return p
-	}
-
-	pager := pagination.NewPager(c, url, createPage)
+	})
 	pager.Headers = headers
 	return pager
 }
@@ -114,46 +108,42 @@
 // To extract just the content, pass the DownloadResult response to the
 // ExtractContent function.
 func Download(c *gophercloud.ServiceClient, containerName, objectName string, opts DownloadOptsBuilder) DownloadResult {
-	var res DownloadResult
-
+	var r DownloadResult
 	url := downloadURL(c, containerName, objectName)
-	h := c.AuthenticatedHeaders()
-
+	h := make(map[string]string)
 	if opts != nil {
 		headers, query, err := opts.ToObjectDownloadParams()
 		if err != nil {
-			res.Err = err
-			return res
+			r.Err = err
+			return r
 		}
-
 		for k, v := range headers {
 			h[k] = v
 		}
-
 		url += query
 	}
 
-	resp, err := c.Request("GET", url, &gophercloud.RequestOpts{
+	resp, err := c.Get(url, nil, &gophercloud.RequestOpts{
 		MoreHeaders: h,
 		OkCodes:     []int{200, 304},
 	})
 	if resp != nil {
-		res.Header = resp.Header
-		res.Body = resp.Body
+		r.Header = resp.Header
+		r.Body = resp.Body
 	}
-	res.Err = err
-
-	return res
+	r.Err = err
+	return r
 }
 
 // CreateOptsBuilder allows extensions to add additional parameters to the
 // Create request.
 type CreateOptsBuilder interface {
-	ToObjectCreateParams() (map[string]string, string, error)
+	ToObjectCreateParams() (io.Reader, map[string]string, string, error)
 }
 
 // CreateOpts is a structure that holds parameters for creating an object.
 type CreateOpts struct {
+	Content            io.Reader
 	Metadata           map[string]string
 	ContentDisposition string `h:"Content-Disposition"`
 	ContentEncoding    string `h:"Content-Encoding"`
@@ -174,81 +164,61 @@
 
 // ToObjectCreateParams formats a CreateOpts into a query string and map of
 // headers.
-func (opts CreateOpts) ToObjectCreateParams() (map[string]string, string, error) {
+func (opts CreateOpts) ToObjectCreateParams() (io.Reader, map[string]string, string, error) {
 	q, err := gophercloud.BuildQueryString(opts)
 	if err != nil {
-		return nil, "", err
+		return nil, nil, "", err
 	}
 	h, err := gophercloud.BuildHeaders(opts)
 	if err != nil {
-		return nil, q.String(), err
+		return nil, nil, "", err
 	}
 
 	for k, v := range opts.Metadata {
 		h["X-Object-Meta-"+k] = v
 	}
 
-	return h, q.String(), nil
+	hash := md5.New()
+	buf := bytes.NewBuffer([]byte{})
+	_, err = io.Copy(io.MultiWriter(hash, buf), opts.Content)
+	if err != nil {
+		return nil, nil, "", err
+	}
+	localChecksum := fmt.Sprintf("%x", hash.Sum(nil))
+	h["ETag"] = localChecksum
+
+	return buf, h, q.String(), nil
 }
 
 // Create is a function that creates a new object or replaces an existing object. If the returned response's ETag
 // header fails to match the local checksum, the failed request will automatically be retried up to a maximum of 3 times.
-func Create(c *gophercloud.ServiceClient, containerName, objectName string, content io.ReadSeeker, opts CreateOptsBuilder) CreateResult {
-	var res CreateResult
-
+func Create(c *gophercloud.ServiceClient, containerName, objectName string, opts CreateOptsBuilder) CreateResult {
+	var r CreateResult
 	url := createURL(c, containerName, objectName)
 	h := make(map[string]string)
-
+	var b io.Reader
 	if opts != nil {
-		headers, query, err := opts.ToObjectCreateParams()
+		tmpB, headers, query, err := opts.ToObjectCreateParams()
 		if err != nil {
-			res.Err = err
-			return res
+			r.Err = err
+			return r
 		}
-
 		for k, v := range headers {
 			h[k] = v
 		}
-
 		url += query
+		b = tmpB
 	}
 
-	hash := md5.New()
-	bufioReader := bufio.NewReader(io.TeeReader(content, hash))
-	io.Copy(ioutil.Discard, bufioReader)
-	localChecksum := hash.Sum(nil)
-
-	h["ETag"] = fmt.Sprintf("%x", localChecksum)
-
-	_, err := content.Seek(0, 0)
-	if err != nil {
-		res.Err = err
-		return res
-	}
-
-	ropts := &gophercloud.RequestOpts{
-		RawBody:     content,
+	resp, err := c.Put(url, nil, nil, &gophercloud.RequestOpts{
+		RawBody:     b,
 		MoreHeaders: h,
-	}
-
-	resp, err := c.Request("PUT", url, ropts)
-	if err != nil {
-		res.Err = err
-		return res
-	}
+	})
+	r.Err = err
 	if resp != nil {
-		res.Header = resp.Header
-		if resp.Header.Get("ETag") == fmt.Sprintf("%x", localChecksum) {
-			res.Err = err
-			return res
-		}
-		err := ErrWrongChecksum{}
-		err.Function = "objects.Create"
-		res.Err = err
-
+		r.Header = resp.Header
 	}
-
-	return res
+	return r
 }
 
 // CopyOptsBuilder allows extensions to add additional parameters to the
@@ -264,17 +234,11 @@
 	ContentDisposition string `h:"Content-Disposition"`
 	ContentEncoding    string `h:"Content-Encoding"`
 	ContentType        string `h:"Content-Type"`
-	Destination        string `h:"Destination,required"`
+	Destination        string `h:"Destination" required:"true"`
 }
 
 // ToObjectCopyMap formats a CopyOpts into a map of headers.
 func (opts CopyOpts) ToObjectCopyMap() (map[string]string, error) {
-	if opts.Destination == "" {
-		err := gophercloud.ErrMissingInput{}
-		err.Function = "objects.ToObjectCopyMap"
-		err.Argument = "objects.CopyOpts.Destination"
-		return nil, err
-	}
 	h, err := gophercloud.BuildHeaders(opts)
 	if err != nil {
 		return nil, err
@@ -287,13 +251,12 @@
 
 // Copy is a function that copies one object to another.
 func Copy(c *gophercloud.ServiceClient, containerName, objectName string, opts CopyOptsBuilder) CopyResult {
-	var res CopyResult
-	h := c.AuthenticatedHeaders()
-
+	var r CopyResult
+	h := make(map[string]string)
 	headers, err := opts.ToObjectCopyMap()
 	if err != nil {
-		res.Err = err
-		return res
+		r.Err = err
+		return r
 	}
 
 	for k, v := range headers {
@@ -306,10 +269,10 @@
 		OkCodes:     []int{201},
 	})
 	if resp != nil {
-		res.Header = resp.Header
+		r.Header = resp.Header
 	}
-	res.Err = err
-	return res
+	r.Err = err
+	return r
 }
 
 // DeleteOptsBuilder allows extensions to add additional parameters to the
@@ -326,32 +289,27 @@
 // ToObjectDeleteQuery formats a DeleteOpts into a query string.
 func (opts DeleteOpts) ToObjectDeleteQuery() (string, error) {
 	q, err := gophercloud.BuildQueryString(opts)
-	if err != nil {
-		return "", err
-	}
-	return q.String(), nil
+	return q.String(), err
 }
 
 // Delete is a function that deletes an object.
 func Delete(c *gophercloud.ServiceClient, containerName, objectName string, opts DeleteOptsBuilder) DeleteResult {
-	var res DeleteResult
+	var r DeleteResult
 	url := deleteURL(c, containerName, objectName)
-
 	if opts != nil {
 		query, err := opts.ToObjectDeleteQuery()
 		if err != nil {
-			res.Err = err
-			return res
+			r.Err = err
+			return r
 		}
 		url += query
 	}
-
 	resp, err := c.Delete(url, nil)
 	if resp != nil {
-		res.Header = resp.Header
+		r.Header = resp.Header
 	}
-	res.Err = err
-	return res
+	r.Err = err
+	return r
 }
 
 // GetOptsBuilder allows extensions to add additional parameters to the
@@ -369,35 +327,30 @@
 // ToObjectGetQuery formats a GetOpts into a query string.
 func (opts GetOpts) ToObjectGetQuery() (string, error) {
 	q, err := gophercloud.BuildQueryString(opts)
-	if err != nil {
-		return "", err
-	}
-	return q.String(), nil
+	return q.String(), err
 }
 
 // Get is a function that retrieves the metadata of an object. To extract just the custom
 // metadata, pass the GetResult response to the ExtractMetadata function.
 func Get(c *gophercloud.ServiceClient, containerName, objectName string, opts GetOptsBuilder) GetResult {
-	var res GetResult
+	var r GetResult
 	url := getURL(c, containerName, objectName)
-
 	if opts != nil {
 		query, err := opts.ToObjectGetQuery()
 		if err != nil {
-			res.Err = err
-			return res
+			r.Err = err
+			return r
 		}
 		url += query
 	}
-
 	resp, err := c.Request("HEAD", url, &gophercloud.RequestOpts{
 		OkCodes: []int{200, 204},
 	})
 	if resp != nil {
-		res.Header = resp.Header
+		r.Header = resp.Header
 	}
-	res.Err = err
-	return res
+	r.Err = err
+	return r
 }
 
 // UpdateOptsBuilder allows extensions to add additional parameters to the
@@ -432,30 +385,28 @@
 
 // Update is a function that creates, updates, or deletes an object's metadata.
 func Update(c *gophercloud.ServiceClient, containerName, objectName string, opts UpdateOptsBuilder) UpdateResult {
-	var res UpdateResult
+	var r UpdateResult
 	h := c.AuthenticatedHeaders()
-
 	if opts != nil {
 		headers, err := opts.ToObjectUpdateMap()
 		if err != nil {
-			res.Err = err
-			return res
+			r.Err = err
+			return r
 		}
 
 		for k, v := range headers {
 			h[k] = v
 		}
 	}
-
 	url := updateURL(c, containerName, objectName)
-	resp, err := c.Request("POST", url, &gophercloud.RequestOpts{
+	resp, err := c.Post(url, nil, nil, &gophercloud.RequestOpts{
 		MoreHeaders: h,
 	})
 	if resp != nil {
-		res.Header = resp.Header
+		r.Header = resp.Header
 	}
-	res.Err = err
-	return res
+	r.Err = err
+	return r
 }
 
 // HTTPMethod represents an HTTP method string (e.g. "GET").
diff --git a/openstack/objectstorage/v1/objects/results.go b/openstack/objectstorage/v1/objects/results.go
index c0d532b..3cfe1f4 100644
--- a/openstack/objectstorage/v1/objects/results.go
+++ b/openstack/objectstorage/v1/objects/results.go
@@ -200,12 +200,16 @@
 
 // CreateResult represents the result of a create operation.
 type CreateResult struct {
+	checksum string
 	gophercloud.HeaderResult
 }
 
 // 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 (r CreateResult) Extract() (*CreateHeader, error) {
+	//if r.Header.Get("ETag") != fmt.Sprintf("%x", localChecksum) {
+	//	return nil, ErrWrongChecksum{}
+	//}
 	var s *CreateHeader
 	err := r.ExtractInto(&s)
 	return s, err