virtual interfaces operations & unit tests; networks unit tests
diff --git a/rackspace/networking/v2/networks/delegate.go b/rackspace/networking/v2/networks/delegate.go
deleted file mode 100644
index e040d58..0000000
--- a/rackspace/networking/v2/networks/delegate.go
+++ /dev/null
@@ -1,11 +0,0 @@
-package networks
-
-import (
-  "github.com/rackspace/gophercloud"
-  os "github.com/rackspace/gophercloud/openstack/networking/v2/networks"
-)
-
-// Delete accepts a unique ID and deletes the network associated with it.
-func Delete(c *gophercloud.ServiceClient, id string) os.DeleteResult {
-  return os.Delete(c, id)
-}
diff --git a/rackspace/networking/v2/networks/delegate_test.go b/rackspace/networking/v2/networks/delegate_test.go
deleted file mode 100644
index 83c4a6a..0000000
--- a/rackspace/networking/v2/networks/delegate_test.go
+++ /dev/null
@@ -1 +0,0 @@
-package networks
diff --git a/rackspace/networking/v2/networks/requests.go b/rackspace/networking/v2/networks/requests.go
index f7896b8..f55aa6c 100644
--- a/rackspace/networking/v2/networks/requests.go
+++ b/rackspace/networking/v2/networks/requests.go
@@ -1,33 +1,34 @@
 package networks
 
 import (
-  "errors"
+	"errors"
 
-  "github.com/rackspace/gophercloud"
-  "github.com/rackspace/gophercloud/pagination"
+	"github.com/rackspace/gophercloud"
+	"github.com/rackspace/gophercloud/pagination"
 
-  "github.com/racker/perigee"
+	"github.com/racker/perigee"
 )
 
 // 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) pagination.Pager {
-  url := listURL(c)
-  return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page {
-    return NetworkPage{pagination.SinglePageBase{PageResult: r}}
-  })
+	createPage := func(r pagination.PageResult) pagination.Page {
+		return NetworkPage{pagination.SinglePageBase(r)}
+	}
+
+	return pagination.NewPager(c, listURL(c), createPage)
 }
 
 // Get retrieves a specific network based on its unique ID.
 func Get(c *gophercloud.ServiceClient, id string) GetResult {
-  var res GetResult
-  _, res.Err = perigee.Request("GET", getURL(c, id), perigee.Options{
-    MoreHeaders: c.Provider.AuthenticatedHeaders(),
-    Results:     &res.Body,
-    OkCodes:     []int{200},
-  })
-  return res
+	var res GetResult
+	_, res.Err = perigee.Request("GET", getURL(c, id), perigee.Options{
+		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		Results:     &res.Body,
+		OkCodes:     []int{200},
+	})
+	return res
 }
 
 // CreateOptsBuilder is the interface options structs have to satisfy in order
@@ -35,32 +36,32 @@
 // extensions decorate or modify the common logic, it is useful for them to
 // satisfy a basic interface in order for them to be used.
 type CreateOptsBuilder interface {
-  ToNetworkCreateMap() (map[string]interface{}, error)
+	ToNetworkCreateMap() (map[string]interface{}, error)
 }
 
 // CreateOpts is the common options struct used in this package's Create
 // operation.
