Repaginate the identity/3/endpoints resource.
diff --git a/openstack/identity/v3/endpoints/requests.go b/openstack/identity/v3/endpoints/requests.go
index a990049..fbbdf07 100644
--- a/openstack/identity/v3/endpoints/requests.go
+++ b/openstack/identity/v3/endpoints/requests.go
@@ -1,6 +1,7 @@
 package endpoints
 
 import (
+	"net/http"
 	"strconv"
 
 	"github.com/racker/perigee"
@@ -94,7 +95,7 @@
 }
 
 // List enumerates endpoints in a paginated collection, optionally filtered by ListOpts criteria.
-func List(client *gophercloud.ServiceClient, opts ListOpts) (*EndpointList, error) {
+func List(client *gophercloud.ServiceClient, opts ListOpts) gophercloud.Pager {
 	q := make(map[string]string)
 	if opts.Availability != "" {
 		q["interface"] = string(opts.Availability)
@@ -110,18 +111,16 @@
 	}
 
 	u := getListURL(client) + utils.BuildQuery(q)
-
-	var respBody EndpointList
-	_, err := perigee.Request("GET", u, perigee.Options{
-		MoreHeaders: client.Provider.AuthenticatedHeaders(),
-		Results:     &respBody,
-		OkCodes:     []int{200},
+	return gophercloud.NewLinkedPager(u, func(next string) (http.Response, error) {
+		r, err := perigee.Request("GET", u, perigee.Options{
+			MoreHeaders: client.Provider.AuthenticatedHeaders(),
+			OkCodes:     []int{200},
+		})
+		if err != nil {
+			return http.Response{}, err
+		}
+		return r.HttpResponse, nil
 	})
-	if err != nil {
-		return nil, err
-	}
-
-	return &respBody, nil
 }
 
 // Update changes an existing endpoint with new data.
diff --git a/openstack/identity/v3/endpoints/requests_test.go b/openstack/identity/v3/endpoints/requests_test.go
index 272860e..70dfd8e 100644
--- a/openstack/identity/v3/endpoints/requests_test.go
+++ b/openstack/identity/v3/endpoints/requests_test.go
@@ -127,13 +127,16 @@
 
 	client := serviceClient()
 
-	actual, err := List(client, ListOpts{})
-	if err != nil {
-		t.Fatalf("Unexpected error listing endpoints: %v", err)
-	}
+	count := 0
+	List(client, ListOpts{}).EachPage(func(page gophercloud.Page) bool {
+		count++
+		actual, err := ExtractEndpoints(page)
+		if err != nil {
+			t.Errorf("Failed to extract endpoints: %v", err)
+			return false
+		}
 
-	expected := &EndpointList{
-		Endpoints: []Endpoint{
+		expected := []Endpoint{
 			Endpoint{
 				ID:           "12",
 				Availability: gophercloud.AvailabilityPublic,
@@ -150,11 +153,16 @@
 				ServiceID:    "asdfasdfasdfasdf",
 				URL:          "https://1.2.3.4:9001/",
 			},
-		},
-	}
+		}
 
-	if !reflect.DeepEqual(expected, actual) {
-		t.Errorf("Expected %#v, got %#v", expected, actual)
+		if !reflect.DeepEqual(expected, actual) {
+			t.Errorf("Expected %#v, got %#v", expected, actual)
+		}
+
+		return true
+	})
+	if count != 1 {
+		t.Errorf("Expected 1 page, got %d", count)
 	}
 }
 
diff --git a/openstack/identity/v3/endpoints/results.go b/openstack/identity/v3/endpoints/results.go
index bd7a013..4d7bfbc 100644
--- a/openstack/identity/v3/endpoints/results.go
+++ b/openstack/identity/v3/endpoints/results.go
@@ -1,70 +1,29 @@
 package endpoints
 
 import (
-	"fmt"
-
 	"github.com/mitchellh/mapstructure"
 	"github.com/rackspace/gophercloud"
 )
 
 // Endpoint describes the entry point for another service's API.
 type Endpoint struct {
-	ID           string                   `json:"id"`
-	Availability gophercloud.Availability `json:"interface"`
-	Name         string                   `json:"name"`
-	Region       string                   `json:"region"`
-	ServiceID    string                   `json:"service_id"`
-	URL          string                   `json:"url"`
+	ID           string                   `mapstructure:"id" json:"id"`
+	Availability gophercloud.Availability `mapstructure:"interface" json:"interface"`
+	Name         string                   `mapstructure:"name" json:"name"`
+	Region       string                   `mapstructure:"region" json:"region"`
+	ServiceID    string                   `mapstructure:"service_id" json:"service_id"`
+	URL          string                   `mapstructure:"url" json:"url"`
 }
 
-// EndpointList contains a page of Endpoint results.
-type EndpointList struct {
-	gophercloud.PaginationLinks `json:"links"`
-
-	client    *gophercloud.ServiceClient
-	Endpoints []Endpoint `json:"endpoints"`
-}
-
-// Pager marks EndpointList as paged by links.
-func (list EndpointList) Pager() gophercloud.Pager {
-	return gophercloud.NewLinkPager(list)
-}
-
-// Concat adds the contents of another Collection to this one.
-func (list EndpointList) Concat(other gophercloud.Collection) gophercloud.Collection {
-	return EndpointList{
-		client:    list.client,
-		Endpoints: append(list.Endpoints, AsEndpoints(other)...),
-	}
-}
-
-// Service returns the ServiceClient used to acquire this list.
-func (list EndpointList) Service() *gophercloud.ServiceClient {
-	return list.client
-}
-
-// Links accesses pagination information for the current page.
-func (list EndpointList) Links() gophercloud.PaginationLinks {
-	return list.PaginationLinks
-}
-
-// Interpret parses a follow-on JSON response as an additional page.
-func (list EndpointList) Interpret(json interface{}) (gophercloud.LinkCollection, error) {
-	mapped, ok := json.(map[string]interface{})
-	if !ok {
-		return nil, fmt.Errorf("Unexpected JSON response: %#v", json)
+// ExtractEndpoints extracts an Endpoint slice from a Page.
+func ExtractEndpoints(page gophercloud.Page) ([]Endpoint, error) {
+	var response struct {
+		Endpoints []Endpoint `mapstructure:"endpoints"`
 	}
 
-	var result EndpointList
-	err := mapstructure.Decode(mapped, &result)
+	err := mapstructure.Decode(page.(gophercloud.LinkedPage).Body, &response)
 	if err != nil {
 		return nil, err
 	}
-	return result, nil
-}
-
-// AsEndpoints extracts an Endpoint slice from a Collection.
-// Panics if `list` was not returned from a List call.
-func AsEndpoints(list gophercloud.Collection) []Endpoint {
-	return list.(*EndpointList).Endpoints
+	return response.Endpoints, nil
 }