Merge pull request #243 from smashwilson/rackspace-compute

Compute v2 service for Rackspace.
diff --git a/README.md b/README.md
index 74a4cd4..96dcd31 100644
--- a/README.md
+++ b/README.md
@@ -80,7 +80,7 @@
 }
 
 // Option 2: Use a utility function to retrieve all your environment variables
-opts, err := utils.AuthOptions()
+opts, err := openstack.AuthOptionsFromEnv()
 ```
 
 Once you have the `opts` variable, you can pass it in and get back a
diff --git a/acceptance/openstack/blockstorage/v1/volumes_test.go b/acceptance/openstack/blockstorage/v1/volumes_test.go
index 21a47ac..f84f5cb 100644
--- a/acceptance/openstack/blockstorage/v1/volumes_test.go
+++ b/acceptance/openstack/blockstorage/v1/volumes_test.go
@@ -10,12 +10,11 @@
 	"github.com/rackspace/gophercloud"
 	"github.com/rackspace/gophercloud/openstack"
 	"github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes"
-	"github.com/rackspace/gophercloud/openstack/utils"
 	"github.com/rackspace/gophercloud/pagination"
 )
 
 func newClient() (*gophercloud.ServiceClient, error) {
-	ao, err := utils.AuthOptions()
+	ao, err := openstack.AuthOptionsFromEnv()
 	if err != nil {
 		return nil, err
 	}
diff --git a/acceptance/openstack/client_test.go b/acceptance/openstack/client_test.go
index 6c0f9ee..6e88819 100644
--- a/acceptance/openstack/client_test.go
+++ b/acceptance/openstack/client_test.go
@@ -8,12 +8,11 @@
 
 	"github.com/rackspace/gophercloud"
 	"github.com/rackspace/gophercloud/openstack"
-	"github.com/rackspace/gophercloud/openstack/utils"
 )
 
 func TestAuthenticatedClient(t *testing.T) {
 	// Obtain credentials from the environment.
-	ao, err := utils.AuthOptions()
+	ao, err := openstack.AuthOptionsFromEnv()
 	if err != nil {
 		t.Fatalf("Unable to acquire credentials: %v", err)
 	}
diff --git a/acceptance/openstack/compute/v2/compute_test.go b/acceptance/openstack/compute/v2/compute_test.go
index 15b5163..46eb9ff 100644
--- a/acceptance/openstack/compute/v2/compute_test.go
+++ b/acceptance/openstack/compute/v2/compute_test.go
@@ -11,11 +11,10 @@
 	"github.com/rackspace/gophercloud/acceptance/tools"
 	"github.com/rackspace/gophercloud/openstack"
 	"github.com/rackspace/gophercloud/openstack/compute/v2/servers"
-	"github.com/rackspace/gophercloud/openstack/utils"
 )
 
 func newClient() (*gophercloud.ServiceClient, error) {
-	ao, err := utils.AuthOptions()
+	ao, err := openstack.AuthOptionsFromEnv()
 	if err != nil {
 		return nil, err
 	}
diff --git a/acceptance/openstack/compute/v2/flavors_test.go b/acceptance/openstack/compute/v2/flavors_test.go
index 9c8e322..cf547f2 100644
--- a/acceptance/openstack/compute/v2/flavors_test.go
+++ b/acceptance/openstack/compute/v2/flavors_test.go
@@ -1,4 +1,4 @@
-// +build acceptance
+// +build acceptance compute flavors
 
 package v2
 
diff --git a/acceptance/openstack/compute/v2/images_test.go b/acceptance/openstack/compute/v2/images_test.go
index 6166fc8..ceab22f 100644
--- a/acceptance/openstack/compute/v2/images_test.go
+++ b/acceptance/openstack/compute/v2/images_test.go
@@ -1,4 +1,4 @@
-// +build acceptance
+// +build acceptance compute images
 
 package v2
 
diff --git a/acceptance/openstack/compute/v2/servers_test.go b/acceptance/openstack/compute/v2/servers_test.go
index cb413c1..2c47a86 100644
--- a/acceptance/openstack/compute/v2/servers_test.go
+++ b/acceptance/openstack/compute/v2/servers_test.go
@@ -1,4 +1,4 @@
-// +build acceptance
+// +build acceptance compute servers
 
 package v2
 
diff --git a/acceptance/openstack/identity/v2/identity_test.go b/acceptance/openstack/identity/v2/identity_test.go
index 2ecd3ca..feae233 100644
--- a/acceptance/openstack/identity/v2/identity_test.go
+++ b/acceptance/openstack/identity/v2/identity_test.go
@@ -7,13 +7,12 @@
 
 	"github.com/rackspace/gophercloud"
 	"github.com/rackspace/gophercloud/openstack"
-	"github.com/rackspace/gophercloud/openstack/utils"
 	th "github.com/rackspace/gophercloud/testhelper"
 )
 
 func v2AuthOptions(t *testing.T) gophercloud.AuthOptions {
 	// Obtain credentials from the environment.
-	ao, err := utils.AuthOptions()
+	ao, err := openstack.AuthOptionsFromEnv()
 	th.AssertNoErr(t, err)
 
 	// Trim out unused fields. Prefer authentication by API key to password.
diff --git a/acceptance/openstack/identity/v3/identity_test.go b/acceptance/openstack/identity/v3/identity_test.go
index e0503e2..293606b 100644
--- a/acceptance/openstack/identity/v3/identity_test.go
+++ b/acceptance/openstack/identity/v3/identity_test.go
@@ -7,12 +7,11 @@
 
 	"github.com/rackspace/gophercloud"
 	"github.com/rackspace/gophercloud/openstack"
-	"github.com/rackspace/gophercloud/openstack/utils"
 )
 
 func createAuthenticatedClient(t *testing.T) *gophercloud.ServiceClient {
 	// Obtain credentials from the environment.
-	ao, err := utils.AuthOptions()
+	ao, err := openstack.AuthOptionsFromEnv()
 	if err != nil {
 		t.Fatalf("Unable to acquire credentials: %v", err)
 	}
diff --git a/acceptance/openstack/identity/v3/token_test.go b/acceptance/openstack/identity/v3/token_test.go
index 341acb7..4342ade 100644
--- a/acceptance/openstack/identity/v3/token_test.go
+++ b/acceptance/openstack/identity/v3/token_test.go
@@ -7,12 +7,11 @@
 
 	"github.com/rackspace/gophercloud/openstack"
 	tokens3 "github.com/rackspace/gophercloud/openstack/identity/v3/tokens"
-	"github.com/rackspace/gophercloud/openstack/utils"
 )
 
 func TestGetToken(t *testing.T) {
 	// Obtain credentials from the environment.
-	ao, err := utils.AuthOptions()
+	ao, err := openstack.AuthOptionsFromEnv()
 	if err != nil {
 		t.Fatalf("Unable to acquire credentials: %v", err)
 	}
diff --git a/acceptance/openstack/networking/v2/common.go b/acceptance/openstack/networking/v2/common.go
index 6dd58af..1efac2c 100644
--- a/acceptance/openstack/networking/v2/common.go
+++ b/acceptance/openstack/networking/v2/common.go
@@ -6,14 +6,13 @@
 
 	"github.com/rackspace/gophercloud"
 	"github.com/rackspace/gophercloud/openstack"
-	"github.com/rackspace/gophercloud/openstack/utils"
 	th "github.com/rackspace/gophercloud/testhelper"
 )
 
 var Client *gophercloud.ServiceClient
 
 func NewClient() (*gophercloud.ServiceClient, error) {
-	opts, err := utils.AuthOptions()
+	opts, err := openstack.AuthOptionsFromEnv()
 	if err != nil {
 		return nil, err
 	}
diff --git a/acceptance/openstack/networking/v2/extensions/lbaas/common.go b/acceptance/openstack/networking/v2/extensions/lbaas/common.go
index a9db1af..27dfe5f 100644
--- a/acceptance/openstack/networking/v2/extensions/lbaas/common.go
+++ b/acceptance/openstack/networking/v2/extensions/lbaas/common.go
@@ -61,7 +61,7 @@
 
 func CreateMonitor(t *testing.T) string {
 	m, err := monitors.Create(base.Client, monitors.CreateOpts{
-		Delay:         5,
+		Delay:         10,
 		Timeout:       10,
 		MaxRetries:    3,
 		Type:          monitors.TypeHTTP,
diff --git a/acceptance/openstack/networking/v2/extensions/lbaas/monitor_test.go b/acceptance/openstack/networking/v2/extensions/lbaas/monitor_test.go
index 57e860c..9056fff 100644
--- a/acceptance/openstack/networking/v2/extensions/lbaas/monitor_test.go
+++ b/acceptance/openstack/networking/v2/extensions/lbaas/monitor_test.go
@@ -51,7 +51,7 @@
 }
 
 func updateMonitor(t *testing.T, monitorID string) {
-	opts := monitors.UpdateOpts{Delay: 5, Timeout: 10, MaxRetries: 3}
+	opts := monitors.UpdateOpts{Delay: 10, Timeout: 10, MaxRetries: 3}
 	m, err := monitors.Update(base.Client, monitorID, opts).Extract()
 
 	th.AssertNoErr(t, err)
diff --git a/acceptance/openstack/networking/v2/extensions/security_test.go b/acceptance/openstack/networking/v2/extensions/security_test.go
index fc9227f..33c9c4b 100644
--- a/acceptance/openstack/networking/v2/extensions/security_test.go
+++ b/acceptance/openstack/networking/v2/extensions/security_test.go
@@ -60,6 +60,9 @@
 
 	// delete security group rule
 	deleteSecRule(t, ruleID)
+
+	// delete security group
+	deleteSecGroup(t, groupID)
 }
 
 func createSecGroup(t *testing.T) string {
diff --git a/acceptance/openstack/objectstorage/v1/common.go b/acceptance/openstack/objectstorage/v1/common.go
index 4e2f9b5..fd1deda 100644
--- a/acceptance/openstack/objectstorage/v1/common.go
+++ b/acceptance/openstack/objectstorage/v1/common.go
@@ -7,14 +7,13 @@
 
 	"github.com/rackspace/gophercloud"
 	"github.com/rackspace/gophercloud/openstack"
-	"github.com/rackspace/gophercloud/openstack/utils"
 	th "github.com/rackspace/gophercloud/testhelper"
 )
 
 var metadata = map[string]string{"gopher": "cloud"}
 
 func newClient() (*gophercloud.ServiceClient, error) {
-	ao, err := utils.AuthOptions()
+	ao, err := openstack.AuthOptionsFromEnv()
 	th.AssertNoErr(t, err)
 
 	client, err := openstack.AuthenticatedClient(ao)
diff --git a/acceptance/rackspace/client_test.go b/acceptance/rackspace/client_test.go
index e68aef8..825e3ac 100644
--- a/acceptance/rackspace/client_test.go
+++ b/acceptance/rackspace/client_test.go
@@ -5,13 +5,12 @@
 import (
 	"testing"
 
-	"github.com/rackspace/gophercloud/openstack/utils"
 	"github.com/rackspace/gophercloud/rackspace"
 )
 
 func TestAuthenticatedClient(t *testing.T) {
 	// Obtain credentials from the environment.
-	ao, err := utils.AuthOptions()
+	ao, err := rackspace.AuthOptionsFromEnv()
 	if err != nil {
 		t.Fatalf("Unable to acquire credentials: %v", err)
 	}
diff --git a/openstack/utils/utils.go b/openstack/auth_env.go
similarity index 80%
rename from openstack/utils/utils.go
rename to openstack/auth_env.go
index 1d09d9e..a4402b6 100644
--- a/openstack/utils/utils.go
+++ b/openstack/auth_env.go
@@ -1,5 +1,4 @@
-// Package utils contains utilities which eases working with Gophercloud's OpenStack APIs.
-package utils
+package openstack
 
 import (
 	"fmt"
@@ -22,7 +21,7 @@
 // OS_* environment variables.  The following variables provide sources of truth: OS_AUTH_URL, OS_USERNAME,
 // OS_PASSWORD, OS_TENANT_ID, and OS_TENANT_NAME.  Of these, OS_USERNAME, OS_PASSWORD, and OS_AUTH_URL must
 // have settings, or an error will result.  OS_TENANT_ID and OS_TENANT_NAME are optional.
-func AuthOptions() (gophercloud.AuthOptions, error) {
+func AuthOptionsFromEnv() (gophercloud.AuthOptions, error) {
 	authURL := os.Getenv("OS_AUTH_URL")
 	username := os.Getenv("OS_USERNAME")
 	userID := os.Getenv("OS_USERID")
@@ -57,17 +56,3 @@
 
 	return ao, nil
 }
-
-// BuildQuery constructs the query section of a URI from a map.
-func BuildQuery(params map[string]string) string {
-	if len(params) == 0 {
-		return ""
-	}
-
-	query := "?"
-	for k, v := range params {
-		query += k + "=" + v + "&"
-	}
-	query = query[:len(query)-1]
-	return query
-}
diff --git a/openstack/blockstorage/v1/apiversions/requests.go b/openstack/blockstorage/v1/apiversions/requests.go
index a56f249..016bf37 100644
--- a/openstack/blockstorage/v1/apiversions/requests.go
+++ b/openstack/blockstorage/v1/apiversions/requests.go
@@ -19,7 +19,7 @@
 func Get(client *gophercloud.ServiceClient, v string) GetResult {
 	var res GetResult
 	_, err := perigee.Request("GET", getURL(client, v), perigee.Options{
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		OkCodes:     []int{200},
 		Results:     &res.Body,
 	})
diff --git a/openstack/blockstorage/v1/apiversions/requests_test.go b/openstack/blockstorage/v1/apiversions/requests_test.go
index c135722..56b5e4f 100644
--- a/openstack/blockstorage/v1/apiversions/requests_test.go
+++ b/openstack/blockstorage/v1/apiversions/requests_test.go
@@ -5,29 +5,18 @@
 	"net/http"
 	"testing"
 
-	"github.com/rackspace/gophercloud"
 	"github.com/rackspace/gophercloud/pagination"
 	th "github.com/rackspace/gophercloud/testhelper"
+	"github.com/rackspace/gophercloud/testhelper/client"
 )
 
-const TokenID = "123"
-
-func ServiceClient() *gophercloud.ServiceClient {
-	return &gophercloud.ServiceClient{
-		Provider: &gophercloud.ProviderClient{
-			TokenID: TokenID,
-		},
-		Endpoint: th.Endpoint(),
-	}
-}
-
 func TestListVersions(t *testing.T) {
 	th.SetupHTTP()
 	defer th.TeardownHTTP()
 
 	th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
 		th.TestMethod(t, r, "GET")
-		th.TestHeader(t, r, "X-Auth-Token", TokenID)
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 
 		w.Header().Add("Content-Type", "application/json")
 		w.WriteHeader(http.StatusOK)
@@ -62,7 +51,7 @@
 
 	count := 0
 
-	List(ServiceClient()).EachPage(func(page pagination.Page) (bool, error) {
+	List(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) {
 		count++
 		actual, err := ExtractAPIVersions(page)
 		if err != nil {
@@ -99,7 +88,7 @@
 
 	th.Mux.HandleFunc("/v1/", func(w http.ResponseWriter, r *http.Request) {
 		th.TestMethod(t, r, "GET")
-		th.TestHeader(t, r, "X-Auth-Token", TokenID)
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 
 		w.Header().Add("Content-Type", "application/json")
 		w.WriteHeader(http.StatusOK)
@@ -139,7 +128,7 @@
 		}`)
 	})
 