-type CreateOpts struct{
-  // REQUIRED. See Network object for more info.
-  CIDR string
-  // REQUIRED. See Network object for more info.
-  Label string
+type CreateOpts struct {
+	// REQUIRED. See Network object for more info.
+	CIDR string
+	// REQUIRED. See Network object for more info.
+	Label string
 }
 
 // ToNetworkCreateMap casts a CreateOpts struct to a map.
 func (opts CreateOpts) ToNetworkCreateMap() (map[string]interface{}, error) {
-  n := make(map[string]interface{})
+	n := make(map[string]interface{})
 
-  if opts.CIDR == "" {
-    return nil, errors.New("Required field CIDR not set.")
-  }
-  if opts.Label == "" {
-    return nil, errors.New("Required field Label not set.")
-  }
+	if opts.CIDR == "" {
+		return nil, errors.New("Required field CIDR not set.")
+	}
+	if opts.Label == "" {
+		return nil, errors.New("Required field Label not set.")
+	}
 
-  n["label"] = opts.Label
-  n["cidr"] = opts.CIDR
-  return map[string]interface{}{"network": n}, nil
+	n["label"] = opts.Label
+	n["cidr"] = opts.CIDR
+	return map[string]interface{}{"network": n}, nil
 }
 
 // Create accepts a CreateOpts struct and creates a new network using the values
@@ -71,20 +72,30 @@
 // network. An admin user, however, has the option of specifying another tenant
 // ID in the CreateOpts struct.
 func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
-  var res CreateResult
+	var res CreateResult
 
-  reqBody, err := opts.ToNetworkCreateMap()
-  if err != nil {
-    res.Err = err
-    return res
-  }
+	reqBody, err := opts.ToNetworkCreateMap()
+	if err != nil {
+		res.Err = err
+		return res
+	}
 
-  // Send request to API
-  _, res.Err = perigee.Request("POST", createURL(c), perigee.Options{
-    MoreHeaders: c.Provider.AuthenticatedHeaders(),
-    ReqBody:     &reqBody,
-    Results:     &res.Body,
-    OkCodes:     []int{201},
-  })
-  return res
+	// Send request to API
+	_, res.Err = perigee.Request("POST", createURL(c), perigee.Options{
+		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		ReqBody:     &reqBody,
+		Results:     &res.Body,
+		OkCodes:     []int{201, 202},
+	})
+	return res
+}
+
+// Delete accepts a unique ID and deletes the network associated with it.
+func Delete(c *gophercloud.ServiceClient, networkID string) DeleteResult {
+	var res DeleteResult
+	_, res.Err = perigee.Request("DELETE", deleteURL(c, networkID), perigee.Options{
+		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		OkCodes:     []int{204},
+	})
+	return res
 }
diff --git a/rackspace/networking/v2/networks/requests_test.go b/rackspace/networking/v2/networks/requests_test.go
index 83c4a6a..441c450 100644
--- a/rackspace/networking/v2/networks/requests_test.go
+++ b/rackspace/networking/v2/networks/requests_test.go
@@ -1 +1,160 @@
 package networks
