Shuffled resources into sub-packages and upgraded to new pagination idiom
diff --git a/openstack/networking/v2/networks/requests.go b/openstack/networking/v2/networks/requests.go
index 06b0fe7..98e70d1 100644
--- a/openstack/networking/v2/networks/requests.go
+++ b/openstack/networking/v2/networks/requests.go
@@ -1,10 +1,24 @@
 package networks
 
 import (
+	"strconv"
+
 	"github.com/racker/perigee"
 	"github.com/rackspace/gophercloud"
+	"github.com/rackspace/gophercloud/openstack/utils"
 )
 
+type ListOpts struct {
+	Status       string
+	Name         string
+	AdminStateUp *bool
+	TenantID     string
+	Shared       *bool
+	ID           string
+	Page         int
+	PerPage      int
+}
+
 type NetworkOpts struct {
 	AdminStateUp bool
 	Name         string
@@ -12,12 +26,54 @@
 	TenantID     string
 }
 
-func Get(c *gophercloud.ServiceClient, id string) (*NetworkResult, error) {
-	var n NetworkResult
-	_, err := perigee.Request("GET", NetworkURL(c, id), perigee.Options{
+func ptrToStr(val *bool) string {
+	if *val == true {
+		return "true"
+	} else if *val == false {
+		return "false"
+	} else {
+		return ""
+	}
+}
+
+func List(c *gophercloud.ServiceClient, opts ListOpts) gophercloud.Pager {
+	// Build query parameters
+	q := make(map[string]string)
+	if opts.Status != "" {
+		q["status"] = opts.Status
+	}
+	if opts.Name != "" {
+		q["name"] = opts.Name
+	}
+	if opts.AdminStateUp != nil {
+		q["admin_state_up"] = ptrToStr(opts.AdminStateUp)
+	}
+	if opts.TenantID != "" {
+		q["tenant_id"] = opts.TenantID
+	}
+	if opts.Shared != nil {
+		q["shared"] = ptrToStr(opts.Shared)
+	}
+	if opts.ID != "" {
+		q["id"] = opts.ID
+	}
+	if opts.Page != 0 {
+		q["page"] = strconv.Itoa(opts.Page)
+	}
+	if opts.PerPage != 0 {
+		q["per_page"] = strconv.Itoa(opts.PerPage)
+	}
+
+	u := ListURL(c) + utils.BuildQuery(q)
+	return gophercloud.NewLinkedPager(c, u)
+}
+
+func Get(c *gophercloud.ServiceClient, id string) (*Network, error) {
+	var n Network
+	_, err := perigee.Request("GET", GetURL(c, id), perigee.Options{
 		MoreHeaders: c.Provider.AuthenticatedHeaders(),
 		Results: &struct {
-			Network *NetworkResult `json:"network"`
+			Network *Network `json:"network"`
 		}{&n},
 		OkCodes: []int{200},
 	})
@@ -73,7 +129,7 @@
 	return res.Network, nil
 }
 
-func Update(c *gophercloud.ServiceClient, networkID string, opts NetworkOpts) (*NetworkResult, error) {
+func Update(c *gophercloud.ServiceClient, networkID string, opts NetworkOpts) (*Network, error) {
 	// Define structures
 	type network struct {
 		AdminStateUp bool    `json:"admin_state_up"`
@@ -86,7 +142,7 @@
 		Network network `json:"network"`
 	}
 	type response struct {
-		Network *NetworkResult `json:"network"`
+		Network *Network `json:"network"`
 	}
 
 	// Populate request body
@@ -102,7 +158,7 @@
 
 	// Send request to API
 	var res response
-	_, err := perigee.Request("PUT", NetworkURL(c, networkID), perigee.Options{
+	_, err := perigee.Request("PUT", GetURL(c, networkID), perigee.Options{
 		MoreHeaders: c.Provider.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res,
@@ -114,3 +170,11 @@
 
 	return res.Network, nil
 }
+
+func Delete(c *gophercloud.ServiceClient, networkID string) error {
+	_, err := perigee.Request("DELETE", DeleteURL(c, networkID), perigee.Options{
+		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		OkCodes:     []int{204},
+	})
+	return err
+}
diff --git a/openstack/networking/v2/networks/requests_test.go b/openstack/networking/v2/networks/requests_test.go
index 6fa8222..e677f8e 100644
--- a/openstack/networking/v2/networks/requests_test.go
+++ b/openstack/networking/v2/networks/requests_test.go
@@ -20,6 +20,105 @@
 	}
 }
 
+func TestList(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+
+	th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "GET")
+		th.TestHeader(t, r, "X-Auth-Token", TokenID)
+
+		w.Header().Add("Content-Type", "application/json")
+		w.WriteHeader(http.StatusOK)
+
+		fmt.Fprintf(w, `
+{
+    "networks": [
+        {
+            "status": "ACTIVE",
+            "subnets": [
+                "54d6f61d-db07-451c-9ab3-b9609b6b6f0b"
+            ],
+            "name": "private-network",
+            "provider:physical_network": null,
+            "admin_state_up": true,
+            "tenant_id": "4fd44f30292945e481c7b8a0c8908869",
+            "provider:network_type": "local",
+            "router:external": true,
+            "shared": true,
+            "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22",
+            "provider:segmentation_id": null
+        },
+        {
+            "status": "ACTIVE",
+            "subnets": [
+                "08eae331-0402-425a-923c-34f7cfe39c1b"
+            ],
+            "name": "private",
+            "provider:physical_network": null,
+            "admin_state_up": true,
+            "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e",
+            "provider:network_type": "local",
+            "router:external": true,
+            "shared": true,
+            "id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324",
+            "provider:segmentation_id": null
+        }
+    ]
+}
+			`)
+	})
+
+	client := ServiceClient()
+	count := 0
+
+	List(client, ListOpts{}).EachPage(func(page gophercloud.Page) (bool, error) {
+		count++
+		actual, err := ExtractNetworks(page)
+		if err != nil {
+			t.Errorf("Failed to extract networks: %v", err)
+			return false, err
+		}
+
+		expected := []Network{
+			Network{
+				Status:  "ACTIVE",
+				Subnets: []interface{}{"54d6f61d-db07-451c-9ab3-b9609b6b6f0b"},
+				Name:    "private-network",
+				ProviderPhysicalNetwork: "",
+				AdminStateUp:            true,
+				TenantID:                "4fd44f30292945e481c7b8a0c8908869",
+				ProviderNetworkType:     "local",
+				RouterExternal:          true,
+				Shared:                  true,
+				ID:                      "d32019d3-bc6e-4319-9c1d-6722fc136a22",
+				ProviderSegmentationID: 0,
+			},
+			Network{
+				Status:  "ACTIVE",
+				Subnets: []interface{}{"08eae331-0402-425a-923c-34f7cfe39c1b"},
+				Name:    "private",
+				ProviderPhysicalNetwork: "",
+				AdminStateUp:            true,
+				TenantID:                "26a7980765d0414dbc1fc1f88cdb7e6e",
+				ProviderNetworkType:     "local",
+				RouterExternal:          true,
+				Shared:                  true,
+				ID:                      "db193ab3-96e3-4cb3-8fc5-05f4296d0324",
+				ProviderSegmentationID: 0,
+			},
+		}
+
+		th.CheckDeepEquals(t, expected, actual)
+
+		return true, nil
+	})
+
+	if count != 1 {
+		t.Errorf("Expected 1 page, got %d", count)
+	}
+}
+
 func TestGet(t *testing.T) {
 	th.SetupHTTP()
 	defer th.TeardownHTTP()
diff --git a/openstack/networking/v2/networks/results.go b/openstack/networking/v2/networks/results.go
index 4678793..b23395a 100644
--- a/openstack/networking/v2/networks/results.go
+++ b/openstack/networking/v2/networks/results.go
@@ -1,5 +1,10 @@
 package networks
 
+import (
+	"github.com/mitchellh/mapstructure"
+	"github.com/rackspace/gophercloud"
+)
+
 type NetworkProvider struct {
 	ProviderSegmentationID  int    `json:"provider:segmentation_id"`
 	ProviderPhysicalNetwork string `json:"provider:physical_network"`
@@ -7,19 +12,17 @@
 }
 
 type Network struct {
-	Status       string        `json:"status"`
-	Subnets      []interface{} `json:"subnets"`
-	Name         string        `json:"name"`
-	AdminStateUp bool          `json:"admin_state_up"`
-	TenantID     string        `json:"tenant_id"`
-	Shared       bool          `json:"shared"`
-	ID           string        `json:"id"`
-}
-
-type NetworkResult struct {
-	Network
-	NetworkProvider
-	RouterExternal bool `json:"router:external"`
+	Status                  string        `mapstructure:"status" json:"status"`
+	Subnets                 []interface{} `mapstructure:"subnets" json:"subnets"`
+	Name                    string        `mapstructure:"name" json:"name"`
+	AdminStateUp            bool          `mapstructure:"admin_state_up" json:"admin_state_up"`
+	TenantID                string        `mapstructure:"tenant_id" json:"tenant_id"`
+	Shared                  bool          `mapstructure:"shared" json:"shared"`
+	ID                      string        `mapstructure:"id" json:"id"`
+	ProviderSegmentationID  int           `mapstructure:"provider:segmentation_id" json:"provider:segmentation_id"`
+	ProviderPhysicalNetwork string        `mapstructure:"provider:physical_network" json:"provider:physical_network"`
+	ProviderNetworkType     string        `mapstructure:"provider:network_type" json:"provider:network_type"`
+	RouterExternal          bool          `mapstructure:"router:external" json:"router:external"`
 }
 
 type NetworkCreateResult struct {
@@ -27,3 +30,16 @@
 	Segments            []NetworkProvider `json:"segments"`
 	PortSecurityEnabled bool              `json:"port_security_enabled"`
 }
+
+func ExtractNetworks(page gophercloud.Page) ([]Network, error) {
+	var resp struct {
+		Networks []Network `mapstructure:"networks" json:"networks"`
+	}
+
+	err := mapstructure.Decode(page.(gophercloud.LinkedPage).Body, &resp)
+	if err != nil {
+		return nil, err
+	}
+
+	return resp.Networks, nil
+}
diff --git a/openstack/networking/v2/networks/urls.go b/openstack/networking/v2/networks/urls.go
index 13fcc03..a0d660a 100644
--- a/openstack/networking/v2/networks/urls.go
+++ b/openstack/networking/v2/networks/urls.go
@@ -4,10 +4,26 @@
 
 const Version = "v2.0"
 
-func NetworkURL(c *gophercloud.ServiceClient, id string) string {
+func ResourceURL(c *gophercloud.ServiceClient, id string) string {
 	return c.ServiceURL(Version, "networks", id)
 }
 
-func CreateURL(c *gophercloud.ServiceClient) string {
+func RootURL(c *gophercloud.ServiceClient) string {
 	return c.ServiceURL(Version, "networks")
 }
+
+func GetURL(c *gophercloud.ServiceClient, id string) string {
+	return ResourceURL(c, id)
+}
+
+func ListURL(c *gophercloud.ServiceClient) string {
+	return RootURL(c)
+}
+
+func CreateURL(c *gophercloud.ServiceClient) string {
+	return RootURL(c)
+}
+
+func DeleteURL(c *gophercloud.ServiceClient, id string) string {
+	return ResourceURL(c, id)
+}
diff --git a/openstack/networking/v2/networks/urls_test.go b/openstack/networking/v2/networks/urls_test.go
index b8970a2..84a7ae6 100644
--- a/openstack/networking/v2/networks/urls_test.go
+++ b/openstack/networking/v2/networks/urls_test.go
@@ -13,8 +13,8 @@
 	return &gophercloud.ServiceClient{Endpoint: Endpoint}
 }
 
-func TestNetworkURL(t *testing.T) {
-	actual := NetworkURL(EndpointClient(), "foo")
+func TestGetURL(t *testing.T) {
+	actual := GetURL(EndpointClient(), "foo")
 	expected := Endpoint + "v2.0/networks/foo"
 	th.AssertEquals(t, expected, actual)
 }
@@ -24,3 +24,15 @@
 	expected := Endpoint + "v2.0/networks"
 	th.AssertEquals(t, expected, actual)
 }
+
+func TestListURL(t *testing.T) {
+	actual := CreateURL(EndpointClient())
+	expected := Endpoint + "v2.0/networks"
+	th.AssertEquals(t, expected, actual)
+}
+
+func TestDeleteURL(t *testing.T) {
+	actual := DeleteURL(EndpointClient(), "foo")
+	expected := Endpoint + "v2.0/networks/foo"
+	th.AssertEquals(t, expected, actual)
+}