Finishing documentation
diff --git a/openstack/networking/v2/networks/doc.go b/openstack/networking/v2/networks/doc.go
index 83c4a6a..c87a7ce 100644
--- a/openstack/networking/v2/networks/doc.go
+++ b/openstack/networking/v2/networks/doc.go
@@ -1 +1,9 @@
+// Package networks contains functionality for working with Neutron network
+// resources. A network is an isolated virtual layer-2 broadcast domain that is
+// typically reserved for the tenant who created it (unless you configure the
+// network to be shared). Tenants can create multiple networks until the
+// thresholds per-tenant quota is reached.
+//
+// In the v2.0 Networking API, the network is the main entity. Ports and subnets
+// are always associated with a network.
 package networks
diff --git a/openstack/networking/v2/networks/errors.go b/openstack/networking/v2/networks/errors.go
index 7a67ef7..83c4a6a 100644
--- a/openstack/networking/v2/networks/errors.go
+++ b/openstack/networking/v2/networks/errors.go
@@ -1,16 +1 @@
 package networks
-
-import "fmt"
-
-func requiredAttr(attr string) error {
-	return fmt.Errorf("You must specify %s for this resource", attr)
-}
-
-func err(str string) error {
-	return fmt.Errorf("%s", str)
-}
-
-var (
-	ErrNameRequired = requiredAttr("name")
-	ErrNoURLFound   = err("Next URL could not be extracted from collection")
-)
diff --git a/openstack/networking/v2/networks/requests.go b/openstack/networking/v2/networks/requests.go
index 4f1037e..f4fbe97 100644
--- a/openstack/networking/v2/networks/requests.go
+++ b/openstack/networking/v2/networks/requests.go
@@ -9,20 +9,6 @@
 	"github.com/rackspace/gophercloud/pagination"
 )
 
-type ListOpts struct {
-	Status       string
-	Name         string
-	AdminStateUp *bool
-	TenantID     string
-	Shared       *bool
-	ID           string
-	Page         int
-	PerPage      int
-	Limit        int
-	SortKey      string
-	SortDir      string
-}
-
 type networkOpts struct {
 	AdminStateUp bool
 	Name         string
@@ -40,6 +26,27 @@
 	}
 }
 
+// ListOpts allows the filtering and sorting of paginated collections through
+// the API. Filtering is achieved by passing in struct field values that map to
+// the network attributes you want to see returned. SortKey allows you to sort
+// by a particular network attribute. SortDir sets the direction, and is either
+// `asc' or `desc'. Marker and Limit are used for pagination.
+type ListOpts struct {
+	Status       string
+	Name         string
+	AdminStateUp *bool
+	TenantID     string
+	Shared       *bool
+	ID           string
+	Marker       string
+	Limit        int
+	SortKey      string
+	SortDir      string
+}
+
+// List returns a Pager which allows you to iterate over a collection of
+// networks. It accepts a ListOpts struct, which allows you to filter and sort
+// the returned collection for greater efficiency.
 func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
 	// Build query parameters
 	q := make(map[string]string)
@@ -61,11 +68,8 @@
 	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)
+	if opts.Marker != "" {
+		q["marker"] = opts.Marker
 	}
 	if opts.Limit != 0 {
 		q["limit"] = strconv.Itoa(opts.Limit)
@@ -77,15 +81,16 @@
 		q["sort_dir"] = opts.SortDir
 	}
 
-	u := ListURL(c) + utils.BuildQuery(q)
+	u := listURL(c) + utils.BuildQuery(q)
 	return pagination.NewPager(c, u, func(r pagination.LastHTTPResponse) pagination.Page {
 		return NetworkPage{pagination.LinkedPageBase(r)}
 	})
 }
 