+
+import (
+	"fmt"
+	"net/http"
+	"testing"
+
+	"github.com/rackspace/gophercloud/pagination"
+	th "github.com/rackspace/gophercloud/testhelper"
+	fake "github.com/rackspace/gophercloud/testhelper/client"
+)
+
+func TestList(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+
+	th.Mux.HandleFunc("/os-networksv2", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "GET")
+		th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
+
+		w.Header().Add("Content-Type", "application/json")
+		w.WriteHeader(http.StatusOK)
+
+		fmt.Fprintf(w, `
+{
+    "networks": [
+        {
+            "label": "test-network-1",
+            "cidr": "192.168.100.0/24",
+            "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22"
+        },
+        {
+            "label": "test-network-2",
+            "cidr": "192.30.250.00/18",
+            "id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324"
+        }
+    ]
+}
+      `)
+	})
+
+	client := fake.ServiceClient()
+	count := 0
+
+	List(client).EachPage(func(page pagination.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{
+				Label: "test-network-1",
+				CIDR:  "192.168.100.0/24",
+				ID:    "d32019d3-bc6e-4319-9c1d-6722fc136a22",
+			},
+			Network{
+				Label: "test-network-2",
+				CIDR:  "192.30.250.00/18",
+				ID:    "db193ab3-96e3-4cb3-8fc5-05f4296d0324",
+			},
+		}
+
+		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()
+
+	th.Mux.HandleFunc("/os-networksv2/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "GET")
+		th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
+
+		w.Header().Add("Content-Type", "application/json")
+		w.WriteHeader(http.StatusOK)
+
+		fmt.Fprintf(w, `
+{
+    "network": {
+        "label": "test-network-1",
+        "cidr": "192.168.100.0/24",
+        "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22"
+    }
+}
+      `)
+	})
+
+	n, err := Get(fake.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22").Extract()
+	th.AssertNoErr(t, err)
+
+	th.AssertEquals(t, n.CIDR, "192.168.100.0/24")
+	th.AssertEquals(t, n.Label, "test-network-1")
+	th.AssertEquals(t, n.ID, "d32019d3-bc6e-4319-9c1d-6722fc136a22")
+}
+
+func TestCreate(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+
+	th.Mux.HandleFunc("/os-networksv2", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "POST")
+		th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
+		th.TestHeader(t, r, "Content-Type", "application/json")
+		th.TestHeader(t, r, "Accept", "application/json")
+		th.TestJSONRequest(t, r, `
+{
+    "network": {
+        "label": "test-network-1",
+        "cidr": "192.168.100.0/24"
+    }
+}
+      `)
+
+		w.Header().Add("Content-Type", "application/json")
+		w.WriteHeader(http.StatusCreated)
+
+		fmt.Fprintf(w, `
+{
+    "network": {
+        "label": "test-network-1",
+        "cidr": "192.168.100.0/24",
+        "id": "4e8e5957-649f-477b-9e5b-f1f75b21c03c"
+    }
+}
+    `)
+	})
+
+	options := CreateOpts{Label: "test-network-1", CIDR: "192.168.100.0/24"}
+	n, err := Create(fake.ServiceClient(), options).Extract()
+	th.AssertNoErr(t, err)
+
+	th.AssertEquals(t, n.Label, "test-network-1")
+	th.AssertEquals(t, n.ID, "4e8e5957-649f-477b-9e5b-f1f75b21c03c")
+}
+
+func TestDelete(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+
+	th.Mux.HandleFunc("/os-networksv2/4e8e5957-649f-477b-9e5b-f1f75b21c03c", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "DELETE")
+		th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
+		w.WriteHeader(http.StatusNoContent)
+	})
+
+	s := fake.ServiceClient()
+	t.Logf("fake.serviceclient: %+v\n", s)
+	res := Delete(s, "4e8e5957-649f-477b-9e5b-f1f75b21c03c")
+	th.AssertNoErr(t, res.Err)
+}
diff --git a/rackspace/networking/v2/networks/results.go b/rackspace/networking/v2/networks/results.go
index 2334faf..823c56e 100644
--- a/rackspace/networking/v2/networks/results.go
+++ b/rackspace/networking/v2/networks/results.go
@@ -1,38 +1,38 @@
 package networks
 
 import (
-  "github.com/mitchellh/mapstructure"
-  "github.com/rackspace/gophercloud"
-  "github.com/rackspace/gophercloud/pagination"
+	"github.com/mitchellh/mapstructure"
+	"github.com/rackspace/gophercloud"
+	"github.com/rackspace/gophercloud/pagination"
 )
 
 type commonResult struct {
-  gophercloud.Result
+	gophercloud.Result
 }
 
 // Extract is a function that accepts a result and extracts a network resource.
 func (r commonResult) Extract() (*Network, error) {
-  if r.Err != nil {
-    return nil, r.Err
-  }
+	if r.Err != nil {
+		return nil, r.Err
+	}
 
-  var res struct {
-    Network *Network `json:"network"`
-  }
+	var res struct {
+		Network *Network `json:"network"`
+	}
 
-  err := mapstructure.Decode(r.Body, &res)
+	err := mapstructure.Decode(r.Body, &res)
 
-  return res.Network, err
+	return res.Network, err
 }
 
 // CreateResult represents the result of a create operation.
 type CreateResult struct {
-  commonResult
+	commonResult
 }
 
 // GetResult represents the result of a get operation.
 type GetResult struct {
-  commonResult
+	commonResult
 }
 
 // DeleteResult represents the result of a delete operation.
@@ -40,31 +40,40 @@
 
 // Network represents, well, a network.
 type Network struct {
-  // UUID for the network
-  ID string `mapstructure:"id" json:"id"`
+	// UUID for the network
+	ID string `mapstructure:"id" json:"id"`
 
-  // Human-readable name for the network. Might not be unique.
-  Label string `mapstructure:"label" json:"label"`
+	// Human-readable name for the network. Might not be unique.
+	Label string `mapstructure:"label" json:"label"`
 
-  // Classless Inter-Domain Routing
-  CIDR string `mapstructure:"cidr" json:"cidr"`
+	// Classless Inter-Domain Routing
+	CIDR string `mapstructure:"cidr" json:"cidr"`
 }
 
 // NetworkPage is the page returned by a pager when traversing over a
 // collection of networks.
 type NetworkPage struct {
-  pagination.SinglePageBase
+	pagination.SinglePageBase
+}
+
+// IsEmpty returns true if the NetworkPage contains no Networks.
+func (r NetworkPage) IsEmpty() (bool, error) {
+	networks, err := ExtractNetworks(r)
+	if err != nil {
+		return true, err
+	}
+	return len(networks) == 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"`
-  }
+	var resp struct {
+		Networks []Network `mapstructure:"networks" json:"networks"`
+	}
 
