diff --git a/collections.go b/collections.go
index 38078f0..1383f24 100644
--- a/collections.go
+++ b/collections.go
@@ -1,62 +1,47 @@
 package gophercloud
 
-import "errors"
+import (
+	"encoding/json"
+	"errors"
+	"io/ioutil"
+	"net/http"
+
+	"github.com/mitchellh/mapstructure"
+)
 
 var (
 	// ErrPageNotAvailable is returned from a Pager when a next or previous page is requested, but does not exist.
 	ErrPageNotAvailable = errors.New("The requested Collection page does not exist.")
 )
 
-// Collection must be satisfied by the result type of any resource collection.
+// Page must be satisfied by the result type of any resource collection.
 // It allows clients to interact with the resource uniformly, regardless of whether or not or how it's paginated.
-type Collection interface {
+type Page interface {
 
 	// NextPageURL generates the URL for the page of data that follows this collection.
 	// Return "" if no such page exists.
 	NextPageURL() string
-
-	// Concat creates a new Collection that contains all of the elements from this page and another page.
-	// It's used to aggregate results for the AllPages method.
-	Concat(Collection) Collection
 }
 
 // Pager knows how to advance through a specific resource collection, one page at a time.
 type Pager struct {
 	initialURL string
 
-	advance func(string) (Collection, error)
+	advance func(string) (Page, error)
 }
 
 // NewPager constructs a manually-configured pager.
 // Supply the URL for the first page and a function that requests a specific page given a URL.
-func NewPager(initialURL string, advance func(string) (Collection, error)) Pager {
+func NewPager(initialURL string, advance func(string) (Page, error)) Pager {
 	return Pager{
 		initialURL: initialURL,
 		advance:    advance,
 	}
 }
 
-// NewSinglePager constructs a Pager that "iterates" over a single-paged Collection.
-// Supply a function that returns the only page.
-func NewSinglePager(only func() (Collection, error)) Pager {
-	consumed := false
-	single := func(_ string) (Collection, error) {
-		if !consumed {
-			consumed = true
-			return only()
-		}
-		return nil, ErrPageNotAvailable
-	}
-
-	return Pager{
-		initialURL: "",
-		advance:    single,
-	}
-}
-
 // EachPage iterates over each page returned by a Pager, yielding one at a time to a handler function.
 // Return "false" from the handler to prematurely stop iterating.
-func (p Pager) EachPage(handler func(Collection) bool) error {
+func (p Pager) EachPage(handler func(Page) bool) error {
 	currentURL := p.initialURL
 	for {
 		currentPage, err := p.advance(currentURL)
@@ -75,28 +60,112 @@
 	}
 }
 
-// AllPages accumulates every page reachable from a Pager into a single Collection, for convenience.
-func (p Pager) AllPages() (Collection, error) {
-	var megaPage Collection
-
-	err := p.EachPage(func(page Collection) bool {
-		if megaPage == nil {
-			megaPage = page
-		} else {
-			megaPage = megaPage.Concat(page)
-		}
-		return true
-	})
-
-	return megaPage, err
+// AllPages accumulates every page reachable from a Pager into a single Page, for convenience.
+func (p Pager) AllPages() (Page, error) {
+	return nil, errors.New("Wat")
 }
 
-// PaginationLinks stores the `next` and `previous` links that are provided by some (but not all) paginated resources.
-type PaginationLinks struct {
+// ConcretePage stores generic information derived from an HTTP response.
+type ConcretePage struct {
+	http.Header
+	Body map[string]interface{}
+}
 
-	// Next is the full URL to the next page of results, or nil if this is the last page.
-	Next *string `json:"next,omitempty"`
+// NewConcretePage parses an HTTP response as JSON and returns a ConcretePage containing the results.
+func NewConcretePage(resp http.Response) (ConcretePage, error) {
+	var parsedBody map[string]interface{}
 
-	// Previous is the full URL to the previous page of results, or nil if this is the first page.
-	Previous *string `json:"previous,omitempty"`
+	defer resp.Body.Close()
+	rawBody, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		return ConcretePage{}, err
+	}
+	err = json.Unmarshal(rawBody, &parsedBody)
+	if err != nil {
+		return ConcretePage{}, err
+	}
+
+	return ConcretePage{Header: resp.Header, Body: parsedBody}, err
+}
+
+// SinglePage is a page that contains all of the results from an operation.
+type SinglePage ConcretePage
+
+// NextPageURL always returns "" to indicate that there are no more pages to return.
+func (current SinglePage) NextPageURL() string {
+	return ""
+}
+
+// NewSinglePager constructs a Pager that "iterates" over a single Page.
+// Supply a function that returns the only page.
+func NewSinglePager(only func() (http.Response, error)) Pager {
+	consumed := false
+	single := func(_ string) (Page, error) {
+		if !consumed {
+			consumed = true
+			resp, err := only()
+			if err != nil {
+				return SinglePage{}, err
+			}
+
+			cp, err := NewConcretePage(resp)
+			if err != nil {
+				return SinglePage{}, err
+			}
+			return SinglePage(cp), nil
+		}
+		return SinglePage{}, ErrPageNotAvailable
+	}
+
+	return Pager{
+		initialURL: "",
+		advance:    single,
+	}
+}
+
+// PaginatedLinksPage is a page in a collection that provides navigational "Next" and "Previous" links within its result.
+type PaginatedLinksPage ConcretePage
+
+// NextPageURL extracts the pagination structure from a JSON response and returns the "next" link, if one is present.
+func (current PaginatedLinksPage) NextPageURL() string {
+	type response struct {
+		Links struct {
+			Next *string `mapstructure:"next,omitempty"`
+		} `mapstructure:"links"`
+	}
+
+	var r response
+	err := mapstructure.Decode(current.Body, &r)
+	if err != nil {
+		// FIXME NextPageURL should be able to fail
+		panic(err)
+	}
+
+	if r.Links.Next == nil {
+		return ""
+	}
+
+	return *r.Links.Next
+}
+
+// NewLinkedPager creates a Pager that uses a "links" element in the JSON response to locate the next page.
+func NewLinkedPager(initialURL string, request func(string) (http.Response, error)) Pager {
+	advance := func(url string) (Page, error) {
+		resp, err := request(url)
+		if err != nil {
+			return nil, err
+		}
+
+		cp, err := NewConcretePage(resp)
+		if err != nil {
+			return nil, err
+		}
+
+		return PaginatedLinksPage(cp), nil
+	}
+
+	return Pager{
+		initialURL: initialURL,
+		advance:    advance,
+	}
 }
diff --git a/collections_test.go b/collections_test.go
index c83bd38..a005fd7 100644
--- a/collections_test.go
+++ b/collections_test.go
@@ -1,45 +1,63 @@
 package gophercloud
 
 import (
-	"fmt"
+	"bytes"
+	"errors"
+	"io"
 	"net/http"
 	"reflect"
 	"testing"
 
-	"github.com/rackspace/gophercloud/testhelper"
+	"github.com/mitchellh/mapstructure"
 )
 
+type nopCloser struct {
+	io.Reader
+}
+
+func (nopCloser) Close() error { return nil }
+
+func responseWithBody(body string) (http.Response, error) {
+	return http.Response{
+		Body: nopCloser{bytes.NewReader([]byte(body))},
+	}, nil
+}
+
 // SinglePage sample and test cases.
 
-type SinglePageCollection struct {
-	results []int
+type SingleIntList struct {
+	SinglePage
 }
 
-func (c SinglePageCollection) NextPageURL() string {
-	panic("NextPageURL should never be called on a single-paged collection.")
-}
+func ExtractSingleInts(page Page) ([]int, error) {
+	var response struct {
+		Ints []int `mapstructure:"ints"`
+	}
 
-func (c SinglePageCollection) Concat(other Collection) Collection {
-	panic("Concat should never be called on a single-paged collection.")
-}
+	err := mapstructure.Decode(page.(SingleIntList).Body, &response)
+	if err != nil {
+		return nil, err
+	}
 
-func ExtractSingleInts(c Collection) []int {
-	return c.(SinglePageCollection).results
+	return response.Ints, nil
 }
 
 func setupSinglePaged() Pager {
-	return NewSinglePager(func() (Collection, error) {
-		return SinglePageCollection{results: []int{1, 2, 3}}, nil
+	return NewSinglePager(func() (http.Response, error) {
+		return responseWithBody(`{ "ints": [1, 2, 3] }`)
 	})
 }
 
 func TestEnumerateSinglePaged(t *testing.T) {
 	callCount := 0
-	err := setupSinglePaged().EachPage(func(page Collection) bool {
+	err := setupSinglePaged().EachPage(func(page Page) bool {
 		callCount++
 
 		expected := []int{1, 2, 3}
-		actual := AsSingleInts(page)
+		actual, err := ExtractSingleInts(page)
+		if err != nil {
+			t.Fatalf("Unexpected error extracting ints: %v", err)
+		}
 		if !reflect.DeepEqual(expected, actual) {
 			t.Errorf("Expected %v, but was %v", expected, actual)
 		}
@@ -54,90 +72,52 @@
 	}
 }
 
-func TestAllSinglePaged(t *testing.T) {
-	r, err := setupSinglePaged().AllPages()
-	if err != nil {
-		t.Fatalf("Unexpected error when iterating pages: %v", err)
-	}
-
-	expected := []int{1, 2, 3}
-	actual := ExtractSingleInts(r)
-	if !reflect.DeepEqual(expected, actual) {
-		t.Errorf("Expected %v, but was %v", expected, actual)
-	}
-}
-
 // LinkedPager sample and test cases.
 
-type LinkedCollection struct {
-	PaginationLinks
-
-	results []int
+type LinkedIntPage struct {
+	PaginatedLinksPage
 }
 
-func (page LinkedCollection) NextPageURL() string {
-	n := page.PaginationLinks.Next
-	if n == nil {
-		return ""
+func ExtractLinkedInts(page Page) ([]int, error) {
+	var response struct {
+		Ints []int `mapstructure:"ints"`
 	}
-	return *n
-}
 
-func (page LinkedCollection) Concat(other Collection) Collection {
-	return LinkedCollection{
-		service: page.service,
-		results: append(c.results, AsLinkedInts(other)...),
+	err := mapstructure.Decode(page.(LinkedIntPage).Body, &response)
+	if err != nil {
+		return nil, err
 	}
+
+	return response.Ints, nil
 }
 
-func AsLinkedInts(results Collection) []int {
-	return results.(LinkedCollection).results
-}
-
-func createLinked() Pager {
-	nextURL := testhelper.Server.URL + "/foo?page=2&perPage=3"
-	return CreatePager(func(url) Collection {
-		LinkedCollection{
-			PaginationLinks: PaginationLinks{Next: &nextURL},
-			results:         []int{1, 2, 3},
-		}
-	})
-}
-
-func setupLinkedResponses(t *testing.T) {
-	testhelper.Mux.HandleFunc("/foo", func(w http.ResponseWriter, r *http.Request) {
-		testhelper.TestMethod(t, r, "GET")
-		testhelper.TestHeader(t, r, "X-Auth-Token", "1234")
-		w.Header().Add("Content-Type", "application/json")
-
-		r.ParseForm()
-
-		pages := r.Form["page"]
-		if len(pages) != 1 {
-			t.Errorf("Endpoint called with unexpected page: %#v", r.Form)
-		}
-
-		switch pages[0] {
-		case "2":
-			fmt.Fprintf(w, `[4, 5, 6]`)
-		case "3":
-			fmt.Fprintf(w, `[7, 8, 9]`)
+func createLinked(t *testing.T) Pager {
+	return NewLinkedPager("page1", func(url string) (http.Response, error) {
+		switch url {
+		case "page1":
+			return responseWithBody(`{ "ints": [1, 2, 3], "links": { "next": "page2" } }`)
+		case "page2":
+			return responseWithBody(`{ "ints": [4, 5, 6], "links": { "next": "page3" } }`)
+		case "page3":
+			return responseWithBody(`{ "ints": [7, 8, 9], "links": { "next": null } }`)
 		default:
-			t.Errorf("Endpoint called with unexpected page: %s", pages[0])
+			t.Fatalf("LinkedPager called with unexpected URL: %v", url)
+			return http.Response{}, errors.New("Wat")
 		}
 	})
 }
 
 func TestEnumerateLinked(t *testing.T) {
-	testhelper.SetupHTTP()
-	defer testhelper.TeardownHTTP()
-
-	setupLinkedResponses(t)
-	lc := createLinked()
+	pager := createLinked(t)
 
 	callCount := 0
-	err := EachPage(lc, func(page Collection) bool {
-		actual := AsLinkedInts(page)
+	err := pager.EachPage(func(page Page) bool {
+		actual, err := ExtractLinkedInts(page)
+		if err != nil {
+			t.Errorf("Unable to extract ints from page: %v", err)
+			return false
+		}
+
 		t.Logf("Handler invoked with %v", actual)
 
 		var expected []int
@@ -168,28 +148,3 @@
 		t.Errorf("Expected 3 calls, but was %d", callCount)
 	}
 }
-
-func TestAllLinked(t *testing.T) {
-	testhelper.SetupHTTP()
-	defer testhelper.TeardownHTTP()
-
-	setupLinkedResponses(t)
-	lc := createLinked()
-
-	all, err := AllPages(lc)
-	if err != nil {
-		t.Fatalf("Unexpected error collection all linked pages: %v", err)
-	}
-
-	actual := AsLinkedInts(all)
-	expected := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
-
-	if !reflect.DeepEqual(expected, actual) {
-		t.Errorf("Expected %v, but was %v", expected, actual)
-	}
-
-	original := []int{1, 2, 3}
-	if !reflect.DeepEqual(AsLinkedInts(lc), original) {
-		t.Errorf("AllPages modified the original page, and now it contains: %v", lc)
-	}
-}
