Moving calls to client helper while I'm at it
diff --git a/_site/acceptance/openstack/identity/v3/endpoint_test.go b/_site/acceptance/openstack/identity/v3/endpoint_test.go
new file mode 100644
index 0000000..9032ec3
--- /dev/null
+++ b/_site/acceptance/openstack/identity/v3/endpoint_test.go
@@ -0,0 +1,108 @@
+// +build acceptance
+
+package v3
+
+import (
+	"testing"
+
+	"github.com/rackspace/gophercloud"
+	endpoints3 "github.com/rackspace/gophercloud/openstack/identity/v3/endpoints"
+	services3 "github.com/rackspace/gophercloud/openstack/identity/v3/services"
+	"github.com/rackspace/gophercloud/pagination"
+)
+
+func TestListEndpoints(t *testing.T) {
+	// Create a service client.
+	serviceClient := createAuthenticatedClient(t)
+	if serviceClient == nil {
+		return
+	}
+
+	// Use the service to list all available endpoints.
+	pager := endpoints3.List(serviceClient, endpoints3.ListOpts{})
+	err := pager.EachPage(func(page pagination.Page) (bool, error) {
+		t.Logf("--- Page ---")
+
+		endpoints, err := endpoints3.ExtractEndpoints(page)
+		if err != nil {
+			t.Fatalf("Error extracting endpoings: %v", err)
+		}
+
+		for _, endpoint := range endpoints {
+			t.Logf("Endpoint: %8s %10s %9s %s",
+				endpoint.ID,
+				endpoint.Availability,
+				endpoint.Name,
+				endpoint.URL)
+		}
+
+		return true, nil
+	})
+	if err != nil {
+		t.Errorf("Unexpected error while iterating endpoint pages: %v", err)
+	}
+}
+
+func TestNavigateCatalog(t *testing.T) {
+	// Create a service client.
+	client := createAuthenticatedClient(t)
+
+	var compute *services3.Service
+	var endpoint *endpoints3.Endpoint
+
+	// Discover the service we're interested in.
+	servicePager := services3.List(client, services3.ListOpts{ServiceType: "compute"})
+	err := servicePager.EachPage(func(page pagination.Page) (bool, error) {
+		part, err := services3.ExtractServices(page)
+		if err != nil {
+			return false, err
+		}
+		if compute != nil {
+			t.Fatalf("Expected one service, got more than one page")
+			return false, nil
+		}
+		if len(part) != 1 {
+			t.Fatalf("Expected one service, got %d", len(part))
+			return false, nil
+		}
+
+		compute = &part[0]
+		return true, nil
+	})
+	if err != nil {
+		t.Fatalf("Unexpected error iterating pages: %v", err)
+	}
+
+	if compute == nil {
+		t.Fatalf("No compute service found.")
+	}
+
+	// Enumerate the endpoints available for this service.
+	computePager := endpoints3.List(client, endpoints3.ListOpts{
+		Availability: gophercloud.AvailabilityPublic,
+		ServiceID:    compute.ID,
+	})
+	err = computePager.EachPage(func(page pagination.Page) (bool, error) {
+		part, err := endpoints3.ExtractEndpoints(page)
+		if err != nil {
+			return false, err
+		}
+		if endpoint != nil {
+			t.Fatalf("Expected one endpoint, got more than one page")
+			return false, nil
+		}
+		if len(part) != 1 {
+			t.Fatalf("Expected one endpoint, got %d", len(part))
+			return false, nil
+		}
+
+		endpoint = &part[0]
+		return true, nil
+	})
+
+	if endpoint == nil {
+		t.Fatalf("No endpoint found.")
+	}
+
+	t.Logf("Success. The compute endpoint is at %s.", endpoint.URL)
+}
diff --git a/_site/acceptance/openstack/identity/v3/identity_test.go b/_site/acceptance/openstack/identity/v3/identity_test.go
new file mode 100644
index 0000000..e0503e2
--- /dev/null
+++ b/_site/acceptance/openstack/identity/v3/identity_test.go
@@ -0,0 +1,41 @@
+// +build acceptance
+
+package v3
+
+import (
+	"testing"
+
+	"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()
+	if err != nil {
+		t.Fatalf("Unable to acquire credentials: %v", err)
+	}
+
+	// Trim out unused fields.
+	ao.Username, ao.TenantID, ao.TenantName = "", "", ""
+
+	if ao.UserID == "" {
+		t.Logf("Skipping identity v3 tests because no OS_USERID is present.")
+		return nil
+	}
+
+	// Create a client and manually authenticate against v3.
+	providerClient, err := openstack.NewClient(ao.IdentityEndpoint)
+	if err != nil {
+		t.Fatalf("Unable to instantiate client: %v", err)
+	}
+
+	err = openstack.AuthenticateV3(providerClient, ao)
+	if err != nil {
+		t.Fatalf("Unable to authenticate against identity v3: %v", err)
+	}
+
+	// Create a service client.
+	return openstack.NewIdentityV3(providerClient)
+}
diff --git a/_site/acceptance/openstack/identity/v3/pkg.go b/_site/acceptance/openstack/identity/v3/pkg.go
new file mode 100644
index 0000000..d3b5573
--- /dev/null
+++ b/_site/acceptance/openstack/identity/v3/pkg.go
@@ -0,0 +1,2 @@
+// Package v3 contains acceptance tests for identity v3 resources.
+package v3
diff --git a/_site/acceptance/openstack/identity/v3/service_test.go b/_site/acceptance/openstack/identity/v3/service_test.go
new file mode 100644
index 0000000..082bd11
--- /dev/null
+++ b/_site/acceptance/openstack/identity/v3/service_test.go
@@ -0,0 +1,36 @@
+// +build acceptance
+
+package v3
+
+import (
+	"testing"
+
+	services3 "github.com/rackspace/gophercloud/openstack/identity/v3/services"
+	"github.com/rackspace/gophercloud/pagination"
+)
+
+func TestListServices(t *testing.T) {
+	// Create a service client.
+	serviceClient := createAuthenticatedClient(t)
+	if serviceClient == nil {
+		return
+	}
+
+	// Use the client to list all available services.
+	pager := services3.List(serviceClient, services3.ListOpts{})
+	err := pager.EachPage(func(page pagination.Page) (bool, error) {
+		parts, err := services3.ExtractServices(page)
+		if err != nil {
+			return false, err
+		}
+
+		t.Logf("--- Page ---")
+		for _, service := range parts {
+			t.Logf("Service: %32s %15s %10s %s", service.ID, service.Type, service.Name, *service.Description)
+		}
+		return true, nil
+	})
+	if err != nil {
+		t.Errorf("Unexpected error traversing pages: %v", err)
+	}
+}
diff --git a/_site/acceptance/openstack/identity/v3/token_test.go b/_site/acceptance/openstack/identity/v3/token_test.go
new file mode 100644
index 0000000..341acb7
--- /dev/null
+++ b/_site/acceptance/openstack/identity/v3/token_test.go
@@ -0,0 +1,43 @@
+// +build acceptance
+
+package v3
+
+import (
+	"testing"
+
+	"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()
+	if err != nil {
+		t.Fatalf("Unable to acquire credentials: %v", err)
+	}
+
+	// Trim out unused fields. Skip if we don't have a UserID.
+	ao.Username, ao.TenantID, ao.TenantName = "", "", ""
+	if ao.UserID == "" {
+		t.Logf("Skipping identity v3 tests because no OS_USERID is present.")
+		return
+	}
+
+	// Create an unauthenticated client.
+	provider, err := openstack.NewClient(ao.IdentityEndpoint)
+	if err != nil {
+		t.Fatalf("Unable to instantiate client: %v", err)
+	}
+
+	// Create a service client.
+	service := openstack.NewIdentityV3(provider)
+
+	// Use the service to create a token.
+	token, err := tokens3.Create(service, ao, nil).Extract()
+	if err != nil {
+		t.Fatalf("Unable to get token: %v", err)
+	}
+
+	t.Logf("Acquired token: %s", token.ID)
+}