+// Get retrieves a specific network based on its unique ID.
 func Get(c *gophercloud.ServiceClient, id string) (*Network, error) {
 	var n Network
-	_, err := perigee.Request("GET", GetURL(c, id), perigee.Options{
+	_, err := perigee.Request("GET", getURL(c, id), perigee.Options{
 		MoreHeaders: c.Provider.AuthenticatedHeaders(),
 		Results: &struct {
 			Network *Network `json:"network"`
@@ -98,13 +103,21 @@
 	return &n, nil
 }
 
+// CreateOpts represents the attributes used when creating a new network.
 type CreateOpts networkOpts
 
+// Create accepts a CreateOpts struct and creates a new network using the values
+// provided. This operation does not actually require a request body, i.e. the
+// CreateOpts struct argument can be empty.
+//
+// The tenant ID that is contained in the URI is the tenant that creates the
+// network. An admin user, however, has the option of specifying another tenant
+// ID in the CreateOpts struct.
 func Create(c *gophercloud.ServiceClient, opts CreateOpts) (*NetworkCreateResult, error) {
 	// Define structures
 	type network struct {
-		AdminStateUp bool    `json:"admin_state_up"`
-		Name         string  `json:"name"`
+		AdminStateUp bool    `json:"admin_state_up,omitempty"`
+		Name         string  `json:"name,omitempty"`
 		Shared       *bool   `json:"shared,omitempty"`
 		TenantID     *string `json:"tenant_id,omitempty"`
 	}
@@ -115,11 +128,6 @@
 		Network *NetworkCreateResult `json:"network"`
 	}
 
-	// Validate
-	if opts.Name == "" {
-		return nil, ErrNameRequired
-	}
-
 	// Populate request body
 	reqBody := request{Network: network{
 		AdminStateUp: opts.AdminStateUp,
@@ -133,7 +141,7 @@
 
 	// Send request to API
 	var res response
-	_, err := perigee.Request("POST", CreateURL(c), perigee.Options{
+	_, err := perigee.Request("POST", createURL(c), perigee.Options{
 		MoreHeaders: c.Provider.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res,
@@ -146,8 +154,11 @@
 	return res.Network, nil
 }
 
+// UpdateOpts represents the attributes used when updating an existing network.
 type UpdateOpts networkOpts
 
+// Update accepts a UpdateOpts struct and updates an existing network using the
+// values provided. For more information, see the Create function.
 func Update(c *gophercloud.ServiceClient, networkID string, opts UpdateOpts) (*Network, error) {
 	// Define structures
 	type network struct {
@@ -172,7 +183,7 @@
 
 	// Send request to API
 	var res response
-	_, err := perigee.Request("PUT", GetURL(c, networkID), perigee.Options{
+	_, err := perigee.Request("PUT", getURL(c, networkID), perigee.Options{
 		MoreHeaders: c.Provider.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
 		Results:     &res,
@@ -185,8 +196,9 @@
 	return res.Network, nil
 }
 
+// Delete accepts a unique ID and deletes the network associated with it.
 func Delete(c *gophercloud.ServiceClient, networkID string) error {
-	_, err := perigee.Request("DELETE", DeleteURL(c, networkID), perigee.Options{
+	_, err := perigee.Request("DELETE", deleteURL(c, networkID), perigee.Options{
 		MoreHeaders: c.Provider.AuthenticatedHeaders(),
 		OkCodes:     []int{204},
 	})
diff --git a/openstack/networking/v2/networks/results.go b/openstack/networking/v2/networks/results.go
index 78bdff5..7f9e51a 100644
--- a/openstack/networking/v2/networks/results.go
+++ b/openstack/networking/v2/networks/results.go
@@ -5,12 +5,14 @@
 	"github.com/rackspace/gophercloud/pagination"
 )
 
+// NetworkProvider represents provider extension data
 type NetworkProvider struct {
 	ProviderSegmentationID  int    `json:"provider:segmentation_id"`
 	ProviderPhysicalNetwork string `json:"provider:physical_network"`
 	ProviderNetworkType     string `json:"provider:network_type"`
 }
 
+// Network represents, well, a network.
 type Network struct {
 	// UUID for the network
 	ID string `mapstructure:"id" json:"id"`
@@ -34,17 +36,23 @@
 	RouterExternal          bool   `mapstructure:"router:external" json:"router:external"`
 }
 
+// NetworkCreateResult represents what is returned by a create operation.
 type NetworkCreateResult struct {
 	Network
 	Segments            []NetworkProvider `json:"segments"`
 	PortSecurityEnabled bool              `json:"port_security_enabled"`
 }
 
+// NetworkPage is the page returned by a pager when traversing over a
+// collection of networks.
 type NetworkPage struct {
 	pagination.LinkedPageBase
 }
 
-func (current NetworkPage) NextPageURL() (string, error) {
+// NextPageURL is invoked when a paginated collection of networks has reached
+// the end of a page and the pager seeks to traverse over a new one. In order
+// to do this, it needs to construct the next page's URL.
+func (p NetworkPage) NextPageURL() (string, error) {
 	type link struct {
 		Href string `mapstructure:"href"`
 		Rel  string `mapstructure:"rel"`
@@ -54,7 +62,7 @@
 	}
 
 	var r resp
-	err := mapstructure.Decode(current.Body, &r)
+	err := mapstructure.Decode(p.Body, &r)
 	if err != nil {
 		return "", err
 	}
@@ -72,14 +80,18 @@
 	return url, nil
 }
 
-func (r NetworkPage) IsEmpty() (bool, error) {
-	is, err := ExtractNetworks(r)
+// IsEmpty checks whether a NetworkPage struct is empty.
+func (p NetworkPage) IsEmpty() (bool, error) {
+	is, err := ExtractNetworks(p)
 	if err != nil {
 		return true, nil
 	}
 	return len(is) == 0, nil
 }
 
+// ExtractNetworks accepts a Page struct, specifically a NetworkPage struct,
+// and extracts the elements into a slice of Network structs. In other words,
+// a generic collection is mapped into a relevant slice.
 func ExtractNetworks(page pagination.Page) ([]Network, error) {
 	var resp struct {
 		Networks []Network `mapstructure:"networks" json:"networks"`
diff --git a/openstack/networking/v2/networks/urls.go b/openstack/networking/v2/networks/urls.go
index a0d660a..80c307c 100644
--- a/openstack/networking/v2/networks/urls.go
+++ b/openstack/networking/v2/networks/urls.go
@@ -4,26 +4,26 @@
 
 const Version = "v2.0"
 
-func ResourceURL(c *gophercloud.ServiceClient, id string) string {
+func resourceURL(c *gophercloud.ServiceClient, id string) string {
 	return c.ServiceURL(Version, "networks", id)
 }
 
-func RootURL(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 getURL(c *gophercloud.ServiceClient, id string) string {
+	return resourceURL(c, id)
 }
 
-func ListURL(c *gophercloud.ServiceClient) string {
-	return RootURL(c)
+func listURL(c *gophercloud.ServiceClient) string {
+	return rootURL(c)
 }
 
-func CreateURL(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)
+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 84a7ae6..713a547 100644
--- a/openstack/networking/v2/networks/urls_test.go
+++ b/openstack/networking/v2/networks/urls_test.go
@@ -7,32 +7,32 @@
 	th "github.com/rackspace/gophercloud/testhelper"
 )
 
-const Endpoint = "http://localhost:57909/"
+const endpoint = "http://localhost:57909/"
 
-func EndpointClient() *gophercloud.ServiceClient {
-	return &gophercloud.ServiceClient{Endpoint: Endpoint}
+func endpointClient() *gophercloud.ServiceClient {
+	return &gophercloud.ServiceClient{Endpoint: endpoint}
 }
 
 func TestGetURL(t *testing.T) {
-	actual := GetURL(EndpointClient(), "foo")
-	expected := Endpoint + "v2.0/networks/foo"
+	actual := getURL(endpointClient(), "foo")
+	expected := endpoint + "v2.0/networks/foo"
 	th.AssertEquals(t, expected, actual)
 }
 
 func TestCreateURL(t *testing.T) {
-	actual := CreateURL(EndpointClient())
-	expected := Endpoint + "v2.0/networks"
+	actual := createURL(endpointClient())
+	expected := endpoint + "v2.0/networks"
 	th.AssertEquals(t, expected, actual)
 }
 
 func TestListURL(t *testing.T) {
-	actual := CreateURL(EndpointClient())
-	expected := Endpoint + "v2.0/networks"
+	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"
+	actual := deleteURL(endpointClient(), "foo")
+	expected := endpoint + "v2.0/networks/foo"
 	th.AssertEquals(t, expected, actual)
 }