-  err := mapstructure.Decode(page.(NetworkPage).Body, &resp)
+	err := mapstructure.Decode(page.(NetworkPage).Body, &resp)
 
-  return resp.Networks, err
+	return resp.Networks, err
 }
diff --git a/rackspace/networking/v2/networks/urls.go b/rackspace/networking/v2/networks/urls.go
index 65d843b..19a21aa 100644
--- a/rackspace/networking/v2/networks/urls.go
+++ b/rackspace/networking/v2/networks/urls.go
@@ -3,25 +3,25 @@
 import "github.com/rackspace/gophercloud"
 
 func resourceURL(c *gophercloud.ServiceClient, id string) string {
-  return c.ServiceURL("os-networksv2", id)
+	return c.ServiceURL("os-networksv2", id)
 }
 
 func rootURL(c *gophercloud.ServiceClient) string {
-  return c.ServiceURL("networks")
+	return c.ServiceURL("os-networksv2")
 }
 
 func getURL(c *gophercloud.ServiceClient, id string) string {
-  return resourceURL(c, id)
+	return resourceURL(c, id)
 }
 
 func listURL(c *gophercloud.ServiceClient) string {
-  return rootURL(c)
+	return rootURL(c)
 }
 
 func createURL(c *gophercloud.ServiceClient) string {
-  return rootURL(c)
+	return rootURL(c)
 }
 
 func deleteURL(c *gophercloud.ServiceClient, id string) string {
-  return resourceURL(c, id)
+	return resourceURL(c, id)
 }
diff --git a/rackspace/networking/v2/networks/urls_test.go b/rackspace/networking/v2/networks/urls_test.go
index 2e064b0..983992e 100644
--- a/rackspace/networking/v2/networks/urls_test.go
+++ b/rackspace/networking/v2/networks/urls_test.go
@@ -1,38 +1,38 @@
 package networks
 
 import (
-  "testing"
+	"testing"
 
-  "github.com/rackspace/gophercloud"
-  th "github.com/rackspace/gophercloud/testhelper"
+	"github.com/rackspace/gophercloud"
+	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}
+	return &gophercloud.ServiceClient{Endpoint: endpoint}
 }
 
 func TestGetURL(t *testing.T) {
-  actual := getURL(endpointClient(), "foo")
-  expected := endpoint + "os-networksv2/foo"
-  th.AssertEquals(t, expected, actual)
+	actual := getURL(endpointClient(), "foo")
+	expected := endpoint + "os-networksv2/foo"
+	th.AssertEquals(t, expected, actual)
 }
 
 func TestCreateURL(t *testing.T) {
-  actual := createURL(endpointClient())
-  expected := endpoint + "os-networksv2"
-  th.AssertEquals(t, expected, actual)
+	actual := createURL(endpointClient())
+	expected := endpoint + "os-networksv2"
+	th.AssertEquals(t, expected, actual)
 }
 
 func TestListURL(t *testing.T) {
-  actual := createURL(endpointClient())
-  expected := endpoint + "os-networksv2"
-  th.AssertEquals(t, expected, actual)
+	actual := createURL(endpointClient())
+	expected := endpoint + "os-networksv2"
+	th.AssertEquals(t, expected, actual)
 }
 
 func TestDeleteURL(t *testing.T) {
-  actual := deleteURL(endpointClient(), "foo")
-  expected := endpoint + "os-networksv2/foo"
-  th.AssertEquals(t, expected, actual)
+	actual := deleteURL(endpointClient(), "foo")
+	expected := endpoint + "os-networksv2/foo"
+	th.AssertEquals(t, expected, actual)
 }