-	actual, err := Get(ServiceClient(), "v1").Extract()
+	actual, err := Get(client.ServiceClient(), "v1").Extract()
 	if err != nil {
 		t.Errorf("Failed to extract version: %v", err)
 	}
diff --git a/openstack/blockstorage/v1/snapshots/requests.go b/openstack/blockstorage/v1/snapshots/requests.go
index 49b637a..8cb130d 100644
--- a/openstack/blockstorage/v1/snapshots/requests.go
+++ b/openstack/blockstorage/v1/snapshots/requests.go
@@ -70,7 +70,7 @@
 	}
 
 	_, res.Err = perigee.Request("POST", createURL(client), perigee.Options{
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		OkCodes:     []int{200, 201},
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
@@ -81,7 +81,7 @@
 // Delete will delete the existing Snapshot with the provided ID.
 func Delete(client *gophercloud.ServiceClient, id string) error {
 	_, err := perigee.Request("DELETE", deleteURL(client, id), perigee.Options{
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		OkCodes:     []int{202, 204},
 	})
 	return err
@@ -93,7 +93,7 @@
 	var res GetResult
 	_, res.Err = perigee.Request("GET", getURL(client, id), perigee.Options{
 		Results:     &res.Body,
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		OkCodes:     []int{200},
 	})
 	return res
@@ -178,7 +178,7 @@
 	}
 
 	_, res.Err = perigee.Request("PUT", updateMetadataURL(client, id), perigee.Options{
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		OkCodes:     []int{200},
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
diff --git a/openstack/blockstorage/v1/snapshots/requests_test.go b/openstack/blockstorage/v1/snapshots/requests_test.go
index ddfa81b..e13a348 100644
--- a/openstack/blockstorage/v1/snapshots/requests_test.go
+++ b/openstack/blockstorage/v1/snapshots/requests_test.go
@@ -5,29 +5,18 @@
 	"net/http"
 	"testing"
 
-	"github.com/rackspace/gophercloud"
 	"github.com/rackspace/gophercloud/pagination"
 	th "github.com/rackspace/gophercloud/testhelper"
+	"github.com/rackspace/gophercloud/testhelper/client"
 )
 
-const TokenID = "123"
-
-func ServiceClient() *gophercloud.ServiceClient {
-	return &gophercloud.ServiceClient{
-		Provider: &gophercloud.ProviderClient{
-			TokenID: TokenID,
-		},
-		Endpoint: th.Endpoint(),
-	}
-}
-
 func TestList(t *testing.T) {
 	th.SetupHTTP()
 	defer th.TeardownHTTP()
 
 	th.Mux.HandleFunc("/snapshots", func(w http.ResponseWriter, r *http.Request) {
 		th.TestMethod(t, r, "GET")
-		th.TestHeader(t, r, "X-Auth-Token", TokenID)
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 
 		w.Header().Add("Content-Type", "application/json")
 		w.WriteHeader(http.StatusOK)
@@ -48,10 +37,8 @@
 		`)
 	})
 
-	client := ServiceClient()
 	count := 0
-
-	List(client, &ListOpts{}).EachPage(func(page pagination.Page) (bool, error) {
+	List(client.ServiceClient(), &ListOpts{}).EachPage(func(page pagination.Page) (bool, error) {
 		count++
 		actual, err := ExtractSnapshots(page)
 		if err != nil {
@@ -86,7 +73,7 @@
 
 	th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) {
 		th.TestMethod(t, r, "GET")
-		th.TestHeader(t, r, "X-Auth-Token", TokenID)
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 
 		w.Header().Add("Content-Type", "application/json")
 		w.WriteHeader(http.StatusOK)
@@ -100,7 +87,7 @@
 			`)
 	})
 
-	v, err := Get(ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract()
+	v, err := Get(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract()
 	th.AssertNoErr(t, err)
 
 	th.AssertEquals(t, v.Name, "snapshot-001")
@@ -113,7 +100,7 @@
 
 	th.Mux.HandleFunc("/snapshots", func(w http.ResponseWriter, r *http.Request) {
 		th.TestMethod(t, r, "POST")
-		th.TestHeader(t, r, "X-Auth-Token", TokenID)
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 		th.TestHeader(t, r, "Content-Type", "application/json")
 		th.TestHeader(t, r, "Accept", "application/json")
 		th.TestJSONRequest(t, r, `
@@ -140,7 +127,7 @@
 	})
 
 	options := &CreateOpts{VolumeID: "1234", Name: "snapshot-001"}
-	n, err := Create(ServiceClient(), options).Extract()
+	n, err := Create(client.ServiceClient(), options).Extract()
 	th.AssertNoErr(t, err)
 
 	th.AssertEquals(t, n.VolumeID, "1234")
@@ -154,7 +141,7 @@
 
 	th.Mux.HandleFunc("/snapshots/123/metadata", func(w http.ResponseWriter, r *http.Request) {
 		th.TestMethod(t, r, "PUT")
-		th.TestHeader(t, r, "X-Auth-Token", TokenID)
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 		th.TestHeader(t, r, "Content-Type", "application/json")
 		th.TestJSONRequest(t, r, `
 		{
@@ -180,7 +167,7 @@
 			"key": "v1",
 		},
 	}
-	actual, err := UpdateMetadata(ServiceClient(), "123", options).ExtractMetadata()
+	actual, err := UpdateMetadata(client.ServiceClient(), "123", options).ExtractMetadata()
 
 	th.AssertNoErr(t, err)
 	th.AssertDeepEquals(t, actual, expected)
@@ -192,10 +179,10 @@
 
 	th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) {
 		th.TestMethod(t, r, "DELETE")
-		th.TestHeader(t, r, "X-Auth-Token", TokenID)
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 		w.WriteHeader(http.StatusNoContent)
 	})
 
-	err := Delete(ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22")
+	err := Delete(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22")
 	th.AssertNoErr(t, err)
 }
diff --git a/openstack/blockstorage/v1/snapshots/util_test.go b/openstack/blockstorage/v1/snapshots/util_test.go
index 46b452e..a4c4c82 100644
--- a/openstack/blockstorage/v1/snapshots/util_test.go
+++ b/openstack/blockstorage/v1/snapshots/util_test.go
@@ -7,6 +7,7 @@
 	"time"
 
 	th "github.com/rackspace/gophercloud/testhelper"
+	"github.com/rackspace/gophercloud/testhelper/client"
 )
 
 func TestWaitForStatus(t *testing.T) {
@@ -27,11 +28,11 @@
 		}`)
 	})
 
-	err := WaitForStatus(ServiceClient(), "1234", "available", 0)
+	err := WaitForStatus(client.ServiceClient(), "1234", "available", 0)
 	if err == nil {
 		t.Errorf("Expected error: 'Time Out in WaitFor'")
 	}
 
-	err = WaitForStatus(ServiceClient(), "1234", "available", 3)
+	err = WaitForStatus(client.ServiceClient(), "1234", "available", 3)
 	th.CheckNoErr(t, err)
 }
diff --git a/openstack/blockstorage/v1/volumes/requests.go b/openstack/blockstorage/v1/volumes/requests.go
index 2b3aaeb..fa2202c 100644
--- a/openstack/blockstorage/v1/volumes/requests.go
+++ b/openstack/blockstorage/v1/volumes/requests.go
@@ -86,7 +86,7 @@
 	}
 
 	_, res.Err = perigee.Request("POST", createURL(client), perigee.Options{
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
 		OkCodes:     []int{200, 201},
@@ -97,7 +97,7 @@
 // Delete will delete the existing Volume with the provided ID.
 func Delete(client *gophercloud.ServiceClient, id string) error {
 	_, err := perigee.Request("DELETE", deleteURL(client, id), perigee.Options{
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		OkCodes:     []int{202, 204},
 	})
 	return err
@@ -109,7 +109,7 @@
 	var res GetResult
 	_, res.Err = perigee.Request("GET", getURL(client, id), perigee.Options{
 		Results:     &res.Body,
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		OkCodes:     []int{200},
 	})
 	return res
@@ -207,7 +207,7 @@
 	}
 
 	_, res.Err = perigee.Request("PUT", updateURL(client, id), perigee.Options{
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		OkCodes:     []int{200},
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
diff --git a/openstack/blockstorage/v1/volumes/requests_test.go b/openstack/blockstorage/v1/volumes/requests_test.go
index 7cd37d5..473a4e7 100644
--- a/openstack/blockstorage/v1/volumes/requests_test.go
+++ b/openstack/blockstorage/v1/volumes/requests_test.go
@@ -5,29 +5,18 @@
 	"net/http"
 	"testing"
 
-	"github.com/rackspace/gophercloud"
 	"github.com/rackspace/gophercloud/pagination"
 	th "github.com/rackspace/gophercloud/testhelper"
+	"github.com/rackspace/gophercloud/testhelper/client"
 )
 
-const TokenID = "123"
-
-func ServiceClient() *gophercloud.ServiceClient {
-	return &gophercloud.ServiceClient{
-		Provider: &gophercloud.ProviderClient{
-			TokenID: TokenID,
-		},
-		Endpoint: th.Endpoint(),
-	}
-}
-
 func TestList(t *testing.T) {
 	th.SetupHTTP()
 	defer th.TeardownHTTP()
 
 	th.Mux.HandleFunc("/volumes", func(w http.ResponseWriter, r *http.Request) {
 		th.TestMethod(t, r, "GET")
-		th.TestHeader(t, r, "X-Auth-Token", TokenID)
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 
 		w.Header().Add("Content-Type", "application/json")
 		w.WriteHeader(http.StatusOK)
@@ -48,10 +37,8 @@
 		`)
 	})
 
-	client := ServiceClient()
 	count := 0
-
-	List(client, &ListOpts{}).EachPage(func(page pagination.Page) (bool, error) {
+	List(client.ServiceClient(), &ListOpts{}).EachPage(func(page pagination.Page) (bool, error) {
 		count++
 		actual, err := ExtractVolumes(page)
 		if err != nil {
@@ -86,7 +73,7 @@
 
 	th.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) {
 		th.TestMethod(t, r, "GET")
-		th.TestHeader(t, r, "X-Auth-Token", TokenID)
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 
 		w.Header().Add("Content-Type", "application/json")
 		w.WriteHeader(http.StatusOK)
@@ -100,7 +87,7 @@
 			`)
 	})
 
-	v, err := Get(ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract()
+	v, err := Get(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract()
 	th.AssertNoErr(t, err)
 
 	th.AssertEquals(t, v.Name, "vol-001")
@@ -113,7 +100,7 @@
 
 	th.Mux.HandleFunc("/volumes", func(w http.ResponseWriter, r *http.Request) {
 		th.TestMethod(t, r, "POST")
-		th.TestHeader(t, r, "X-Auth-Token", TokenID)
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 		th.TestHeader(t, r, "Content-Type", "application/json")
 		th.TestHeader(t, r, "Accept", "application/json")
 		th.TestJSONRequest(t, r, `
@@ -138,7 +125,7 @@
 	})
 
 	options := &CreateOpts{Size: 4}
-	n, err := Create(ServiceClient(), options).Extract()
+	n, err := Create(client.ServiceClient(), options).Extract()
 	th.AssertNoErr(t, err)
 
 	th.AssertEquals(t, n.Size, 4)
@@ -151,11 +138,11 @@
 
 	th.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) {
 		th.TestMethod(t, r, "DELETE")
-		th.TestHeader(t, r, "X-Auth-Token", TokenID)
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 		w.WriteHeader(http.StatusNoContent)
 	})
 
-	err := Delete(ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22")
+	err := Delete(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22")
 	th.AssertNoErr(t, err)
 }
 
@@ -165,7 +152,7 @@
 
 	th.Mux.HandleFunc("/volumes/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) {
 		th.TestMethod(t, r, "PUT")
-		th.TestHeader(t, r, "X-Auth-Token", TokenID)
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 		w.WriteHeader(http.StatusOK)
 		fmt.Fprintf(w, `
 		{
@@ -178,7 +165,7 @@
 	})
 
 	options := &UpdateOpts{Name: "vol-002"}
-	v, err := Update(ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", options).Extract()
+	v, err := Update(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", options).Extract()
 	th.AssertNoErr(t, err)
 	th.CheckEquals(t, "vol-002", v.Name)
 }
diff --git a/openstack/blockstorage/v1/volumes/util_test.go b/openstack/blockstorage/v1/volumes/util_test.go
index 7de1326..a6754e2 100644
--- a/openstack/blockstorage/v1/volumes/util_test.go
+++ b/openstack/blockstorage/v1/volumes/util_test.go
@@ -7,6 +7,7 @@
 	"time"
 
 	th "github.com/rackspace/gophercloud/testhelper"
+	"github.com/rackspace/gophercloud/testhelper/client"
 )
 
 func TestWaitForStatus(t *testing.T) {
@@ -27,11 +28,11 @@
 		}`)
 	})
 
-	err := WaitForStatus(ServiceClient(), "1234", "available", 0)
+	err := WaitForStatus(client.ServiceClient(), "1234", "available", 0)
 	if err == nil {
 		t.Errorf("Expected error: 'Time Out in WaitFor'")
 	}
 
-	err = WaitForStatus(ServiceClient(), "1234", "available", 3)
+	err = WaitForStatus(client.ServiceClient(), "1234", "available", 3)
 	th.CheckNoErr(t, err)
 }
diff --git a/openstack/blockstorage/v1/volumetypes/requests.go b/openstack/blockstorage/v1/volumetypes/requests.go
index c1c3dd5..32d323d 100644
--- a/openstack/blockstorage/v1/volumetypes/requests.go
+++ b/openstack/blockstorage/v1/volumetypes/requests.go
@@ -46,7 +46,7 @@
 	}
 
 	_, res.Err = perigee.Request("POST", createURL(client), perigee.Options{
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		OkCodes:     []int{200, 201},
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
@@ -57,7 +57,7 @@
 // Delete will delete the volume type with the provided ID.
 func Delete(client *gophercloud.ServiceClient, id string) error {
 	_, err := perigee.Request("DELETE", deleteURL(client, id), perigee.Options{
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		OkCodes:     []int{202},
 	})
 	return err
@@ -68,7 +68,7 @@
 func Get(client *gophercloud.ServiceClient, id string) GetResult {
 	var res GetResult
 	_, err := perigee.Request("GET", getURL(client, id), perigee.Options{
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		OkCodes:     []int{200},
 		Results:     &res.Body,
 	})
diff --git a/openstack/blockstorage/v1/volumetypes/requests_test.go b/openstack/blockstorage/v1/volumetypes/requests_test.go
index a9c6512..412e335 100644
--- a/openstack/blockstorage/v1/volumetypes/requests_test.go
+++ b/openstack/blockstorage/v1/volumetypes/requests_test.go
@@ -5,29 +5,18 @@
 	"net/http"
 	"testing"
 
-	"github.com/rackspace/gophercloud"
 	"github.com/rackspace/gophercloud/pagination"
 	th "github.com/rackspace/gophercloud/testhelper"
+	"github.com/rackspace/gophercloud/testhelper/client"
 )
 
-const TokenID = "123"
-
-func ServiceClient() *gophercloud.ServiceClient {
-	return &gophercloud.ServiceClient{
-		Provider: &gophercloud.ProviderClient{
-			TokenID: TokenID,
-		},
-		Endpoint: th.Endpoint(),
-	}
-}
-
 func TestList(t *testing.T) {
 	th.SetupHTTP()
 	defer th.TeardownHTTP()
 
 	th.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) {
 		th.TestMethod(t, r, "GET")
-		th.TestHeader(t, r, "X-Auth-Token", TokenID)
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 
 		w.Header().Add("Content-Type", "application/json")
 		w.WriteHeader(http.StatusOK)
@@ -52,10 +41,8 @@
 		`)
 	})
 
-	client := ServiceClient()
 	count := 0
-
-	List(client).EachPage(func(page pagination.Page) (bool, error) {
+	List(client.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) {
 		count++
 		actual, err := ExtractVolumeTypes(page)
 		if err != nil {
@@ -94,7 +81,7 @@
 
 	th.Mux.HandleFunc("/types/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) {
 		th.TestMethod(t, r, "GET")
-		th.TestHeader(t, r, "X-Auth-Token", TokenID)
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 
 		w.Header().Add("Content-Type", "application/json")
 		w.WriteHeader(http.StatusOK)
@@ -111,7 +98,7 @@
 			`)
 	})
 
-	vt, err := Get(ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract()
+	vt, err := Get(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract()
 	th.AssertNoErr(t, err)
 
 	th.AssertDeepEquals(t, vt.ExtraSpecs, map[string]interface{}{"serverNumber": "2"})
@@ -125,7 +112,7 @@
 
 	th.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) {
 		th.TestMethod(t, r, "POST")
-		th.TestHeader(t, r, "X-Auth-Token", TokenID)
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 		th.TestHeader(t, r, "Content-Type", "application/json")
 		th.TestHeader(t, r, "Accept", "application/json")
 		th.TestJSONRequest(t, r, `
@@ -150,7 +137,7 @@
 	})
 
 	options := &CreateOpts{Name: "vol-type-001"}
-	n, err := Create(ServiceClient(), options).Extract()
+	n, err := Create(client.ServiceClient(), options).Extract()
 	th.AssertNoErr(t, err)
 
 	th.AssertEquals(t, n.Name, "vol-type-001")
@@ -163,10 +150,10 @@
 
 	th.Mux.HandleFunc("/types/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) {
 		th.TestMethod(t, r, "DELETE")
-		th.TestHeader(t, r, "X-Auth-Token", TokenID)
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 		w.WriteHeader(http.StatusAccepted)
 	})
 
-	err := Delete(ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22")
+	err := Delete(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22")
 	th.AssertNoErr(t, err)
 }
diff --git a/openstack/client.go b/openstack/client.go
index a00ed72..99b3d46 100644
--- a/openstack/client.go
+++ b/openstack/client.go
@@ -145,8 +145,8 @@
 	v2Endpoint := client.IdentityBase + "v2.0/"
 
 	return &gophercloud.ServiceClient{
-		Provider: client,
-		Endpoint: v2Endpoint,
+		ProviderClient: client,
+		Endpoint:       v2Endpoint,
 	}
 }
 
@@ -155,8 +155,8 @@
 	v3Endpoint := client.IdentityBase + "v3/"
 
 	return &gophercloud.ServiceClient{
-		Provider: client,
-		Endpoint: v3Endpoint,
+		ProviderClient: client,
+		Endpoint:       v3Endpoint,
 	}
 }
 
@@ -167,7 +167,7 @@
 	if err != nil {
 		return nil, err
 	}
-	return &gophercloud.ServiceClient{Provider: client, Endpoint: url}, nil
+	return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
 }
 
 // NewComputeV2 creates a ServiceClient that may be used with the v2 compute package.
@@ -177,7 +177,7 @@
 	if err != nil {
 		return nil, err
 	}
-	return &gophercloud.ServiceClient{Provider: client, Endpoint: url}, nil
+	return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
 }
 
 // NewNetworkV2 creates a ServiceClient that may be used with the v2 network package.
@@ -188,9 +188,9 @@
 		return nil, err
 	}
 	return &gophercloud.ServiceClient{
-		Provider:     client,
-		Endpoint:     url,
-		ResourceBase: url + "v2.0/",
+		ProviderClient: client,
+		Endpoint:       url,
+		ResourceBase:   url + "v2.0/",
 	}, nil
 }
 
@@ -201,5 +201,5 @@
 	if err != nil {
 		return nil, err
 	}
-	return &gophercloud.ServiceClient{Provider: client, Endpoint: url}, nil
+	return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
 }
diff --git a/openstack/common/extensions/requests.go b/openstack/common/extensions/requests.go
index f1b9c22..3ca6e12 100755
--- a/openstack/common/extensions/requests.go
+++ b/openstack/common/extensions/requests.go
@@ -10,7 +10,7 @@
 func Get(c *gophercloud.ServiceClient, alias string) GetResult {
 	var res GetResult
 	_, res.Err = perigee.Request("GET", ExtensionURL(c, alias), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		Results:     &res.Body,
 		OkCodes:     []int{200},
 	})
diff --git a/openstack/compute/v2/flavors/requests.go b/openstack/compute/v2/flavors/requests.go
index b77a79a..95eb7f9 100644
--- a/openstack/compute/v2/flavors/requests.go
+++ b/openstack/compute/v2/flavors/requests.go
@@ -66,7 +66,7 @@
 	var gr GetResult
 	gr.Err = perigee.Get(getURL(client, id), perigee.Options{
 		Results:     &gr.Body,
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 	})
 	return gr
 }
diff --git a/openstack/compute/v2/images/requests.go b/openstack/compute/v2/images/requests.go
index 4f93ffa..1422cd0 100644
--- a/openstack/compute/v2/images/requests.go
+++ b/openstack/compute/v2/images/requests.go
@@ -63,7 +63,7 @@
 func Get(client *gophercloud.ServiceClient, id string) GetResult {
 	var result GetResult
 	_, result.Err = perigee.Request("GET", getURL(client, id), perigee.Options{
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		Results:     &result.Body,
 		OkCodes:     []int{200},
 	})
diff --git a/openstack/compute/v2/servers/requests.go b/openstack/compute/v2/servers/requests.go
index a997484..632ba28 100644
--- a/openstack/compute/v2/servers/requests.go
+++ b/openstack/compute/v2/servers/requests.go
@@ -192,7 +192,7 @@
 	_, result.Err = perigee.Request("POST", listURL(client), perigee.Options{
 		Results:     &result.Body,
 		ReqBody:     opts.ToServerCreateMap(),
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		OkCodes:     []int{202},
 	})
 	return result
@@ -201,7 +201,7 @@
 // Delete requests that a server previously provisioned be removed from your account.
 func Delete(client *gophercloud.ServiceClient, id string) error {
 	_, err := perigee.Request("DELETE", deleteURL(client, id), perigee.Options{
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		OkCodes:     []int{204},
 	})
 	return err
@@ -212,7 +212,7 @@
 	var result GetResult
 	_, result.Err = perigee.Request("GET", getURL(client, id), perigee.Options{
 		Results:     &result.Body,
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 	})
 	return result
 }
@@ -257,7 +257,7 @@
 	_, result.Err = perigee.Request("PUT", updateURL(client, id), perigee.Options{
 		Results:     &result.Body,
 		ReqBody:     opts.ToServerUpdateMap(),
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 	})
 	return result
 }
@@ -277,7 +277,7 @@
 	_, res.Err = perigee.Request("POST", actionURL(client, id), perigee.Options{
 		ReqBody:     req,
 		Results:     &res.Body,
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		OkCodes:     []int{202},
 	})
 
@@ -350,7 +350,7 @@
 		}{
 			map[string]string{"type": string(how)},
 		},
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		OkCodes:     []int{202},
 	})
 
@@ -449,7 +449,7 @@
 	_, result.Err = perigee.Request("POST", actionURL(client, id), perigee.Options{
 		ReqBody:     &reqBody,
 		Results:     &result.Body,
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		OkCodes:     []int{202},
 	})
 
@@ -472,7 +472,7 @@
 		}{
 			map[string]interface{}{"flavorRef": flavorRef},
 		},
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		OkCodes:     []int{202},
 	})
 
@@ -486,7 +486,7 @@
 
 	_, res.Err = perigee.Request("POST", actionURL(client, id), perigee.Options{
 		ReqBody:     map[string]interface{}{"confirmResize": nil},
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		OkCodes:     []int{204},
 	})
 
@@ -500,7 +500,7 @@
 
 	_, res.Err = perigee.Request("POST", actionURL(client, id), perigee.Options{
 		ReqBody:     map[string]interface{}{"revertResize": nil},
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		OkCodes:     []int{202},
 	})
 
diff --git a/openstack/identity/v3/endpoints/requests.go b/openstack/identity/v3/endpoints/requests.go
index f05cae7..4bec427 100644
--- a/openstack/identity/v3/endpoints/requests.go
+++ b/openstack/identity/v3/endpoints/requests.go
@@ -5,7 +5,6 @@
 
 	"github.com/racker/perigee"
 	"github.com/rackspace/gophercloud"
-	"github.com/rackspace/gophercloud/openstack/utils"
 	"github.com/rackspace/gophercloud/pagination"
 )
 
@@ -61,7 +60,7 @@
 
 	var result CreateResult
 	_, result.Err = perigee.Request("POST", listURL(client), perigee.Options{
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &result.Body,
 		OkCodes:     []int{201},
@@ -98,7 +97,7 @@
 		return EndpointPage{pagination.LinkedPageBase{PageResult: r}}
 	}
 
-	u := listURL(client) + utils.BuildQuery(q)
+	u := listURL(client) + gophercloud.BuildQuery(q)
 	return pagination.NewPager(client, u, createPage)
 }
 
@@ -126,7 +125,7 @@
 
 	var result UpdateResult
 	_, result.Err = perigee.Request("PATCH", endpointURL(client, endpointID), perigee.Options{
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &result.Body,
 		OkCodes:     []int{200},
@@ -137,7 +136,7 @@
 // Delete removes an endpoint from the service catalog.
 func Delete(client *gophercloud.ServiceClient, endpointID string) error {
 	_, err := perigee.Request("DELETE", endpointURL(client, endpointID), perigee.Options{
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		OkCodes:     []int{204},
 	})
 	return err
diff --git a/openstack/identity/v3/endpoints/requests_test.go b/openstack/identity/v3/endpoints/requests_test.go
index c30bd55..381461c 100644
--- a/openstack/identity/v3/endpoints/requests_test.go
+++ b/openstack/identity/v3/endpoints/requests_test.go
@@ -9,24 +9,16 @@
 	"github.com/rackspace/gophercloud"
 	"github.com/rackspace/gophercloud/pagination"
 	"github.com/rackspace/gophercloud/testhelper"
+	"github.com/rackspace/gophercloud/testhelper/client"
 )
 
-const tokenID = "abcabcabcabc"
-
-func serviceClient() *gophercloud.ServiceClient {
-	return &gophercloud.ServiceClient{
-		Provider: &gophercloud.ProviderClient{TokenID: tokenID},
-		Endpoint: testhelper.Endpoint(),
-	}
-}
-
 func TestCreateSuccessful(t *testing.T) {
 	testhelper.SetupHTTP()
 	defer testhelper.TeardownHTTP()
 
 	testhelper.Mux.HandleFunc("/endpoints", func(w http.ResponseWriter, r *http.Request) {
 		testhelper.TestMethod(t, r, "POST")
-		testhelper.TestHeader(t, r, "X-Auth-Token", tokenID)
+		testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 		testhelper.TestJSONRequest(t, r, `
       {
         "endpoint": {
@@ -57,9 +49,7 @@
     `)
 	})
 
-	client := serviceClient()
-
-	actual, err := Create(client, EndpointOpts{
+	actual, err := Create(client.ServiceClient(), EndpointOpts{
 		Availability: gophercloud.AvailabilityPublic,
 		Name:         "the-endiest-of-points",
 		Region:       "underground",
@@ -90,7 +80,7 @@
 
 	testhelper.Mux.HandleFunc("/endpoints", func(w http.ResponseWriter, r *http.Request) {
 		testhelper.TestMethod(t, r, "GET")
-		testhelper.TestHeader(t, r, "X-Auth-Token", tokenID)
+		testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 
 		w.Header().Add("Content-Type", "application/json")
 		fmt.Fprintf(w, `
@@ -127,10 +117,8 @@
 		`)
 	})
 
-	client := serviceClient()
-
 	count := 0
-	List(client, ListOpts{}).EachPage(func(page pagination.Page) (bool, error) {
+	List(client.ServiceClient(), ListOpts{}).EachPage(func(page pagination.Page) (bool, error) {
 		count++
 		actual, err := ExtractEndpoints(page)
 		if err != nil {
@@ -174,7 +162,7 @@
 
 	testhelper.Mux.HandleFunc("/endpoints/12", func(w http.ResponseWriter, r *http.Request) {
 		testhelper.TestMethod(t, r, "PATCH")
-		testhelper.TestHeader(t, r, "X-Auth-Token", tokenID)
+		testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 		testhelper.TestJSONRequest(t, r, `
 		{
 	    "endpoint": {
@@ -201,8 +189,7 @@
 	`)
 	})
 
-	client := serviceClient()
-	actual, err := Update(client, "12", EndpointOpts{
+	actual, err := Update(client.ServiceClient(), "12", EndpointOpts{
 		Name:   "renamed",
 		Region: "somewhere-else",
 	}).Extract()
@@ -229,14 +216,12 @@
 
 	testhelper.Mux.HandleFunc("/endpoints/34", func(w http.ResponseWriter, r *http.Request) {
 		testhelper.TestMethod(t, r, "DELETE")
-		testhelper.TestHeader(t, r, "X-Auth-Token", tokenID)
+		testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 
 		w.WriteHeader(http.StatusNoContent)
 	})
 
-	client := serviceClient()
-
-	err := Delete(client, "34")
+	err := Delete(client.ServiceClient(), "34")
 	if err != nil {
 		t.Fatalf("Unexpected error from Delete: %v", err)
 	}
diff --git a/openstack/identity/v3/services/requests.go b/openstack/identity/v3/services/requests.go
index a3eefea..425a67c 100644
--- a/openstack/identity/v3/services/requests.go
+++ b/openstack/identity/v3/services/requests.go
@@ -5,7 +5,6 @@
 
 	"github.com/racker/perigee"
 	"github.com/rackspace/gophercloud"
-	"github.com/rackspace/gophercloud/openstack/utils"
 	"github.com/rackspace/gophercloud/pagination"
 )
 
@@ -23,7 +22,7 @@
 
 	var result CreateResult
 	_, result.Err = perigee.Request("POST", listURL(client), perigee.Options{
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		ReqBody:     &req,
 		Results:     &result.Body,
 		OkCodes:     []int{201},
@@ -50,7 +49,7 @@
 	if opts.PerPage != 0 {
 		q["perPage"] = strconv.Itoa(opts.PerPage)
 	}
-	u := listURL(client) + utils.BuildQuery(q)
+	u := listURL(client) + gophercloud.BuildQuery(q)
 
 	createPage := func(r pagination.PageResult) pagination.Page {
 		return ServicePage{pagination.LinkedPageBase{PageResult: r}}
@@ -63,7 +62,7 @@
 func Get(client *gophercloud.ServiceClient, serviceID string) GetResult {
 	var result GetResult
 	_, result.Err = perigee.Request("GET", serviceURL(client, serviceID), perigee.Options{
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		Results:     &result.Body,
 		OkCodes:     []int{200},
 	})
@@ -80,7 +79,7 @@
 
 	var result UpdateResult
 	_, result.Err = perigee.Request("PATCH", serviceURL(client, serviceID), perigee.Options{
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		ReqBody:     &req,
 		Results:     &result.Body,
 		OkCodes:     []int{200},
@@ -92,7 +91,7 @@
 // It either deletes all associated endpoints, or fails until all endpoints are deleted.
 func Delete(client *gophercloud.ServiceClient, serviceID string) error {
 	_, err := perigee.Request("DELETE", serviceURL(client, serviceID), perigee.Options{
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
+		MoreHeaders: client.AuthenticatedHeaders(),
 		OkCodes:     []int{204},
 	})
 	return err
diff --git a/openstack/identity/v3/services/requests_test.go b/openstack/identity/v3/services/requests_test.go
index a3d345b..337647c 100644
--- a/openstack/identity/v3/services/requests_test.go
+++ b/openstack/identity/v3/services/requests_test.go
@@ -6,29 +6,18 @@
 	"reflect"
 	"testing"
 
-	"github.com/rackspace/gophercloud"
 	"github.com/rackspace/gophercloud/pagination"
 	"github.com/rackspace/gophercloud/testhelper"
+	"github.com/rackspace/gophercloud/testhelper/client"
 )
 
-const tokenID = "111111"
-
-func serviceClient() *gophercloud.ServiceClient {
-	return &gophercloud.ServiceClient{
-		Provider: &gophercloud.ProviderClient{
-			TokenID: tokenID,
-		},
-		Endpoint: testhelper.Endpoint(),
-	}
-}
-
 func TestCreateSuccessful(t *testing.T) {
 	testhelper.SetupHTTP()
 	defer testhelper.TeardownHTTP()
 
 	testhelper.Mux.HandleFunc("/services", func(w http.ResponseWriter, r *http.Request) {
 		testhelper.TestMethod(t, r, "POST")
-		testhelper.TestHeader(t, r, "X-Auth-Token", tokenID)
+		testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 		testhelper.TestJSONRequest(t, r, `{ "type": "compute" }`)
 
 		w.Header().Add("Content-Type", "application/json")
@@ -43,9 +32,7 @@
     }`)
 	})
 
-	client := serviceClient()
-
-	result, err := Create(client, "compute").Extract()
+	result, err := Create(client.ServiceClient(), "compute").Extract()
 	if err != nil {
 		t.Fatalf("Unexpected error from Create: %v", err)
 	}
@@ -70,7 +57,7 @@
 
 	testhelper.Mux.HandleFunc("/services", func(w http.ResponseWriter, r *http.Request) {
 		testhelper.TestMethod(t, r, "GET")
-		testhelper.TestHeader(t, r, "X-Auth-Token", tokenID)
+		testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 
 		w.Header().Add("Content-Type", "application/json")
 		fmt.Fprintf(w, `
@@ -97,10 +84,8 @@
 		`)
 	})
 
-	client := serviceClient()
-
 	count := 0
-	err := List(client, ListOpts{}).EachPage(func(page pagination.Page) (bool, error) {
+	err := List(client.ServiceClient(), ListOpts{}).EachPage(func(page pagination.Page) (bool, error) {
 		count++
 		actual, err := ExtractServices(page)
 		if err != nil {
@@ -144,7 +129,7 @@
 
 	testhelper.Mux.HandleFunc("/services/12345", func(w http.ResponseWriter, r *http.Request) {
 		testhelper.TestMethod(t, r, "GET")
-		testhelper.TestHeader(t, r, "X-Auth-Token", tokenID)
+		testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 
 		w.Header().Add("Content-Type", "application/json")
 		fmt.Fprintf(w, `
@@ -159,9 +144,7 @@
 		`)
 	})
 
-	client := serviceClient()
-
-	result, err := Get(client, "12345").Extract()
+	result, err := Get(client.ServiceClient(), "12345").Extract()
 	if err != nil {
 		t.Fatalf("Error fetching service information: %v", err)
 	}
@@ -186,7 +169,7 @@
 
 	testhelper.Mux.HandleFunc("/services/12345", func(w http.ResponseWriter, r *http.Request) {
 		testhelper.TestMethod(t, r, "PATCH")
-		testhelper.TestHeader(t, r, "X-Auth-Token", tokenID)
+		testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 		testhelper.TestJSONRequest(t, r, `{ "type": "lasermagic" }`)
 
 		w.Header().Add("Content-Type", "application/json")
@@ -200,9 +183,7 @@
 		`)
 	})
 
-	client := serviceClient()
-
-	result, err := Update(client, "12345", "lasermagic").Extract()
+	result, err := Update(client.ServiceClient(), "12345", "lasermagic").Extract()
 	if err != nil {
 		t.Fatalf("Unable to update service: %v", err)
 	}
@@ -218,14 +199,12 @@
 
 	testhelper.Mux.HandleFunc("/services/12345", func(w http.ResponseWriter, r *http.Request) {
 		testhelper.TestMethod(t, r, "DELETE")
-		testhelper.TestHeader(t, r, "X-Auth-Token", tokenID)
+		testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID)
 
 		w.WriteHeader(http.StatusNoContent)
 	})
 
-	client := serviceClient()
-
-	err := Delete(client, "12345")
+	err := Delete(client.ServiceClient(), "12345")
 	if err != nil {
 		t.Fatalf("Unable to delete service: %v", err)
 	}
diff --git a/openstack/identity/v3/tokens/requests.go b/openstack/identity/v3/tokens/requests.go
index dfef0ce..351d7d6 100644
--- a/openstack/identity/v3/tokens/requests.go
+++ b/openstack/identity/v3/tokens/requests.go
@@ -14,7 +14,7 @@
 }
 
 func subjectTokenHeaders(c *gophercloud.ServiceClient, subjectToken string) map[string]string {
-	h := c.Provider.AuthenticatedHeaders()
+	h := c.AuthenticatedHeaders()
 	h["X-Subject-Token"] = subjectToken
 	return h
 }
@@ -83,7 +83,7 @@
 	}
 
 	if options.Password == "" {
-		if c.Provider.TokenID != "" {
+		if c.TokenID != "" {
 			// Because we aren't using password authentication, it's an error to also provide any of the user-based authentication
 			// parameters.
 			if options.Username != "" {
@@ -102,7 +102,7 @@
 			// Configure the request for Token authentication.
 			req.Auth.Identity.Methods = []string{"token"}
 			req.Auth.Identity.Token = &tokenReq{
-				ID: c.Provider.TokenID,
+				ID: c.TokenID,
 			}
 		} else {
 			// If no password or token ID are available, authentication can't continue.
diff --git a/openstack/identity/v3/tokens/requests_test.go b/openstack/identity/v3/tokens/requests_test.go
index 367c73c..a61bb2c 100644
--- a/openstack/identity/v3/tokens/requests_test.go
+++ b/openstack/identity/v3/tokens/requests_test.go
@@ -16,7 +16,7 @@
 	defer testhelper.TeardownHTTP()
 
 	client := gophercloud.ServiceClient{
-		Provider: &gophercloud.ProviderClient{
+		ProviderClient: &gophercloud.ProviderClient{
 			TokenID: "12345abcdef",
 		},
 		Endpoint: testhelper.Endpoint(),
@@ -47,11 +47,11 @@
 	defer testhelper.TeardownHTTP()
 
 	client := gophercloud.ServiceClient{
-		Provider: &gophercloud.ProviderClient{},
-		Endpoint: testhelper.Endpoint(),
+		ProviderClient: &gophercloud.ProviderClient{},
+		Endpoint:       testhelper.Endpoint(),
 	}
 	if includeToken {
-		client.Provider.TokenID = "abcdef123456"
+		client.TokenID = "abcdef123456"
 	}
 
 	_, err := Create(&client, options, scope).Extract()
@@ -246,8 +246,8 @@
 	defer testhelper.TeardownHTTP()
 
 	client := gophercloud.ServiceClient{
-		Provider: &gophercloud.ProviderClient{},
-		Endpoint: testhelper.Endpoint(),
+		ProviderClient: &gophercloud.ProviderClient{},
+		Endpoint:       testhelper.Endpoint(),
 	}
 
 	testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
@@ -401,7 +401,7 @@
 	defer testhelper.TeardownHTTP()
 
 	client := gophercloud.ServiceClient{
-		Provider: &gophercloud.ProviderClient{
+		ProviderClient: &gophercloud.ProviderClient{
 			TokenID: "12345abcdef",
 		},
 		Endpoint: testhelper.Endpoint(),
@@ -433,7 +433,7 @@
 
 func prepareAuthTokenHandler(t *testing.T, expectedMethod string, status int) gophercloud.ServiceClient {
 	client := gophercloud.ServiceClient{
-		Provider: &gophercloud.ProviderClient{
+		ProviderClient: &gophercloud.ProviderClient{
 			TokenID: "12345abcdef",
 		},
 		Endpoint: testhelper.Endpoint(),
diff --git a/openstack/networking/v2/extensions/layer3/floatingips/requests.go b/openstack/networking/v2/extensions/layer3/floatingips/requests.go
index a0a17fd..d23f9e2 100644
--- a/openstack/networking/v2/extensions/layer3/floatingips/requests.go
+++ b/openstack/networking/v2/extensions/layer3/floatingips/requests.go
@@ -115,7 +115,7 @@
 
 	// Send request to API
 	_, res.Err = perigee.Request("POST", rootURL(c), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
 		OkCodes:     []int{201},
@@ -128,7 +128,7 @@
 func Get(c *gophercloud.ServiceClient, id string) GetResult {
 	var res GetResult
 	_, res.Err = perigee.Request("GET", resourceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		Results:     &res.Body,
 		OkCodes:     []int{200},
 	})
@@ -168,7 +168,7 @@
 	// Send request to API
 	var res UpdateResult
 	_, res.Err = perigee.Request("PUT", resourceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
 		OkCodes:     []int{200},
@@ -183,7 +183,7 @@
 func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
 	var res DeleteResult
 	_, res.Err = perigee.Request("DELETE", resourceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		OkCodes:     []int{204},
 	})
 	return res
diff --git a/openstack/networking/v2/extensions/layer3/routers/requests.go b/openstack/networking/v2/extensions/layer3/routers/requests.go
index 52afc4f..e3a1441 100755
--- a/openstack/networking/v2/extensions/layer3/routers/requests.go
+++ b/openstack/networking/v2/extensions/layer3/routers/requests.go
@@ -83,7 +83,7 @@
 
 	var res CreateResult
 	_, res.Err = perigee.Request("POST", rootURL(c), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
 		OkCodes:     []int{201},
@@ -95,7 +95,7 @@
 func Get(c *gophercloud.ServiceClient, id string) GetResult {
 	var res GetResult
 	_, res.Err = perigee.Request("GET", resourceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		Results:     &res.Body,
 		OkCodes:     []int{200},
 	})
@@ -137,7 +137,7 @@
 	// Send request to API
 	var res UpdateResult
 	_, res.Err = perigee.Request("PUT", resourceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
 		OkCodes:     []int{200},
@@ -150,7 +150,7 @@
 func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
 	var res DeleteResult
 	_, res.Err = perigee.Request("DELETE", resourceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		OkCodes:     []int{204},
 	})
 	return res
@@ -203,7 +203,7 @@
 	body := request{SubnetID: opts.SubnetID, PortID: opts.PortID}
 
 	_, res.Err = perigee.Request("PUT", addInterfaceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &body,
 		Results:     &res.Body,
 		OkCodes:     []int{200},
@@ -236,7 +236,7 @@
 	body := request{SubnetID: opts.SubnetID, PortID: opts.PortID}
 
 	_, res.Err = perigee.Request("PUT", removeInterfaceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &body,
 		Results:     &res.Body,
 		OkCodes:     []int{200},
diff --git a/openstack/networking/v2/extensions/lbaas/members/requests.go b/openstack/networking/v2/extensions/lbaas/members/requests.go
index c13f0fe..58ec580 100644
--- a/openstack/networking/v2/extensions/lbaas/members/requests.go
+++ b/openstack/networking/v2/extensions/lbaas/members/requests.go
@@ -81,7 +81,7 @@
 
 	var res CreateResult
 	_, res.Err = perigee.Request("POST", rootURL(c), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
 		OkCodes:     []int{201},
@@ -93,7 +93,7 @@
 func Get(c *gophercloud.ServiceClient, id string) GetResult {
 	var res GetResult
 	_, res.Err = perigee.Request("GET", resourceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		Results:     &res.Body,
 		OkCodes:     []int{200},
 	})
@@ -120,7 +120,7 @@
 	// Send request to API
 	var res UpdateResult
 	_, res.Err = perigee.Request("PUT", resourceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
 		OkCodes:     []int{200},
@@ -132,7 +132,7 @@
 func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
 	var res DeleteResult
 	_, res.Err = perigee.Request("DELETE", resourceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		OkCodes:     []int{204},
 	})
 	return res
diff --git a/openstack/networking/v2/extensions/lbaas/monitors/requests.go b/openstack/networking/v2/extensions/lbaas/monitors/requests.go
index 9f8ac9a..e2b590e 100644
--- a/openstack/networking/v2/extensions/lbaas/monitors/requests.go
+++ b/openstack/networking/v2/extensions/lbaas/monitors/requests.go
@@ -64,6 +64,7 @@
 	errMaxRetriesRequired    = fmt.Errorf("MaxRetries is required")
 	errURLPathRequired       = fmt.Errorf("URL path is required")
 	errExpectedCodesRequired = fmt.Errorf("ExpectedCodes is required")
+	errDelayMustGETimeout    = fmt.Errorf("Delay must be greater than or equal to timeout")
 )
 
 // CreateOpts contains all the values needed to create a new health monitor.
@@ -141,6 +142,9 @@
 			res.Err = errExpectedCodesRequired
 		}
 	}
+	if opts.Delay < opts.Timeout {
+		res.Err = errDelayMustGETimeout
+	}
 	if res.Err != nil {
 		return res
 	}
@@ -174,7 +178,7 @@
 	}}
 
 	_, res.Err = perigee.Request("POST", rootURL(c), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
 		OkCodes:     []int{201},
@@ -187,7 +191,7 @@
 func Get(c *gophercloud.ServiceClient, id string) GetResult {
 	var res GetResult
 	_, res.Err = perigee.Request("GET", resourceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		Results:     &res.Body,
 		OkCodes:     []int{200},
 	})
@@ -227,6 +231,12 @@
 
 // Update is an operation which modifies the attributes of the specified monitor.
 func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) UpdateResult {
+	var res UpdateResult
+
+	if opts.Delay > 0 && opts.Timeout > 0 && opts.Delay < opts.Timeout {
+		res.Err = errDelayMustGETimeout
+	}
+
 	type monitor struct {
 		Delay         int     `json:"delay"`
 		Timeout       int     `json:"timeout"`
@@ -251,10 +261,8 @@
 		AdminStateUp:  opts.AdminStateUp,
 	}}
 
-	var res UpdateResult
-
 	_, res.Err = perigee.Request("PUT", resourceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
 		OkCodes:     []int{200, 202},
@@ -267,7 +275,7 @@
 func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
 	var res DeleteResult
 	_, res.Err = perigee.Request("DELETE", resourceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		OkCodes:     []int{204},
 	})
 	return res
diff --git a/openstack/networking/v2/extensions/lbaas/monitors/requests_test.go b/openstack/networking/v2/extensions/lbaas/monitors/requests_test.go
index 5c5a1d2..79a99bf 100644
--- a/openstack/networking/v2/extensions/lbaas/monitors/requests_test.go
+++ b/openstack/networking/v2/extensions/lbaas/monitors/requests_test.go
@@ -100,6 +100,30 @@
 	}
 }
 
+func TestDelayMustBeGreaterOrEqualThanTimeout(t *testing.T) {
+	_, err := Create(fake.ServiceClient(), CreateOpts{
+		Type:          "HTTP",
+		Delay:         1,
+		Timeout:       10,
+		MaxRetries:    5,
+		URLPath:       "/check",
+		ExpectedCodes: "200-299",
+	}).Extract()
+
+	if err == nil {
+		t.Fatalf("Expected error, got none")
+	}
+
+	_, err = Update(fake.ServiceClient(), "453105b9-1754-413f-aab1-55f1af620750", UpdateOpts{
+		Delay:   1,
+		Timeout: 10,
+	}).Extract()
+
+	if err == nil {
+		t.Fatalf("Expected error, got none")
+	}
+}
+
 func TestCreate(t *testing.T) {
 	th.SetupHTTP()
 	defer th.TeardownHTTP()
diff --git a/openstack/networking/v2/extensions/lbaas/pools/requests.go b/openstack/networking/v2/extensions/lbaas/pools/requests.go
index 6e5b87a..ca8d33b 100644
--- a/openstack/networking/v2/extensions/lbaas/pools/requests.go
+++ b/openstack/networking/v2/extensions/lbaas/pools/requests.go
@@ -101,7 +101,7 @@
 
 	var res CreateResult
 	_, res.Err = perigee.Request("POST", rootURL(c), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
 		OkCodes:     []int{201},
@@ -113,7 +113,7 @@
 func Get(c *gophercloud.ServiceClient, id string) GetResult {
 	var res GetResult
 	_, res.Err = perigee.Request("GET", resourceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		Results:     &res.Body,
 		OkCodes:     []int{200},
 	})
@@ -149,7 +149,7 @@
 	// Send request to API
 	var res UpdateResult
 	_, res.Err = perigee.Request("PUT", resourceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
 		OkCodes:     []int{200},
@@ -161,7 +161,7 @@
 func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
 	var res DeleteResult
 	_, res.Err = perigee.Request("DELETE", resourceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		OkCodes:     []int{204},
 	})
 	return res
@@ -184,7 +184,7 @@
 
 	var res AssociateResult
 	_, res.Err = perigee.Request("POST", associateURL(c, poolID), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
 		OkCodes:     []int{201},
@@ -198,7 +198,7 @@
 func DisassociateMonitor(c *gophercloud.ServiceClient, poolID, monitorID string) AssociateResult {
 	var res AssociateResult
 	_, res.Err = perigee.Request("DELETE", disassociateURL(c, poolID, monitorID), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		OkCodes:     []int{204},
 	})
 	return res
diff --git a/openstack/networking/v2/extensions/lbaas/vips/requests.go b/openstack/networking/v2/extensions/lbaas/vips/requests.go
index 6c4ee3d..ec929d6 100644
--- a/openstack/networking/v2/extensions/lbaas/vips/requests.go
+++ b/openstack/networking/v2/extensions/lbaas/vips/requests.go
@@ -180,7 +180,7 @@
 	}
 
 	_, res.Err = perigee.Request("POST", rootURL(c), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
 		OkCodes:     []int{201},
@@ -193,7 +193,7 @@
 func Get(c *gophercloud.ServiceClient, id string) GetResult {
 	var res GetResult
 	_, res.Err = perigee.Request("GET", resourceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		Results:     &res.Body,
 		OkCodes:     []int{200},
 	})
@@ -253,7 +253,7 @@
 
 	var res UpdateResult
 	_, res.Err = perigee.Request("PUT", resourceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
 		OkCodes:     []int{200, 202},
@@ -266,7 +266,7 @@
 func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
 	var res DeleteResult
 	_, res.Err = perigee.Request("DELETE", resourceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		OkCodes:     []int{204},
 	})
 	return res
diff --git a/openstack/networking/v2/extensions/security/groups/requests.go b/openstack/networking/v2/extensions/security/groups/requests.go
index 6b33e06..0c970ae 100644
--- a/openstack/networking/v2/extensions/security/groups/requests.go
+++ b/openstack/networking/v2/extensions/security/groups/requests.go
@@ -76,7 +76,7 @@
 	}}
 
 	_, res.Err = perigee.Request("POST", rootURL(c), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
 		OkCodes:     []int{201},
@@ -89,7 +89,7 @@
 func Get(c *gophercloud.ServiceClient, id string) GetResult {
 	var res GetResult
 	_, res.Err = perigee.Request("GET", resourceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		Results:     &res.Body,
 		OkCodes:     []int{200},
 	})
@@ -100,7 +100,7 @@
 func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
 	var res DeleteResult
 	_, res.Err = perigee.Request("DELETE", resourceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		OkCodes:     []int{204},
 	})
 	return res
diff --git a/openstack/networking/v2/extensions/security/rules/requests.go b/openstack/networking/v2/extensions/security/rules/requests.go
index f243572..edaebe8 100644
--- a/openstack/networking/v2/extensions/security/rules/requests.go
+++ b/openstack/networking/v2/extensions/security/rules/requests.go
@@ -152,7 +152,7 @@
 	}}
 
 	_, res.Err = perigee.Request("POST", rootURL(c), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
 		OkCodes:     []int{201},
@@ -165,7 +165,7 @@
 func Get(c *gophercloud.ServiceClient, id string) GetResult {
 	var res GetResult
 	_, res.Err = perigee.Request("GET", resourceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		Results:     &res.Body,
 		OkCodes:     []int{200},
 	})
@@ -176,7 +176,7 @@
 func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
 	var res DeleteResult
 	_, res.Err = perigee.Request("DELETE", resourceURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		OkCodes:     []int{204},
 	})
 	return res
diff --git a/openstack/networking/v2/networks/requests.go b/openstack/networking/v2/networks/requests.go
index a82eeb2..eaa7136 100644
--- a/openstack/networking/v2/networks/requests.go
+++ b/openstack/networking/v2/networks/requests.go
@@ -82,7 +82,7 @@
 func Get(c *gophercloud.ServiceClient, id string) GetResult {
 	var res GetResult
 	_, res.Err = perigee.Request("GET", getURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		Results:     &res.Body,
 		OkCodes:     []int{200},
 	})
@@ -139,7 +139,7 @@
 
 	// Send request to API
 	_, res.Err = perigee.Request("POST", createURL(c), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
 		OkCodes:     []int{201},
@@ -189,7 +189,7 @@
 
 	// Send request to API
 	_, res.Err = perigee.Request("PUT", getURL(c, networkID), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
 		OkCodes:     []int{200, 201},
@@ -202,7 +202,7 @@
 func Delete(c *gophercloud.ServiceClient, networkID string) DeleteResult {
 	var res DeleteResult
 	_, res.Err = perigee.Request("DELETE", deleteURL(c, networkID), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		OkCodes:     []int{204},
 	})
 	return res
diff --git a/openstack/networking/v2/ports/requests.go b/openstack/networking/v2/ports/requests.go
index 78aebae..8210801 100644
--- a/openstack/networking/v2/ports/requests.go
+++ b/openstack/networking/v2/ports/requests.go
@@ -82,7 +82,7 @@
 func Get(c *gophercloud.ServiceClient, id string) GetResult {
 	var res GetResult
 	_, res.Err = perigee.Request("GET", getURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		Results:     &res.Body,
 		OkCodes:     []int{200},
 	})
@@ -160,7 +160,7 @@
 
 	// Response
 	_, res.Err = perigee.Request("POST", createURL(c), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
 		OkCodes:     []int{201},
@@ -226,7 +226,7 @@
 	}
 
 	_, res.Err = perigee.Request("PUT", updateURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
 		OkCodes:     []int{200, 201},
@@ -238,7 +238,7 @@
 func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
 	var res DeleteResult
 	_, res.Err = perigee.Request("DELETE", deleteURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		OkCodes:     []int{204},
 	})
 	return res
diff --git a/openstack/networking/v2/subnets/requests.go b/openstack/networking/v2/subnets/requests.go
index 17c5b82..2e6d670 100644
--- a/openstack/networking/v2/subnets/requests.go
+++ b/openstack/networking/v2/subnets/requests.go
@@ -81,7 +81,7 @@
 func Get(c *gophercloud.ServiceClient, id string) GetResult {
 	var res GetResult
 	_, res.Err = perigee.Request("GET", getURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		Results:     &res.Body,
 		OkCodes:     []int{200},
 	})
@@ -175,7 +175,7 @@
 	}
 
 	_, res.Err = perigee.Request("POST", createURL(c), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
 		OkCodes:     []int{201},
@@ -234,7 +234,7 @@
 	}
 
 	_, res.Err = perigee.Request("PUT", updateURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res.Body,
 		OkCodes:     []int{200, 201},
@@ -247,7 +247,7 @@
 func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
 	var res DeleteResult
 	_, res.Err = perigee.Request("DELETE", deleteURL(c, id), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		OkCodes:     []int{204},
 	})
 	return res
diff --git a/openstack/objectstorage/v1/accounts/requests.go b/openstack/objectstorage/v1/accounts/requests.go
index a364bcc..55b4217 100644
--- a/openstack/objectstorage/v1/accounts/requests.go
+++ b/openstack/objectstorage/v1/accounts/requests.go
@@ -28,7 +28,7 @@
 // ExtractHeaders method on the GetResult.
 func Get(c *gophercloud.ServiceClient, opts GetOptsBuilder) GetResult {
 	var res GetResult
-	h := c.Provider.AuthenticatedHeaders()
+	h := c.AuthenticatedHeaders()
 
 	if opts != nil {
 		headers, err := opts.ToAccountGetMap()
@@ -83,7 +83,7 @@
 // To extract the headers returned, call the Extract method on the UpdateResult.
 func Update(c *gophercloud.ServiceClient, opts UpdateOptsBuilder) UpdateResult {
 	var res UpdateResult
-	h := c.Provider.AuthenticatedHeaders()
+	h := c.AuthenticatedHeaders()
 
 	if opts != nil {
 		headers, err := opts.ToAccountUpdateMap()
diff --git a/openstack/objectstorage/v1/containers/requests.go b/openstack/objectstorage/v1/containers/requests.go
index 89fa014..3fae4d9 100644
--- a/openstack/objectstorage/v1/containers/requests.go
+++ b/openstack/objectstorage/v1/containers/requests.go
@@ -97,7 +97,7 @@
 // Create is a function that creates a new container.
 func Create(c *gophercloud.ServiceClient, containerName string, opts CreateOptsBuilder) CreateResult {
 	var res CreateResult
-	h := c.Provider.AuthenticatedHeaders()
+	h := c.AuthenticatedHeaders()
 
 	if opts != nil {
 		headers, err := opts.ToContainerCreateMap()
@@ -124,7 +124,7 @@
 func Delete(c *gophercloud.ServiceClient, containerName string) DeleteResult {
 	var res DeleteResult
 	resp, err := perigee.Request("DELETE", deleteURL(c, containerName), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		OkCodes:     []int{202, 204},
 	})
 	res.Header = resp.HttpResponse.Header
@@ -168,7 +168,7 @@
 // metadata.
 func Update(c *gophercloud.ServiceClient, containerName string, opts UpdateOptsBuilder) UpdateResult {
 	var res UpdateResult
-	h := c.Provider.AuthenticatedHeaders()
+	h := c.AuthenticatedHeaders()
 
 	if opts != nil {
 		headers, err := opts.ToContainerUpdateMap()
@@ -197,7 +197,7 @@
 func Get(c *gophercloud.ServiceClient, containerName string) GetResult {
 	var res GetResult
 	resp, err := perigee.Request("HEAD", getURL(c, containerName), perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		OkCodes:     []int{200, 204},
 	})
 	res.Header = resp.HttpResponse.Header
diff --git a/openstack/objectstorage/v1/objects/requests.go b/openstack/objectstorage/v1/objects/requests.go
index 7d598b8..1b6cb5c 100644
--- a/openstack/objectstorage/v1/objects/requests.go
+++ b/openstack/objectstorage/v1/objects/requests.go
@@ -109,7 +109,7 @@
 	var res DownloadResult
 
 	url := downloadURL(c, containerName, objectName)
-	h := c.Provider.AuthenticatedHeaders()
+	h := c.AuthenticatedHeaders()
 
 	if opts != nil {
 		headers, query, err := opts.ToObjectDownloadParams()
@@ -187,7 +187,7 @@
 	var res CreateResult
 
 	url := createURL(c, containerName, objectName)
-	h := c.Provider.AuthenticatedHeaders()
+	h := c.AuthenticatedHeaders()
 
 	if opts != nil {
 		headers, query, err := opts.ToObjectCreateParams()
@@ -250,7 +250,7 @@
 // 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.Provider.AuthenticatedHeaders()
+	h := c.AuthenticatedHeaders()
 
 	headers, err := opts.ToObjectCopyMap()
 	if err != nil {
@@ -306,7 +306,7 @@
 	}
 
 	resp, err := perigee.Request("DELETE", url, perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		OkCodes:     []int{204},
 	})
 	res.Header = resp.HttpResponse.Header
@@ -351,7 +351,7 @@
 	}
 
 	resp, err := perigee.Request("HEAD", url, perigee.Options{
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		OkCodes:     []int{200, 204},
 	})
 	res.Header = resp.HttpResponse.Header
@@ -392,7 +392,7 @@
 // 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
-	h := c.Provider.AuthenticatedHeaders()
+	h := c.AuthenticatedHeaders()
 
 	if opts != nil {
 		headers, err := opts.ToObjectUpdateMap()
diff --git a/pagination/http.go b/pagination/http.go
index ba2c615..1e108c8 100644
--- a/pagination/http.go
+++ b/pagination/http.go
@@ -48,7 +48,7 @@
 
 // Request performs a Perigee request and extracts the http.Response from the result.
 func Request(client *gophercloud.ServiceClient, headers map[string]string, url string) (http.Response, error) {
-	h := client.Provider.AuthenticatedHeaders()
+	h := client.AuthenticatedHeaders()
 	for key, value := range headers {
 		h[key] = value
 	}
diff --git a/pagination/pagination_test.go b/pagination/pagination_test.go
index 779bd79..f3e4de1 100644
--- a/pagination/pagination_test.go
+++ b/pagination/pagination_test.go
@@ -7,7 +7,7 @@
 
 func createClient() *gophercloud.ServiceClient {
 	return &gophercloud.ServiceClient{
-		Provider: &gophercloud.ProviderClient{TokenID: "abc123"},
-		Endpoint: testhelper.Endpoint(),
+		ProviderClient: &gophercloud.ProviderClient{TokenID: "abc123"},
+		Endpoint:       testhelper.Endpoint(),
 	}
 }
diff --git a/rackspace/auth_env.go b/rackspace/auth_env.go
new file mode 100644
index 0000000..1706cc4
--- /dev/null
+++ b/rackspace/auth_env.go
@@ -0,0 +1,49 @@
+package rackspace
+
+import (
+	"fmt"
+	"os"
+
+	"github.com/rackspace/gophercloud"
+)
+
+var nilOptions = gophercloud.AuthOptions{}
+
+// ErrNoAuthUrl, ErrNoUsername, and ErrNoPassword errors indicate of the
+// required RAX_AUTH_URL, RAX_USERNAME, or RAX_PASSWORD environment variables,
+// respectively, remain undefined.  See the AuthOptions() function for more details.
+var (
+	ErrNoAuthURL  = fmt.Errorf("Environment variable RAX_AUTH_URL needs to be set.")
+	ErrNoUsername = fmt.Errorf("Environment variable RAX_USERNAME needs to be set.")
+	ErrNoPassword = fmt.Errorf("Environment variable RAX_API_KEY or RAX_PASSWORD needs to be set.")
+)
+
+// AuthOptionsFromEnv fills out an identity.AuthOptions structure with the
+// settings found on the various Rackspace RAX_* environment variables.
+func AuthOptionsFromEnv() (gophercloud.AuthOptions, error) {
+	authURL := os.Getenv("RAX_AUTH_URL")
+	username := os.Getenv("RAX_USERNAME")
+	password := os.Getenv("RAX_PASSWORD")
+	apiKey := os.Getenv("RAX_API_KEY")
+
+	if authURL == "" {
+		return nilOptions, ErrNoAuthURL
+	}
+
+	if username == "" {
+		return nilOptions, ErrNoUsername
+	}
+
+	if password == "" && apiKey == "" {
+		return nilOptions, ErrNoPassword
+	}
+
+	ao := gophercloud.AuthOptions{
+		IdentityEndpoint: authURL,
+		Username:         username,
+		Password:         password,
+		APIKey:           apiKey,
+	}
+
+	return ao, nil
+}
diff --git a/rackspace/client.go b/rackspace/client.go
index cf00dc7..6488829 100644
--- a/rackspace/client.go
+++ b/rackspace/client.go
@@ -109,8 +109,8 @@
 	v2Endpoint := client.IdentityBase + "v2.0/"
 
 	return &gophercloud.ServiceClient{
-		Provider: client,
-		Endpoint: v2Endpoint,
+		ProviderClient: client,
+		Endpoint:       v2Endpoint,
 	}
 }
 
@@ -135,7 +135,7 @@
 	if err != nil {
 		return nil, err
 	}
-	return &gophercloud.ServiceClient{Provider: client, Endpoint: url}, nil
+	return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
 }
 
 // NewObjectStorageV1 creates a ServiceClient that may be used with the Rackspace v1 object storage package.
diff --git a/rackspace/objectstorage/v1/bulk/requests.go b/rackspace/objectstorage/v1/bulk/requests.go
index 7a08869..d252609 100644
--- a/rackspace/objectstorage/v1/bulk/requests.go
+++ b/rackspace/objectstorage/v1/bulk/requests.go
@@ -40,7 +40,7 @@
 
 	resp, err := perigee.Request("DELETE", deleteURL(c), perigee.Options{
 		ContentType: "text/plain",
-		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		MoreHeaders: c.AuthenticatedHeaders(),
 		OkCodes:     []int{200},
 		ReqBody:     reqBody,
 		Results:     &res.Body,
diff --git a/rackspace/objectstorage/v1/cdncontainers/requests.go b/rackspace/objectstorage/v1/cdncontainers/requests.go
index 9cb6e9c..0567833 100644
--- a/rackspace/objectstorage/v1/cdncontainers/requests.go
+++ b/rackspace/objectstorage/v1/cdncontainers/requests.go
@@ -34,7 +34,7 @@
 // Enable is a function that enables/disables a CDN container.
 func Enable(c *gophercloud.ServiceClient, containerName string, opts EnableOptsBuilder) EnableResult {
 	var res EnableResult
-	h := c.Provider.AuthenticatedHeaders()
+	h := c.AuthenticatedHeaders()
 
 	if opts != nil {
 		headers, err := opts.ToCDNContainerEnableMap()
diff --git a/service_client.go b/service_client.go
index 55d3b98..3490da0 100644
--- a/service_client.go
+++ b/service_client.go
@@ -5,8 +5,8 @@
 // ServiceClient stores details required to interact with a specific service API implemented by a provider.
 // Generally, you'll acquire these by calling the appropriate `New` method on a ProviderClient.
 type ServiceClient struct {
-	// Provider is a reference to the provider that implements this service.
-	Provider *ProviderClient
+	// ProviderClient is a reference to the provider that implements this service.
+	*ProviderClient
 
 	// Endpoint is the base URL of the service's API, acquired from a service catalog.
 	// It MUST end with a /.
@@ -30,9 +30,3 @@
 func (client *ServiceClient) ServiceURL(parts ...string) string {
 	return client.ResourceBaseURL() + strings.Join(parts, "/")
 }
-
-// AuthenticatedHeaders returns a collection of HTTP request headers that mark a request as
-// belonging to the currently authenticated user.
-func (client *ServiceClient) AuthenticatedHeaders() map[string]string {
-	return client.Provider.AuthenticatedHeaders()
-}
diff --git a/testhelper/client/fake.go b/testhelper/client/fake.go
index 3eb9e12..5b69b05 100644
--- a/testhelper/client/fake.go
+++ b/testhelper/client/fake.go
@@ -11,7 +11,7 @@
 // ServiceClient returns a generic service client for use in tests.
 func ServiceClient() *gophercloud.ServiceClient {
 	return &gophercloud.ServiceClient{
-		Provider: &gophercloud.ProviderClient{TokenID: TokenID},
-		Endpoint: testhelper.Endpoint(),
+		ProviderClient: &gophercloud.ProviderClient{TokenID: TokenID},
+		Endpoint:       testhelper.Endpoint(),
 	}
 }
diff --git a/util.go b/util.go
index 1715458..c66af89 100644
--- a/util.go
+++ b/util.go
@@ -29,3 +29,17 @@
 	}
 	return url
 }
+
+// BuildQuery constructs the query section of a URI from a map.
+func BuildQuery(params map[string]string) string {
+	if len(params) == 0 {
+		return ""
+	}
+
+	query := "?"
+	for k, v := range params {
+		query += k + "=" + v + "&"
+	}
+	query = query[:len(query)-1]
+	return query
+}